"),rowsCache[t].cellRenderQueue.push(o),rowsCache[t].cellColSpans[o]=n}function cleanupRows(e){for(var t in rowsCache)(t=parseInt(t,10))!==activeRow&&(te.bottom)&&removeRowFromCache(t);options.enableAsyncPostRenderCleanup&&startPostProcessingCleanup()}function invalidate(){updateRowCount(),invalidateAllRows(),render()}function invalidateAllRows(){currentEditor&&makeActiveCellNormal();for(var e in rowsCache)removeRowFromCache(e);options.enableAsyncPostRenderCleanup&&startPostProcessingCleanup()}function queuePostProcessedRowForCleanup(e,t,o){postProcessgroupId++;for(var n in t)t.hasOwnProperty(n)&&postProcessedCleanupQueue.push({actionType:"C",groupId:postProcessgroupId,node:e.cellNodesByColumnIdx[0|n],columnIdx:0|n,rowIdx:o});postProcessedCleanupQueue.push({actionType:"R",groupId:postProcessgroupId,node:e.rowNode}),(0,_jquery2.default)(e.rowNode).detach()}function queuePostProcessedCellForCleanup(e,t,o){postProcessedCleanupQueue.push({actionType:"C",groupId:postProcessgroupId,node:e,columnIdx:t,rowIdx:o}),(0,_jquery2.default)(e).detach()}function removeRowFromCache(e){var t=rowsCache[e];t&&(rowNodeFromLastMouseWheelEvent===t.rowNode?(t.rowNode.style.display="none",zombieRowNodeFromLastMouseWheelEvent=rowNodeFromLastMouseWheelEvent,zombieRowCacheFromLastMouseWheelEvent=t,zombieRowPostProcessedFromLastMouseWheelEvent=postProcessedRows[e]):options.enableAsyncPostRenderCleanup&&postProcessedRows[e]?queuePostProcessedRowForCleanup(t,postProcessedRows[e],e):$canvas[0].removeChild(t.rowNode),delete rowsCache[e],delete postProcessedRows[e],renderedRows--,counter_rows_removed++)}function invalidateRows(e){var t,o;if(e&&e.length){for(vScrollDir=0,t=0,o=e.length;tviewportH,viewportHasHScroll=canvasWidth>viewportW-scrollbarDimensions.width,makeActiveCellNormal();var r=e-1;for(var i in rowsCache)i>r&&removeRowFromCache(i);options.enableAsyncPostRenderCleanup&&startPostProcessingCleanup(),activeCellNode&&activeRow>r&&resetActiveCell();var s=h;th=Math.max(options.rowHeight*t,viewportH-scrollbarDimensions.height),the.rightPx||columnPosRight[Math.min(columns.length-1,i+s-1)]e.rightPx);u++)if(null==(n=t.cellColSpans[u])){if(n=1,c){var p=c[columns[u].id]||c[u];n=p&&p.colspan||1,"*"===n&&(n=h-u)}columnPosRight[Math.min(h-1,u+n-1)]>e.leftPx&&(appendCellHtml(r,l,u,n,d),o++),u+=n>1?n-1:0}else u+=n>1?n-1:0;o&&(s+=o,i.push(l))}if(r.length){var f=document.createElement("div");f.innerHTML=r.join("");for(var g,v;null!=(g=i.pop());){t=rowsCache[g];for(var m;null!=(m=t.cellRenderQueue.pop());)v=f.lastChild,t.rowNode.appendChild(v),t.cellNodesByColumnIdx[m]=v}}}function renderRows(e){for(var t=$canvas[0],o=[],n=[],r=!1,i=getDataLength(),s=e.top,l=e.bottom;s<=l;s++)rowsCache[s]||(renderedRows++,n.push(s),rowsCache[s]={rowNode:null,cellColSpans:[],cellNodesByColumnIdx:[],cellRenderQueue:[]},appendRowHtml(o,s,e,i),activeCellNode&&activeRow===s&&(r=!0),counter_rows_rendered++);if(n.length){var a=document.createElement("div");a.innerHTML=o.join("");for(var s=0,l=n.length;s20||Math.abs(lastRenderedScrollLeft-scrollLeft)>20)&&(options.forceSyncScrolling||Math.abs(lastRenderedScrollTop-scrollTop)=0?postProcessFromRow++:postProcessToRow--,o=rowsCache[t];if(o&&!(t>=e)){postProcessedRows[t]||(postProcessedRows[t]={}),ensureCellNodesInRowsCache(t);for(var n in o.cellNodesByColumnIdx)if(o.cellNodesByColumnIdx.hasOwnProperty(n)){n|=0;var r=columns[n],i=postProcessedRows[t][n];if(r.asyncPostRender&&"R"!==i){var s=o.cellNodesByColumnIdx[n];s&&r.asyncPostRender(s,t,getDataItem(t),r,"C"===i),postProcessedRows[t][n]="R"}}return void(h_postrender=setTimeout(asyncPostProcessRows,options.asyncPostRenderDelay))}}}function asyncPostProcessCleanupRows(){if(postProcessedCleanupQueue.length>0){for(var e=postProcessedCleanupQueue[0].groupId;postProcessedCleanupQueue.length>0&&postProcessedCleanupQueue[0].groupId==e;){var t=postProcessedCleanupQueue.shift();if("R"==t.actionType&&(0,_jquery2.default)(t.node).remove(),"C"==t.actionType){var o=columns[t.columnIdx];
+o.asyncPostRenderCleanup&&t.node&&o.asyncPostRenderCleanup(t.node,t.rowIdx,o)}}h_postrenderCleanup=setTimeout(asyncPostProcessCleanupRows,options.asyncPostRenderCleanupDelay)}}function updateCellCssStylesOnRenderedRows(e,t){var o,n,r,i;for(var s in rowsCache){if(i=t&&t[s],r=e&&e[s],i)for(n in i)r&&i[n]==r[n]||(o=getCellNode(s,getColumnIndex(n)),o&&(0,_jquery2.default)(o).removeClass(i[n]));if(r)for(n in r)i&&i[n]==r[n]||(o=getCellNode(s,getColumnIndex(n)),o&&(0,_jquery2.default)(o).addClass(r[n]))}}function addCellCssStyles(e,t){if(cellCssClasses[e])throw"addCellCssStyles: cell CSS hash with key '"+e+"' already exists.";cellCssClasses[e]=t,updateCellCssStylesOnRenderedRows(t,null),trigger(self.onCellCssStylesChanged,{key:e,hash:t,grid:self})}function removeCellCssStyles(e){cellCssClasses[e]&&(updateCellCssStylesOnRenderedRows(null,cellCssClasses[e]),delete cellCssClasses[e],trigger(self.onCellCssStylesChanged,{key:e,hash:null,grid:self}))}function setCellCssStyles(e,t){var o=cellCssClasses[e];cellCssClasses[e]=t,updateCellCssStylesOnRenderedRows(t,o),trigger(self.onCellCssStylesChanged,{key:e,hash:t,grid:self})}function getCellCssStyles(e){return cellCssClasses[e]}function flashCell(e,t,o){if(o=o||100,rowsCache[e]){var n=function e(t){t&&setTimeout(function(){r.queue(function(){r.toggleClass(options.cellFlashingCssClass).dequeue(),e(t-1)})},o)},r=(0,_jquery2.default)(getCellNode(e,t));n(4)}}function handleMouseWheel(e){var t=(0,_jquery2.default)(e.target).closest(".slick-row")[0];t!=rowNodeFromLastMouseWheelEvent&&(zombieRowNodeFromLastMouseWheelEvent&&zombieRowNodeFromLastMouseWheelEvent!=t&&(options.enableAsyncPostRenderCleanup&&zombieRowPostProcessedFromLastMouseWheelEvent?queuePostProcessedRowForCleanup(zombieRowCacheFromLastMouseWheelEvent,zombieRowPostProcessedFromLastMouseWheelEvent):$canvas[0].removeChild(zombieRowNodeFromLastMouseWheelEvent),zombieRowNodeFromLastMouseWheelEvent=null,zombieRowCacheFromLastMouseWheelEvent=null,zombieRowPostProcessedFromLastMouseWheelEvent=null,options.enableAsyncPostRenderCleanup&&startPostProcessingCleanup()),rowNodeFromLastMouseWheelEvent=t)}function handleDragStart(e){var t=_jquery2.default.Event(e.originalEvent.type,e.originalEvent),o=getCellFromEvent(t);if(!o||!cellExists(o.row,o.cell))return!1;var n=trigger(self.onDragStart,e,t);return!!t.isImmediatePropagationStopped()&&n}function handleDrag(e){var t=_jquery2.default.Event(e.originalEvent.type,e.originalEvent);return trigger(self.onDrag,e,t)}function handleDragEnd(e){trigger(self.onDragEnd,e,_jquery2.default.Event("mousedown"))}function handleKeyDown(e){trigger(self.onKeyDown,{row:activeRow,cell:activeCell,grid:self},e);var t=e.isImmediatePropagationStopped(),o=_slick2.default.keyCode;if(!t)if(e.shiftKey||e.altKey||e.ctrlKey)e.which!=o.TAB||!e.shiftKey||e.ctrlKey||e.altKey||(t=navigatePrev());else{if(options.editable&¤tEditor&¤tEditor.keyCaptureList&¤tEditor.keyCaptureList.indexOf(e.which)>-1)return;if(e.which==o.ESCAPE){if(!getEditorLock().isActive())return;cancelEditAndSetFocus()}else e.which==o.PAGE_DOWN?(navigatePageDown(),t=!0):e.which==o.PAGE_UP?(navigatePageUp(),t=!0):e.which==o.LEFT?t=navigateLeft():e.which==o.RIGHT?t=navigateRight():e.which==o.UP?t=navigateUp():e.which==o.DOWN?t=navigateDown():e.which==o.TAB?t=navigateNext():e.which==o.ENTER&&(options.editable&&(currentEditor?activeRow===getDataLength()?navigateDown():commitEditAndSetFocus():getEditorLock().commitCurrentEdit()&&makeActiveCellEditable()),t=!0)}if(t){e.stopPropagation(),e.preventDefault();try{e.originalEvent.keyCode=0}catch(e){}}}function handleClick(e){currentEditor||(e.target!=document.activeElement||(0,_jquery2.default)(e.target).hasClass("slick-cell"))&&setFocus();var t=getCellFromEvent(e);!t||null!==currentEditor&&activeRow==t.row&&activeCell==t.cell||(trigger(self.onClick,{row:t.row,cell:t.cell,grid:self},e),e.isImmediatePropagationStopped()||activeCell==t.cell&&activeRow==t.row||!canCellBeActive(t.row,t.cell)||getEditorLock().isActive()&&!getEditorLock().commitCurrentEdit()||(scrollRowIntoView(t.row,!1),setActiveCellInternal(getCellNode(t.row,t.cell))))}function handleContextMenu(e){var t=(0,_jquery2.default)(e.target).closest(".slick-cell",$canvas);0!==t.length&&(activeCellNode===t[0]&&null!==currentEditor||trigger(self.onContextMenu,{grid:self},e))}function handleDblClick(e){var t=getCellFromEvent(e);!t||null!==currentEditor&&activeRow==t.row&&activeCell==t.cell||(trigger(self.onDblClick,{row:t.row,cell:t.cell,grid:self},e),e.isImmediatePropagationStopped()||options.editable&&gotoCell(t.row,t.cell,!0))}function handleHeaderMouseEnter(e){trigger(self.onHeaderMouseEnter,{column:(0,_jquery2.default)(this).data("column"),grid:self},e)}function handleHeaderMouseLeave(e){trigger(self.onHeaderMouseLeave,{column:(0,_jquery2.default)(this).data("column"),grid:self},e)}function handleHeaderContextMenu(e){var t=(0,_jquery2.default)(e.target).closest(".slick-header-column",".slick-header-columns"),o=t&&t.data("column");trigger(self.onHeaderContextMenu,{column:o,grid:self},e)}function handleHeaderClick(e){var t=(0,_jquery2.default)(e.target).closest(".slick-header-column",".slick-header-columns"),o=t&&t.data("column");o&&trigger(self.onHeaderClick,{column:o,grid:self},e)}function handleMouseEnter(e){trigger(self.onMouseEnter,{grid:self},e)}function handleMouseLeave(e){trigger(self.onMouseLeave,{grid:self},e)}function cellExists(e,t){return!(e<0||e>=getDataLength()||t<0||t>=columns.length)}function getCellFromPoint(e,t){for(var o=getRowFromPosition(t),n=0,r=0,i=0;i1?n-1:0)],s=scrollLeft+viewportW;rs&&($viewport.scrollLeft(Math.min(r,i-$viewport[0].clientWidth)),handleScroll(),render())}function setActiveCellInternal(e,t){null!==activeCellNode&&(makeActiveCellNormal(),(0,_jquery2.default)(activeCellNode).removeClass("active"),rowsCache[activeRow]&&(0,_jquery2.default)(rowsCache[activeRow].rowNode).removeClass("active"));var o=activeCellNode!==e;activeCellNode=e,null!=activeCellNode?(activeRow=getRowFromNode(activeCellNode.parentNode),activeCell=activePosX=getCellFromNode(activeCellNode),null==t&&(t=activeRow==getDataLength()||options.autoEdit),(0,_jquery2.default)(activeCellNode).addClass("active"),(0,_jquery2.default)(rowsCache[activeRow].rowNode).addClass("active"),options.editable&&t&&isCellPotentiallyEditable(activeRow,activeCell)&&(clearTimeout(h_editorLoader),options.asyncEditorLoading?h_editorLoader=setTimeout(function(){makeActiveCellEditable()},options.asyncEditorLoadDelay):makeActiveCellEditable())):activeRow=activeCell=null,o&&trigger(self.onActiveCellChanged,getActiveCell())}function clearTextSelection(){if(document.selection&&document.selection.empty)try{document.selection.empty()}catch(e){}else if(window.getSelection){var e=window.getSelection();e&&e.removeAllRanges&&e.removeAllRanges()}}function isCellPotentiallyEditable(e,t){var o=getDataLength();return!(e=o)&&!!getEditor(e,t))}function makeActiveCellNormal(){if(currentEditor){if(trigger(self.onBeforeCellEditorDestroy,{editor:currentEditor,grid:self}),currentEditor.destroy(),currentEditor=null,activeCellNode){var e=getDataItem(activeRow);if((0,_jquery2.default)(activeCellNode).removeClass("editable invalid"),e){var t=columns[activeCell],o=getFormatter(activeRow,t);activeCellNode.innerHTML=o(activeRow,activeCell,getDataItemValueForColumn(e,t),t,e,self),invalidatePostProcessingResults(activeRow)}}navigator.userAgent.toLowerCase().match(/msie/)&&clearTextSelection(),getEditorLock().deactivate(editController)}}function makeActiveCellEditable(e){if(activeCellNode){if(!options.editable)throw"Grid : makeActiveCellEditable : should never get called when options.editable is false";if(clearTimeout(h_editorLoader),isCellPotentiallyEditable(activeRow,activeCell)){var t=columns[activeCell],o=getDataItem(activeRow);if(trigger(self.onBeforeEditCell,{row:activeRow,cell:activeCell,item:o,column:t,grid:self})===!1)return void setFocus();getEditorLock().activate(editController),(0,_jquery2.default)(activeCellNode).addClass("editable");var n=e||getEditor(activeRow,activeCell);e||n.suppressClearOnEdit||(activeCellNode.innerHTML=""),currentEditor=new n({grid:self,gridPosition:absBox($container[0]),position:absBox(activeCellNode),container:activeCellNode,column:t,item:o||{},commitChanges:commitEditAndSetFocus,cancelChanges:cancelEditAndSetFocus}),o&¤tEditor.loadValue(o),serializedEditorValue=currentEditor.serializeValue(),currentEditor.position&&handleActiveCellPositionChange()}}}function commitEditAndSetFocus(){getEditorLock().commitCurrentEdit()&&(setFocus(),options.autoEdit&&navigateDown())}function cancelEditAndSetFocus(){getEditorLock().cancelCurrentEdit()&&setFocus()}function absBox(e){var t={top:e.offsetTop,left:e.offsetLeft,bottom:0,right:0,width:(0,_jquery2.default)(e).outerWidth(),height:(0,_jquery2.default)(e).outerHeight(),visible:!0};t.bottom=t.top+t.height,t.right=t.left+t.width;for(var o=e.offsetParent;(e=e.parentNode)!=document.body&&null!=e;)t.visible&&e.scrollHeight!=e.offsetHeight&&"visible"!=(0,_jquery2.default)(e).css("overflowY")&&(t.visible=t.bottom>e.scrollTop&&t.tope.scrollLeft&&t.leftscrollTop+viewportH+offset?(scrollTo(t?o:n),render()):e*options.rowHeight=n&&(o=n-1),o<0&&(o=0);for(var r=0,i=null,s=activePosX;r<=activePosX;)canCellBeActive(o,r)&&(i=r),r+=getColspan(o,r);null!==i?(setActiveCellInternal(getCellNode(o,i)),activePosX=s):resetActiveCell()}}function navigatePageDown(){scrollPage(1)}function navigatePageUp(){scrollPage(-1)}function getColspan(e,t){var o=data.getItemMetadata&&data.getItemMetadata(e);if(!o||!o.columns)return 1;var n=o.columns[columns[t].id]||o.columns[t],r=n&&n.colspan;return r="*"===r?columns.length-t:r||1}function findFirstFocusableCell(e){for(var t=0;t=columns.length)return null;do t+=getColspan(e,t);while(t=t)return null;for(var r,i={row:e,cell:n,posX:n};;){if(r=gotoRight(i.row,i.cell,i.posX),!r)return null;if(r.cell>=t)return i;i=r}}function gotoDown(e,t,o){for(var n,r=getDataLengthIncludingAddNew();;){if(++e>=r)return null;for(n=t=0;t<=o;)n=t,t+=getColspan(e,t);if(canCellBeActive(e,n))return{row:e,cell:n,posX:o}}}function gotoUp(e,t,o){for(var n;;){if(--e<0)return null;for(n=t=0;t<=o;)n=t,t+=getColspan(e,t);if(canCellBeActive(e,n))return{row:e,cell:n,posX:o}}}function gotoNext(e,t,o){if(null==e&&null==t&&(e=t=o=0,canCellBeActive(e,t)))return{row:e,cell:t,posX:t};var n=gotoRight(e,t,o);if(n)return n;for(var r=null,i=getDataLengthIncludingAddNew();++egetDataLength()||e<0||t>=columns.length||t<0||options.enableCellNavigation&&(scrollCellIntoView(e,t,!1),setActiveCellInternal(getCellNode(e,t),!1)))}function canCellBeActive(e,t){if(!options.enableCellNavigation||e>=getDataLengthIncludingAddNew()||e<0||t>=columns.length||t<0)return!1;var o=data.getItemMetadata&&data.getItemMetadata(e);if(o&&"boolean"==typeof o.focusable)return o.focusable;var n=o&&o.columns;return n&&n[columns[t].id]&&"boolean"==typeof n[columns[t].id].focusable?n[columns[t].id].focusable:n&&n[t]&&"boolean"==typeof n[t].focusable?n[t].focusable:columns[t].focusable}function canCellBeSelected(e,t){if(e>=getDataLength()||e<0||t>=columns.length||t<0)return!1;var o=data.getItemMetadata&&data.getItemMetadata(e);if(o&&"boolean"==typeof o.selectable)return o.selectable;var n=o&&o.columns&&(o.columns[columns[t].id]||o.columns[t]);return n&&"boolean"==typeof n.selectable?n.selectable:columns[t].selectable}function gotoCell(e,t,o){if(initialized&&canCellBeActive(e,t)&&getEditorLock().commitCurrentEdit()){scrollCellIntoView(e,t,!1);var n=getCellNode(e,t);setActiveCellInternal(n,o||e===getDataLength()||options.autoEdit),currentEditor||setFocus()}}function commitCurrentEdit(){var e=getDataItem(activeRow),t=columns[activeCell];if(currentEditor){if(currentEditor.isValueChanged()){var o=currentEditor.validate();if(o.valid){if(activeRow"+i.title+""}function o(e,t,o,n,r){return n.groupTotalsFormatter&&n.groupTotalsFormatter(r,n)||""}function n(e){u=e,u.onClick.subscribe(i),u.onKeyDown.subscribe(l)}function r(){u&&(u.onClick.unsubscribe(i),u.onKeyDown.unsubscribe(l))}function i(t,o){var n=this.getDataItem(o.row);if(n&&n instanceof a.default.Group&&(0,s.default)(t.target).hasClass(e.toggleCssClass)){var r=u.getRenderedRange();this.getData().setRefreshHints({ignoreDiffsBefore:r.top,ignoreDiffsAfter:r.bottom+1}),n.collapsed?this.getData().expandGroup(n.groupingKey):this.getData().collapseGroup(n.groupingKey),t.stopImmediatePropagation(),t.preventDefault()}}function l(t){if(e.enableExpandCollapse&&t.which==a.default.keyCode.SPACE){var o=this.getActiveCell();if(o){var n=this.getDataItem(o.row);if(n&&n instanceof a.default.Group){var r=u.getRenderedRange();this.getData().setRefreshHints({ignoreDiffsBefore:r.top,ignoreDiffsAfter:r.bottom+1}),n.collapsed?this.getData().expandGroup(n.groupingKey):this.getData().collapseGroup(n.groupingKey),t.stopImmediatePropagation(),t.preventDefault()}}}}function c(t){return{selectable:!1,focusable:e.groupFocusable,cssClasses:e.groupCssClass,columns:{0:{colspan:"*",formatter:e.groupFormatter,editor:null}}}}function d(t){return{selectable:!1,focusable:e.totalsFocusable,cssClasses:e.totalsCssClass,formatter:e.totalsFormatter,editor:null}}var u=void 0,h={groupCssClass:"slick-group",groupTitleCssClass:"slick-group-title",totalsCssClass:"slick-group-totals",groupFocusable:!0,totalsFocusable:!1,toggleCssClass:"slick-group-toggle",toggleExpandedCssClass:"expanded",toggleCollapsedCssClass:"collapsed",enableExpandCollapse:!0,groupFormatter:t,totalsFormatter:o};return e=s.default.extend(!0,{},h,e),{init:n,destroy:r,getGroupRowMetadata:c,getTotalsRowMetadata:d}}Object.defineProperty(t,"__esModule",{value:!0});var i=o(2),s=n(i),l=o(1),a=n(l);t.default=r},function(e,t){e.exports=require("flatpickr")}]));
//# sourceMappingURL=slick.es6.min.js.map
\ No newline at end of file
diff --git a/dist/slick.es6.min.js.map b/dist/slick.es6.min.js.map
index 7c738d1..52ddcd1 100644
--- a/dist/slick.es6.min.js.map
+++ b/dist/slick.es6.min.js.map
@@ -1 +1 @@
-{"version":3,"sources":["webpack:///slick.es6.min.js","webpack:///webpack/bootstrap 954b9e24953f6fac1bb7","webpack:///../src/slick.core.js","webpack:///external \"jquery\"","webpack:///../plugins/slick.cellrangedecorator/slick.cellrangedecorator.js","webpack:///../plugins/slick.cellrangeselector/slick.cellrangeselector.js","webpack:///../src/interact.js","webpack:///../plugins/index.js","webpack:///../plugins/slick.autotooltips/index.js","webpack:///../plugins/slick.autotooltips/slick.autotooltips.js","webpack:///../plugins/slick.cellcopymanager/index.js","webpack:///../plugins/slick.cellcopymanager/slick.cellcopymanager.js","webpack:///../plugins/slick.cellrangedecorator/index.js","webpack:///../plugins/slick.cellrangeselector/index.js","webpack:///../plugins/slick.cellselectionmodel/index.js","webpack:///../plugins/slick.cellselectionmodel/slick.cellselectionmodel.js","webpack:///../plugins/slick.checkboxselectcolumn/index.js","webpack:///../plugins/slick.checkboxselectcolumn/slick.checkboxselectcolumn.js","webpack:///../plugins/slick.headerbuttons/index.js","webpack:///../plugins/slick.headerbuttons/slick.headerbuttons.js","webpack:///../plugins/slick.headermenu/index.js","webpack:///../plugins/slick.headermenu/slick.headermenu.js","webpack:///../plugins/slick.rowmovemanager/index.js","webpack:///../plugins/slick.rowmovemanager/slick.rowmovemanager.js","webpack:///../plugins/slick.rowselectionmodel/index.js","webpack:///../plugins/slick.rowselectionmodel/slick.rowselectionmodel.js","webpack:///../src/index.js","webpack:///../src/slick-frozen.grid.js","webpack:///../src/slick.dataview.js","webpack:///../src/slick.editors.js","webpack:///../src/slick.formatters.js","webpack:///../src/slick.grid.js","webpack:///../src/slick.groupmetadataprovider.js","webpack:///external \"flatpickr\""],"names":["e","a","i","exports","modules","__webpack_require__","moduleId","installedModules","module","id","loaded","call","m","c","p","EventData","isPropagationStopped","isImmediatePropagationStopped","this","stopPropagation","stopImmediatePropagation","Event","handlers","subscribe","fn","push","unsubscribe","length","splice","notify","args","scope","returnValue","EventHandler","event","handler","unsubscribeAll","Range","fromRow","fromCell","toRow","toCell","undefined","Math","min","max","isSingleRow","isSingleCell","contains","row","cell","toString","NonDataItem","__nonDataRow","Group","__group","level","count","value","title","collapsed","totals","rows","groups","groupingKey","GroupTotals","__groupTotals","group","initialized","EditorLock","activeEditController","isActive","editController","activate","commitCurrentEdit","cancelCurrentEdit","deactivate","TreeColumns","treeColumns","init","mapToId","columns","forEach","column","columnsById","filter","node","condition","valid","sort","grid","b","indexA","getOrDefault","getColumnIndex","indexB","getDepth","getColumnsInDepth","depth","current","n","extractColumns","concat","result","hasOwnProperty","cloneTreeColumns","$","extend","hasDepth","getTreeColumns","getColumnsInGroup","visibleColumns","visible","reOrder","getById","getInIds","ids","map","Object","defineProperty","Slick","NonDataRow","GlobalEditorLock","keyCode","BACKSPACE","DELETE","DOWN","END","ENTER","ESCAPE","HOME","INSERT","LEFT","PAGE_DOWN","PAGE_UP","RIGHT","TAB","UP","SPACE","default","prototype","equals","require","_interopRequireDefault","obj","__esModule","CellRangeDecorator","options","show","range","_elem","_jquery2","css","selectionCss","addClass","selectionCssClass","appendTo","getCanvasNode","from","getCellNodeBox","to","top","left","height","bottom","width","right","hide","remove","_defaults","zIndex","border","assign","_jquery","_slick","CellRangeSelector","_decorator","_slick4","_grid","_canvas","_handler","onDragInit","handleDragInit","onDragStart","handleDragStart","onDrag","handleDrag","onDragEnd","handleDragEnd","destroy","dd","jqueryEvent","interactEvent","getCellFromEvent","originalEvent","_self","onBeforeCellRangeSelected","canCellBeSelected","_dragging","focus","start","getCellFromPoint","x0","offset","y0","_range","end","_slick2","pageX","pageY","onCellRangeSelected","_slick3","_typeof","Symbol","iterator","constructor","realWindow","blank","isElement","o","_window","getWindow","window","test","Element","nodeType","nodeName","isWindow","thing","Window","isDocFrag","DocumentFragment","isArray","isObject","isFunction","isNumber","isBool","isString","trySelector","document","querySelector","dest","source","prop","pointerExtend","deprecated","vendor","prefixedPropREs","indexOf","copyCoords","src","page","x","y","client","timeStamp","setEventXY","targetObj","pointers","interaction","pointer","pointerAverage","getPageXY","tmpXY","getClientXY","Date","getTime","setEventDeltas","prev","cur","dt","speed","hypot","vx","vy","isNativePointer","supportsTouch","Touch","getXY","type","xy","isOperaMobile","scrollX","scrollY","getScrollXY","win","documentElement","scrollLeft","scrollTop","getPointerId","pointerId","identifier","getActualElement","element","SVGElementInstance","correspondingUseElement","rootNode","ownerDocument","defaultView","parentWindow","getElementClientRect","clientRect","SVGElement","getBoundingClientRect","getClientRects","getElementRect","isIOS7","scroll","getTouchPair","touches","changedTouches","average","clientX","clientY","screenX","screenY","touchBBox","minX","minY","maxX","maxY","touchDistance","deltaSource","defaultOptions","sourceX","sourceY","dx","dy","touchAngle","prevAngle","angle","atan","PI","dr","drClamped","getOriginXY","interactable","origin","parentElement","getRect","closest","_getQBezierValue","t","p1","p2","p3","iT","getQuadraticCurvePoint","startX","startY","cpX","cpY","endX","endY","position","easeOutQuad","d","nodeContains","parent","child","parentNode","selector","matchesSelector","host","inContext","_context","testIgnore","interactableElement","ignoreFrom","matchesUpTo","testAllow","allowFrom","checkAxis","axis","thisAxis","drag","checkSnap","action","snap","enabled","checkRestrict","restrict","checkAutoScroll","autoScroll","withinInteractionLimit","maxActions","name","maxPerElement","activeInteractions","targetCount","targetElementCount","len","interactions","otherAction","prepared","active","interacting","maxInteractions","target","indexOfDeepestElement","elements","dropzone","deepestZone","index","deepestZoneParents","dropzoneParents","unshift","HTMLElement","SVGSVGElement","ownerSVGElement","parents","lastChild","previousSibling","Interaction","dropTarget","dropElement","prevDropTarget","prevDropElement","edges","matches","matchElements","inertiaStatus","smoothEnd","ending","startEvent","upCoords","xe","ye","sx","sy","t0","vx0","vys","duration","resumeDx","resumeDy","lambda_v0","one_ve_v0","Function","bind","boundInertiaFrame","inertiaFrame","boundSmoothEndFrame","smoothEndFrame","that","activeDrops","dropzones","rects","pointerIds","downTargets","downTimes","holdTimers","prevCoords","curCoords","startCoords","pointerDelta","downEvent","downPointer","_eventTarget","_curEventTarget","prevEvent","tapTime","prevTap","startOffset","restrictOffset","snapOffsets","gesture","startDistance","prevDistance","distance","scale","startAngle","snapStatus","realX","realY","snappedX","snappedY","targets","locked","changed","restrictStatus","restrictedX","restrictedY","restricted","pointerIsDown","pointerWasMoved","gesturing","dragging","resizing","resizeAxes","mouse","getInteractionFromPointer","eventType","eventTarget","mouseEvent","pointerType","inertia","allowResume","supportsPointerEvent","doOnInteractions","method","path","curEventTarget","currentTarget","prevTouchTime","_updateEventTargets","InteractEvent","phase","related","starting","coords","relativePoints","elementRect","clientX0","clientY0","ctrlKey","altKey","shiftKey","metaKey","button","buttons","detail","relatedTarget","zeroResumeDelta","resize","square","axes","box","ds","da","prevScale","velocityX","velocityY","atan2","overlap","up","down","swipe","velocity","preventOriginalDefault","preventDefault","getActionCursor","cursor","actionCursors","cursorKey","edgeNames","checkResizeEdge","rect","margin","defaultActionChecker","resizeEdges","shouldResize","actionIsEnabled","resizeOptions","edge","validateAction","actionName","delegateListener","useCapture","fakeEvent","delegated","delegatedEvents","selectors","context","contexts","listeners","j","delegateUseCapture","interact","interactables","get","Interactable","_element","_iEvents","Node","events","add","pEventTypes","pointerDown","move","pointerHover","_doc","documents","listenToDocument","set","warnOnce","message","warned","console","warn","apply","arguments","endAllInteractions","pointerEnd","doc","PointerEvent","MSPointerEvent","over","out","cancel","selectorDown","pointerMove","pointerOver","pointerOut","pointerUp","pointerCancel","autoScrollMove","frameElement","parentDoc","error","windowParentError","checkAndPreventDefault","useAttachEvent","currentAction","array","nodeList","ie8MatchesSelector","replace","prefixedMatchesSelector","limit","el","createTextNode","wrap","sqrt","dynamicDrop","base","accept","actionChecker","styleCursor","dropChecker","manualStart","Infinity","drop","preserveAspectRatio","NaN","invert","perAction","endOnly","offsets","container","resistance","minSpeed","endSpeed","smoothEndDuration","_holdDuration","now","dtx","prevTimeX","dty","prevTimeY","scrollBy","isScrolling","cancelFrame","reqFrame","stop","DocumentTouch","navigator","userAgent","pointerMoveTolerance","all","atob","resizex","resizey","resizexy","resizetop","resizeleft","resizebottom","resizeright","resizetopleft","resizebottomright","resizetopright","resizebottomleft","wheelEvent","eventTypes","globalEvents","appName","match","platform","appVersion","requestAnimationFrame","cancelAnimationFrame","listener","elementIndex","typeCount","attachedListeners","supplied","wrapped","useCount","ret","listenerIndex","immediatePropagationStopped","srcElement","preventDef","stopProp","stopImmProp","addEvent","on","Boolean","removeEvent","cancelBubble","_elements","_targets","_attachedListeners","webkit","ptr","pushCurMatches","curMatches","curMatchElements","prevTargetElement","addPointer","elementInteractable","elementAction","getAction","forEachSelector","validateSelector","style","pushMatches","querySelectorAll","eventCopy","pointerIndex","setTimeout","pointerHold","collectEventTargets","forceAction","newAction","setModifications","preEnd","shouldMove","shouldSnap","shouldRestrict","setSnapping","setRestriction","setStartOffsets","snapOffset","pageUp","clientUp","inertiaPosition","recordPointer","duplicateMove","clearTimeout","absX","abs","absY","targetAxis","thisInteraction","getDraggable","selectorInteractable","dragStart","dragEvent","fire","setActiveDrops","dropEvents","getDropEvents","fireActiveDrops","dragMove","draggableElement","getDrop","leave","enter","resizeStart","resizeEvent","startRect","linkedEdges","_linkedEdges","resizeStartAspectRatio","resizeRects","previous","delta","deltaRect","resizeMove","invertible","originalEdges","swap","gestureStart","gestureEvent","gestureMove","isNaN","removePointer","ie8Dblclick","endEvent","inertiaOptions","pointerSpeed","inertiaPossible","endSnap","endRestrict","snapRestrict","vy0","v0","calcInertia","statusObject","useStatusXY","modifiedXe","modifiedYe","collectDrops","drops","dropElements","currentElement","prevElement","dragElement","possibleDrops","validDrops","dropCheck","dropIndex","pointerEvent","draggable","dragLeave","prevDropzone","dragEnter","dragmove","clearTargets","lambda","te","progress","exp","quadPoint","collectSelectors","els","isSet","firePointers","interval","createNewDoubleTap","originalPointer","double","propagationStopped","doubleTap","matchElement","pageCoords","status","relIndex","relative","inRange","snapChanged","restriction","prevent","inertiaDur","log","innerWidth","innerHeight","interactionListeners","indexOfElement","callback","setOnEvents","phases","ondrop","ondropactivate","ondropdeactivate","ondragenter","ondragleave","ondropmove","onstart","onmove","onend","oninertiastart","setPerAction","option","checker","dropped","dropOverlap","horizontal","vertical","dragRect","cx","cy","overlapArea","overlapRatio","newValue","resizable","squareResize","gesturable","actions","setOptions","thisOption","mode","createSnapGrid","gridOffset","anchors","paths","elementOrigin","allActions","rectChecker","iEvent","onEvent","funcName","search","trim","split","off","eventList","matchFound","useCap","methods","perActions","settings","setting","unset","enableDragging","enableResizing","enableGesturing","debug","downTime","getPointerAverage","getTouchBBox","getTouchDistance","getTouchAngle","newvalue","offsetX","offsetY","gridx","round","gridy","newX","newY","elems","lastTime","vendors","currTime","timeToCall","RowSelectionModel","RowMoveManager","HeaderMenu","HeaderButtons","CheckboxSelectColumn","CellSelectionModel","CellCopyManager","AutoTooltips","_slick5","_slick6","_slick7","_slick8","_slick9","_slick10","_slick11","_slick12","_slick13","_slick14","_slick15","_slick16","_slick17","_slick18","_slick19","_slick20","enableForCells","onMouseEnter","handleMouseEnter","enableForHeaderCells","onHeaderMouseEnter","handleHeaderMouseEnter","$node","getCellNode","text","scrollWidth","maxToolTipLength","substr","attr","toolTip","onKeyDown","handleKeyDown","ranges","getEditorLock","which","_copiedRanges","clearCopySelection","onCopyCancelled","getSelectionModel","getSelectedRanges","markCopySelection","onCopyCells","onPasteCells","getColumns","hash","k","setCellCssStyles","removeCellCssStyles","_options","onActiveCellChanged","handleActiveCellChange","registerPlugin","_selector","handleCellRangeSelected","handleBeforeCellRangeSelected","unregisterPlugin","removeInvalidRanges","r","setSelectedRanges","_ranges","onSelectedRangesChanged","selectActiveCell","last","getActiveCell","pop","dRow","dCell","dirRow","dirCell","new_last","viewRow","viewCell","scrollRowIntoView","scrollCellIntoView","onSelectedRowsChanged","handleSelectedRowsChanged","onClick","handleClick","onHeaderClick","handleHeaderClick","selectedRows","getSelectedRows","lookup","_selectedRowsLookup","invalidateRow","render","getDataLength","updateColumnHeader","columnId","toggleRowSelection","is","setSelectedRows","grep","getColumnDefinition","field","sortable","cssClass","formatter","checkboxSelectionFormatter","columnDef","dataContext","onHeaderCellRendered","handleHeaderCellRendered","onBeforeHeaderCellDestroy","handleBeforeHeaderCellDestroy","setColumns","header","btn","buttonCssClass","data","showOnHover","image","tooltip","command","handleButtonClick","classList","find","onCommand","body","handleBodyMouseDown","unbind","$menu","hideMenu","$activeHeaderColumn","removeClass","menu","$el","buttonImage","showMenu","$menuButton","onBeforeMenuShow","getContainerNode","empty","items","item","$li","handleMenuItemClick","disabled","$icon","iconCssClass","iconImage","cancelEditOnDrag","behavior","inArray","rowHeight","getOptions","selectionProxy","guide","insertBefore","eventData","onBeforeMoveRows","canMove","onMoveRows","wrapHandler","_inHandler","rangesToRows","rowsToRanges","lastCell","getRowsRange","selectActiveRow","activeRow","canCellBeActive","multiSelect","selection","idx","setActiveCell","_interopRequireWildcard","newObj","key","Plugins","FrozenGrid","Grid","Data","Formatters","Editors","_slickFrozen","_slickFrozen2","_plugins","SlickGrid","$container","Error","maxSupportedCssHeight","getMaxSupportedCssHeight","scrollbarDimensions","measureScrollbar","defaults","validateAndEnforceOptions","columnDefaults","defaultColumnWidth","minWidth","maxWidth","uid","$focusSink","$paneHeaderL","$paneHeaderR","$paneTopL","$paneTopR","$paneBottomL","$paneBottomR","$headerScrollerL","$headerScrollerR","$headerScroller","$groupHeadersL","$groupHeadersR","$groupHeaders","$headerL","$headerR","$headers","$headerRowScrollerL","$headerRowScrollerR","$headerRowScroller","$headerRowSpacerL","getCanvasWidth","$headerRowSpacerR","$headerRowL","$headerRowR","$headerRow","$topPanelScrollerL","$topPanelScrollerR","$topPanelScroller","$topPanelL","$topPanelR","$topPanel","showTopPanel","showHeaderRow","$viewportTopL","$viewportTopR","$viewportBottomL","$viewportBottomR","$viewport","$activeViewportNode","$canvasTopL","$canvasTopR","$canvasBottomL","$canvasBottomR","$canvas","$activeCanvasNode","$footerRowScrollerR","$footerRowScrollerL","$footerRowScroller","$footerRowSpacerL","$footerRowSpacerR","$footerRowL","$footerRowR","$footerRow","showFooterRow","$focusSink2","clone","explicitInitialization","finishInitialization","getViewportWidth","getViewportHeight","measureCellPaddingAndBorder","disableSelection","enableTextSelectionOnCells","setFrozenOptions","setPaneVisibility","setScroller","setOverflow","updateColumnCaches","createColumnHeaders","createColumnGroupHeaders","createColumnFooter","setupColumnSort","createCssRules","resizeCanvas","bindAncestorScrollEvents","handleScroll","mousewheel","frozenColumn","hasFrozenRows","handleMouseWheel","handleHeaderContextMenu","delegate","handleHeaderMouseLeave","handleHeaderRowScroll","handleFooterRowScroll","handleDblClick","handleContextMenu","handleMouseLeave","_interact2","toLowerCase","hasFrozenColumns","plugin","plugins","self","setSelectionModel","model","selectionModel","handleSelectedRangesChanged","getActiveCanvasNode","setActiveCanvasNode","getCanvases","getViewportNode","getActiveViewportNode","setActiveViewPortNode","setActiveViewportNode","$c","dim","clientWidth","clientHeight","getHeadersWidth","headersWidth","headersWidthL","headersWidthR","ii","viewportW","getHeadersWidthL","getHeadersWidthR","availableWidth","viewportHasVScroll","canvasWidthL","canvasWidthR","totalRowWidth","fullWidthRows","updateCanvasWidth","forceColumnWidthsUpdate","widthChanged","oldCanvasWidth","canvasWidth","oldCanvasWidthL","oldCanvasWidthR","viewportHasHScroll","applyColumnWidths","$target","jquery","supportedHeight","testUpTo","div","elem","frozenBottom","scrollHeight","$elem","$boundAncestors","handleActiveCellPositionChange","unbindAncestorScrollEvents","$header","children","eq","trigger","html","getHeaderRow","getHeaderRowColumn","$headerRowTarget","getFooterRow","getFooterRowColumn","$footerRowTarget","$footer","each","onBeforeFooterRowCellDestroy","footerRowCell","onFooterRowCellRendered","columnsLength","frozenColumnsValid","groupColumns","indexGroup","headerCssClass","alert","applyColumnGroupHeaderWidths","onMouseLeave","onBeforeHeaderRowCellDestroy","$headerTarget","headerColumnWidthDiff","enableColumnReorder","append","headerRowCell","onHeaderRowCellRendered","setSortColumns","sortColumns","setupColumnResize","setupColumnReorder","click","hasClass","$col","sortOpts","sortAsc","multiColumnSort","defaultSortAsc","onSort","sortCols","col","sortCol","currentPositionInHeader","currentPosition","limitPositionInGroup","idColumn","groupColumnOfPreviousPosition","startLimit","endLimit","some","groupColumn","arr","lastIndexOf","columnPositionValidInGroup","$item","positionValid","placeholder","createElement","className","offsetWidth","offsetHeight","after","marginLeft","transform","validPositionInGroup","removeChild","newColumns","removeData","onColumnsReordered","impactedColumns","getImpactedColumns","columnElements","firstResizable","lastResizable","forceFitColumns","$handle","activeColumn","previousWidth","autosizeColumns","applyColumnHeaderWidths","syncColumnCellResize","invalidateAllRows","onColumnsResized","getVBoxDelta","val","parseFloat","parseInt","frozenRow","numVisibleRows","frozenRowsHeight","dataLength","actualFrozenRow","overflow-x","overflow-y","$headerScrollContainer","$headerRowScrollContainer","$footerRowScrollContainer","$viewportScrollContainerX","$viewportScrollContainerY","h","v","headerColumnHeightDiff","cellWidthDiff","cellHeightDiff","absoluteColumnMinWidth","$style","rules","topPanelHeight","headerRowHeight","footerRowHeight","styleSheet","cssText","join","appendChild","getColumnCssRules","stylesheet","sheets","styleSheets","ownerNode","owningElement","columnCssRulesL","columnCssRulesR","columnIdx","cssRules","selectorText","exec","removeCssRules","onBeforeDestroy","evt","editorLock","getEditController","prevTotal","widths","shrinkLeeway","total","availWidth","shrinkProportion","absMinWidth","shrinkSize","floor","growProportion","growSize","currentWidth","reRender","rerenderOnResize","$groupHeader","currentColumnIndex","$groupHeaderColumn","$headerColumn","next","outerWidth","headers","w","rule","setSortColumn","ascending","cols","headerColumnEls","columnIndex","getSortColumns","selectedCellCssClass","columnPosLeft","columnPosRight","columnDefinitions","_treeColumns","makeActiveCellNormal","enableAddRow","zombieRowNodeFromLastMouseWheelEvent","autoHeight","leaveSpaceForNewRows","setData","newData","scrollToTop","updateRowCount","scrollTo","getData","getLength","getDataLengthIncludingAddNew","getDataItem","getItem","getTopPanel","setTopPanelVisibility","slideDown","slideUp","setHeaderRowVisibility","setFooterRowVisibility","fadeIn","getRowTop","getRowFromPosition","th","oldOffset","ph","cj","newScrollTop","getVisibleRange","cleanupRows","updateRowPositions","prevScrollTop","vScrollDir","lastRenderedScrollTop","onViewportChanged","defaultFormatter","getFormatter","rowMetadata","getItemMetadata","columnOverrides","formatterFactory","callFormatter","metadata","columnData","getEditor","columnMetadata","editor","editorFactory","getDataItemValueForColumn","dataItemColumnValueExtractor","appendRowHtml","stringArrayL","stringArrayR","dataLoading","rowCss","addNewRowCssClass","cssClasses","frozenRowOffset","getFrozenRowOffset","rowHtml","colspan","leftPx","rightPx","appendCellHtml","stringArray","cellCss","activeCell","cellCssClasses","rowsCache","cellRenderQueue","cellColSpans","rangeToKeep","removeFrozenRow","removeRowFromCache","invalidate","currentEditor","cacheEntry","rowNodeFromLastMouseWheelEvent","rowNode","postProcessedRows","renderedRows","counter_rows_removed","invalidateRows","rl","updateCell","cellNode","loadValue","innerHTML","invalidatePostProcessingResults","updateRow","ensureCellNodesInRowsCache","cellNodesByColumnIdx","viewportH","outerHeight","topPanelH","headerRowH","footerRowH","ceil","paneTopH","paneBottomH","viewportTopH","viewportBottomH","paneBottomTop","lastRenderedScrollLeft","dataLengthIncludingAddNew","numberOfRows","oldH","tempViewportH","oldViewportHasVScroll","l","activeCellNode","resetActiveCell","oldScrollTopInRange","viewportTop","viewportLeft","getRenderedRange","buffer","minBuffer","$lastNode","cleanUpCells","totalCellsRemoved","cellsToRemove","cellToRemove","cleanUpAndRenderCells","cellsAdded","processedRows","totalCellsAdded","btm","processedRow","renderRows","needToReselectCell","counter_rows_rendered","xRight","firstChild","startPostProcessing","enableAsyncPostRender","h_postrender","asyncPostProcessRows","asyncPostRenderDelay","postProcessFromRow","postProcessToRow","rendered","renderedFrozenRows","h_render","deltaX","deltaY","$rowNode","$gridCanvas","zombieRow","handled","_handleScroll","isMouseWheel","maxScrollDistanceY","maxScrollDistanceX","hasFrozenCols","vScrollDist","hScrollDist","prevScrollLeft","forceSyncScrolling","onScroll","asyncPostRender","updateCellCssStylesOnRenderedRows","addedHash","removedHash","addedRowHash","removedRowHash","addCellCssStyles","onCellCssStylesChanged","prevHash","getCellCssStyles","flashCell","toggleCellClass","times","$cell","queue","toggleClass","cellFlashingCssClass","dequeue","cellExists","retval","navigatePrev","cancelEditAndSetFocus","navigatePageDown","navigatePageUp","navigateLeft","navigateRight","navigateUp","navigateDown","navigateNext","editable","commitEditAndSetFocus","makeActiveCellEditable","activeElement","setFocus","setActiveCellInternal","onContextMenu","onDblClick","gotoCell","onHeaderMouseLeave","onHeaderContextMenu","getCellFromNode","cls","getRowFromNode","rowOffset","isBottom","y1","y2","x1","x2","tabbingDirection","doPaging","getColspan","scrollRight","newCell","opt_editMode","activeCellChanged","$activeCellNode","$activeCellOffset","activePosX","autoEdit","isCellPotentiallyEditable","h_editorLoader","asyncEditorLoading","asyncEditorLoadDelay","scrollActiveCellIntoView","clearTextSelection","getSelection","sel","removeAllRanges","cannotTriggerInsert","onBeforeCellEditorDestroy","onBeforeEditCell","gridPosition","absBox","commitChanges","cancelChanges","serializedEditorValue","serializeValue","offsetTop","offsetLeft","offsetParent","getActiveCellPosition","getGridPosition","onActiveCellPositionChanged","cellBox","getCellEditor","getActiveCellNode","viewportScrollH","rowAtTop","rowAtBottom","scrollRowToTop","scrollPage","dir","deltaRows","enableCellNavigation","prevCell","prevActivePosX","findFirstFocusableCell","findLastFocusableCell","lastFocusableCell","gotoRight","posX","gotoLeft","firstFocusableCell","pos","gotoDown","gotoUp","gotoNext","gotoPrev","lastSelectableCell","navigate","tabbingDirections","stepFunctions","stepFn","isAddNewRow","focusable","selectable","forceEdit","isValueChanged","validationResults","validate","editCommand","serializedValue","prevSerializedValue","execute","applyValue","onCellChange","undo","editCommandHandler","newItem","onAddNewRow","onValidationError","random","s","eval","expr","slickGridVersion","getViewport","editActiveCell","_interact","DataView","beginUpdate","suspend","endUpdate","refresh","setRefreshHints","hints","refreshHints","setFilterArgs","filterArgs","updateIdxById","startingIndex","idProperty","idxById","ensureIdUniqueness","getItems","setItems","objectIdProperty","filteredItems","setPagingOptions","pageSize","pagesize","pagenum","totalRows","pageNum","onPagingInfoChanged","getPagingInfo","totalPages","dataView","comparer","sortComparer","fastSortField","reverse","fastSort","oldToString","reSort","setFilter","filterFn","inlineFilters","compiledFilter","compileFilter","compiledFilterWithCaching","compileFilterWithCaching","getGrouping","groupingInfos","setGrouping","groupingInfo","groupItemMetadataProvider","GroupItemMetadataProvider","toggledGroupsByLevel","Array","gi","groupingInfoDefaults","getterIsAFn","getter","compiledAccumulators","aggregators","compileAccumulatorLoop","groupBy","valueGetter","valueFormatter","setAggregators","groupAggregators","includeCollapsed","aggregateCollapsed","getItemByIdx","getIdxById","ensureRowsByIdCache","rowsById","getRowById","getItemById","mapIdsToRows","idArray","mapRowsToIds","rowArray","updateItem","updated","insertItem","addItem","deleteItem","displayTotalsRow","calculateTotals","getGroupRowMetadata","getTotalsRowMetadata","expandCollapseAllGroups","collapse","collapseAllGroups","expandAllGroups","expandCollapseGroup","collapseGroup","letArgs","slice","arg0","groupingDelimiter","expandGroup","getGroups","extractGroups","parentGroup","groupsByVal","predefinedValues","isLeafLevel","agg","aggregateChildGroups","storeResult","addGroupTotals","lazyTotalsCalculation","addTotals","groupCollapsed","toggledGroups","g","aggregateEmpty","flattenGroupedRows","groupedRows","gl","jj","getFunctionInfo","fnRegex","params","aggregator","accumulatorInfo","accumulate","displayName","filterInfo","filterPath1","filterPath2","filterBody","tpl","uncompiledFilter","uncompiledFilterWithCaching","cache","getFilteredAndPagedItems","batchFilter","batchFilterWithCaching","isFilterNarrowing","isFilterExpanding","filterCache","isFilterUnchanged","paged","getRowDiffs","newRows","eitherIsNonData","diff","ignoreDiffsBefore","ignoreDiffsAfter","recalc","_items","prevRefreshHints","countBefore","totalRowsBefore","onRowCountChanged","onRowsChanged","syncGridSelection","preserveHidden","preserveHiddenOnSelectionChange","setSelectedRowIds","rowIds","selectedRowIds","onSelectedRowIdsChanged","update","inHandler","newSelectedRowIds","existing","syncGridCellCssStyles","storeCellCssStyles","hashById","newHash","AvgAggregator","field_","count_","nonNullCount_","sum_","groupTotals","avg","MinAggregator","min_","MaxAggregator","max_","SumAggregator","sum","Aggregators","Avg","Min","Max","Sum","GroupMetaDataProvider","TextEditor","$input","defaultValue","select","getValue","setValue","state","msg","validator","IntegerEditor","FloatEditor","getDecimalPlaces","rtn","editorFixedDecimalPlaces","DefaultDecimalPlaces","decPlaces","toFixed","DateEditor","flatInstance","defaultDate","date","_flatpickr2","open","positionCalendar","close","YesNoSelectEditor","$select","CheckboxEditor","LongTextEditor","$wrapper","save","_flatpickr","Text","Integer","Float","YesNoSelect","Checkbox","LongText","PercentCompleteFormatter","PercentCompleteBarFormatter","color","YesNoFormatter","CheckmarkFormatter","PercentComplete","PercentCompleteBar","YesNo","Checkmark","cacheCssForHiddenInit","$headerRowSpacer","createFooterRow","$footerRowSpacer","restoreCssFromHiddenInit","$hiddenParents","addBack","not","old","cssShow","oldProps","rowWidth","verArray","jQueryNewWidthBehaviour","enableAsyncPostRenderCleanup","startPostProcessingCleanup","queuePostProcessedRowForCleanup","postProcessedRow","rowIdx","postProcessgroupId","postProcessedCleanupQueue","actionType","groupId","detach","queuePostProcessedCellForCleanup","cellnode","display","zombieRowCacheFromLastMouseWheelEvent","zombieRowPostProcessedFromLastMouseWheelEvent","h_postrenderCleanup","asyncPostProcessCleanupRows","asyncPostRenderCleanupDelay","processedStatus","entry","shift","asyncPostRenderCleanup","keyCaptureList","useEditor","suppressClearOnEdit","visibility","defaultGroupCellFormatter","enableExpandCollapse","indentation","toggleCssClass","toggleCollapsedCssClass","toggleExpandedCssClass","groupTitleCssClass","defaultTotalsCellFormatter","groupTotalsFormatter","handleGridClick","handleGridKeyDown","groupFocusable","groupCssClass","0","groupFormatter","totalsFocusable","totalsCssClass","totalsFormatter"],"mappings":"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","file":"slick.es6.min.js","sourcesContent":["(function(e, a) { for(var i in a) e[i] = a[i]; }(exports, /******/ (function(modules) { // webpackBootstrap\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n/******/\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId])\n/******/ \t\t\treturn installedModules[moduleId].exports;\n/******/\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\texports: {},\n/******/ \t\t\tid: moduleId,\n/******/ \t\t\tloaded: false\n/******/ \t\t};\n/******/\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.loaded = true;\n/******/\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/\n/******/\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n/******/\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n/******/\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = \"/\";\n/******/\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(0);\n/******/ })\n/************************************************************************/\n/******/ ([\n/* 0 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\tmodule.exports = __webpack_require__(25);\n\n\n/***/ }),\n/* 1 */\n/***/ (function(module, exports) {\n\n\t\"use strict\";\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t/** *\n\t * Contains core SlickGrid classes.\n\t * @module Core\n\t * @namespace Slick\n\t */\n\tvar Slick = {\n\t Event: Event,\n\t EventData: EventData,\n\t EventHandler: EventHandler,\n\t Range: Range,\n\t NonDataRow: NonDataItem,\n\t Group: Group,\n\t GroupTotals: GroupTotals,\n\t EditorLock: EditorLock,\n\t /** *\n\t * A global singleton editor lock.\n\t * @class GlobalEditorLock\n\t * @static\n\t * @constructor\n\t */\n\t GlobalEditorLock: new EditorLock(),\n\t TreeColumns: TreeColumns,\n\t\n\t keyCode: {\n\t BACKSPACE: 8,\n\t DELETE: 46,\n\t DOWN: 40,\n\t END: 35,\n\t ENTER: 13,\n\t ESCAPE: 27,\n\t HOME: 36,\n\t INSERT: 45,\n\t LEFT: 37,\n\t PAGE_DOWN: 34,\n\t PAGE_UP: 33,\n\t RIGHT: 39,\n\t TAB: 9,\n\t UP: 38,\n\t SPACE: 32\n\t }\n\t};\n\t\n\texports.default = Slick;\n\t\n\t/***\n\t * An event object for passing data to event handlers and letting them control propagation.\n\t *
This is pretty much identical to how W3C and jQuery implement events.
\n\t * @class EventData\n\t * @constructor\n\t */\n\t\n\tfunction EventData() {\n\t var isPropagationStopped = false;\n\t var isImmediatePropagationStopped = false;\n\t\n\t /***\n\t * Stops event from propagating up the DOM tree.\n\t * @method stopPropagation\n\t */\n\t this.stopPropagation = function () {\n\t isPropagationStopped = true;\n\t };\n\t\n\t /***\n\t * Returns whether stopPropagation was called on this event object.\n\t * @method isPropagationStopped\n\t * @return {Boolean}\n\t */\n\t this.isPropagationStopped = function () {\n\t return isPropagationStopped;\n\t };\n\t\n\t /***\n\t * Prevents the rest of the handlers from being executed.\n\t * @method stopImmediatePropagation\n\t */\n\t this.stopImmediatePropagation = function () {\n\t isImmediatePropagationStopped = true;\n\t };\n\t\n\t /***\n\t * Returns whether stopImmediatePropagation was called on this event object.\\\n\t * @method isImmediatePropagationStopped\n\t * @return {Boolean}\n\t */\n\t this.isImmediatePropagationStopped = function () {\n\t return isImmediatePropagationStopped;\n\t };\n\t}\n\t\n\t/***\n\t * A simple publisher-subscriber implementation.\n\t * @class Event\n\t * @constructor\n\t */\n\tfunction Event() {\n\t var handlers = [];\n\t\n\t /***\n\t * Adds an event handler to be called when the event is fired.\n\t *
Event handler will receive two arguments - an EventData and the data\n\t * object the event was fired with.
\n\t * @method subscribe\n\t * @param fn {Function} Event handler.\n\t */\n\t this.subscribe = function (fn) {\n\t handlers.push(fn);\n\t };\n\t\n\t /***\n\t * Removes an event handler added with subscribe(fn).\n\t * @method unsubscribe\n\t * @param fn {Function} Event handler to be removed.\n\t */\n\t this.unsubscribe = function (fn) {\n\t for (var i = handlers.length - 1; i >= 0; i--) {\n\t if (handlers[i] === fn) {\n\t handlers.splice(i, 1);\n\t }\n\t }\n\t };\n\t\n\t /***\n\t * Fires an event notifying all subscribers.\n\t * @method notify\n\t * @param args {Object} Additional data object to be passed to all handlers.\n\t * @param e {EventData}\n\t * Optional.\n\t * An EventData object to be passed to all handlers.\n\t * For DOM events, an existing W3C/jQuery event object can be passed in.\n\t * @param scope {Object}\n\t * Optional.\n\t * The scope (\"this\") within which the handler will be executed.\n\t * If not specified, the scope will be set to the Event instance.\n\t */\n\t this.notify = function (args, e, scope) {\n\t e = e || new EventData();\n\t scope = scope || this;\n\t\n\t var returnValue;\n\t for (var i = 0; i < handlers.length && !(e.isPropagationStopped() || e.isImmediatePropagationStopped()); i++) {\n\t returnValue = handlers[i].call(scope, e, args);\n\t }\n\t\n\t return returnValue;\n\t };\n\t}\n\t\n\tfunction EventHandler() {\n\t var handlers = [];\n\t\n\t this.subscribe = function (event, handler) {\n\t handlers.push({\n\t event: event,\n\t handler: handler\n\t });\n\t event.subscribe(handler);\n\t\n\t return this; // allow chaining\n\t };\n\t\n\t this.unsubscribe = function (event, handler) {\n\t var i = handlers.length;\n\t while (i--) {\n\t if (handlers[i].event === event && handlers[i].handler === handler) {\n\t handlers.splice(i, 1);\n\t event.unsubscribe(handler);\n\t return;\n\t }\n\t }\n\t\n\t return this; // allow chaining\n\t };\n\t\n\t this.unsubscribeAll = function () {\n\t var i = handlers.length;\n\t while (i--) {\n\t handlers[i].event.unsubscribe(handlers[i].handler);\n\t }\n\t handlers = [];\n\t\n\t return this; // allow chaining\n\t };\n\t}\n\t\n\t/***\n\t * A structure containing a range of cells.\n\t * @class Range\n\t * @constructor\n\t * @param fromRow {Integer} Starting row.\n\t * @param fromCell {Integer} Starting cell.\n\t * @param toRow {Integer} Optional. Ending row. Defaults to fromRow.\n\t * @param toCell {Integer} Optional. Ending cell. Defaults to fromCell.\n\t */\n\tfunction Range(fromRow, fromCell, toRow, toCell) {\n\t if (toRow === undefined && toCell === undefined) {\n\t toRow = fromRow;\n\t toCell = fromCell;\n\t }\n\t\n\t /***\n\t * @property fromRow\n\t * @type {Integer}\n\t */\n\t this.fromRow = Math.min(fromRow, toRow);\n\t\n\t /***\n\t * @property fromCell\n\t * @type {Integer}\n\t */\n\t this.fromCell = Math.min(fromCell, toCell);\n\t\n\t /***\n\t * @property toRow\n\t * @type {Integer}\n\t */\n\t this.toRow = Math.max(fromRow, toRow);\n\t\n\t /***\n\t * @property toCell\n\t * @type {Integer}\n\t */\n\t this.toCell = Math.max(fromCell, toCell);\n\t\n\t /***\n\t * Returns whether a range represents a single row.\n\t * @method isSingleRow\n\t * @return {Boolean}\n\t */\n\t this.isSingleRow = function () {\n\t return this.fromRow == this.toRow;\n\t };\n\t\n\t /***\n\t * Returns whether a range represents a single cell.\n\t * @method isSingleCell\n\t * @return {Boolean}\n\t */\n\t this.isSingleCell = function () {\n\t return this.fromRow == this.toRow && this.fromCell == this.toCell;\n\t };\n\t\n\t /***\n\t * Returns whether a range contains a given cell.\n\t * @method contains\n\t * @param row {Integer}\n\t * @param cell {Integer}\n\t * @return {Boolean}\n\t */\n\t this.contains = function (row, cell) {\n\t return row >= this.fromRow && row <= this.toRow && cell >= this.fromCell && cell <= this.toCell;\n\t };\n\t\n\t /***\n\t * Returns a readable representation of a range.\n\t * @method toString\n\t * @return {String}\n\t */\n\t this.toString = function () {\n\t if (this.isSingleCell()) {\n\t return \"(\" + this.fromRow + \":\" + this.fromCell + \")\";\n\t } else {\n\t return \"(\" + this.fromRow + \":\" + this.fromCell + \" - \" + this.toRow + \":\" + this.toCell + \")\";\n\t }\n\t };\n\t}\n\t\n\t/***\n\t * A base class that all special / non-data rows (like Group and GroupTotals) derive from.\n\t * @class NonDataItem\n\t * @constructor\n\t */\n\tfunction NonDataItem() {\n\t this.__nonDataRow = true;\n\t}\n\t\n\t/***\n\t * Information about a group of rows.\n\t * @class Group\n\t * @extends Slick.NonDataItem\n\t * @constructor\n\t */\n\tfunction Group() {\n\t this.__group = true;\n\t\n\t /**\n\t * Grouping level, starting with 0.\n\t * @property level\n\t * @type {Number}\n\t */\n\t this.level = 0;\n\t\n\t /***\n\t * Number of rows in the group.\n\t * @property count\n\t * @type {Integer}\n\t */\n\t this.count = 0;\n\t\n\t /***\n\t * Grouping value.\n\t * @property value\n\t * @type {Object}\n\t */\n\t this.value = null;\n\t\n\t /***\n\t * Formatted display value of the group.\n\t * @property title\n\t * @type {String}\n\t */\n\t this.title = null;\n\t\n\t /***\n\t * Whether a group is collapsed.\n\t * @property collapsed\n\t * @type {Boolean}\n\t */\n\t this.collapsed = false;\n\t\n\t /***\n\t * GroupTotals, if any.\n\t * @property totals\n\t * @type {GroupTotals}\n\t */\n\t this.totals = null;\n\t\n\t /**\n\t * Rows that are part of the group.\n\t * @property rows\n\t * @type {Array}\n\t */\n\t this.rows = [];\n\t\n\t /**\n\t * Sub-groups that are part of the group.\n\t * @property groups\n\t * @type {Array}\n\t */\n\t this.groups = null;\n\t\n\t /**\n\t * A unique key used to identify the group. This key can be used in calls to DataView\n\t * collapseGroup() or expandGroup().\n\t * @property groupingKey\n\t * @type {Object}\n\t */\n\t this.groupingKey = null;\n\t}\n\t\n\tGroup.prototype = new NonDataItem();\n\t\n\t/***\n\t * Compares two Group instances.\n\t * @method equals\n\t * @return {Boolean}\n\t * @param group {Group} Group instance to compare to.\n\t */\n\tGroup.prototype.equals = function (group) {\n\t return this.value === group.value && this.count === group.count && this.collapsed === group.collapsed && this.title === group.title;\n\t};\n\t\n\t/***\n\t * Information about group totals.\n\t * An instance of GroupTotals will be created for each totals row and passed to the aggregators\n\t * so that they can store arbitrary data in it. That data can later be accessed by group totals\n\t * formatters during the display.\n\t * @class GroupTotals\n\t * @extends Slick.NonDataItem\n\t * @constructor\n\t */\n\tfunction GroupTotals() {\n\t this.__groupTotals = true;\n\t\n\t /***\n\t * Parent Group.\n\t * @param group\n\t * @type {Group}\n\t */\n\t this.group = null;\n\t\n\t /***\n\t * Whether the totals have been fully initialized / calculated.\n\t * Will be set to false for lazy-calculated group totals.\n\t * @param initialized\n\t * @type {Boolean}\n\t */\n\t this.initialized = false;\n\t}\n\t\n\tGroupTotals.prototype = new NonDataItem();\n\t\n\t/***\n\t * A locking helper to track the active edit controller and ensure that only a single controller\n\t * can be active at a time. This prevents a whole class of state and validation synchronization\n\t * issues. An edit controller (such as SlickGrid) can query if an active edit is in progress\n\t * and attempt a commit or cancel before proceeding.\n\t * @class EditorLock\n\t * @constructor\n\t */\n\tfunction EditorLock() {\n\t var activeEditController = null;\n\t\n\t /***\n\t * Returns true if a specified edit controller is active (has the edit lock).\n\t * If the parameter is not specified, returns true if any edit controller is active.\n\t * @method isActive\n\t * @param editController {EditController}\n\t * @return {Boolean}\n\t */\n\t this.isActive = function (editController) {\n\t return editController ? activeEditController === editController : activeEditController !== null;\n\t };\n\t\n\t /***\n\t * Sets the specified edit controller as the active edit controller (acquire edit lock).\n\t * If another edit controller is already active, and exception will be thrown.\n\t * @method activate\n\t * @param editController {EditController} edit controller acquiring the lock\n\t */\n\t this.activate = function (editController) {\n\t if (editController === activeEditController) {\n\t // already activated?\n\t return;\n\t }\n\t if (activeEditController !== null) {\n\t throw \"SlickGrid.EditorLock.activate: an editController is still active, can't activate another editController\";\n\t }\n\t if (!editController.commitCurrentEdit) {\n\t throw \"SlickGrid.EditorLock.activate: editController must implement .commitCurrentEdit()\";\n\t }\n\t if (!editController.cancelCurrentEdit) {\n\t throw \"SlickGrid.EditorLock.activate: editController must implement .cancelCurrentEdit()\";\n\t }\n\t activeEditController = editController;\n\t };\n\t\n\t /***\n\t * Unsets the specified edit controller as the active edit controller (release edit lock).\n\t * If the specified edit controller is not the active one, an exception will be thrown.\n\t * @method deactivate\n\t * @param editController {EditController} edit controller releasing the lock\n\t */\n\t this.deactivate = function (editController) {\n\t if (activeEditController !== editController) {\n\t throw \"SlickGrid.EditorLock.deactivate: specified editController is not the currently active one\";\n\t }\n\t activeEditController = null;\n\t };\n\t\n\t /***\n\t * Attempts to commit the current edit by calling \"commitCurrentEdit\" method on the active edit\n\t * controller and returns whether the commit attempt was successful (commit may fail due to validation\n\t * errors, etc.). Edit controller's \"commitCurrentEdit\" must return true if the commit has succeeded\n\t * and false otherwise. If no edit controller is active, returns true.\n\t * @method commitCurrentEdit\n\t * @return {Boolean}\n\t */\n\t this.commitCurrentEdit = function () {\n\t return activeEditController ? activeEditController.commitCurrentEdit() : true;\n\t };\n\t\n\t /***\n\t * Attempts to cancel the current edit by calling \"cancelCurrentEdit\" method on the active edit\n\t * controller and returns whether the edit was successfully cancelled. If no edit controller is\n\t * active, returns true.\n\t * @method cancelCurrentEdit\n\t * @return {Boolean}\n\t */\n\t this.cancelCurrentEdit = function cancelCurrentEdit() {\n\t return activeEditController ? activeEditController.cancelCurrentEdit() : true;\n\t };\n\t}\n\t\n\t/**\n\t *\n\t * @param {Array} treeColumns Array com levels of columns\n\t * @returns {{hasDepth: 'hasDepth', getTreeColumns: 'getTreeColumns', extractColumns: 'extractColumns', getDepth: 'getDepth', getColumnsInDepth: 'getColumnsInDepth', getColumnsInGroup: 'getColumnsInGroup', visibleColumns: 'visibleColumns', filter: 'filter', reOrder: reOrder}}\n\t * @constructor\n\t */\n\tfunction TreeColumns(treeColumns) {\n\t\n\t var columnsById = {};\n\t\n\t function init() {\n\t mapToId(treeColumns);\n\t }\n\t\n\t function mapToId(columns) {\n\t columns.forEach(function (column) {\n\t columnsById[column.id] = column;\n\t\n\t if (column.columns) mapToId(column.columns);\n\t });\n\t }\n\t\n\t function filter(node, condition) {\n\t\n\t return node.filter(function (column) {\n\t\n\t var valid = condition.call(column);\n\t\n\t if (valid && column.columns) column.columns = filter(column.columns, condition);\n\t\n\t return valid && (!column.columns || column.columns.length);\n\t });\n\t }\n\t\n\t function sort(columns, grid) {\n\t columns.sort(function (a, b) {\n\t var indexA = getOrDefault(grid.getColumnIndex(a.id)),\n\t indexB = getOrDefault(grid.getColumnIndex(b.id));\n\t\n\t return indexA - indexB;\n\t }).forEach(function (column) {\n\t if (column.columns) sort(column.columns, grid);\n\t });\n\t }\n\t\n\t function getOrDefault(value) {\n\t return typeof value === 'undefined' ? -1 : value;\n\t }\n\t\n\t function getDepth(node) {\n\t if (node.length) for (var i in node) {\n\t return getDepth(node[i]);\n\t } else if (node.columns) return 1 + getDepth(node.columns);else return 1;\n\t }\n\t\n\t function getColumnsInDepth(node, depth, current) {\n\t var columns = [];\n\t current = current || 0;\n\t\n\t if (depth == current) {\n\t\n\t if (node.length) node.forEach(function (n) {\n\t if (n.columns) n.extractColumns = function () {\n\t return extractColumns(n);\n\t };\n\t });\n\t\n\t return node;\n\t } else for (var i in node) {\n\t if (node[i].columns) {\n\t columns = columns.concat(getColumnsInDepth(node[i].columns, depth, current + 1));\n\t }\n\t }return columns;\n\t }\n\t\n\t function extractColumns(node) {\n\t var result = [];\n\t\n\t if (node.hasOwnProperty('length')) {\n\t\n\t for (var i = 0; i < node.length; i++) {\n\t result = result.concat(extractColumns(node[i]));\n\t }\n\t } else {\n\t\n\t if (node.hasOwnProperty('columns')) result = result.concat(extractColumns(node.columns));else return node;\n\t }\n\t\n\t return result;\n\t }\n\t\n\t function cloneTreeColumns() {\n\t return $.extend(true, [], treeColumns);\n\t }\n\t\n\t init();\n\t\n\t this.hasDepth = function () {\n\t\n\t for (var i in treeColumns) {\n\t if (treeColumns[i].hasOwnProperty('columns')) return true;\n\t }return false;\n\t };\n\t\n\t this.getTreeColumns = function () {\n\t return treeColumns;\n\t };\n\t\n\t this.extractColumns = function () {\n\t return this.hasDepth() ? extractColumns(treeColumns) : treeColumns;\n\t };\n\t\n\t this.getDepth = function () {\n\t return getDepth(treeColumns);\n\t };\n\t\n\t this.getColumnsInDepth = function (depth) {\n\t return getColumnsInDepth(treeColumns, depth);\n\t };\n\t\n\t this.getColumnsInGroup = function (groups) {\n\t return extractColumns(groups);\n\t };\n\t\n\t this.visibleColumns = function () {\n\t return filter(cloneTreeColumns(), function () {\n\t return this.visible;\n\t });\n\t };\n\t\n\t this.filter = function (condition) {\n\t return filter(cloneTreeColumns(), condition);\n\t };\n\t\n\t this.reOrder = function (grid) {\n\t return sort(treeColumns, grid);\n\t };\n\t\n\t this.getById = function (id) {\n\t return columnsById[id];\n\t };\n\t\n\t this.getInIds = function (ids) {\n\t return ids.map(function (id) {\n\t return columnsById[id];\n\t });\n\t };\n\t}\n\n/***/ }),\n/* 2 */\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"jquery\");\n\n/***/ }),\n/* 3 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _jquery = __webpack_require__(2);\n\t\n\tvar _jquery2 = _interopRequireDefault(_jquery);\n\t\n\tvar _slick = __webpack_require__(1);\n\t\n\tvar _slick2 = _interopRequireDefault(_slick);\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\t\n\texports.default = CellRangeDecorator;\n\t\n\t/** *\n\t * Displays an overlay on top of a given cell range.\n\t *\n\t * TODO:\n\t * Currently, it blocks mouse events to DOM nodes behind it.\n\t * Use FF and WebKit-specific 'pointer-events' CSS style, or some kind of event forwarding.\n\t * Could also construct the borders separately using 4 individual DIVs.\n\t *\n\t * @param {Grid} grid\n\t * @param {Object} options\n\t */\n\t\n\tfunction CellRangeDecorator(grid, options) {\n\t var _elem = void 0;\n\t var _defaults = {\n\t selectionCssClass: 'slick-range-decorator',\n\t selectionCss: {\n\t zIndex: '9999',\n\t border: '2px dashed red'\n\t }\n\t };\n\t\n\t options = Object.assign({}, _defaults, options);\n\t\n\t function show(range) {\n\t if (!_elem) {\n\t _elem = (0, _jquery2.default)('
', { css: options.selectionCss }).addClass(options.selectionCssClass).css('position', 'absolute').appendTo(grid.getCanvasNode());\n\t }\n\t\n\t var from = grid.getCellNodeBox(range.fromRow, range.fromCell);\n\t var to = grid.getCellNodeBox(range.toRow, range.toCell);\n\t\n\t _elem.css({\n\t top: from.top - 1,\n\t left: from.left - 1,\n\t height: to.bottom - from.top - 2,\n\t width: to.right - from.left - 2\n\t });\n\t\n\t return _elem;\n\t }\n\t\n\t function hide() {\n\t if (_elem) {\n\t _elem.remove();\n\t _elem = null;\n\t }\n\t }\n\t\n\t Object.assign(this, {\n\t show: show,\n\t hide: hide\n\t });\n\t}\n\n/***/ }),\n/* 4 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _jquery = __webpack_require__(2);\n\t\n\tvar _jquery2 = _interopRequireDefault(_jquery);\n\t\n\tvar _slick = __webpack_require__(1);\n\t\n\tvar _slick2 = _interopRequireDefault(_slick);\n\t\n\tvar _slick3 = __webpack_require__(3);\n\t\n\tvar _slick4 = _interopRequireDefault(_slick3);\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\t\n\texports.default = CellRangeSelector;\n\t\n\t\n\tfunction CellRangeSelector(options) {\n\t var _grid = void 0;\n\t var _canvas = void 0;\n\t var _dragging = void 0;\n\t var _decorator = void 0;\n\t var _range = {};\n\t\n\t var _self = this;\n\t var _handler = new _slick2.default.EventHandler();\n\t var _defaults = {\n\t selectionCss: {\n\t // 'border': '2px dashed blue'\n\t }\n\t };\n\t\n\t function init(grid) {\n\t options = Object.assign({}, _defaults, options);\n\t _decorator = new _slick4.default(grid, options);\n\t _grid = grid;\n\t _canvas = _grid.getCanvasNode();\n\t _handler.subscribe(_grid.onDragInit, handleDragInit).subscribe(_grid.onDragStart, handleDragStart).subscribe(_grid.onDrag, handleDrag).subscribe(_grid.onDragEnd, handleDragEnd);\n\t }\n\t\n\t function destroy() {\n\t _handler.unsubscribeAll();\n\t }\n\t\n\t function handleDragInit(e, dd) {\n\t // prevent the grid from cancelling drag'n'drop by default\n\t e.stopImmediatePropagation();\n\t }\n\t\n\t function handleDragStart(jqueryEvent, interactEvent) {\n\t var cell = _grid.getCellFromEvent(interactEvent.originalEvent);\n\t if (_self.onBeforeCellRangeSelected.notify(cell) !== false) {\n\t if (_grid.canCellBeSelected(cell.row, cell.cell)) {\n\t _dragging = true;\n\t // jqueryEvent.stopImmediatePropagation();\n\t }\n\t }\n\t if (!_dragging) {\n\t return;\n\t }\n\t\n\t _grid.focus();\n\t\n\t var start = _grid.getCellFromPoint(interactEvent.x0 - (0, _jquery2.default)(_canvas).offset().left, interactEvent.y0 - (0, _jquery2.default)(_canvas).offset().top);\n\t\n\t _range = {\n\t start: start,\n\t end: {}\n\t };\n\t\n\t return _decorator.show(new _slick2.default.Range(start.row, start.cell));\n\t }\n\t\n\t function handleDrag(e, interactEvent) {\n\t if (!_dragging) {\n\t return;\n\t }\n\t // e.stopImmediatePropagation();\n\t\n\t var end = _grid.getCellFromPoint(interactEvent.pageX - (0, _jquery2.default)(_canvas).offset().left, interactEvent.pageY - (0, _jquery2.default)(_canvas).offset().top);\n\t\n\t if (!_grid.canCellBeSelected(end.row, end.cell)) {\n\t return;\n\t }\n\t\n\t _range.end = end;\n\t _decorator.show(new _slick2.default.Range(_range.start.row, _range.start.cell, end.row, end.cell));\n\t }\n\t\n\t function handleDragEnd(e) {\n\t if (!_dragging) {\n\t return;\n\t }\n\t\n\t _dragging = false;\n\t // e.stopImmediatePropagation();\n\t\n\t _decorator.hide();\n\t _self.onCellRangeSelected.notify({\n\t range: new _slick2.default.Range(_range.start.row, _range.start.cell, _range.end.row, _range.end.cell)\n\t });\n\t _range = {};\n\t }\n\t\n\t Object.assign(this, {\n\t init: init,\n\t destroy: destroy,\n\t\n\t onBeforeCellRangeSelected: new _slick2.default.Event(),\n\t onCellRangeSelected: new _slick2.default.Event()\n\t });\n\t}\n\n/***/ }),\n/* 5 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tvar _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; };\n\t\n\t/**\n\t * interact.js v1.2.6\n\t *\n\t * Copyright (c) 2012-2015 Taye Adeyemi \n\t * Open source under the MIT License.\n\t * https://raw.github.com/taye/interact.js/master/LICENSE\n\t *\n\t * This file has been monkey patched to pass the originalEvent on to drag events\n\t */\n\t(function (realWindow) {\n\t 'use strict';\n\t\n\t // return early if there's no window to work with (eg. Node.js)\n\t\n\t if (!realWindow) {\n\t return;\n\t }\n\t\n\t var // get wrapped window if using Shadow DOM polyfill\n\t window = function () {\n\t // create a TextNode\n\t var el = realWindow.document.createTextNode('');\n\t\n\t // check if it's wrapped by a polyfill\n\t if (el.ownerDocument !== realWindow.document && typeof realWindow.wrap === 'function' && realWindow.wrap(el) === el) {\n\t // return wrapped window\n\t return realWindow.wrap(realWindow);\n\t }\n\t\n\t // no Shadow DOM polyfil or native implementation\n\t return realWindow;\n\t }(),\n\t document = window.document,\n\t DocumentFragment = window.DocumentFragment || blank,\n\t SVGElement = window.SVGElement || blank,\n\t SVGSVGElement = window.SVGSVGElement || blank,\n\t SVGElementInstance = window.SVGElementInstance || blank,\n\t HTMLElement = window.HTMLElement || window.Element,\n\t PointerEvent = window.PointerEvent || window.MSPointerEvent,\n\t pEventTypes,\n\t hypot = Math.hypot || function (x, y) {\n\t return Math.sqrt(x * x + y * y);\n\t },\n\t tmpXY = {},\n\t // reduce object creation in getXY()\n\t\n\t documents = [],\n\t // all documents being listened to\n\t\n\t interactables = [],\n\t // all set interactables\n\t interactions = [],\n\t // all interactions\n\t\n\t dynamicDrop = false,\n\t\n\t\n\t // {\n\t // type: {\n\t // selectors: ['selector', ...],\n\t // contexts : [document, ...],\n\t // listeners: [[listener, useCapture], ...]\n\t // }\n\t // }\n\t delegatedEvents = {},\n\t defaultOptions = {\n\t base: {\n\t accept: null,\n\t actionChecker: null,\n\t styleCursor: true,\n\t preventDefault: 'auto',\n\t origin: { x: 0, y: 0 },\n\t deltaSource: 'page',\n\t allowFrom: null,\n\t ignoreFrom: null,\n\t _context: document,\n\t dropChecker: null\n\t },\n\t\n\t drag: {\n\t enabled: false,\n\t manualStart: true,\n\t max: Infinity,\n\t maxPerElement: 1,\n\t\n\t snap: null,\n\t restrict: null,\n\t inertia: null,\n\t autoScroll: null,\n\t\n\t axis: 'xy'\n\t },\n\t\n\t drop: {\n\t enabled: false,\n\t accept: null,\n\t overlap: 'pointer'\n\t },\n\t\n\t resize: {\n\t enabled: false,\n\t manualStart: false,\n\t max: Infinity,\n\t maxPerElement: 1,\n\t\n\t snap: null,\n\t restrict: null,\n\t inertia: null,\n\t autoScroll: null,\n\t\n\t square: false,\n\t preserveAspectRatio: false,\n\t axis: 'xy',\n\t\n\t // use default margin\n\t margin: NaN,\n\t\n\t // object with props left, right, top, bottom which are\n\t // true/false values to resize when the pointer is over that edge,\n\t // CSS selectors to match the handles for each direction\n\t // or the Elements for each handle\n\t edges: null,\n\t\n\t // a value of 'none' will limit the resize rect to a minimum of 0x0\n\t // 'negate' will alow the rect to have negative width/height\n\t // 'reposition' will keep the width/height positive by swapping\n\t // the top and bottom edges and/or swapping the left and right edges\n\t invert: 'none'\n\t },\n\t\n\t gesture: {\n\t manualStart: false,\n\t enabled: false,\n\t max: Infinity,\n\t maxPerElement: 1,\n\t\n\t restrict: null\n\t },\n\t\n\t perAction: {\n\t manualStart: false,\n\t max: Infinity,\n\t maxPerElement: 1,\n\t\n\t snap: {\n\t enabled: false,\n\t endOnly: false,\n\t range: Infinity,\n\t targets: null,\n\t offsets: null,\n\t\n\t relativePoints: null\n\t },\n\t\n\t restrict: {\n\t enabled: false,\n\t endOnly: false\n\t },\n\t\n\t autoScroll: {\n\t enabled: false,\n\t container: null, // the item that is scrolled (Window or HTMLElement)\n\t margin: 60,\n\t speed: 300 // the scroll speed in pixels per second\n\t },\n\t\n\t inertia: {\n\t enabled: false,\n\t resistance: 10, // the lambda in exponential decay\n\t minSpeed: 100, // target speed must be above this for inertia to start\n\t endSpeed: 10, // the speed at which inertia is slow enough to stop\n\t allowResume: true, // allow resuming an action in inertia phase\n\t zeroResumeDelta: true, // if an action is resumed after launch, set dx/dy to 0\n\t smoothEndDuration: 300 // animate to snap/restrict endOnly if there's no inertia\n\t }\n\t },\n\t\n\t _holdDuration: 600\n\t },\n\t\n\t\n\t // Things related to autoScroll\n\t autoScroll = {\n\t interaction: null,\n\t i: null, // the handle returned by window.setInterval\n\t x: 0, y: 0, // Direction each pulse is to scroll in\n\t\n\t // scroll the window by the values in scroll.x/y\n\t scroll: function scroll() {\n\t var options = autoScroll.interaction.target.options[autoScroll.interaction.prepared.name].autoScroll,\n\t container = options.container || getWindow(autoScroll.interaction.element),\n\t now = new Date().getTime(),\n\t\n\t // change in time in seconds\n\t dtx = (now - autoScroll.prevTimeX) / 1000,\n\t dty = (now - autoScroll.prevTimeY) / 1000,\n\t vx,\n\t vy,\n\t sx,\n\t sy;\n\t\n\t // displacement\n\t if (options.velocity) {\n\t vx = options.velocity.x;\n\t vy = options.velocity.y;\n\t } else {\n\t vx = vy = options.speed;\n\t }\n\t\n\t sx = vx * dtx;\n\t sy = vy * dty;\n\t\n\t if (sx >= 1 || sy >= 1) {\n\t if (isWindow(container)) {\n\t container.scrollBy(autoScroll.x * sx, autoScroll.y * sy);\n\t } else if (container) {\n\t container.scrollLeft += autoScroll.x * sx;\n\t container.scrollTop += autoScroll.y * sy;\n\t }\n\t\n\t if (sx >= 1) autoScroll.prevTimeX = now;\n\t if (sy >= 1) autoScroll.prevTimeY = now;\n\t }\n\t\n\t if (autoScroll.isScrolling) {\n\t cancelFrame(autoScroll.i);\n\t autoScroll.i = reqFrame(autoScroll.scroll);\n\t }\n\t },\n\t\n\t isScrolling: false,\n\t prevTimeX: 0,\n\t prevTimeY: 0,\n\t\n\t start: function start(interaction) {\n\t autoScroll.isScrolling = true;\n\t cancelFrame(autoScroll.i);\n\t\n\t autoScroll.interaction = interaction;\n\t autoScroll.prevTimeX = new Date().getTime();\n\t autoScroll.prevTimeY = new Date().getTime();\n\t autoScroll.i = reqFrame(autoScroll.scroll);\n\t },\n\t\n\t stop: function stop() {\n\t autoScroll.isScrolling = false;\n\t cancelFrame(autoScroll.i);\n\t }\n\t },\n\t\n\t\n\t // Does the browser support touch input?\n\t supportsTouch = 'ontouchstart' in window || window.DocumentTouch && document instanceof window.DocumentTouch,\n\t\n\t\n\t // Does the browser support PointerEvents\n\t supportsPointerEvent = PointerEvent && !/Chrome/.test(navigator.userAgent),\n\t\n\t\n\t // Less Precision with touch input\n\t margin = supportsTouch || supportsPointerEvent ? 20 : 10,\n\t pointerMoveTolerance = 1,\n\t\n\t\n\t // for ignoring browser's simulated mouse events\n\t prevTouchTime = 0,\n\t\n\t\n\t // Allow this many interactions to happen simultaneously\n\t maxInteractions = Infinity,\n\t\n\t\n\t // Check if is IE9 or older\n\t actionCursors = document.all && !window.atob ? {\n\t drag: 'move',\n\t resizex: 'e-resize',\n\t resizey: 's-resize',\n\t resizexy: 'se-resize',\n\t\n\t resizetop: 'n-resize',\n\t resizeleft: 'w-resize',\n\t resizebottom: 's-resize',\n\t resizeright: 'e-resize',\n\t resizetopleft: 'se-resize',\n\t resizebottomright: 'se-resize',\n\t resizetopright: 'ne-resize',\n\t resizebottomleft: 'ne-resize',\n\t\n\t gesture: ''\n\t } : {\n\t drag: 'move',\n\t resizex: 'ew-resize',\n\t resizey: 'ns-resize',\n\t resizexy: 'nwse-resize',\n\t\n\t resizetop: 'ns-resize',\n\t resizeleft: 'ew-resize',\n\t resizebottom: 'ns-resize',\n\t resizeright: 'ew-resize',\n\t resizetopleft: 'nwse-resize',\n\t resizebottomright: 'nwse-resize',\n\t resizetopright: 'nesw-resize',\n\t resizebottomleft: 'nesw-resize',\n\t\n\t gesture: ''\n\t },\n\t actionIsEnabled = {\n\t drag: true,\n\t resize: true,\n\t gesture: true\n\t },\n\t\n\t\n\t // because Webkit and Opera still use 'mousewheel' event type\n\t wheelEvent = 'onmousewheel' in document ? 'mousewheel' : 'wheel',\n\t eventTypes = ['dragstart', 'dragmove', 'draginertiastart', 'dragend', 'dragenter', 'dragleave', 'dropactivate', 'dropdeactivate', 'dropmove', 'drop', 'resizestart', 'resizemove', 'resizeinertiastart', 'resizeend', 'gesturestart', 'gesturemove', 'gestureinertiastart', 'gestureend', 'down', 'move', 'up', 'cancel', 'tap', 'doubletap', 'hold'],\n\t globalEvents = {},\n\t\n\t\n\t // Opera Mobile must be handled differently\n\t isOperaMobile = navigator.appName == 'Opera' && supportsTouch && navigator.userAgent.match('Presto'),\n\t\n\t\n\t // scrolling doesn't change the result of getClientRects on iOS 7\n\t isIOS7 = /iP(hone|od|ad)/.test(navigator.platform) && /OS 7[^\\d]/.test(navigator.appVersion),\n\t\n\t\n\t // prefix matchesSelector\n\t prefixedMatchesSelector = 'matches' in Element.prototype ? 'matches' : 'webkitMatchesSelector' in Element.prototype ? 'webkitMatchesSelector' : 'mozMatchesSelector' in Element.prototype ? 'mozMatchesSelector' : 'oMatchesSelector' in Element.prototype ? 'oMatchesSelector' : 'msMatchesSelector',\n\t\n\t\n\t // will be polyfill function if browser is IE8\n\t ie8MatchesSelector,\n\t\n\t\n\t // native requestAnimationFrame or polyfill\n\t reqFrame = realWindow.requestAnimationFrame,\n\t cancelFrame = realWindow.cancelAnimationFrame,\n\t\n\t\n\t // Events wrapper\n\t events = function () {\n\t var useAttachEvent = 'attachEvent' in window && !('addEventListener' in window),\n\t addEvent = useAttachEvent ? 'attachEvent' : 'addEventListener',\n\t removeEvent = useAttachEvent ? 'detachEvent' : 'removeEventListener',\n\t on = useAttachEvent ? 'on' : '',\n\t elements = [],\n\t targets = [],\n\t attachedListeners = [];\n\t\n\t function add(element, type, listener, useCapture) {\n\t var elementIndex = indexOf(elements, element),\n\t target = targets[elementIndex];\n\t\n\t if (!target) {\n\t target = {\n\t events: {},\n\t typeCount: 0\n\t };\n\t\n\t elementIndex = elements.push(element) - 1;\n\t targets.push(target);\n\t\n\t attachedListeners.push(useAttachEvent ? {\n\t supplied: [],\n\t wrapped: [],\n\t useCount: []\n\t } : null);\n\t }\n\t\n\t if (!target.events[type]) {\n\t target.events[type] = [];\n\t target.typeCount++;\n\t }\n\t\n\t if (!contains(target.events[type], listener)) {\n\t var ret;\n\t\n\t if (useAttachEvent) {\n\t var listeners = attachedListeners[elementIndex],\n\t listenerIndex = indexOf(listeners.supplied, listener);\n\t\n\t var wrapped = listeners.wrapped[listenerIndex] || function (event) {\n\t if (!event.immediatePropagationStopped) {\n\t event.target = event.srcElement;\n\t event.currentTarget = element;\n\t\n\t event.preventDefault = event.preventDefault || preventDef;\n\t event.stopPropagation = event.stopPropagation || stopProp;\n\t event.stopImmediatePropagation = event.stopImmediatePropagation || stopImmProp;\n\t\n\t if (/mouse|click/.test(event.type)) {\n\t event.pageX = event.clientX + getWindow(element).document.documentElement.scrollLeft;\n\t event.pageY = event.clientY + getWindow(element).document.documentElement.scrollTop;\n\t }\n\t\n\t listener(event);\n\t }\n\t };\n\t\n\t ret = element[addEvent](on + type, wrapped, Boolean(useCapture));\n\t\n\t if (listenerIndex === -1) {\n\t listeners.supplied.push(listener);\n\t listeners.wrapped.push(wrapped);\n\t listeners.useCount.push(1);\n\t } else {\n\t listeners.useCount[listenerIndex]++;\n\t }\n\t } else {\n\t ret = element[addEvent](type, listener, useCapture || false);\n\t }\n\t target.events[type].push(listener);\n\t\n\t return ret;\n\t }\n\t }\n\t\n\t function remove(element, type, listener, useCapture) {\n\t var i,\n\t elementIndex = indexOf(elements, element),\n\t target = targets[elementIndex],\n\t listeners,\n\t listenerIndex,\n\t wrapped = listener;\n\t\n\t if (!target || !target.events) {\n\t return;\n\t }\n\t\n\t if (useAttachEvent) {\n\t listeners = attachedListeners[elementIndex];\n\t listenerIndex = indexOf(listeners.supplied, listener);\n\t wrapped = listeners.wrapped[listenerIndex];\n\t }\n\t\n\t if (type === 'all') {\n\t for (type in target.events) {\n\t if (target.events.hasOwnProperty(type)) {\n\t remove(element, type, 'all');\n\t }\n\t }\n\t return;\n\t }\n\t\n\t if (target.events[type]) {\n\t var len = target.events[type].length;\n\t\n\t if (listener === 'all') {\n\t for (i = 0; i < len; i++) {\n\t remove(element, type, target.events[type][i], Boolean(useCapture));\n\t }\n\t return;\n\t } else {\n\t for (i = 0; i < len; i++) {\n\t if (target.events[type][i] === listener) {\n\t element[removeEvent](on + type, wrapped, useCapture || false);\n\t target.events[type].splice(i, 1);\n\t\n\t if (useAttachEvent && listeners) {\n\t listeners.useCount[listenerIndex]--;\n\t if (listeners.useCount[listenerIndex] === 0) {\n\t listeners.supplied.splice(listenerIndex, 1);\n\t listeners.wrapped.splice(listenerIndex, 1);\n\t listeners.useCount.splice(listenerIndex, 1);\n\t }\n\t }\n\t\n\t break;\n\t }\n\t }\n\t }\n\t\n\t if (target.events[type] && target.events[type].length === 0) {\n\t target.events[type] = null;\n\t target.typeCount--;\n\t }\n\t }\n\t\n\t if (!target.typeCount) {\n\t targets.splice(elementIndex, 1);\n\t elements.splice(elementIndex, 1);\n\t attachedListeners.splice(elementIndex, 1);\n\t }\n\t }\n\t\n\t function preventDef() {\n\t this.returnValue = false;\n\t }\n\t\n\t function stopProp() {\n\t this.cancelBubble = true;\n\t }\n\t\n\t function stopImmProp() {\n\t this.cancelBubble = true;\n\t this.immediatePropagationStopped = true;\n\t }\n\t\n\t return {\n\t add: add,\n\t remove: remove,\n\t useAttachEvent: useAttachEvent,\n\t\n\t _elements: elements,\n\t _targets: targets,\n\t _attachedListeners: attachedListeners\n\t };\n\t }();\n\t\n\t function blank() {}\n\t\n\t function isElement(o) {\n\t if (!o || (typeof o === 'undefined' ? 'undefined' : _typeof(o)) !== 'object') {\n\t return false;\n\t }\n\t\n\t var _window = getWindow(o) || window;\n\t\n\t return (/object|function/.test(_typeof(_window.Element)) ? o instanceof _window.Element // DOM2\n\t : o.nodeType === 1 && typeof o.nodeName === 'string'\n\t );\n\t }\n\t function isWindow(thing) {\n\t return thing === window || !!(thing && thing.Window) && thing instanceof thing.Window;\n\t }\n\t function isDocFrag(thing) {\n\t return !!thing && thing instanceof DocumentFragment;\n\t }\n\t function isArray(thing) {\n\t return isObject(thing) && _typeof(thing.length) !== undefined && isFunction(thing.splice);\n\t }\n\t function isObject(thing) {\n\t return !!thing && (typeof thing === 'undefined' ? 'undefined' : _typeof(thing)) === 'object';\n\t }\n\t function isFunction(thing) {\n\t return typeof thing === 'function';\n\t }\n\t function isNumber(thing) {\n\t return typeof thing === 'number';\n\t }\n\t function isBool(thing) {\n\t return typeof thing === 'boolean';\n\t }\n\t function isString(thing) {\n\t return typeof thing === 'string';\n\t }\n\t\n\t function trySelector(value) {\n\t if (!isString(value)) {\n\t return false;\n\t }\n\t\n\t // an exception will be raised if it is invalid\n\t document.querySelector(value);\n\t return true;\n\t }\n\t\n\t function extend(dest, source) {\n\t for (var prop in source) {\n\t dest[prop] = source[prop];\n\t }\n\t return dest;\n\t }\n\t\n\t var prefixedPropREs = {\n\t webkit: /(Movement[XY]|Radius[XY]|RotationAngle|Force)$/\n\t };\n\t\n\t function pointerExtend(dest, source) {\n\t for (var prop in source) {\n\t var deprecated = false;\n\t\n\t // skip deprecated prefixed properties\n\t for (var vendor in prefixedPropREs) {\n\t if (prop.indexOf(vendor) === 0 && prefixedPropREs[vendor].test(prop)) {\n\t deprecated = true;\n\t break;\n\t }\n\t }\n\t\n\t if (!deprecated) {\n\t dest[prop] = source[prop];\n\t }\n\t }\n\t return dest;\n\t }\n\t\n\t function copyCoords(dest, src) {\n\t dest.page = dest.page || {};\n\t dest.page.x = src.page.x;\n\t dest.page.y = src.page.y;\n\t\n\t dest.client = dest.client || {};\n\t dest.client.x = src.client.x;\n\t dest.client.y = src.client.y;\n\t\n\t dest.timeStamp = src.timeStamp;\n\t }\n\t\n\t function _setEventXY(targetObj, pointers, interaction) {\n\t var pointer = pointers.length > 1 ? pointerAverage(pointers) : pointers[0];\n\t\n\t _getPageXY(pointer, tmpXY, interaction);\n\t targetObj.page.x = tmpXY.x;\n\t targetObj.page.y = tmpXY.y;\n\t\n\t _getClientXY(pointer, tmpXY, interaction);\n\t targetObj.client.x = tmpXY.x;\n\t targetObj.client.y = tmpXY.y;\n\t\n\t targetObj.timeStamp = new Date().getTime();\n\t }\n\t\n\t function setEventDeltas(targetObj, prev, cur) {\n\t targetObj.page.x = cur.page.x - prev.page.x;\n\t targetObj.page.y = cur.page.y - prev.page.y;\n\t targetObj.client.x = cur.client.x - prev.client.x;\n\t targetObj.client.y = cur.client.y - prev.client.y;\n\t targetObj.timeStamp = new Date().getTime() - prev.timeStamp;\n\t\n\t // set pointer velocity\n\t var dt = Math.max(targetObj.timeStamp / 1000, 0.001);\n\t targetObj.page.speed = hypot(targetObj.page.x, targetObj.page.y) / dt;\n\t targetObj.page.vx = targetObj.page.x / dt;\n\t targetObj.page.vy = targetObj.page.y / dt;\n\t\n\t targetObj.client.speed = hypot(targetObj.client.x, targetObj.page.y) / dt;\n\t targetObj.client.vx = targetObj.client.x / dt;\n\t targetObj.client.vy = targetObj.client.y / dt;\n\t }\n\t\n\t function isNativePointer(pointer) {\n\t return pointer instanceof window.Event || supportsTouch && window.Touch && pointer instanceof window.Touch;\n\t }\n\t\n\t // Get specified X/Y coords for mouse or event.touches[0]\n\t function getXY(type, pointer, xy) {\n\t xy = xy || {};\n\t type = type || 'page';\n\t\n\t xy.x = pointer[type + 'X'];\n\t xy.y = pointer[type + 'Y'];\n\t\n\t return xy;\n\t }\n\t\n\t function _getPageXY(pointer, page) {\n\t page = page || {};\n\t\n\t // Opera Mobile handles the viewport and scrolling oddly\n\t if (isOperaMobile && isNativePointer(pointer)) {\n\t getXY('screen', pointer, page);\n\t\n\t page.x += window.scrollX;\n\t page.y += window.scrollY;\n\t } else {\n\t getXY('page', pointer, page);\n\t }\n\t\n\t return page;\n\t }\n\t\n\t function _getClientXY(pointer, client) {\n\t client = client || {};\n\t\n\t if (isOperaMobile && isNativePointer(pointer)) {\n\t // Opera Mobile handles the viewport and scrolling oddly\n\t getXY('screen', pointer, client);\n\t } else {\n\t getXY('client', pointer, client);\n\t }\n\t\n\t return client;\n\t }\n\t\n\t function getScrollXY(win) {\n\t win = win || window;\n\t return {\n\t x: win.scrollX || win.document.documentElement.scrollLeft,\n\t y: win.scrollY || win.document.documentElement.scrollTop\n\t };\n\t }\n\t\n\t function getPointerId(pointer) {\n\t return isNumber(pointer.pointerId) ? pointer.pointerId : pointer.identifier;\n\t }\n\t\n\t function getActualElement(element) {\n\t return element instanceof SVGElementInstance ? element.correspondingUseElement : element;\n\t }\n\t\n\t function getWindow(node) {\n\t if (isWindow(node)) {\n\t return node;\n\t }\n\t\n\t var rootNode = node.ownerDocument || node;\n\t\n\t return rootNode.defaultView || rootNode.parentWindow || window;\n\t }\n\t\n\t function getElementClientRect(element) {\n\t var clientRect = element instanceof SVGElement ? element.getBoundingClientRect() : element.getClientRects()[0];\n\t\n\t return clientRect && {\n\t left: clientRect.left,\n\t right: clientRect.right,\n\t top: clientRect.top,\n\t bottom: clientRect.bottom,\n\t width: clientRect.width || clientRect.right - clientRect.left,\n\t height: clientRect.height || clientRect.bottom - clientRect.top\n\t };\n\t }\n\t\n\t function getElementRect(element) {\n\t var clientRect = getElementClientRect(element);\n\t\n\t if (!isIOS7 && clientRect) {\n\t var scroll = getScrollXY(getWindow(element));\n\t\n\t clientRect.left += scroll.x;\n\t clientRect.right += scroll.x;\n\t clientRect.top += scroll.y;\n\t clientRect.bottom += scroll.y;\n\t }\n\t\n\t return clientRect;\n\t }\n\t\n\t function getTouchPair(event) {\n\t var touches = [];\n\t\n\t // array of touches is supplied\n\t if (isArray(event)) {\n\t touches[0] = event[0];\n\t touches[1] = event[1];\n\t }\n\t // an event\n\t else {\n\t if (event.type === 'touchend') {\n\t if (event.touches.length === 1) {\n\t touches[0] = event.touches[0];\n\t touches[1] = event.changedTouches[0];\n\t } else if (event.touches.length === 0) {\n\t touches[0] = event.changedTouches[0];\n\t touches[1] = event.changedTouches[1];\n\t }\n\t } else {\n\t touches[0] = event.touches[0];\n\t touches[1] = event.touches[1];\n\t }\n\t }\n\t\n\t return touches;\n\t }\n\t\n\t function pointerAverage(pointers) {\n\t var average = {\n\t pageX: 0,\n\t pageY: 0,\n\t clientX: 0,\n\t clientY: 0,\n\t screenX: 0,\n\t screenY: 0\n\t };\n\t var prop;\n\t\n\t for (var i = 0; i < pointers.length; i++) {\n\t for (prop in average) {\n\t average[prop] += pointers[i][prop];\n\t }\n\t }\n\t for (prop in average) {\n\t average[prop] /= pointers.length;\n\t }\n\t\n\t return average;\n\t }\n\t\n\t function touchBBox(event) {\n\t if (!event.length && !(event.touches && event.touches.length > 1)) {\n\t return;\n\t }\n\t\n\t var touches = getTouchPair(event),\n\t minX = Math.min(touches[0].pageX, touches[1].pageX),\n\t minY = Math.min(touches[0].pageY, touches[1].pageY),\n\t maxX = Math.max(touches[0].pageX, touches[1].pageX),\n\t maxY = Math.max(touches[0].pageY, touches[1].pageY);\n\t\n\t return {\n\t x: minX,\n\t y: minY,\n\t left: minX,\n\t top: minY,\n\t width: maxX - minX,\n\t height: maxY - minY\n\t };\n\t }\n\t\n\t function touchDistance(event, deltaSource) {\n\t deltaSource = deltaSource || defaultOptions.deltaSource;\n\t\n\t var sourceX = deltaSource + 'X',\n\t sourceY = deltaSource + 'Y',\n\t touches = getTouchPair(event);\n\t\n\t var dx = touches[0][sourceX] - touches[1][sourceX],\n\t dy = touches[0][sourceY] - touches[1][sourceY];\n\t\n\t return hypot(dx, dy);\n\t }\n\t\n\t function touchAngle(event, prevAngle, deltaSource) {\n\t deltaSource = deltaSource || defaultOptions.deltaSource;\n\t\n\t var sourceX = deltaSource + 'X',\n\t sourceY = deltaSource + 'Y',\n\t touches = getTouchPair(event),\n\t dx = touches[0][sourceX] - touches[1][sourceX],\n\t dy = touches[0][sourceY] - touches[1][sourceY],\n\t angle = 180 * Math.atan(dy / dx) / Math.PI;\n\t\n\t if (isNumber(prevAngle)) {\n\t var dr = angle - prevAngle,\n\t drClamped = dr % 360;\n\t\n\t if (drClamped > 315) {\n\t angle -= 360 + angle / 360 | 0 * 360;\n\t } else if (drClamped > 135) {\n\t angle -= 180 + angle / 360 | 0 * 360;\n\t } else if (drClamped < -315) {\n\t angle += 360 + angle / 360 | 0 * 360;\n\t } else if (drClamped < -135) {\n\t angle += 180 + angle / 360 | 0 * 360;\n\t }\n\t }\n\t\n\t return angle;\n\t }\n\t\n\t function getOriginXY(interactable, element) {\n\t var origin = interactable ? interactable.options.origin : defaultOptions.origin;\n\t\n\t if (origin === 'parent') {\n\t origin = parentElement(element);\n\t } else if (origin === 'self') {\n\t origin = interactable.getRect(element);\n\t } else if (trySelector(origin)) {\n\t origin = closest(element, origin) || { x: 0, y: 0 };\n\t }\n\t\n\t if (isFunction(origin)) {\n\t origin = origin(interactable && element);\n\t }\n\t\n\t if (isElement(origin)) {\n\t origin = getElementRect(origin);\n\t }\n\t\n\t origin.x = 'x' in origin ? origin.x : origin.left;\n\t origin.y = 'y' in origin ? origin.y : origin.top;\n\t\n\t return origin;\n\t }\n\t\n\t // http://stackoverflow.com/a/5634528/2280888\n\t function _getQBezierValue(t, p1, p2, p3) {\n\t var iT = 1 - t;\n\t return iT * iT * p1 + 2 * iT * t * p2 + t * t * p3;\n\t }\n\t\n\t function getQuadraticCurvePoint(startX, startY, cpX, cpY, endX, endY, position) {\n\t return {\n\t x: _getQBezierValue(position, startX, cpX, endX),\n\t y: _getQBezierValue(position, startY, cpY, endY)\n\t };\n\t }\n\t\n\t // http://gizma.com/easing/\n\t function easeOutQuad(t, b, c, d) {\n\t t /= d;\n\t return -c * t * (t - 2) + b;\n\t }\n\t\n\t function nodeContains(parent, child) {\n\t while (child) {\n\t if (child === parent) {\n\t return true;\n\t }\n\t\n\t child = child.parentNode;\n\t }\n\t\n\t return false;\n\t }\n\t\n\t function closest(child, selector) {\n\t var parent = parentElement(child);\n\t\n\t while (isElement(parent)) {\n\t if (matchesSelector(parent, selector)) {\n\t return parent;\n\t }\n\t\n\t parent = parentElement(parent);\n\t }\n\t\n\t return null;\n\t }\n\t\n\t function parentElement(node) {\n\t var parent = node.parentNode;\n\t\n\t if (isDocFrag(parent)) {\n\t // skip past #shado-root fragments\n\t while ((parent = parent.host) && isDocFrag(parent)) {}\n\t\n\t return parent;\n\t }\n\t\n\t return parent;\n\t }\n\t\n\t function inContext(interactable, element) {\n\t return interactable._context === element.ownerDocument || nodeContains(interactable._context, element);\n\t }\n\t\n\t function testIgnore(interactable, interactableElement, element) {\n\t var ignoreFrom = interactable.options.ignoreFrom;\n\t\n\t if (!ignoreFrom || !isElement(element)) {\n\t return false;\n\t }\n\t\n\t if (isString(ignoreFrom)) {\n\t return matchesUpTo(element, ignoreFrom, interactableElement);\n\t } else if (isElement(ignoreFrom)) {\n\t return nodeContains(ignoreFrom, element);\n\t }\n\t\n\t return false;\n\t }\n\t\n\t function testAllow(interactable, interactableElement, element) {\n\t var allowFrom = interactable.options.allowFrom;\n\t\n\t if (!allowFrom) {\n\t return true;\n\t }\n\t\n\t if (!isElement(element)) {\n\t return false;\n\t }\n\t\n\t if (isString(allowFrom)) {\n\t return matchesUpTo(element, allowFrom, interactableElement);\n\t } else if (isElement(allowFrom)) {\n\t return nodeContains(allowFrom, element);\n\t }\n\t\n\t return false;\n\t }\n\t\n\t function checkAxis(axis, interactable) {\n\t if (!interactable) {\n\t return false;\n\t }\n\t\n\t var thisAxis = interactable.options.drag.axis;\n\t\n\t return axis === 'xy' || thisAxis === 'xy' || thisAxis === axis;\n\t }\n\t\n\t function checkSnap(interactable, action) {\n\t var options = interactable.options;\n\t\n\t if (/^resize/.test(action)) {\n\t action = 'resize';\n\t }\n\t\n\t return options[action].snap && options[action].snap.enabled;\n\t }\n\t\n\t function checkRestrict(interactable, action) {\n\t var options = interactable.options;\n\t\n\t if (/^resize/.test(action)) {\n\t action = 'resize';\n\t }\n\t\n\t return options[action].restrict && options[action].restrict.enabled;\n\t }\n\t\n\t function checkAutoScroll(interactable, action) {\n\t var options = interactable.options;\n\t\n\t if (/^resize/.test(action)) {\n\t action = 'resize';\n\t }\n\t\n\t return options[action].autoScroll && options[action].autoScroll.enabled;\n\t }\n\t\n\t function withinInteractionLimit(interactable, element, action) {\n\t var options = interactable.options,\n\t maxActions = options[action.name].max,\n\t maxPerElement = options[action.name].maxPerElement,\n\t activeInteractions = 0,\n\t targetCount = 0,\n\t targetElementCount = 0;\n\t\n\t for (var i = 0, len = interactions.length; i < len; i++) {\n\t var interaction = interactions[i],\n\t otherAction = interaction.prepared.name,\n\t active = interaction.interacting();\n\t\n\t if (!active) {\n\t continue;\n\t }\n\t\n\t activeInteractions++;\n\t\n\t if (activeInteractions >= maxInteractions) {\n\t return false;\n\t }\n\t\n\t if (interaction.target !== interactable) {\n\t continue;\n\t }\n\t\n\t targetCount += otherAction === action.name | 0;\n\t\n\t if (targetCount >= maxActions) {\n\t return false;\n\t }\n\t\n\t if (interaction.element === element) {\n\t targetElementCount++;\n\t\n\t if (otherAction !== action.name || targetElementCount >= maxPerElement) {\n\t return false;\n\t }\n\t }\n\t }\n\t\n\t return maxInteractions > 0;\n\t }\n\t\n\t // Test for the element that's \"above\" all other qualifiers\n\t function indexOfDeepestElement(elements) {\n\t var dropzone,\n\t deepestZone = elements[0],\n\t index = deepestZone ? 0 : -1,\n\t parent,\n\t deepestZoneParents = [],\n\t dropzoneParents = [],\n\t child,\n\t i,\n\t n;\n\t\n\t for (i = 1; i < elements.length; i++) {\n\t dropzone = elements[i];\n\t\n\t // an element might belong to multiple selector dropzones\n\t if (!dropzone || dropzone === deepestZone) {\n\t continue;\n\t }\n\t\n\t if (!deepestZone) {\n\t deepestZone = dropzone;\n\t index = i;\n\t continue;\n\t }\n\t\n\t // check if the deepest or current are document.documentElement or document.rootElement\n\t // - if the current dropzone is, do nothing and continue\n\t if (dropzone.parentNode === dropzone.ownerDocument) {\n\t continue;\n\t }\n\t // - if deepest is, update with the current dropzone and continue to next\n\t else if (deepestZone.parentNode === dropzone.ownerDocument) {\n\t deepestZone = dropzone;\n\t index = i;\n\t continue;\n\t }\n\t\n\t if (!deepestZoneParents.length) {\n\t parent = deepestZone;\n\t while (parent.parentNode && parent.parentNode !== parent.ownerDocument) {\n\t deepestZoneParents.unshift(parent);\n\t parent = parent.parentNode;\n\t }\n\t }\n\t\n\t // if this element is an svg element and the current deepest is\n\t // an HTMLElement\n\t if (deepestZone instanceof HTMLElement && dropzone instanceof SVGElement && !(dropzone instanceof SVGSVGElement)) {\n\t if (dropzone === deepestZone.parentNode) {\n\t continue;\n\t }\n\t\n\t parent = dropzone.ownerSVGElement;\n\t } else {\n\t parent = dropzone;\n\t }\n\t\n\t dropzoneParents = [];\n\t\n\t while (parent.parentNode !== parent.ownerDocument) {\n\t dropzoneParents.unshift(parent);\n\t parent = parent.parentNode;\n\t }\n\t\n\t n = 0;\n\t\n\t // get (position of last common ancestor) + 1\n\t while (dropzoneParents[n] && dropzoneParents[n] === deepestZoneParents[n]) {\n\t n++;\n\t }\n\t\n\t var parents = [dropzoneParents[n - 1], dropzoneParents[n], deepestZoneParents[n]];\n\t\n\t child = parents[0].lastChild;\n\t\n\t while (child) {\n\t if (child === parents[1]) {\n\t deepestZone = dropzone;\n\t index = i;\n\t deepestZoneParents = [];\n\t\n\t break;\n\t } else if (child === parents[2]) {\n\t break;\n\t }\n\t\n\t child = child.previousSibling;\n\t }\n\t }\n\t\n\t return index;\n\t }\n\t\n\t function Interaction() {\n\t this.target = null; // current interactable being interacted with\n\t this.element = null; // the target element of the interactable\n\t this.dropTarget = null; // the dropzone a drag target might be dropped into\n\t this.dropElement = null; // the element at the time of checking\n\t this.prevDropTarget = null; // the dropzone that was recently dragged away from\n\t this.prevDropElement = null; // the element at the time of checking\n\t\n\t this.prepared = { // action that's ready to be fired on next move event\n\t name: null,\n\t axis: null,\n\t edges: null\n\t };\n\t\n\t this.matches = []; // all selectors that are matched by target element\n\t this.matchElements = []; // corresponding elements\n\t\n\t this.inertiaStatus = {\n\t active: false,\n\t smoothEnd: false,\n\t ending: false,\n\t\n\t startEvent: null,\n\t upCoords: {},\n\t\n\t xe: 0, ye: 0,\n\t sx: 0, sy: 0,\n\t\n\t t0: 0,\n\t vx0: 0, vys: 0,\n\t duration: 0,\n\t\n\t resumeDx: 0,\n\t resumeDy: 0,\n\t\n\t lambda_v0: 0,\n\t one_ve_v0: 0,\n\t i: null\n\t };\n\t\n\t if (isFunction(Function.prototype.bind)) {\n\t this.boundInertiaFrame = this.inertiaFrame.bind(this);\n\t this.boundSmoothEndFrame = this.smoothEndFrame.bind(this);\n\t } else {\n\t var that = this;\n\t\n\t this.boundInertiaFrame = function () {\n\t return that.inertiaFrame();\n\t };\n\t this.boundSmoothEndFrame = function () {\n\t return that.smoothEndFrame();\n\t };\n\t }\n\t\n\t this.activeDrops = {\n\t dropzones: [], // the dropzones that are mentioned below\n\t elements: [], // elements of dropzones that accept the target draggable\n\t rects: [] // the rects of the elements mentioned above\n\t };\n\t\n\t // keep track of added pointers\n\t this.pointers = [];\n\t this.pointerIds = [];\n\t this.downTargets = [];\n\t this.downTimes = [];\n\t this.holdTimers = [];\n\t\n\t // Previous native pointer move event coordinates\n\t this.prevCoords = {\n\t page: { x: 0, y: 0 },\n\t client: { x: 0, y: 0 },\n\t timeStamp: 0\n\t };\n\t // current native pointer move event coordinates\n\t this.curCoords = {\n\t page: { x: 0, y: 0 },\n\t client: { x: 0, y: 0 },\n\t timeStamp: 0\n\t };\n\t\n\t // Starting InteractEvent pointer coordinates\n\t this.startCoords = {\n\t page: { x: 0, y: 0 },\n\t client: { x: 0, y: 0 },\n\t timeStamp: 0\n\t };\n\t\n\t // Change in coordinates and time of the pointer\n\t this.pointerDelta = {\n\t page: { x: 0, y: 0, vx: 0, vy: 0, speed: 0 },\n\t client: { x: 0, y: 0, vx: 0, vy: 0, speed: 0 },\n\t timeStamp: 0\n\t };\n\t\n\t this.downEvent = null; // pointerdown/mousedown/touchstart event\n\t this.downPointer = {};\n\t\n\t this._eventTarget = null;\n\t this._curEventTarget = null;\n\t\n\t this.prevEvent = null; // previous action event\n\t this.tapTime = 0; // time of the most recent tap event\n\t this.prevTap = null;\n\t\n\t this.startOffset = { left: 0, right: 0, top: 0, bottom: 0 };\n\t this.restrictOffset = { left: 0, right: 0, top: 0, bottom: 0 };\n\t this.snapOffsets = [];\n\t\n\t this.gesture = {\n\t start: { x: 0, y: 0 },\n\t\n\t startDistance: 0, // distance between two touches of touchStart\n\t prevDistance: 0,\n\t distance: 0,\n\t\n\t scale: 1, // gesture.distance / gesture.startDistance\n\t\n\t startAngle: 0, // angle of line joining two touches\n\t prevAngle: 0 // angle of the previous gesture event\n\t };\n\t\n\t this.snapStatus = {\n\t x: 0, y: 0,\n\t dx: 0, dy: 0,\n\t realX: 0, realY: 0,\n\t snappedX: 0, snappedY: 0,\n\t targets: [],\n\t locked: false,\n\t changed: false\n\t };\n\t\n\t this.restrictStatus = {\n\t dx: 0, dy: 0,\n\t restrictedX: 0, restrictedY: 0,\n\t snap: null,\n\t restricted: false,\n\t changed: false\n\t };\n\t\n\t this.restrictStatus.snap = this.snapStatus;\n\t\n\t this.pointerIsDown = false;\n\t this.pointerWasMoved = false;\n\t this.gesturing = false;\n\t this.dragging = false;\n\t this.resizing = false;\n\t this.resizeAxes = 'xy';\n\t\n\t this.mouse = false;\n\t\n\t interactions.push(this);\n\t }\n\t\n\t Interaction.prototype = {\n\t getPageXY: function getPageXY(pointer, xy) {\n\t return _getPageXY(pointer, xy, this);\n\t },\n\t getClientXY: function getClientXY(pointer, xy) {\n\t return _getClientXY(pointer, xy, this);\n\t },\n\t setEventXY: function setEventXY(target, ptr) {\n\t return _setEventXY(target, ptr, this);\n\t },\n\t\n\t pointerOver: function pointerOver(pointer, event, eventTarget) {\n\t if (this.prepared.name || !this.mouse) {\n\t return;\n\t }\n\t\n\t var curMatches = [],\n\t curMatchElements = [],\n\t prevTargetElement = this.element;\n\t\n\t this.addPointer(pointer);\n\t\n\t if (this.target && (testIgnore(this.target, this.element, eventTarget) || !testAllow(this.target, this.element, eventTarget))) {\n\t // if the eventTarget should be ignored or shouldn't be allowed\n\t // clear the previous target\n\t this.target = null;\n\t this.element = null;\n\t this.matches = [];\n\t this.matchElements = [];\n\t }\n\t\n\t var elementInteractable = interactables.get(eventTarget),\n\t elementAction = elementInteractable && !testIgnore(elementInteractable, eventTarget, eventTarget) && testAllow(elementInteractable, eventTarget, eventTarget) && validateAction(elementInteractable.getAction(pointer, event, this, eventTarget), elementInteractable);\n\t\n\t if (elementAction && !withinInteractionLimit(elementInteractable, eventTarget, elementAction)) {\n\t elementAction = null;\n\t }\n\t\n\t function pushCurMatches(interactable, selector) {\n\t if (interactable && inContext(interactable, eventTarget) && !testIgnore(interactable, eventTarget, eventTarget) && testAllow(interactable, eventTarget, eventTarget) && matchesSelector(eventTarget, selector)) {\n\t curMatches.push(interactable);\n\t curMatchElements.push(eventTarget);\n\t }\n\t }\n\t\n\t if (elementAction) {\n\t this.target = elementInteractable;\n\t this.element = eventTarget;\n\t this.matches = [];\n\t this.matchElements = [];\n\t } else {\n\t interactables.forEachSelector(pushCurMatches);\n\t\n\t if (this.validateSelector(pointer, event, curMatches, curMatchElements)) {\n\t this.matches = curMatches;\n\t this.matchElements = curMatchElements;\n\t\n\t this.pointerHover(pointer, event, this.matches, this.matchElements);\n\t events.add(eventTarget, supportsPointerEvent ? pEventTypes.move : 'mousemove', listeners.pointerHover);\n\t } else if (this.target) {\n\t if (nodeContains(prevTargetElement, eventTarget)) {\n\t this.pointerHover(pointer, event, this.matches, this.matchElements);\n\t events.add(this.element, supportsPointerEvent ? pEventTypes.move : 'mousemove', listeners.pointerHover);\n\t } else {\n\t this.target = null;\n\t this.element = null;\n\t this.matches = [];\n\t this.matchElements = [];\n\t }\n\t }\n\t }\n\t },\n\t\n\t // Check what action would be performed on pointerMove target if a mouse\n\t // button were pressed and change the cursor accordingly\n\t pointerHover: function pointerHover(pointer, event, eventTarget, curEventTarget, matches, matchElements) {\n\t var target = this.target;\n\t\n\t if (!this.prepared.name && this.mouse) {\n\t var action;\n\t\n\t // update pointer coords for defaultActionChecker to use\n\t this.setEventXY(this.curCoords, [pointer]);\n\t\n\t if (matches) {\n\t action = this.validateSelector(pointer, event, matches, matchElements);\n\t } else if (target) {\n\t action = validateAction(target.getAction(this.pointers[0], event, this, this.element), this.target);\n\t }\n\t\n\t if (target && target.options.styleCursor) {\n\t if (action) {\n\t target._doc.documentElement.style.cursor = getActionCursor(action);\n\t } else {\n\t target._doc.documentElement.style.cursor = '';\n\t }\n\t }\n\t } else if (this.prepared.name) {\n\t this.checkAndPreventDefault(event, target, this.element);\n\t }\n\t },\n\t\n\t pointerOut: function pointerOut(pointer, event, eventTarget) {\n\t if (this.prepared.name) {\n\t return;\n\t }\n\t\n\t // Remove temporary event listeners for selector Interactables\n\t if (!interactables.get(eventTarget)) {\n\t events.remove(eventTarget, supportsPointerEvent ? pEventTypes.move : 'mousemove', listeners.pointerHover);\n\t }\n\t\n\t if (this.target && this.target.options.styleCursor && !this.interacting()) {\n\t this.target._doc.documentElement.style.cursor = '';\n\t }\n\t },\n\t\n\t selectorDown: function selectorDown(pointer, event, eventTarget, curEventTarget) {\n\t var that = this,\n\t\n\t // copy event to be used in timeout for IE8\n\t eventCopy = events.useAttachEvent ? extend({}, event) : event,\n\t element = eventTarget,\n\t pointerIndex = this.addPointer(pointer),\n\t action;\n\t\n\t this.holdTimers[pointerIndex] = setTimeout(function () {\n\t that.pointerHold(events.useAttachEvent ? eventCopy : pointer, eventCopy, eventTarget, curEventTarget);\n\t }, defaultOptions._holdDuration);\n\t\n\t this.pointerIsDown = true;\n\t\n\t // Check if the down event hits the current inertia target\n\t if (this.inertiaStatus.active && this.target.selector) {\n\t // climb up the DOM tree from the event target\n\t while (isElement(element)) {\n\t // if this element is the current inertia target element\n\t if (element === this.element\n\t // and the prospective action is the same as the ongoing one\n\t && validateAction(this.target.getAction(pointer, event, this, this.element), this.target).name === this.prepared.name) {\n\t // stop inertia so that the next move will be a normal one\n\t cancelFrame(this.inertiaStatus.i);\n\t this.inertiaStatus.active = false;\n\t\n\t this.collectEventTargets(pointer, event, eventTarget, 'down');\n\t return;\n\t }\n\t element = parentElement(element);\n\t }\n\t }\n\t\n\t // do nothing if interacting\n\t if (this.interacting()) {\n\t this.collectEventTargets(pointer, event, eventTarget, 'down');\n\t return;\n\t }\n\t\n\t function pushMatches(interactable, selector, context) {\n\t var elements = ie8MatchesSelector ? context.querySelectorAll(selector) : undefined;\n\t\n\t if (inContext(interactable, element) && !testIgnore(interactable, element, eventTarget) && testAllow(interactable, element, eventTarget) && matchesSelector(element, selector, elements)) {\n\t that.matches.push(interactable);\n\t that.matchElements.push(element);\n\t }\n\t }\n\t\n\t // update pointer coords for defaultActionChecker to use\n\t this.setEventXY(this.curCoords, [pointer]);\n\t this.downEvent = event;\n\t\n\t while (isElement(element) && !action) {\n\t this.matches = [];\n\t this.matchElements = [];\n\t\n\t interactables.forEachSelector(pushMatches);\n\t\n\t action = this.validateSelector(pointer, event, this.matches, this.matchElements);\n\t element = parentElement(element);\n\t }\n\t\n\t if (action) {\n\t this.prepared.name = action.name;\n\t this.prepared.axis = action.axis;\n\t this.prepared.edges = action.edges;\n\t\n\t this.collectEventTargets(pointer, event, eventTarget, 'down');\n\t\n\t return this.pointerDown(pointer, event, eventTarget, curEventTarget, action);\n\t } else {\n\t // do these now since pointerDown isn't being called from here\n\t this.downTimes[pointerIndex] = new Date().getTime();\n\t this.downTargets[pointerIndex] = eventTarget;\n\t pointerExtend(this.downPointer, pointer);\n\t\n\t copyCoords(this.prevCoords, this.curCoords);\n\t this.pointerWasMoved = false;\n\t }\n\t\n\t this.collectEventTargets(pointer, event, eventTarget, 'down');\n\t },\n\t\n\t // Determine action to be performed on next pointerMove and add appropriate\n\t // style and event Listeners\n\t pointerDown: function pointerDown(pointer, event, eventTarget, curEventTarget, forceAction) {\n\t if (!forceAction && !this.inertiaStatus.active && this.pointerWasMoved && this.prepared.name) {\n\t this.checkAndPreventDefault(event, this.target, this.element);\n\t\n\t return;\n\t }\n\t\n\t this.pointerIsDown = true;\n\t this.downEvent = event;\n\t\n\t var pointerIndex = this.addPointer(pointer),\n\t action;\n\t\n\t // If it is the second touch of a multi-touch gesture, keep the\n\t // target the same and get a new action if a target was set by the\n\t // first touch\n\t if (this.pointerIds.length > 1 && this.target._element === this.element) {\n\t var newAction = validateAction(forceAction || this.target.getAction(pointer, event, this, this.element), this.target);\n\t\n\t if (withinInteractionLimit(this.target, this.element, newAction)) {\n\t action = newAction;\n\t }\n\t\n\t this.prepared.name = null;\n\t }\n\t // Otherwise, set the target if there is no action prepared\n\t else if (!this.prepared.name) {\n\t var interactable = interactables.get(curEventTarget);\n\t\n\t if (interactable && !testIgnore(interactable, curEventTarget, eventTarget) && testAllow(interactable, curEventTarget, eventTarget) && (action = validateAction(forceAction || interactable.getAction(pointer, event, this, curEventTarget), interactable, eventTarget)) && withinInteractionLimit(interactable, curEventTarget, action)) {\n\t this.target = interactable;\n\t this.element = curEventTarget;\n\t }\n\t }\n\t\n\t var target = this.target,\n\t options = target && target.options;\n\t\n\t if (target && (forceAction || !this.prepared.name)) {\n\t action = action || validateAction(forceAction || target.getAction(pointer, event, this, curEventTarget), target, this.element);\n\t\n\t this.setEventXY(this.startCoords, this.pointers);\n\t\n\t if (!action) {\n\t return;\n\t }\n\t\n\t if (options.styleCursor) {\n\t target._doc.documentElement.style.cursor = getActionCursor(action);\n\t }\n\t\n\t this.resizeAxes = action.name === 'resize' ? action.axis : null;\n\t\n\t if (action === 'gesture' && this.pointerIds.length < 2) {\n\t action = null;\n\t }\n\t\n\t this.prepared.name = action.name;\n\t this.prepared.axis = action.axis;\n\t this.prepared.edges = action.edges;\n\t\n\t this.snapStatus.snappedX = this.snapStatus.snappedY = this.restrictStatus.restrictedX = this.restrictStatus.restrictedY = NaN;\n\t\n\t this.downTimes[pointerIndex] = new Date().getTime();\n\t this.downTargets[pointerIndex] = eventTarget;\n\t pointerExtend(this.downPointer, pointer);\n\t\n\t copyCoords(this.prevCoords, this.startCoords);\n\t this.pointerWasMoved = false;\n\t\n\t this.checkAndPreventDefault(event, target, this.element);\n\t }\n\t // if inertia is active try to resume action\n\t else if (this.inertiaStatus.active && curEventTarget === this.element && validateAction(target.getAction(pointer, event, this, this.element), target).name === this.prepared.name) {\n\t cancelFrame(this.inertiaStatus.i);\n\t this.inertiaStatus.active = false;\n\t\n\t this.checkAndPreventDefault(event, target, this.element);\n\t }\n\t },\n\t\n\t setModifications: function setModifications(coords, preEnd) {\n\t var target = this.target,\n\t shouldMove = true,\n\t shouldSnap = checkSnap(target, this.prepared.name) && (!target.options[this.prepared.name].snap.endOnly || preEnd),\n\t shouldRestrict = checkRestrict(target, this.prepared.name) && (!target.options[this.prepared.name].restrict.endOnly || preEnd);\n\t\n\t if (shouldSnap) {\n\t this.setSnapping(coords);\n\t } else {\n\t this.snapStatus.locked = false;\n\t }\n\t if (shouldRestrict) {\n\t this.setRestriction(coords);\n\t } else {\n\t this.restrictStatus.restricted = false;\n\t }\n\t\n\t if (shouldSnap && this.snapStatus.locked && !this.snapStatus.changed) {\n\t shouldMove = shouldRestrict && this.restrictStatus.restricted && this.restrictStatus.changed;\n\t } else if (shouldRestrict && this.restrictStatus.restricted && !this.restrictStatus.changed) {\n\t shouldMove = false;\n\t }\n\t\n\t return shouldMove;\n\t },\n\t\n\t setStartOffsets: function setStartOffsets(action, interactable, element) {\n\t var rect = interactable.getRect(element),\n\t origin = getOriginXY(interactable, element),\n\t snap = interactable.options[this.prepared.name].snap,\n\t restrict = interactable.options[this.prepared.name].restrict,\n\t width,\n\t height;\n\t\n\t if (rect) {\n\t this.startOffset.left = this.startCoords.page.x - rect.left;\n\t this.startOffset.top = this.startCoords.page.y - rect.top;\n\t\n\t this.startOffset.right = rect.right - this.startCoords.page.x;\n\t this.startOffset.bottom = rect.bottom - this.startCoords.page.y;\n\t\n\t if ('width' in rect) {\n\t width = rect.width;\n\t } else {\n\t width = rect.right - rect.left;\n\t }\n\t if ('height' in rect) {\n\t height = rect.height;\n\t } else {\n\t height = rect.bottom - rect.top;\n\t }\n\t } else {\n\t this.startOffset.left = this.startOffset.top = this.startOffset.right = this.startOffset.bottom = 0;\n\t }\n\t\n\t this.snapOffsets.splice(0);\n\t\n\t var snapOffset = snap && snap.offset === 'startCoords' ? {\n\t x: this.startCoords.page.x - origin.x,\n\t y: this.startCoords.page.y - origin.y\n\t } : snap && snap.offset || { x: 0, y: 0 };\n\t\n\t if (rect && snap && snap.relativePoints && snap.relativePoints.length) {\n\t for (var i = 0; i < snap.relativePoints.length; i++) {\n\t this.snapOffsets.push({\n\t x: this.startOffset.left - width * snap.relativePoints[i].x + snapOffset.x,\n\t y: this.startOffset.top - height * snap.relativePoints[i].y + snapOffset.y\n\t });\n\t }\n\t } else {\n\t this.snapOffsets.push(snapOffset);\n\t }\n\t\n\t if (rect && restrict.elementRect) {\n\t this.restrictOffset.left = this.startOffset.left - width * restrict.elementRect.left;\n\t this.restrictOffset.top = this.startOffset.top - height * restrict.elementRect.top;\n\t\n\t this.restrictOffset.right = this.startOffset.right - width * (1 - restrict.elementRect.right);\n\t this.restrictOffset.bottom = this.startOffset.bottom - height * (1 - restrict.elementRect.bottom);\n\t } else {\n\t this.restrictOffset.left = this.restrictOffset.top = this.restrictOffset.right = this.restrictOffset.bottom = 0;\n\t }\n\t },\n\t\n\t /* \\\n\t * Interaction.start\n\t [ method ]\n\t *\n\t * Start an action with the given Interactable and Element as tartgets. The\n\t * action must be enabled for the target Interactable and an appropriate number\n\t * of pointers must be held down – 1 for drag/resize, 2 for gesture.\n\t *\n\t * Use it with `interactable.able({ manualStart: false })` to always\n\t * [start actions manually](https://github.com/taye/interact.js/issues/114)\n\t *\n\t - action (object) The action to be performed - drag, resize, etc.\n\t - interactable (Interactable) The Interactable to target\n\t - element (Element) The DOM Element to target\n\t = (object) interact\n\t **\n\t | interact(target)\n\t | .draggable({\n\t | // disable the default drag start by down->move\n\t | manualStart: true\n\t | })\n\t | // start dragging after the user holds the pointer down\n\t | .on('hold', function (event) {\n\t | var interaction = event.interaction;\n\t |\n\t | if (!interaction.interacting()) {\n\t | interaction.start({ name: 'drag' },\n\t | event.interactable,\n\t | event.currentTarget);\n\t | }\n\t | });\n\t \\*/\n\t start: function start(action, interactable, element) {\n\t if (this.interacting() || !this.pointerIsDown || this.pointerIds.length < (action.name === 'gesture' ? 2 : 1)) {\n\t return;\n\t }\n\t\n\t // if this interaction had been removed after stopping\n\t // add it back\n\t if (indexOf(interactions, this) === -1) {\n\t interactions.push(this);\n\t }\n\t\n\t // set the startCoords if there was no prepared action\n\t if (!this.prepared.name) {\n\t this.setEventXY(this.startCoords);\n\t }\n\t\n\t this.prepared.name = action.name;\n\t this.prepared.axis = action.axis;\n\t this.prepared.edges = action.edges;\n\t this.target = interactable;\n\t this.element = element;\n\t\n\t this.setStartOffsets(action.name, interactable, element);\n\t this.setModifications(this.startCoords.page);\n\t\n\t this.prevEvent = this[this.prepared.name + 'Start'](this.downEvent);\n\t },\n\t\n\t pointerMove: function pointerMove(pointer, event, eventTarget, curEventTarget, preEnd) {\n\t if (this.inertiaStatus.active) {\n\t var pageUp = this.inertiaStatus.upCoords.page;\n\t var clientUp = this.inertiaStatus.upCoords.client;\n\t\n\t var inertiaPosition = {\n\t pageX: pageUp.x + this.inertiaStatus.sx,\n\t pageY: pageUp.y + this.inertiaStatus.sy,\n\t clientX: clientUp.x + this.inertiaStatus.sx,\n\t clientY: clientUp.y + this.inertiaStatus.sy\n\t };\n\t\n\t this.setEventXY(this.curCoords, [inertiaPosition]);\n\t } else {\n\t this.recordPointer(pointer);\n\t this.setEventXY(this.curCoords, this.pointers);\n\t }\n\t\n\t var duplicateMove = this.curCoords.page.x === this.prevCoords.page.x && this.curCoords.page.y === this.prevCoords.page.y && this.curCoords.client.x === this.prevCoords.client.x && this.curCoords.client.y === this.prevCoords.client.y;\n\t\n\t var dx,\n\t dy,\n\t pointerIndex = this.mouse ? 0 : indexOf(this.pointerIds, getPointerId(pointer));\n\t\n\t // register movement greater than pointerMoveTolerance\n\t if (this.pointerIsDown && !this.pointerWasMoved) {\n\t dx = this.curCoords.client.x - this.startCoords.client.x;\n\t dy = this.curCoords.client.y - this.startCoords.client.y;\n\t\n\t this.pointerWasMoved = hypot(dx, dy) > pointerMoveTolerance;\n\t }\n\t\n\t if (!duplicateMove && (!this.pointerIsDown || this.pointerWasMoved)) {\n\t if (this.pointerIsDown) {\n\t clearTimeout(this.holdTimers[pointerIndex]);\n\t }\n\t\n\t this.collectEventTargets(pointer, event, eventTarget, 'move');\n\t }\n\t\n\t if (!this.pointerIsDown) {\n\t return;\n\t }\n\t\n\t if (duplicateMove && this.pointerWasMoved && !preEnd) {\n\t this.checkAndPreventDefault(event, this.target, this.element);\n\t return;\n\t }\n\t\n\t // set pointer coordinate, time changes and speeds\n\t setEventDeltas(this.pointerDelta, this.prevCoords, this.curCoords);\n\t\n\t if (!this.prepared.name) {\n\t return;\n\t }\n\t\n\t if (this.pointerWasMoved\n\t // ignore movement while inertia is active\n\t && (!this.inertiaStatus.active || pointer instanceof InteractEvent && /inertiastart/.test(pointer.type))) {\n\t // if just starting an action, calculate the pointer speed now\n\t if (!this.interacting()) {\n\t setEventDeltas(this.pointerDelta, this.prevCoords, this.curCoords);\n\t\n\t // check if a drag is in the correct axis\n\t if (this.prepared.name === 'drag') {\n\t var absX = Math.abs(dx),\n\t absY = Math.abs(dy),\n\t targetAxis = this.target.options.drag.axis,\n\t axis = absX > absY ? 'x' : absX < absY ? 'y' : 'xy';\n\t\n\t // if the movement isn't in the axis of the interactable\n\t if (axis !== 'xy' && targetAxis !== 'xy' && targetAxis !== axis) {\n\t // cancel the prepared action\n\t this.prepared.name = null;\n\t\n\t // then try to get a drag from another ineractable\n\t\n\t var element = eventTarget;\n\t\n\t // check element interactables\n\t while (isElement(element)) {\n\t var elementInteractable = interactables.get(element);\n\t\n\t if (elementInteractable && elementInteractable !== this.target && !elementInteractable.options.drag.manualStart && elementInteractable.getAction(this.downPointer, this.downEvent, this, element).name === 'drag' && checkAxis(axis, elementInteractable)) {\n\t this.prepared.name = 'drag';\n\t this.target = elementInteractable;\n\t this.element = element;\n\t break;\n\t }\n\t\n\t element = parentElement(element);\n\t }\n\t\n\t // if there's no drag from element interactables,\n\t // check the selector interactables\n\t if (!this.prepared.name) {\n\t var thisInteraction = this;\n\t\n\t var getDraggable = function getDraggable(interactable, selector, context) {\n\t var elements = ie8MatchesSelector ? context.querySelectorAll(selector) : undefined;\n\t\n\t if (interactable === thisInteraction.target) {\n\t return;\n\t }\n\t\n\t if (inContext(interactable, eventTarget) && !interactable.options.drag.manualStart && !testIgnore(interactable, element, eventTarget) && testAllow(interactable, element, eventTarget) && matchesSelector(element, selector, elements) && interactable.getAction(thisInteraction.downPointer, thisInteraction.downEvent, thisInteraction, element).name === 'drag' && checkAxis(axis, interactable) && withinInteractionLimit(interactable, element, 'drag')) {\n\t return interactable;\n\t }\n\t };\n\t\n\t element = eventTarget;\n\t\n\t while (isElement(element)) {\n\t var selectorInteractable = interactables.forEachSelector(getDraggable);\n\t\n\t if (selectorInteractable) {\n\t this.prepared.name = 'drag';\n\t this.target = selectorInteractable;\n\t this.element = element;\n\t break;\n\t }\n\t\n\t element = parentElement(element);\n\t }\n\t }\n\t }\n\t }\n\t }\n\t\n\t var starting = !!this.prepared.name && !this.interacting();\n\t\n\t if (starting && (this.target.options[this.prepared.name].manualStart || !withinInteractionLimit(this.target, this.element, this.prepared))) {\n\t this.stop(event);\n\t return;\n\t }\n\t\n\t if (this.prepared.name && this.target) {\n\t if (starting) {\n\t this.start(this.prepared, this.target, this.element);\n\t }\n\t\n\t var shouldMove = this.setModifications(this.curCoords.page, preEnd);\n\t\n\t // move if snapping or restriction doesn't prevent it\n\t if (shouldMove || starting) {\n\t this.prevEvent = this[this.prepared.name + 'Move'](event);\n\t }\n\t\n\t this.checkAndPreventDefault(event, this.target, this.element);\n\t }\n\t }\n\t\n\t copyCoords(this.prevCoords, this.curCoords);\n\t\n\t if (this.dragging || this.resizing) {\n\t this.autoScrollMove(pointer);\n\t }\n\t },\n\t\n\t dragStart: function dragStart(event) {\n\t var dragEvent = new InteractEvent(this, event, 'drag', 'start', this.element);\n\t\n\t dragEvent.originalEvent = event;\n\t this.dragging = true;\n\t this.target.fire(dragEvent);\n\t\n\t // reset active dropzones\n\t this.activeDrops.dropzones = [];\n\t this.activeDrops.elements = [];\n\t this.activeDrops.rects = [];\n\t\n\t if (!this.dynamicDrop) {\n\t this.setActiveDrops(this.element);\n\t }\n\t\n\t var dropEvents = this.getDropEvents(event, dragEvent);\n\t\n\t if (dropEvents.activate) {\n\t this.fireActiveDrops(dropEvents.activate);\n\t }\n\t\n\t return dragEvent;\n\t },\n\t\n\t dragMove: function dragMove(event) {\n\t var target = this.target,\n\t dragEvent = new InteractEvent(this, event, 'drag', 'move', this.element),\n\t draggableElement = this.element,\n\t drop = this.getDrop(dragEvent, event, draggableElement);\n\t\n\t dragEvent.originalEvent = event;\n\t\n\t this.dropTarget = drop.dropzone;\n\t this.dropElement = drop.element;\n\t\n\t var dropEvents = this.getDropEvents(event, dragEvent);\n\t\n\t target.fire(dragEvent);\n\t\n\t if (dropEvents.leave) {\n\t this.prevDropTarget.fire(dropEvents.leave);\n\t }\n\t if (dropEvents.enter) {\n\t this.dropTarget.fire(dropEvents.enter);\n\t }\n\t if (dropEvents.move) {\n\t this.dropTarget.fire(dropEvents.move);\n\t }\n\t\n\t this.prevDropTarget = this.dropTarget;\n\t this.prevDropElement = this.dropElement;\n\t\n\t return dragEvent;\n\t },\n\t\n\t resizeStart: function resizeStart(event) {\n\t var resizeEvent = new InteractEvent(this, event, 'resize', 'start', this.element);\n\t\n\t if (this.prepared.edges) {\n\t var startRect = this.target.getRect(this.element);\n\t\n\t /*\n\t * When using the `resizable.square` or `resizable.preserveAspectRatio` options, resizing from one edge\n\t * will affect another. E.g. with `resizable.square`, resizing to make the right edge larger will make\n\t * the bottom edge larger by the same amount. We call these 'linked' edges. Any linked edges will depend\n\t * on the active edges and the edge being interacted with.\n\t */\n\t if (this.target.options.resize.square || this.target.options.resize.preserveAspectRatio) {\n\t var linkedEdges = extend({}, this.prepared.edges);\n\t\n\t linkedEdges.top = linkedEdges.top || linkedEdges.left && !linkedEdges.bottom;\n\t linkedEdges.left = linkedEdges.left || linkedEdges.top && !linkedEdges.right;\n\t linkedEdges.bottom = linkedEdges.bottom || linkedEdges.right && !linkedEdges.top;\n\t linkedEdges.right = linkedEdges.right || linkedEdges.bottom && !linkedEdges.left;\n\t\n\t this.prepared._linkedEdges = linkedEdges;\n\t } else {\n\t this.prepared._linkedEdges = null;\n\t }\n\t\n\t // if using `resizable.preserveAspectRatio` option, record aspect ratio at the start of the resize\n\t if (this.target.options.resize.preserveAspectRatio) {\n\t this.resizeStartAspectRatio = startRect.width / startRect.height;\n\t }\n\t\n\t this.resizeRects = {\n\t start: startRect,\n\t current: extend({}, startRect),\n\t restricted: extend({}, startRect),\n\t previous: extend({}, startRect),\n\t delta: {\n\t left: 0, right: 0, width: 0,\n\t top: 0, bottom: 0, height: 0\n\t }\n\t };\n\t\n\t resizeEvent.rect = this.resizeRects.restricted;\n\t resizeEvent.deltaRect = this.resizeRects.delta;\n\t }\n\t\n\t this.target.fire(resizeEvent);\n\t\n\t this.resizing = true;\n\t\n\t return resizeEvent;\n\t },\n\t\n\t resizeMove: function resizeMove(event) {\n\t var resizeEvent = new InteractEvent(this, event, 'resize', 'move', this.element);\n\t\n\t var edges = this.prepared.edges,\n\t invert = this.target.options.resize.invert,\n\t invertible = invert === 'reposition' || invert === 'negate';\n\t\n\t if (edges) {\n\t var dx = resizeEvent.dx,\n\t dy = resizeEvent.dy,\n\t start = this.resizeRects.start,\n\t current = this.resizeRects.current,\n\t restricted = this.resizeRects.restricted,\n\t delta = this.resizeRects.delta,\n\t previous = extend(this.resizeRects.previous, restricted),\n\t originalEdges = edges;\n\t\n\t // `resize.preserveAspectRatio` takes precedence over `resize.square`\n\t if (this.target.options.resize.preserveAspectRatio) {\n\t var resizeStartAspectRatio = this.resizeStartAspectRatio;\n\t\n\t edges = this.prepared._linkedEdges;\n\t\n\t if (originalEdges.left && originalEdges.bottom || originalEdges.right && originalEdges.top) {\n\t dy = -dx / resizeStartAspectRatio;\n\t } else if (originalEdges.left || originalEdges.right) {\n\t dy = dx / resizeStartAspectRatio;\n\t } else if (originalEdges.top || originalEdges.bottom) {\n\t dx = dy * resizeStartAspectRatio;\n\t }\n\t } else if (this.target.options.resize.square) {\n\t edges = this.prepared._linkedEdges;\n\t\n\t if (originalEdges.left && originalEdges.bottom || originalEdges.right && originalEdges.top) {\n\t dy = -dx;\n\t } else if (originalEdges.left || originalEdges.right) {\n\t dy = dx;\n\t } else if (originalEdges.top || originalEdges.bottom) {\n\t dx = dy;\n\t }\n\t }\n\t\n\t // update the 'current' rect without modifications\n\t if (edges.top) {\n\t current.top += dy;\n\t }\n\t if (edges.bottom) {\n\t current.bottom += dy;\n\t }\n\t if (edges.left) {\n\t current.left += dx;\n\t }\n\t if (edges.right) {\n\t current.right += dx;\n\t }\n\t\n\t if (invertible) {\n\t // if invertible, copy the current rect\n\t extend(restricted, current);\n\t\n\t if (invert === 'reposition') {\n\t // swap edge values if necessary to keep width/height positive\n\t var swap;\n\t\n\t if (restricted.top > restricted.bottom) {\n\t swap = restricted.top;\n\t\n\t restricted.top = restricted.bottom;\n\t restricted.bottom = swap;\n\t }\n\t if (restricted.left > restricted.right) {\n\t swap = restricted.left;\n\t\n\t restricted.left = restricted.right;\n\t restricted.right = swap;\n\t }\n\t }\n\t } else {\n\t // if not invertible, restrict to minimum of 0x0 rect\n\t restricted.top = Math.min(current.top, start.bottom);\n\t restricted.bottom = Math.max(current.bottom, start.top);\n\t restricted.left = Math.min(current.left, start.right);\n\t restricted.right = Math.max(current.right, start.left);\n\t }\n\t\n\t restricted.width = restricted.right - restricted.left;\n\t restricted.height = restricted.bottom - restricted.top;\n\t\n\t for (var edge in restricted) {\n\t delta[edge] = restricted[edge] - previous[edge];\n\t }\n\t\n\t resizeEvent.edges = this.prepared.edges;\n\t resizeEvent.rect = restricted;\n\t resizeEvent.deltaRect = delta;\n\t }\n\t\n\t this.target.fire(resizeEvent);\n\t\n\t return resizeEvent;\n\t },\n\t\n\t gestureStart: function gestureStart(event) {\n\t var gestureEvent = new InteractEvent(this, event, 'gesture', 'start', this.element);\n\t\n\t gestureEvent.ds = 0;\n\t\n\t this.gesture.startDistance = this.gesture.prevDistance = gestureEvent.distance;\n\t this.gesture.startAngle = this.gesture.prevAngle = gestureEvent.angle;\n\t this.gesture.scale = 1;\n\t\n\t this.gesturing = true;\n\t\n\t this.target.fire(gestureEvent);\n\t\n\t return gestureEvent;\n\t },\n\t\n\t gestureMove: function gestureMove(event) {\n\t if (!this.pointerIds.length) {\n\t return this.prevEvent;\n\t }\n\t\n\t var gestureEvent;\n\t\n\t gestureEvent = new InteractEvent(this, event, 'gesture', 'move', this.element);\n\t gestureEvent.ds = gestureEvent.scale - this.gesture.scale;\n\t\n\t this.target.fire(gestureEvent);\n\t\n\t this.gesture.prevAngle = gestureEvent.angle;\n\t this.gesture.prevDistance = gestureEvent.distance;\n\t\n\t if (gestureEvent.scale !== Infinity && gestureEvent.scale !== null && gestureEvent.scale !== undefined && !isNaN(gestureEvent.scale)) {\n\t this.gesture.scale = gestureEvent.scale;\n\t }\n\t\n\t return gestureEvent;\n\t },\n\t\n\t pointerHold: function pointerHold(pointer, event, eventTarget) {\n\t this.collectEventTargets(pointer, event, eventTarget, 'hold');\n\t },\n\t\n\t pointerUp: function pointerUp(pointer, event, eventTarget, curEventTarget) {\n\t var pointerIndex = this.mouse ? 0 : indexOf(this.pointerIds, getPointerId(pointer));\n\t\n\t clearTimeout(this.holdTimers[pointerIndex]);\n\t\n\t this.collectEventTargets(pointer, event, eventTarget, 'up');\n\t this.collectEventTargets(pointer, event, eventTarget, 'tap');\n\t\n\t this.pointerEnd(pointer, event, eventTarget, curEventTarget);\n\t\n\t this.removePointer(pointer);\n\t },\n\t\n\t pointerCancel: function pointerCancel(pointer, event, eventTarget, curEventTarget) {\n\t var pointerIndex = this.mouse ? 0 : indexOf(this.pointerIds, getPointerId(pointer));\n\t\n\t clearTimeout(this.holdTimers[pointerIndex]);\n\t\n\t this.collectEventTargets(pointer, event, eventTarget, 'cancel');\n\t this.pointerEnd(pointer, event, eventTarget, curEventTarget);\n\t\n\t this.removePointer(pointer);\n\t },\n\t\n\t // http://www.quirksmode.org/dom/events/click.html\n\t // >Events leading to dblclick\n\t //\n\t // IE8 doesn't fire down event before dblclick.\n\t // This workaround tries to fire a tap and doubletap after dblclick\n\t ie8Dblclick: function ie8Dblclick(pointer, event, eventTarget) {\n\t if (this.prevTap && event.clientX === this.prevTap.clientX && event.clientY === this.prevTap.clientY && eventTarget === this.prevTap.target) {\n\t this.downTargets[0] = eventTarget;\n\t this.downTimes[0] = new Date().getTime();\n\t this.collectEventTargets(pointer, event, eventTarget, 'tap');\n\t }\n\t },\n\t\n\t // End interact move events and stop auto-scroll unless inertia is enabled\n\t pointerEnd: function pointerEnd(pointer, event, eventTarget, curEventTarget) {\n\t var endEvent,\n\t target = this.target,\n\t options = target && target.options,\n\t inertiaOptions = options && this.prepared.name && options[this.prepared.name].inertia,\n\t inertiaStatus = this.inertiaStatus;\n\t\n\t if (this.interacting()) {\n\t if (inertiaStatus.active && !inertiaStatus.ending) {\n\t return;\n\t }\n\t\n\t var pointerSpeed,\n\t now = new Date().getTime(),\n\t inertiaPossible = false,\n\t inertia = false,\n\t smoothEnd = false,\n\t endSnap = checkSnap(target, this.prepared.name) && options[this.prepared.name].snap.endOnly,\n\t endRestrict = checkRestrict(target, this.prepared.name) && options[this.prepared.name].restrict.endOnly,\n\t dx = 0,\n\t dy = 0,\n\t startEvent;\n\t\n\t if (this.dragging) {\n\t if (options.drag.axis === 'x') {\n\t pointerSpeed = Math.abs(this.pointerDelta.client.vx);\n\t } else if (options.drag.axis === 'y') {\n\t pointerSpeed = Math.abs(this.pointerDelta.client.vy);\n\t } else /* options.drag.axis === 'xy'*/{\n\t pointerSpeed = this.pointerDelta.client.speed;\n\t }\n\t } else {\n\t pointerSpeed = this.pointerDelta.client.speed;\n\t }\n\t\n\t // check if inertia should be started\n\t inertiaPossible = inertiaOptions && inertiaOptions.enabled && this.prepared.name !== 'gesture' && event !== inertiaStatus.startEvent;\n\t\n\t inertia = inertiaPossible && now - this.curCoords.timeStamp < 50 && pointerSpeed > inertiaOptions.minSpeed && pointerSpeed > inertiaOptions.endSpeed;\n\t\n\t if (inertiaPossible && !inertia && (endSnap || endRestrict)) {\n\t var snapRestrict = {};\n\t\n\t snapRestrict.snap = snapRestrict.restrict = snapRestrict;\n\t\n\t if (endSnap) {\n\t this.setSnapping(this.curCoords.page, snapRestrict);\n\t if (snapRestrict.locked) {\n\t dx += snapRestrict.dx;\n\t dy += snapRestrict.dy;\n\t }\n\t }\n\t\n\t if (endRestrict) {\n\t this.setRestriction(this.curCoords.page, snapRestrict);\n\t if (snapRestrict.restricted) {\n\t dx += snapRestrict.dx;\n\t dy += snapRestrict.dy;\n\t }\n\t }\n\t\n\t if (dx || dy) {\n\t smoothEnd = true;\n\t }\n\t }\n\t\n\t if (inertia || smoothEnd) {\n\t copyCoords(inertiaStatus.upCoords, this.curCoords);\n\t\n\t this.pointers[0] = inertiaStatus.startEvent = startEvent = new InteractEvent(this, event, this.prepared.name, 'inertiastart', this.element);\n\t\n\t inertiaStatus.t0 = now;\n\t\n\t target.fire(inertiaStatus.startEvent);\n\t\n\t if (inertia) {\n\t inertiaStatus.vx0 = this.pointerDelta.client.vx;\n\t inertiaStatus.vy0 = this.pointerDelta.client.vy;\n\t inertiaStatus.v0 = pointerSpeed;\n\t\n\t this.calcInertia(inertiaStatus);\n\t\n\t var page = extend({}, this.curCoords.page),\n\t origin = getOriginXY(target, this.element),\n\t statusObject;\n\t\n\t page.x = page.x + inertiaStatus.xe - origin.x;\n\t page.y = page.y + inertiaStatus.ye - origin.y;\n\t\n\t statusObject = {\n\t useStatusXY: true,\n\t x: page.x,\n\t y: page.y,\n\t dx: 0,\n\t dy: 0,\n\t snap: null\n\t };\n\t\n\t statusObject.snap = statusObject;\n\t\n\t dx = dy = 0;\n\t\n\t if (endSnap) {\n\t var snap = this.setSnapping(this.curCoords.page, statusObject);\n\t\n\t if (snap.locked) {\n\t dx += snap.dx;\n\t dy += snap.dy;\n\t }\n\t }\n\t\n\t if (endRestrict) {\n\t var restrict = this.setRestriction(this.curCoords.page, statusObject);\n\t\n\t if (restrict.restricted) {\n\t dx += restrict.dx;\n\t dy += restrict.dy;\n\t }\n\t }\n\t\n\t inertiaStatus.modifiedXe += dx;\n\t inertiaStatus.modifiedYe += dy;\n\t\n\t inertiaStatus.i = reqFrame(this.boundInertiaFrame);\n\t } else {\n\t inertiaStatus.smoothEnd = true;\n\t inertiaStatus.xe = dx;\n\t inertiaStatus.ye = dy;\n\t\n\t inertiaStatus.sx = inertiaStatus.sy = 0;\n\t\n\t inertiaStatus.i = reqFrame(this.boundSmoothEndFrame);\n\t }\n\t\n\t inertiaStatus.active = true;\n\t return;\n\t }\n\t\n\t if (endSnap || endRestrict) {\n\t // fire a move event at the snapped coordinates\n\t this.pointerMove(pointer, event, eventTarget, curEventTarget, true);\n\t }\n\t }\n\t\n\t if (this.dragging) {\n\t endEvent = new InteractEvent(this, event, 'drag', 'end', this.element);\n\t\n\t var draggableElement = this.element,\n\t drop = this.getDrop(endEvent, event, draggableElement);\n\t\n\t this.dropTarget = drop.dropzone;\n\t this.dropElement = drop.element;\n\t\n\t var dropEvents = this.getDropEvents(event, endEvent);\n\t\n\t if (dropEvents.leave) {\n\t this.prevDropTarget.fire(dropEvents.leave);\n\t }\n\t if (dropEvents.enter) {\n\t this.dropTarget.fire(dropEvents.enter);\n\t }\n\t if (dropEvents.drop) {\n\t this.dropTarget.fire(dropEvents.drop);\n\t }\n\t if (dropEvents.deactivate) {\n\t this.fireActiveDrops(dropEvents.deactivate);\n\t }\n\t\n\t target.fire(endEvent);\n\t } else if (this.resizing) {\n\t endEvent = new InteractEvent(this, event, 'resize', 'end', this.element);\n\t target.fire(endEvent);\n\t } else if (this.gesturing) {\n\t endEvent = new InteractEvent(this, event, 'gesture', 'end', this.element);\n\t target.fire(endEvent);\n\t }\n\t\n\t this.stop(event);\n\t },\n\t\n\t collectDrops: function collectDrops(element) {\n\t var drops = [],\n\t elements = [],\n\t i;\n\t\n\t element = element || this.element;\n\t\n\t // collect all dropzones and their elements which qualify for a drop\n\t for (i = 0; i < interactables.length; i++) {\n\t if (!interactables[i].options.drop.enabled) {\n\t continue;\n\t }\n\t\n\t var current = interactables[i],\n\t accept = current.options.drop.accept;\n\t\n\t // test the draggable element against the dropzone's accept setting\n\t if (isElement(accept) && accept !== element || isString(accept) && !matchesSelector(element, accept)) {\n\t continue;\n\t }\n\t\n\t // query for new elements if necessary\n\t var dropElements = current.selector ? current._context.querySelectorAll(current.selector) : [current._element];\n\t\n\t for (var j = 0, len = dropElements.length; j < len; j++) {\n\t var currentElement = dropElements[j];\n\t\n\t if (currentElement === element) {\n\t continue;\n\t }\n\t\n\t drops.push(current);\n\t elements.push(currentElement);\n\t }\n\t }\n\t\n\t return {\n\t dropzones: drops,\n\t elements: elements\n\t };\n\t },\n\t\n\t fireActiveDrops: function fireActiveDrops(event) {\n\t var i, current, currentElement, prevElement;\n\t\n\t // loop through all active dropzones and trigger event\n\t for (i = 0; i < this.activeDrops.dropzones.length; i++) {\n\t current = this.activeDrops.dropzones[i];\n\t currentElement = this.activeDrops.elements[i];\n\t\n\t // prevent trigger of duplicate events on same element\n\t if (currentElement !== prevElement) {\n\t // set current element as event target\n\t event.target = currentElement;\n\t current.fire(event);\n\t }\n\t prevElement = currentElement;\n\t }\n\t },\n\t\n\t // Collect a new set of possible drops and save them in activeDrops.\n\t // setActiveDrops should always be called when a drag has just started or a\n\t // drag event happens while dynamicDrop is true\n\t setActiveDrops: function setActiveDrops(dragElement) {\n\t // get dropzones and their elements that could receive the draggable\n\t var possibleDrops = this.collectDrops(dragElement, true);\n\t\n\t this.activeDrops.dropzones = possibleDrops.dropzones;\n\t this.activeDrops.elements = possibleDrops.elements;\n\t this.activeDrops.rects = [];\n\t\n\t for (var i = 0; i < this.activeDrops.dropzones.length; i++) {\n\t this.activeDrops.rects[i] = this.activeDrops.dropzones[i].getRect(this.activeDrops.elements[i]);\n\t }\n\t },\n\t\n\t getDrop: function getDrop(dragEvent, event, dragElement) {\n\t var validDrops = [];\n\t\n\t if (dynamicDrop) {\n\t this.setActiveDrops(dragElement);\n\t }\n\t\n\t // collect all dropzones and their elements which qualify for a drop\n\t for (var j = 0; j < this.activeDrops.dropzones.length; j++) {\n\t var current = this.activeDrops.dropzones[j],\n\t currentElement = this.activeDrops.elements[j],\n\t rect = this.activeDrops.rects[j];\n\t\n\t validDrops.push(current.dropCheck(dragEvent, event, this.target, dragElement, currentElement, rect) ? currentElement : null);\n\t }\n\t\n\t // get the most appropriate dropzone based on DOM depth and order\n\t var dropIndex = indexOfDeepestElement(validDrops),\n\t dropzone = this.activeDrops.dropzones[dropIndex] || null,\n\t element = this.activeDrops.elements[dropIndex] || null;\n\t\n\t return {\n\t dropzone: dropzone,\n\t element: element\n\t };\n\t },\n\t\n\t getDropEvents: function getDropEvents(pointerEvent, dragEvent) {\n\t var dropEvents = {\n\t enter: null,\n\t leave: null,\n\t activate: null,\n\t deactivate: null,\n\t move: null,\n\t drop: null\n\t };\n\t\n\t if (this.dropElement !== this.prevDropElement) {\n\t // if there was a prevDropTarget, create a dragleave event\n\t if (this.prevDropTarget) {\n\t dropEvents.leave = {\n\t target: this.prevDropElement,\n\t dropzone: this.prevDropTarget,\n\t relatedTarget: dragEvent.target,\n\t draggable: dragEvent.interactable,\n\t dragEvent: dragEvent,\n\t interaction: this,\n\t timeStamp: dragEvent.timeStamp,\n\t type: 'dragleave'\n\t };\n\t\n\t dragEvent.dragLeave = this.prevDropElement;\n\t dragEvent.prevDropzone = this.prevDropTarget;\n\t }\n\t // if the dropTarget is not null, create a dragenter event\n\t if (this.dropTarget) {\n\t dropEvents.enter = {\n\t target: this.dropElement,\n\t dropzone: this.dropTarget,\n\t relatedTarget: dragEvent.target,\n\t draggable: dragEvent.interactable,\n\t dragEvent: dragEvent,\n\t interaction: this,\n\t timeStamp: dragEvent.timeStamp,\n\t type: 'dragenter'\n\t };\n\t\n\t dragEvent.dragEnter = this.dropElement;\n\t dragEvent.dropzone = this.dropTarget;\n\t }\n\t }\n\t\n\t if (dragEvent.type === 'dragend' && this.dropTarget) {\n\t dropEvents.drop = {\n\t target: this.dropElement,\n\t dropzone: this.dropTarget,\n\t relatedTarget: dragEvent.target,\n\t draggable: dragEvent.interactable,\n\t dragEvent: dragEvent,\n\t interaction: this,\n\t timeStamp: dragEvent.timeStamp,\n\t type: 'drop'\n\t };\n\t\n\t dragEvent.dropzone = this.dropTarget;\n\t }\n\t if (dragEvent.type === 'dragstart') {\n\t dropEvents.activate = {\n\t target: null,\n\t dropzone: null,\n\t relatedTarget: dragEvent.target,\n\t draggable: dragEvent.interactable,\n\t dragEvent: dragEvent,\n\t interaction: this,\n\t timeStamp: dragEvent.timeStamp,\n\t type: 'dropactivate'\n\t };\n\t }\n\t if (dragEvent.type === 'dragend') {\n\t dropEvents.deactivate = {\n\t target: null,\n\t dropzone: null,\n\t relatedTarget: dragEvent.target,\n\t draggable: dragEvent.interactable,\n\t dragEvent: dragEvent,\n\t interaction: this,\n\t timeStamp: dragEvent.timeStamp,\n\t type: 'dropdeactivate'\n\t };\n\t }\n\t if (dragEvent.type === 'dragmove' && this.dropTarget) {\n\t dropEvents.move = {\n\t target: this.dropElement,\n\t dropzone: this.dropTarget,\n\t relatedTarget: dragEvent.target,\n\t draggable: dragEvent.interactable,\n\t dragEvent: dragEvent,\n\t interaction: this,\n\t dragmove: dragEvent,\n\t timeStamp: dragEvent.timeStamp,\n\t type: 'dropmove'\n\t };\n\t dragEvent.dropzone = this.dropTarget;\n\t }\n\t\n\t return dropEvents;\n\t },\n\t\n\t currentAction: function currentAction() {\n\t return this.dragging && 'drag' || this.resizing && 'resize' || this.gesturing && 'gesture' || null;\n\t },\n\t\n\t interacting: function interacting() {\n\t return this.dragging || this.resizing || this.gesturing;\n\t },\n\t\n\t clearTargets: function clearTargets() {\n\t this.target = this.element = null;\n\t\n\t this.dropTarget = this.dropElement = this.prevDropTarget = this.prevDropElement = null;\n\t },\n\t\n\t stop: function stop(event) {\n\t if (this.interacting()) {\n\t autoScroll.stop();\n\t this.matches = [];\n\t this.matchElements = [];\n\t\n\t var target = this.target;\n\t\n\t if (target.options.styleCursor) {\n\t target._doc.documentElement.style.cursor = '';\n\t }\n\t\n\t // prevent Default only if were previously interacting\n\t if (event && isFunction(event.preventDefault)) {\n\t this.checkAndPreventDefault(event, target, this.element);\n\t }\n\t\n\t if (this.dragging) {\n\t this.activeDrops.dropzones = this.activeDrops.elements = this.activeDrops.rects = null;\n\t }\n\t }\n\t\n\t this.clearTargets();\n\t\n\t this.pointerIsDown = this.snapStatus.locked = this.dragging = this.resizing = this.gesturing = false;\n\t this.prepared.name = this.prevEvent = null;\n\t this.inertiaStatus.resumeDx = this.inertiaStatus.resumeDy = 0;\n\t\n\t // remove pointers if their ID isn't in this.pointerIds\n\t for (var i = 0; i < this.pointers.length; i++) {\n\t if (indexOf(this.pointerIds, getPointerId(this.pointers[i])) === -1) {\n\t this.pointers.splice(i, 1);\n\t }\n\t }\n\t },\n\t\n\t inertiaFrame: function inertiaFrame() {\n\t var inertiaStatus = this.inertiaStatus,\n\t options = this.target.options[this.prepared.name].inertia,\n\t lambda = options.resistance,\n\t t = new Date().getTime() / 1000 - inertiaStatus.t0;\n\t\n\t if (t < inertiaStatus.te) {\n\t var progress = 1 - (Math.exp(-lambda * t) - inertiaStatus.lambda_v0) / inertiaStatus.one_ve_v0;\n\t\n\t if (inertiaStatus.modifiedXe === inertiaStatus.xe && inertiaStatus.modifiedYe === inertiaStatus.ye) {\n\t inertiaStatus.sx = inertiaStatus.xe * progress;\n\t inertiaStatus.sy = inertiaStatus.ye * progress;\n\t } else {\n\t var quadPoint = getQuadraticCurvePoint(0, 0, inertiaStatus.xe, inertiaStatus.ye, inertiaStatus.modifiedXe, inertiaStatus.modifiedYe, progress);\n\t\n\t inertiaStatus.sx = quadPoint.x;\n\t inertiaStatus.sy = quadPoint.y;\n\t }\n\t\n\t this.pointerMove(inertiaStatus.startEvent, inertiaStatus.startEvent);\n\t\n\t inertiaStatus.i = reqFrame(this.boundInertiaFrame);\n\t } else {\n\t inertiaStatus.ending = true;\n\t\n\t inertiaStatus.sx = inertiaStatus.modifiedXe;\n\t inertiaStatus.sy = inertiaStatus.modifiedYe;\n\t\n\t this.pointerMove(inertiaStatus.startEvent, inertiaStatus.startEvent);\n\t this.pointerEnd(inertiaStatus.startEvent, inertiaStatus.startEvent);\n\t\n\t inertiaStatus.active = inertiaStatus.ending = false;\n\t }\n\t },\n\t\n\t smoothEndFrame: function smoothEndFrame() {\n\t var inertiaStatus = this.inertiaStatus,\n\t t = new Date().getTime() - inertiaStatus.t0,\n\t duration = this.target.options[this.prepared.name].inertia.smoothEndDuration;\n\t\n\t if (t < duration) {\n\t inertiaStatus.sx = easeOutQuad(t, 0, inertiaStatus.xe, duration);\n\t inertiaStatus.sy = easeOutQuad(t, 0, inertiaStatus.ye, duration);\n\t\n\t this.pointerMove(inertiaStatus.startEvent, inertiaStatus.startEvent);\n\t\n\t inertiaStatus.i = reqFrame(this.boundSmoothEndFrame);\n\t } else {\n\t inertiaStatus.ending = true;\n\t\n\t inertiaStatus.sx = inertiaStatus.xe;\n\t inertiaStatus.sy = inertiaStatus.ye;\n\t\n\t this.pointerMove(inertiaStatus.startEvent, inertiaStatus.startEvent);\n\t this.pointerEnd(inertiaStatus.startEvent, inertiaStatus.startEvent);\n\t\n\t inertiaStatus.smoothEnd = inertiaStatus.active = inertiaStatus.ending = false;\n\t }\n\t },\n\t\n\t addPointer: function addPointer(pointer) {\n\t var id = getPointerId(pointer),\n\t index = this.mouse ? 0 : indexOf(this.pointerIds, id);\n\t\n\t if (index === -1) {\n\t index = this.pointerIds.length;\n\t }\n\t\n\t this.pointerIds[index] = id;\n\t this.pointers[index] = pointer;\n\t\n\t return index;\n\t },\n\t\n\t removePointer: function removePointer(pointer) {\n\t var id = getPointerId(pointer),\n\t index = this.mouse ? 0 : indexOf(this.pointerIds, id);\n\t\n\t if (index === -1) {\n\t return;\n\t }\n\t\n\t this.pointers.splice(index, 1);\n\t this.pointerIds.splice(index, 1);\n\t this.downTargets.splice(index, 1);\n\t this.downTimes.splice(index, 1);\n\t this.holdTimers.splice(index, 1);\n\t },\n\t\n\t recordPointer: function recordPointer(pointer) {\n\t var index = this.mouse ? 0 : indexOf(this.pointerIds, getPointerId(pointer));\n\t\n\t if (index === -1) {\n\t return;\n\t }\n\t\n\t this.pointers[index] = pointer;\n\t },\n\t\n\t collectEventTargets: function collectEventTargets(pointer, event, eventTarget, eventType) {\n\t var pointerIndex = this.mouse ? 0 : indexOf(this.pointerIds, getPointerId(pointer));\n\t\n\t // do not fire a tap event if the pointer was moved before being lifted\n\t if (eventType === 'tap' && (this.pointerWasMoved\n\t // or if the pointerup target is different to the pointerdown target\n\t || !(this.downTargets[pointerIndex] && this.downTargets[pointerIndex] === eventTarget))) {\n\t return;\n\t }\n\t\n\t var targets = [],\n\t elements = [],\n\t element = eventTarget;\n\t\n\t function collectSelectors(interactable, selector, context) {\n\t var els = ie8MatchesSelector ? context.querySelectorAll(selector) : undefined;\n\t\n\t if (interactable._iEvents[eventType] && isElement(element) && inContext(interactable, element) && !testIgnore(interactable, element, eventTarget) && testAllow(interactable, element, eventTarget) && matchesSelector(element, selector, els)) {\n\t targets.push(interactable);\n\t elements.push(element);\n\t }\n\t }\n\t\n\t while (element) {\n\t if (interact.isSet(element) && interact(element)._iEvents[eventType]) {\n\t targets.push(interact(element));\n\t elements.push(element);\n\t }\n\t\n\t interactables.forEachSelector(collectSelectors);\n\t\n\t element = parentElement(element);\n\t }\n\t\n\t // create the tap event even if there are no listeners so that\n\t // doubletap can still be created and fired\n\t if (targets.length || eventType === 'tap') {\n\t this.firePointers(pointer, event, eventTarget, targets, elements, eventType);\n\t }\n\t },\n\t\n\t firePointers: function firePointers(pointer, event, eventTarget, targets, elements, eventType) {\n\t var pointerIndex = this.mouse ? 0 : indexOf(this.pointerIds, getPointerId(pointer)),\n\t pointerEvent = {},\n\t i,\n\t\n\t // for tap events\n\t interval,\n\t createNewDoubleTap;\n\t\n\t // if it's a doubletap then the event properties would have been\n\t // copied from the tap event and provided as the pointer argument\n\t if (eventType === 'doubletap') {\n\t pointerEvent = pointer;\n\t } else {\n\t pointerExtend(pointerEvent, event);\n\t if (event !== pointer) {\n\t pointerExtend(pointerEvent, pointer);\n\t }\n\t\n\t pointerEvent.preventDefault = preventOriginalDefault;\n\t pointerEvent.stopPropagation = InteractEvent.prototype.stopPropagation;\n\t pointerEvent.stopImmediatePropagation = InteractEvent.prototype.stopImmediatePropagation;\n\t pointerEvent.interaction = this;\n\t\n\t pointerEvent.timeStamp = new Date().getTime();\n\t pointerEvent.originalEvent = event;\n\t pointerEvent.originalPointer = pointer;\n\t pointerEvent.type = eventType;\n\t pointerEvent.pointerId = getPointerId(pointer);\n\t pointerEvent.pointerType = this.mouse ? 'mouse' : !supportsPointerEvent ? 'touch' : isString(pointer.pointerType) ? pointer.pointerType : [,, 'touch', 'pen', 'mouse'][pointer.pointerType];\n\t }\n\t\n\t if (eventType === 'tap') {\n\t pointerEvent.dt = pointerEvent.timeStamp - this.downTimes[pointerIndex];\n\t\n\t interval = pointerEvent.timeStamp - this.tapTime;\n\t createNewDoubleTap = !!(this.prevTap && this.prevTap.type !== 'doubletap' && this.prevTap.target === pointerEvent.target && interval < 500);\n\t\n\t pointerEvent.double = createNewDoubleTap;\n\t\n\t this.tapTime = pointerEvent.timeStamp;\n\t }\n\t\n\t for (i = 0; i < targets.length; i++) {\n\t pointerEvent.currentTarget = elements[i];\n\t pointerEvent.interactable = targets[i];\n\t targets[i].fire(pointerEvent);\n\t\n\t if (pointerEvent.immediatePropagationStopped || pointerEvent.propagationStopped && elements[i + 1] !== pointerEvent.currentTarget) {\n\t break;\n\t }\n\t }\n\t\n\t if (createNewDoubleTap) {\n\t var doubleTap = {};\n\t\n\t extend(doubleTap, pointerEvent);\n\t\n\t doubleTap.dt = interval;\n\t doubleTap.type = 'doubletap';\n\t\n\t this.collectEventTargets(doubleTap, event, eventTarget, 'doubletap');\n\t\n\t this.prevTap = doubleTap;\n\t } else if (eventType === 'tap') {\n\t this.prevTap = pointerEvent;\n\t }\n\t },\n\t\n\t validateSelector: function validateSelector(pointer, event, matches, matchElements) {\n\t for (var i = 0, len = matches.length; i < len; i++) {\n\t var match = matches[i],\n\t matchElement = matchElements[i],\n\t action = validateAction(match.getAction(pointer, event, this, matchElement), match);\n\t\n\t if (action && withinInteractionLimit(match, matchElement, action)) {\n\t this.target = match;\n\t this.element = matchElement;\n\t\n\t return action;\n\t }\n\t }\n\t },\n\t\n\t setSnapping: function setSnapping(pageCoords, status) {\n\t var snap = this.target.options[this.prepared.name].snap,\n\t targets = [],\n\t target,\n\t page,\n\t i;\n\t\n\t status = status || this.snapStatus;\n\t\n\t if (status.useStatusXY) {\n\t page = { x: status.x, y: status.y };\n\t } else {\n\t var origin = getOriginXY(this.target, this.element);\n\t\n\t page = extend({}, pageCoords);\n\t\n\t page.x -= origin.x;\n\t page.y -= origin.y;\n\t }\n\t\n\t status.realX = page.x;\n\t status.realY = page.y;\n\t\n\t page.x = page.x - this.inertiaStatus.resumeDx;\n\t page.y = page.y - this.inertiaStatus.resumeDy;\n\t\n\t var len = snap.targets ? snap.targets.length : 0;\n\t\n\t for (var relIndex = 0; relIndex < this.snapOffsets.length; relIndex++) {\n\t var relative = {\n\t x: page.x - this.snapOffsets[relIndex].x,\n\t y: page.y - this.snapOffsets[relIndex].y\n\t };\n\t\n\t for (i = 0; i < len; i++) {\n\t if (isFunction(snap.targets[i])) {\n\t target = snap.targets[i](relative.x, relative.y, this);\n\t } else {\n\t target = snap.targets[i];\n\t }\n\t\n\t if (!target) {\n\t continue;\n\t }\n\t\n\t targets.push({\n\t x: isNumber(target.x) ? target.x + this.snapOffsets[relIndex].x : relative.x,\n\t y: isNumber(target.y) ? target.y + this.snapOffsets[relIndex].y : relative.y,\n\t\n\t range: isNumber(target.range) ? target.range : snap.range\n\t });\n\t }\n\t }\n\t\n\t var closest = {\n\t target: null,\n\t inRange: false,\n\t distance: 0,\n\t range: 0,\n\t dx: 0,\n\t dy: 0\n\t };\n\t\n\t for (i = 0, len = targets.length; i < len; i++) {\n\t target = targets[i];\n\t\n\t var range = target.range,\n\t dx = target.x - page.x,\n\t dy = target.y - page.y,\n\t distance = hypot(dx, dy),\n\t inRange = distance <= range;\n\t\n\t // Infinite targets count as being out of range\n\t // compared to non infinite ones that are in range\n\t if (range === Infinity && closest.inRange && closest.range !== Infinity) {\n\t inRange = false;\n\t }\n\t\n\t if (!closest.target || (inRange\n\t // is the closest target in range?\n\t ? closest.inRange && range !== Infinity\n\t // the pointer is relatively deeper in this target\n\t ? distance / range < closest.distance / closest.range\n\t // this target has Infinite range and the closest doesn't\n\t : range === Infinity && closest.range !== Infinity ||\n\t // OR this target is closer that the previous closest\n\t distance < closest.distance :\n\t // The other is not in range and the pointer is closer to this target\n\t !closest.inRange && distance < closest.distance)) {\n\t if (range === Infinity) {\n\t inRange = true;\n\t }\n\t\n\t closest.target = target;\n\t closest.distance = distance;\n\t closest.range = range;\n\t closest.inRange = inRange;\n\t closest.dx = dx;\n\t closest.dy = dy;\n\t\n\t status.range = range;\n\t }\n\t }\n\t\n\t var snapChanged;\n\t\n\t if (closest.target) {\n\t snapChanged = status.snappedX !== closest.target.x || status.snappedY !== closest.target.y;\n\t\n\t status.snappedX = closest.target.x;\n\t status.snappedY = closest.target.y;\n\t } else {\n\t snapChanged = true;\n\t\n\t status.snappedX = NaN;\n\t status.snappedY = NaN;\n\t }\n\t\n\t status.dx = closest.dx;\n\t status.dy = closest.dy;\n\t\n\t status.changed = snapChanged || closest.inRange && !status.locked;\n\t status.locked = closest.inRange;\n\t\n\t return status;\n\t },\n\t\n\t setRestriction: function setRestriction(pageCoords, status) {\n\t var target = this.target,\n\t restrict = target && target.options[this.prepared.name].restrict,\n\t restriction = restrict && restrict.restriction,\n\t page;\n\t\n\t if (!restriction) {\n\t return status;\n\t }\n\t\n\t status = status || this.restrictStatus;\n\t\n\t page = status.useStatusXY ? page = { x: status.x, y: status.y } : page = extend({}, pageCoords);\n\t\n\t if (status.snap && status.snap.locked) {\n\t page.x += status.snap.dx || 0;\n\t page.y += status.snap.dy || 0;\n\t }\n\t\n\t page.x -= this.inertiaStatus.resumeDx;\n\t page.y -= this.inertiaStatus.resumeDy;\n\t\n\t status.dx = 0;\n\t status.dy = 0;\n\t status.restricted = false;\n\t\n\t var rect, restrictedX, restrictedY;\n\t\n\t if (isString(restriction)) {\n\t if (restriction === 'parent') {\n\t restriction = parentElement(this.element);\n\t } else if (restriction === 'self') {\n\t restriction = target.getRect(this.element);\n\t } else {\n\t restriction = closest(this.element, restriction);\n\t }\n\t\n\t if (!restriction) {\n\t return status;\n\t }\n\t }\n\t\n\t if (isFunction(restriction)) {\n\t restriction = restriction(page.x, page.y, this.element);\n\t }\n\t\n\t if (isElement(restriction)) {\n\t restriction = getElementRect(restriction);\n\t }\n\t\n\t rect = restriction;\n\t\n\t if (!restriction) {\n\t restrictedX = page.x;\n\t restrictedY = page.y;\n\t }\n\t // object is assumed to have\n\t // x, y, width, height or\n\t // left, top, right, bottom\n\t else if ('x' in restriction && 'y' in restriction) {\n\t restrictedX = Math.max(Math.min(rect.x + rect.width - this.restrictOffset.right, page.x), rect.x + this.restrictOffset.left);\n\t restrictedY = Math.max(Math.min(rect.y + rect.height - this.restrictOffset.bottom, page.y), rect.y + this.restrictOffset.top);\n\t } else {\n\t restrictedX = Math.max(Math.min(rect.right - this.restrictOffset.right, page.x), rect.left + this.restrictOffset.left);\n\t restrictedY = Math.max(Math.min(rect.bottom - this.restrictOffset.bottom, page.y), rect.top + this.restrictOffset.top);\n\t }\n\t\n\t status.dx = restrictedX - page.x;\n\t status.dy = restrictedY - page.y;\n\t\n\t status.changed = status.restrictedX !== restrictedX || status.restrictedY !== restrictedY;\n\t status.restricted = !!(status.dx || status.dy);\n\t\n\t status.restrictedX = restrictedX;\n\t status.restrictedY = restrictedY;\n\t\n\t return status;\n\t },\n\t\n\t checkAndPreventDefault: function checkAndPreventDefault(event, interactable, element) {\n\t if (!(interactable = interactable || this.target)) {\n\t return;\n\t }\n\t\n\t var options = interactable.options,\n\t prevent = options.preventDefault;\n\t\n\t if (prevent === 'auto' && element && !/^(input|select|textarea)$/i.test(event.target.nodeName)) {\n\t // do not preventDefault on pointerdown if the prepared action is a drag\n\t // and dragging can only start from a certain direction - this allows\n\t // a touch to pan the viewport if a drag isn't in the right direction\n\t if (/down|start/i.test(event.type) && this.prepared.name === 'drag' && options.drag.axis !== 'xy') {\n\t return;\n\t }\n\t\n\t // with manualStart, only preventDefault while interacting\n\t if (options[this.prepared.name] && options[this.prepared.name].manualStart && !this.interacting()) {\n\t return;\n\t }\n\t\n\t event.preventDefault();\n\t return;\n\t }\n\t\n\t if (prevent === 'always') {\n\t event.preventDefault();\n\t return;\n\t }\n\t },\n\t\n\t calcInertia: function calcInertia(status) {\n\t var inertiaOptions = this.target.options[this.prepared.name].inertia,\n\t lambda = inertiaOptions.resistance,\n\t inertiaDur = -Math.log(inertiaOptions.endSpeed / status.v0) / lambda;\n\t\n\t status.x0 = this.prevEvent.pageX;\n\t status.y0 = this.prevEvent.pageY;\n\t status.t0 = status.startEvent.timeStamp / 1000;\n\t status.sx = status.sy = 0;\n\t\n\t status.modifiedXe = status.xe = (status.vx0 - inertiaDur) / lambda;\n\t status.modifiedYe = status.ye = (status.vy0 - inertiaDur) / lambda;\n\t status.te = inertiaDur;\n\t\n\t status.lambda_v0 = lambda / status.v0;\n\t status.one_ve_v0 = 1 - inertiaOptions.endSpeed / status.v0;\n\t },\n\t\n\t autoScrollMove: function autoScrollMove(pointer) {\n\t if (!(this.interacting() && checkAutoScroll(this.target, this.prepared.name))) {\n\t return;\n\t }\n\t\n\t if (this.inertiaStatus.active) {\n\t autoScroll.x = autoScroll.y = 0;\n\t return;\n\t }\n\t\n\t var top,\n\t right,\n\t bottom,\n\t left,\n\t options = this.target.options[this.prepared.name].autoScroll,\n\t container = options.container || getWindow(this.element);\n\t\n\t if (isWindow(container)) {\n\t left = pointer.clientX < autoScroll.margin;\n\t top = pointer.clientY < autoScroll.margin;\n\t right = pointer.clientX > container.innerWidth - autoScroll.margin;\n\t bottom = pointer.clientY > container.innerHeight - autoScroll.margin;\n\t } else {\n\t var rect = getElementClientRect(container);\n\t\n\t left = pointer.clientX < rect.left + autoScroll.margin;\n\t top = pointer.clientY < rect.top + autoScroll.margin;\n\t right = pointer.clientX > rect.right - autoScroll.margin;\n\t bottom = pointer.clientY > rect.bottom - autoScroll.margin;\n\t }\n\t\n\t autoScroll.x = right ? 1 : left ? -1 : 0;\n\t autoScroll.y = bottom ? 1 : top ? -1 : 0;\n\t\n\t if (!autoScroll.isScrolling) {\n\t // set the autoScroll properties to those of the target\n\t autoScroll.margin = options.margin;\n\t autoScroll.speed = options.speed;\n\t\n\t autoScroll.start(this);\n\t }\n\t },\n\t\n\t _updateEventTargets: function _updateEventTargets(target, currentTarget) {\n\t this._eventTarget = target;\n\t this._curEventTarget = currentTarget;\n\t }\n\t\n\t };\n\t\n\t function getInteractionFromPointer(pointer, eventType, eventTarget) {\n\t var i = 0,\n\t len = interactions.length,\n\t mouseEvent = /mouse/i.test(pointer.pointerType || eventType)\n\t // MSPointerEvent.MSPOINTER_TYPE_MOUSE\n\t || pointer.pointerType === 4,\n\t interaction;\n\t\n\t var id = getPointerId(pointer);\n\t\n\t // try to resume inertia with a new pointer\n\t if (/down|start/i.test(eventType)) {\n\t for (i = 0; i < len; i++) {\n\t interaction = interactions[i];\n\t\n\t var element = eventTarget;\n\t\n\t if (interaction.inertiaStatus.active && interaction.target.options[interaction.prepared.name].inertia.allowResume && interaction.mouse === mouseEvent) {\n\t while (element) {\n\t // if the element is the interaction element\n\t if (element === interaction.element) {\n\t return interaction;\n\t }\n\t element = parentElement(element);\n\t }\n\t }\n\t }\n\t }\n\t\n\t // if it's a mouse interaction\n\t if (mouseEvent || !supportsTouch || supportsPointerEvent) {\n\t // find a mouse interaction that's not in inertia phase\n\t for (i = 0; i < len; i++) {\n\t if (interactions[i].mouse && !interactions[i].inertiaStatus.active) {\n\t return interactions[i];\n\t }\n\t }\n\t\n\t // find any interaction specifically for mouse.\n\t // if the eventType is a mousedown, and inertia is active\n\t // ignore the interaction\n\t for (i = 0; i < len; i++) {\n\t if (interactions[i].mouse && !(/down/.test(eventType) && interactions[i].inertiaStatus.active)) {\n\t return interaction;\n\t }\n\t }\n\t\n\t // create a new interaction for mouse\n\t interaction = new Interaction();\n\t interaction.mouse = true;\n\t\n\t return interaction;\n\t }\n\t\n\t // get interaction that has this pointer\n\t for (i = 0; i < len; i++) {\n\t if (contains(interactions[i].pointerIds, id)) {\n\t return interactions[i];\n\t }\n\t }\n\t\n\t // at this stage, a pointerUp should not return an interaction\n\t if (/up|end|out/i.test(eventType)) {\n\t return null;\n\t }\n\t\n\t // get first idle interaction\n\t for (i = 0; i < len; i++) {\n\t interaction = interactions[i];\n\t\n\t if ((!interaction.prepared.name || interaction.target.options.gesture.enabled) && !interaction.interacting() && !(!mouseEvent && interaction.mouse)) {\n\t return interaction;\n\t }\n\t }\n\t\n\t return new Interaction();\n\t }\n\t\n\t function doOnInteractions(method) {\n\t return function (event) {\n\t var interaction,\n\t eventTarget = getActualElement(event.path ? event.path[0] : event.target),\n\t curEventTarget = getActualElement(event.currentTarget),\n\t i;\n\t\n\t if (supportsTouch && /touch/.test(event.type)) {\n\t prevTouchTime = new Date().getTime();\n\t\n\t for (i = 0; i < event.changedTouches.length; i++) {\n\t var pointer = event.changedTouches[i];\n\t\n\t interaction = getInteractionFromPointer(pointer, event.type, eventTarget);\n\t\n\t if (!interaction) {\n\t continue;\n\t }\n\t\n\t interaction._updateEventTargets(eventTarget, curEventTarget);\n\t\n\t interaction[method](pointer, event, eventTarget, curEventTarget);\n\t }\n\t } else {\n\t if (!supportsPointerEvent && /mouse/.test(event.type)) {\n\t // ignore mouse events while touch interactions are active\n\t for (i = 0; i < interactions.length; i++) {\n\t if (!interactions[i].mouse && interactions[i].pointerIsDown) {\n\t return;\n\t }\n\t }\n\t\n\t // try to ignore mouse events that are simulated by the browser\n\t // after a touch event\n\t if (new Date().getTime() - prevTouchTime < 500) {\n\t return;\n\t }\n\t }\n\t\n\t interaction = getInteractionFromPointer(event, event.type, eventTarget);\n\t\n\t if (!interaction) {\n\t return;\n\t }\n\t\n\t interaction._updateEventTargets(eventTarget, curEventTarget);\n\t\n\t interaction[method](event, event, eventTarget, curEventTarget);\n\t }\n\t };\n\t }\n\t\n\t function InteractEvent(interaction, event, action, phase, element, related) {\n\t var client,\n\t page,\n\t target = interaction.target,\n\t snapStatus = interaction.snapStatus,\n\t restrictStatus = interaction.restrictStatus,\n\t pointers = interaction.pointers,\n\t deltaSource = (target && target.options || defaultOptions).deltaSource,\n\t sourceX = deltaSource + 'X',\n\t sourceY = deltaSource + 'Y',\n\t options = target ? target.options : defaultOptions,\n\t origin = getOriginXY(target, element),\n\t starting = phase === 'start',\n\t ending = phase === 'end',\n\t coords = starting ? interaction.startCoords : interaction.curCoords;\n\t\n\t element = element || interaction.element;\n\t\n\t page = extend({}, coords.page);\n\t client = extend({}, coords.client);\n\t\n\t page.x -= origin.x;\n\t page.y -= origin.y;\n\t\n\t client.x -= origin.x;\n\t client.y -= origin.y;\n\t\n\t var relativePoints = options[action].snap && options[action].snap.relativePoints;\n\t\n\t if (checkSnap(target, action) && !(starting && relativePoints && relativePoints.length)) {\n\t this.snap = {\n\t range: snapStatus.range,\n\t locked: snapStatus.locked,\n\t x: snapStatus.snappedX,\n\t y: snapStatus.snappedY,\n\t realX: snapStatus.realX,\n\t realY: snapStatus.realY,\n\t dx: snapStatus.dx,\n\t dy: snapStatus.dy\n\t };\n\t\n\t if (snapStatus.locked) {\n\t page.x += snapStatus.dx;\n\t page.y += snapStatus.dy;\n\t client.x += snapStatus.dx;\n\t client.y += snapStatus.dy;\n\t }\n\t }\n\t\n\t if (checkRestrict(target, action) && !(starting && options[action].restrict.elementRect) && restrictStatus.restricted) {\n\t page.x += restrictStatus.dx;\n\t page.y += restrictStatus.dy;\n\t client.x += restrictStatus.dx;\n\t client.y += restrictStatus.dy;\n\t\n\t this.restrict = {\n\t dx: restrictStatus.dx,\n\t dy: restrictStatus.dy\n\t };\n\t }\n\t\n\t this.pageX = page.x;\n\t this.pageY = page.y;\n\t this.clientX = client.x;\n\t this.clientY = client.y;\n\t\n\t this.x0 = interaction.startCoords.page.x - origin.x;\n\t this.y0 = interaction.startCoords.page.y - origin.y;\n\t this.clientX0 = interaction.startCoords.client.x - origin.x;\n\t this.clientY0 = interaction.startCoords.client.y - origin.y;\n\t this.ctrlKey = event.ctrlKey;\n\t this.altKey = event.altKey;\n\t this.shiftKey = event.shiftKey;\n\t this.metaKey = event.metaKey;\n\t this.button = event.button;\n\t this.buttons = event.buttons;\n\t this.target = element;\n\t this.t0 = interaction.downTimes[0];\n\t this.type = action + (phase || '');\n\t\n\t this.interaction = interaction;\n\t this.interactable = target;\n\t\n\t var inertiaStatus = interaction.inertiaStatus;\n\t\n\t if (inertiaStatus.active) {\n\t this.detail = 'inertia';\n\t }\n\t\n\t if (related) {\n\t this.relatedTarget = related;\n\t }\n\t\n\t // end event dx, dy is difference between start and end points\n\t if (ending) {\n\t if (deltaSource === 'client') {\n\t this.dx = client.x - interaction.startCoords.client.x;\n\t this.dy = client.y - interaction.startCoords.client.y;\n\t } else {\n\t this.dx = page.x - interaction.startCoords.page.x;\n\t this.dy = page.y - interaction.startCoords.page.y;\n\t }\n\t } else if (starting) {\n\t this.dx = 0;\n\t this.dy = 0;\n\t }\n\t // copy properties from previousmove if starting inertia\n\t else if (phase === 'inertiastart') {\n\t this.dx = interaction.prevEvent.dx;\n\t this.dy = interaction.prevEvent.dy;\n\t } else {\n\t if (deltaSource === 'client') {\n\t this.dx = client.x - interaction.prevEvent.clientX;\n\t this.dy = client.y - interaction.prevEvent.clientY;\n\t } else {\n\t this.dx = page.x - interaction.prevEvent.pageX;\n\t this.dy = page.y - interaction.prevEvent.pageY;\n\t }\n\t }\n\t if (interaction.prevEvent && interaction.prevEvent.detail === 'inertia' && !inertiaStatus.active && options[action].inertia && options[action].inertia.zeroResumeDelta) {\n\t inertiaStatus.resumeDx += this.dx;\n\t inertiaStatus.resumeDy += this.dy;\n\t\n\t this.dx = this.dy = 0;\n\t }\n\t\n\t if (action === 'resize' && interaction.resizeAxes) {\n\t if (options.resize.square) {\n\t if (interaction.resizeAxes === 'y') {\n\t this.dx = this.dy;\n\t } else {\n\t this.dy = this.dx;\n\t }\n\t this.axes = 'xy';\n\t } else {\n\t this.axes = interaction.resizeAxes;\n\t\n\t if (interaction.resizeAxes === 'x') {\n\t this.dy = 0;\n\t } else if (interaction.resizeAxes === 'y') {\n\t this.dx = 0;\n\t }\n\t }\n\t } else if (action === 'gesture') {\n\t this.touches = [pointers[0], pointers[1]];\n\t\n\t if (starting) {\n\t this.distance = touchDistance(pointers, deltaSource);\n\t this.box = touchBBox(pointers);\n\t this.scale = 1;\n\t this.ds = 0;\n\t this.angle = touchAngle(pointers, undefined, deltaSource);\n\t this.da = 0;\n\t } else if (ending || event instanceof InteractEvent) {\n\t this.distance = interaction.prevEvent.distance;\n\t this.box = interaction.prevEvent.box;\n\t this.scale = interaction.prevEvent.scale;\n\t this.ds = this.scale - 1;\n\t this.angle = interaction.prevEvent.angle;\n\t this.da = this.angle - interaction.gesture.startAngle;\n\t } else {\n\t this.distance = touchDistance(pointers, deltaSource);\n\t this.box = touchBBox(pointers);\n\t this.scale = this.distance / interaction.gesture.startDistance;\n\t this.angle = touchAngle(pointers, interaction.gesture.prevAngle, deltaSource);\n\t\n\t this.ds = this.scale - interaction.gesture.prevScale;\n\t this.da = this.angle - interaction.gesture.prevAngle;\n\t }\n\t }\n\t\n\t if (starting) {\n\t this.timeStamp = interaction.downTimes[0];\n\t this.dt = 0;\n\t this.duration = 0;\n\t this.speed = 0;\n\t this.velocityX = 0;\n\t this.velocityY = 0;\n\t } else if (phase === 'inertiastart') {\n\t this.timeStamp = interaction.prevEvent.timeStamp;\n\t this.dt = interaction.prevEvent.dt;\n\t this.duration = interaction.prevEvent.duration;\n\t this.speed = interaction.prevEvent.speed;\n\t this.velocityX = interaction.prevEvent.velocityX;\n\t this.velocityY = interaction.prevEvent.velocityY;\n\t } else {\n\t this.timeStamp = new Date().getTime();\n\t this.dt = this.timeStamp - interaction.prevEvent.timeStamp;\n\t this.duration = this.timeStamp - interaction.downTimes[0];\n\t\n\t if (event instanceof InteractEvent) {\n\t var dx = this[sourceX] - interaction.prevEvent[sourceX],\n\t dy = this[sourceY] - interaction.prevEvent[sourceY],\n\t dt = this.dt / 1000;\n\t\n\t this.speed = hypot(dx, dy) / dt;\n\t this.velocityX = dx / dt;\n\t this.velocityY = dy / dt;\n\t }\n\t // if normal move or end event, use previous user event coords\n\t else {\n\t // speed and velocity in pixels per second\n\t this.speed = interaction.pointerDelta[deltaSource].speed;\n\t this.velocityX = interaction.pointerDelta[deltaSource].vx;\n\t this.velocityY = interaction.pointerDelta[deltaSource].vy;\n\t }\n\t }\n\t\n\t if ((ending || phase === 'inertiastart') && interaction.prevEvent.speed > 600 && this.timeStamp - interaction.prevEvent.timeStamp < 150) {\n\t var angle = 180 * Math.atan2(interaction.prevEvent.velocityY, interaction.prevEvent.velocityX) / Math.PI,\n\t overlap = 22.5;\n\t\n\t if (angle < 0) {\n\t angle += 360;\n\t }\n\t\n\t var left = 135 - overlap <= angle && angle < 225 + overlap,\n\t up = 225 - overlap <= angle && angle < 315 + overlap,\n\t right = !left && (315 - overlap <= angle || angle < 45 + overlap),\n\t down = !up && 45 - overlap <= angle && angle < 135 + overlap;\n\t\n\t this.swipe = {\n\t up: up,\n\t down: down,\n\t left: left,\n\t right: right,\n\t angle: angle,\n\t speed: interaction.prevEvent.speed,\n\t velocity: {\n\t x: interaction.prevEvent.velocityX,\n\t y: interaction.prevEvent.velocityY\n\t }\n\t };\n\t }\n\t }\n\t\n\t InteractEvent.prototype = {\n\t preventDefault: blank,\n\t stopImmediatePropagation: function stopImmediatePropagation() {\n\t this.immediatePropagationStopped = this.propagationStopped = true;\n\t },\n\t stopPropagation: function stopPropagation() {\n\t this.propagationStopped = true;\n\t }\n\t };\n\t\n\t function preventOriginalDefault() {\n\t this.originalEvent.preventDefault();\n\t }\n\t\n\t function getActionCursor(action) {\n\t var cursor = '';\n\t\n\t if (action.name === 'drag') {\n\t cursor = actionCursors.drag;\n\t }\n\t if (action.name === 'resize') {\n\t if (action.axis) {\n\t cursor = actionCursors[action.name + action.axis];\n\t } else if (action.edges) {\n\t var cursorKey = 'resize',\n\t edgeNames = ['top', 'bottom', 'left', 'right'];\n\t\n\t for (var i = 0; i < 4; i++) {\n\t if (action.edges[edgeNames[i]]) {\n\t cursorKey += edgeNames[i];\n\t }\n\t }\n\t\n\t cursor = actionCursors[cursorKey];\n\t }\n\t }\n\t\n\t return cursor;\n\t }\n\t\n\t function checkResizeEdge(name, value, page, element, interactableElement, rect, margin) {\n\t // false, '', undefined, null\n\t if (!value) {\n\t return false;\n\t }\n\t\n\t // true value, use pointer coords and element rect\n\t if (value === true) {\n\t // if dimensions are negative, \"switch\" edges\n\t var width = isNumber(rect.width) ? rect.width : rect.right - rect.left,\n\t height = isNumber(rect.height) ? rect.height : rect.bottom - rect.top;\n\t\n\t if (width < 0) {\n\t if (name === 'left') {\n\t name = 'right';\n\t } else if (name === 'right') {\n\t name = 'left';\n\t }\n\t }\n\t if (height < 0) {\n\t if (name === 'top') {\n\t name = 'bottom';\n\t } else if (name === 'bottom') {\n\t name = 'top';\n\t }\n\t }\n\t\n\t if (name === 'left') {\n\t return page.x < (width >= 0 ? rect.left : rect.right) + margin;\n\t }\n\t if (name === 'top') {\n\t return page.y < (height >= 0 ? rect.top : rect.bottom) + margin;\n\t }\n\t\n\t if (name === 'right') {\n\t return page.x > (width >= 0 ? rect.right : rect.left) - margin;\n\t }\n\t if (name === 'bottom') {\n\t return page.y > (height >= 0 ? rect.bottom : rect.top) - margin;\n\t }\n\t }\n\t\n\t // the remaining checks require an element\n\t if (!isElement(element)) {\n\t return false;\n\t }\n\t\n\t return isElement(value)\n\t // the value is an element to use as a resize handle\n\t ? value === element\n\t // otherwise check if element matches value as selector\n\t : matchesUpTo(element, value, interactableElement);\n\t }\n\t\n\t function defaultActionChecker(pointer, interaction, element) {\n\t var rect = this.getRect(element),\n\t shouldResize = false,\n\t action = null,\n\t resizeAxes = null,\n\t resizeEdges,\n\t page = extend({}, interaction.curCoords.page),\n\t options = this.options;\n\t\n\t if (!rect) {\n\t return null;\n\t }\n\t\n\t if (actionIsEnabled.resize && options.resize.enabled) {\n\t var resizeOptions = options.resize;\n\t\n\t resizeEdges = {\n\t left: false, right: false, top: false, bottom: false\n\t };\n\t\n\t // if using resize.edges\n\t if (isObject(resizeOptions.edges)) {\n\t for (var edge in resizeEdges) {\n\t resizeEdges[edge] = checkResizeEdge(edge, resizeOptions.edges[edge], page, interaction._eventTarget, element, rect, resizeOptions.margin || margin);\n\t }\n\t\n\t resizeEdges.left = resizeEdges.left && !resizeEdges.right;\n\t resizeEdges.top = resizeEdges.top && !resizeEdges.bottom;\n\t\n\t shouldResize = resizeEdges.left || resizeEdges.right || resizeEdges.top || resizeEdges.bottom;\n\t } else {\n\t var right = options.resize.axis !== 'y' && page.x > rect.right - margin,\n\t bottom = options.resize.axis !== 'x' && page.y > rect.bottom - margin;\n\t\n\t shouldResize = right || bottom;\n\t resizeAxes = (right ? 'x' : '') + (bottom ? 'y' : '');\n\t }\n\t }\n\t\n\t action = shouldResize ? 'resize' : actionIsEnabled.drag && options.drag.enabled ? 'drag' : null;\n\t\n\t if (actionIsEnabled.gesture && interaction.pointerIds.length >= 2 && !(interaction.dragging || interaction.resizing)) {\n\t action = 'gesture';\n\t }\n\t\n\t if (action) {\n\t return {\n\t name: action,\n\t axis: resizeAxes,\n\t edges: resizeEdges\n\t };\n\t }\n\t\n\t return null;\n\t }\n\t\n\t // Check if action is enabled globally and the current target supports it\n\t // If so, return the validated action. Otherwise, return null\n\t function validateAction(action, interactable) {\n\t if (!isObject(action)) {\n\t return null;\n\t }\n\t\n\t var actionName = action.name,\n\t options = interactable.options;\n\t\n\t if ((actionName === 'resize' && options.resize.enabled || actionName === 'drag' && options.drag.enabled || actionName === 'gesture' && options.gesture.enabled) && actionIsEnabled[actionName]) {\n\t if (actionName === 'resize' || actionName === 'resizeyx') {\n\t actionName = 'resizexy';\n\t }\n\t\n\t return action;\n\t }\n\t return null;\n\t }\n\t\n\t var listeners = {},\n\t interactionListeners = ['dragStart', 'dragMove', 'resizeStart', 'resizeMove', 'gestureStart', 'gestureMove', 'pointerOver', 'pointerOut', 'pointerHover', 'selectorDown', 'pointerDown', 'pointerMove', 'pointerUp', 'pointerCancel', 'pointerEnd', 'addPointer', 'removePointer', 'recordPointer', 'autoScrollMove'];\n\t\n\t for (var i = 0, len = interactionListeners.length; i < len; i++) {\n\t var name = interactionListeners[i];\n\t\n\t listeners[name] = doOnInteractions(name);\n\t }\n\t\n\t // bound to the interactable context when a DOM event\n\t // listener is added to a selector interactable\n\t function delegateListener(event, useCapture) {\n\t var fakeEvent = {},\n\t delegated = delegatedEvents[event.type],\n\t eventTarget = getActualElement(event.path ? event.path[0] : event.target),\n\t element = eventTarget;\n\t\n\t useCapture = useCapture ? true : false;\n\t\n\t // duplicate the event so that currentTarget can be changed\n\t for (var prop in event) {\n\t fakeEvent[prop] = event[prop];\n\t }\n\t\n\t fakeEvent.originalEvent = event;\n\t fakeEvent.preventDefault = preventOriginalDefault;\n\t\n\t // climb up document tree looking for selector matches\n\t while (isElement(element)) {\n\t for (var i = 0; i < delegated.selectors.length; i++) {\n\t var selector = delegated.selectors[i],\n\t context = delegated.contexts[i];\n\t\n\t if (matchesSelector(element, selector) && nodeContains(context, eventTarget) && nodeContains(context, element)) {\n\t var listeners = delegated.listeners[i];\n\t\n\t fakeEvent.currentTarget = element;\n\t\n\t for (var j = 0; j < listeners.length; j++) {\n\t if (listeners[j][1] === useCapture) {\n\t listeners[j][0](fakeEvent);\n\t }\n\t }\n\t }\n\t }\n\t\n\t element = parentElement(element);\n\t }\n\t }\n\t\n\t function delegateUseCapture(event) {\n\t return delegateListener.call(this, event, true);\n\t }\n\t\n\t interactables.indexOfElement = function indexOfElement(element, context) {\n\t context = context || document;\n\t\n\t for (var i = 0; i < this.length; i++) {\n\t var interactable = this[i];\n\t\n\t if (interactable.selector === element && interactable._context === context || !interactable.selector && interactable._element === element) {\n\t return i;\n\t }\n\t }\n\t return -1;\n\t };\n\t\n\t interactables.get = function interactableGet(element, options) {\n\t return this[this.indexOfElement(element, options && options.context)];\n\t };\n\t\n\t interactables.forEachSelector = function (callback) {\n\t for (var i = 0; i < this.length; i++) {\n\t var interactable = this[i];\n\t\n\t if (!interactable.selector) {\n\t continue;\n\t }\n\t\n\t var ret = callback(interactable, interactable.selector, interactable._context, i, this);\n\t\n\t if (ret !== undefined) {\n\t return ret;\n\t }\n\t }\n\t };\n\t\n\t /* \\\n\t * interact\n\t [ method ]\n\t *\n\t * The methods of this variable can be used to set elements as\n\t * interactables and also to change various default settings.\n\t *\n\t * Calling it as a function and passing an element or a valid CSS selector\n\t * string returns an Interactable object which has various methods to\n\t * configure it.\n\t *\n\t - element (Element | string) The HTML or SVG Element to interact with or CSS selector\n\t = (object) An @Interactable\n\t *\n\t > Usage\n\t | interact(document.getElementById('draggable')).draggable(true);\n\t |\n\t | var rectables = interact('rect');\n\t | rectables\n\t | .gesturable(true)\n\t | .on('gesturemove', function (event) {\n\t | // something cool...\n\t | })\n\t | .autoScroll(true);\n\t \\*/\n\t function interact(element, options) {\n\t return interactables.get(element, options) || new Interactable(element, options);\n\t }\n\t\n\t /* \\\n\t * Interactable\n\t [ property ]\n\t **\n\t * Object type returned by @interact\n\t \\*/\n\t function Interactable(element, options) {\n\t this._element = element;\n\t this._iEvents = this._iEvents || {};\n\t\n\t var _window;\n\t\n\t if (trySelector(element)) {\n\t this.selector = element;\n\t\n\t var context = options && options.context;\n\t\n\t _window = context ? getWindow(context) : window;\n\t\n\t if (context && (_window.Node ? context instanceof _window.Node : isElement(context) || context === _window.document)) {\n\t this._context = context;\n\t }\n\t } else {\n\t _window = getWindow(element);\n\t\n\t if (isElement(element, _window)) {\n\t if (supportsPointerEvent) {\n\t events.add(this._element, pEventTypes.down, listeners.pointerDown);\n\t events.add(this._element, pEventTypes.move, listeners.pointerHover);\n\t } else {\n\t events.add(this._element, 'mousedown', listeners.pointerDown);\n\t events.add(this._element, 'mousemove', listeners.pointerHover);\n\t events.add(this._element, 'touchstart', listeners.pointerDown);\n\t events.add(this._element, 'touchmove', listeners.pointerHover);\n\t }\n\t }\n\t }\n\t\n\t this._doc = _window.document;\n\t\n\t if (!contains(documents, this._doc)) {\n\t listenToDocument(this._doc);\n\t }\n\t\n\t interactables.push(this);\n\t\n\t this.set(options);\n\t }\n\t\n\t Interactable.prototype = {\n\t setOnEvents: function setOnEvents(action, phases) {\n\t if (action === 'drop') {\n\t if (isFunction(phases.ondrop)) {\n\t this.ondrop = phases.ondrop;\n\t }\n\t if (isFunction(phases.ondropactivate)) {\n\t this.ondropactivate = phases.ondropactivate;\n\t }\n\t if (isFunction(phases.ondropdeactivate)) {\n\t this.ondropdeactivate = phases.ondropdeactivate;\n\t }\n\t if (isFunction(phases.ondragenter)) {\n\t this.ondragenter = phases.ondragenter;\n\t }\n\t if (isFunction(phases.ondragleave)) {\n\t this.ondragleave = phases.ondragleave;\n\t }\n\t if (isFunction(phases.ondropmove)) {\n\t this.ondropmove = phases.ondropmove;\n\t }\n\t } else {\n\t action = 'on' + action;\n\t\n\t if (isFunction(phases.onstart)) {\n\t this[action + 'start'] = phases.onstart;\n\t }\n\t if (isFunction(phases.onmove)) {\n\t this[action + 'move'] = phases.onmove;\n\t }\n\t if (isFunction(phases.onend)) {\n\t this[action + 'end'] = phases.onend;\n\t }\n\t if (isFunction(phases.oninertiastart)) {\n\t this[action + 'inertiastart'] = phases.oninertiastart;\n\t }\n\t }\n\t\n\t return this;\n\t },\n\t\n\t /* \\\n\t * Interactable.draggable\n\t [ method ]\n\t *\n\t * Gets or sets whether drag actions can be performed on the\n\t * Interactable\n\t *\n\t = (boolean) Indicates if this can be the target of drag events\n\t | var isDraggable = interact('ul li').draggable();\n\t * or\n\t - options (boolean | object) #optional true/false or An object with event listeners to be fired on drag events (object makes the Interactable draggable)\n\t = (object) This Interactable\n\t | interact(element).draggable({\n\t | onstart: function (event) {},\n\t | onmove : function (event) {},\n\t | onend : function (event) {},\n\t |\n\t | // the axis in which the first movement must be\n\t | // for the drag sequence to start\n\t | // 'xy' by default - any direction\n\t | axis: 'x' || 'y' || 'xy',\n\t |\n\t | // max number of drags that can happen concurrently\n\t | // with elements of this Interactable. Infinity by default\n\t | max: Infinity,\n\t |\n\t | // max number of drags that can target the same element+Interactable\n\t | // 1 by default\n\t | maxPerElement: 2\n\t | });\n\t \\*/\n\t draggable: function draggable(options) {\n\t if (isObject(options)) {\n\t this.options.drag.enabled = options.enabled === false ? false : true;\n\t this.setPerAction('drag', options);\n\t this.setOnEvents('drag', options);\n\t\n\t if (/^x$|^y$|^xy$/.test(options.axis)) {\n\t this.options.drag.axis = options.axis;\n\t } else if (options.axis === null) {\n\t delete this.options.drag.axis;\n\t }\n\t\n\t return this;\n\t }\n\t\n\t if (isBool(options)) {\n\t this.options.drag.enabled = options;\n\t\n\t return this;\n\t }\n\t\n\t return this.options.drag;\n\t },\n\t\n\t setPerAction: function setPerAction(action, options) {\n\t // for all the default per-action options\n\t for (var option in options) {\n\t // if this option exists for this action\n\t if (option in defaultOptions[action]) {\n\t // if the option in the options arg is an object value\n\t if (isObject(options[option])) {\n\t // duplicate the object\n\t this.options[action][option] = extend(this.options[action][option] || {}, options[option]);\n\t\n\t if (isObject(defaultOptions.perAction[option]) && 'enabled' in defaultOptions.perAction[option]) {\n\t this.options[action][option].enabled = options[option].enabled === false ? false : true;\n\t }\n\t } else if (isBool(options[option]) && isObject(defaultOptions.perAction[option])) {\n\t this.options[action][option].enabled = options[option];\n\t } else if (options[option] !== undefined) {\n\t // or if it's not undefined, do a plain assignment\n\t this.options[action][option] = options[option];\n\t }\n\t }\n\t }\n\t },\n\t\n\t /* \\\n\t * Interactable.dropzone\n\t [ method ]\n\t *\n\t * Returns or sets whether elements can be dropped onto this\n\t * Interactable to trigger drop events\n\t *\n\t * Dropzones can receive the following events:\n\t * - `dropactivate` and `dropdeactivate` when an acceptable drag starts and ends\n\t * - `dragenter` and `dragleave` when a draggable enters and leaves the dropzone\n\t * - `dragmove` when a draggable that has entered the dropzone is moved\n\t * - `drop` when a draggable is dropped into this dropzone\n\t *\n\t * Use the `accept` option to allow only elements that match the given CSS selector or element.\n\t *\n\t * Use the `overlap` option to set how drops are checked for. The allowed values are:\n\t * - `'pointer'`, the pointer must be over the dropzone (default)\n\t * - `'center'`, the draggable element's center must be over the dropzone\n\t * - a number from 0-1 which is the `(intersection area) / (draggable area)`.\n\t * e.g. `0.5` for drop to happen when half of the area of the\n\t * draggable is over the dropzone\n\t *\n\t - options (boolean | object | null) #optional The new value to be set.\n\t | interact('.drop').dropzone({\n\t | accept: '.can-drop' || document.getElementById('single-drop'),\n\t | overlap: 'pointer' || 'center' || zeroToOne\n\t | }\n\t = (boolean | object) The current setting or this Interactable\n\t \\*/\n\t dropzone: function dropzone(options) {\n\t if (isObject(options)) {\n\t this.options.drop.enabled = options.enabled === false ? false : true;\n\t this.setOnEvents('drop', options);\n\t\n\t if (/^(pointer|center)$/.test(options.overlap)) {\n\t this.options.drop.overlap = options.overlap;\n\t } else if (isNumber(options.overlap)) {\n\t this.options.drop.overlap = Math.max(Math.min(1, options.overlap), 0);\n\t }\n\t if ('accept' in options) {\n\t this.options.drop.accept = options.accept;\n\t }\n\t if ('checker' in options) {\n\t this.options.drop.checker = options.checker;\n\t }\n\t\n\t return this;\n\t }\n\t\n\t if (isBool(options)) {\n\t this.options.drop.enabled = options;\n\t\n\t return this;\n\t }\n\t\n\t return this.options.drop;\n\t },\n\t\n\t dropCheck: function dropCheck(dragEvent, event, draggable, draggableElement, dropElement, rect) {\n\t var dropped = false;\n\t\n\t // if the dropzone has no rect (eg. display: none)\n\t // call the custom dropChecker or just return false\n\t if (!(rect = rect || this.getRect(dropElement))) {\n\t return this.options.drop.checker ? this.options.drop.checker(dragEvent, event, dropped, this, dropElement, draggable, draggableElement) : false;\n\t }\n\t\n\t var dropOverlap = this.options.drop.overlap;\n\t\n\t if (dropOverlap === 'pointer') {\n\t var page = _getPageXY(dragEvent),\n\t origin = getOriginXY(draggable, draggableElement),\n\t horizontal,\n\t vertical;\n\t\n\t page.x += origin.x;\n\t page.y += origin.y;\n\t\n\t horizontal = page.x > rect.left && page.x < rect.right;\n\t vertical = page.y > rect.top && page.y < rect.bottom;\n\t\n\t dropped = horizontal && vertical;\n\t }\n\t\n\t var dragRect = draggable.getRect(draggableElement);\n\t\n\t if (dropOverlap === 'center') {\n\t var cx = dragRect.left + dragRect.width / 2,\n\t cy = dragRect.top + dragRect.height / 2;\n\t\n\t dropped = cx >= rect.left && cx <= rect.right && cy >= rect.top && cy <= rect.bottom;\n\t }\n\t\n\t if (isNumber(dropOverlap)) {\n\t var overlapArea = Math.max(0, Math.min(rect.right, dragRect.right) - Math.max(rect.left, dragRect.left)) * Math.max(0, Math.min(rect.bottom, dragRect.bottom) - Math.max(rect.top, dragRect.top)),\n\t overlapRatio = overlapArea / (dragRect.width * dragRect.height);\n\t\n\t dropped = overlapRatio >= dropOverlap;\n\t }\n\t\n\t if (this.options.drop.checker) {\n\t dropped = this.options.drop.checker(dragEvent, event, dropped, this, dropElement, draggable, draggableElement);\n\t }\n\t\n\t return dropped;\n\t },\n\t\n\t /* \\\n\t * Interactable.dropChecker\n\t [ method ]\n\t *\n\t * DEPRECATED. Use interactable.dropzone({ checker: function... }) instead.\n\t *\n\t * Gets or sets the function used to check if a dragged element is\n\t * over this Interactable.\n\t *\n\t - checker (function) #optional The function that will be called when checking for a drop\n\t = (Function | Interactable) The checker function or this Interactable\n\t *\n\t * The checker function takes the following arguments:\n\t *\n\t - dragEvent (InteractEvent) The related dragmove or dragend event\n\t - event (TouchEvent | PointerEvent | MouseEvent) The user move/up/end Event related to the dragEvent\n\t - dropped (boolean) The value from the default drop checker\n\t - dropzone (Interactable) The dropzone interactable\n\t - dropElement (Element) The dropzone element\n\t - draggable (Interactable) The Interactable being dragged\n\t - draggableElement (Element) The actual element that's being dragged\n\t *\n\t > Usage:\n\t | interact(target)\n\t | .dropChecker(function(dragEvent, // related dragmove or dragend event\n\t | event, // TouchEvent/PointerEvent/MouseEvent\n\t | dropped, // bool result of the default checker\n\t | dropzone, // dropzone Interactable\n\t | dropElement, // dropzone elemnt\n\t | draggable, // draggable Interactable\n\t | draggableElement) {// draggable element\n\t |\n\t | return dropped && event.target.hasAttribute('allow-drop');\n\t | }\n\t \\*/\n\t dropChecker: function dropChecker(checker) {\n\t if (isFunction(checker)) {\n\t this.options.drop.checker = checker;\n\t\n\t return this;\n\t }\n\t if (checker === null) {\n\t delete this.options.getRect;\n\t\n\t return this;\n\t }\n\t\n\t return this.options.drop.checker;\n\t },\n\t\n\t /* \\\n\t * Interactable.accept\n\t [ method ]\n\t *\n\t * Deprecated. add an `accept` property to the options object passed to\n\t * @Interactable.dropzone instead.\n\t *\n\t * Gets or sets the Element or CSS selector match that this\n\t * Interactable accepts if it is a dropzone.\n\t *\n\t - newValue (Element | string | null) #optional\n\t * If it is an Element, then only that element can be dropped into this dropzone.\n\t * If it is a string, the element being dragged must match it as a selector.\n\t * If it is null, the accept options is cleared - it accepts any element.\n\t *\n\t = (string | Element | null | Interactable) The current accept option if given `undefined` or this Interactable\n\t \\*/\n\t accept: function accept(newValue) {\n\t if (isElement(newValue)) {\n\t this.options.drop.accept = newValue;\n\t\n\t return this;\n\t }\n\t\n\t // test if it is a valid CSS selector\n\t if (trySelector(newValue)) {\n\t this.options.drop.accept = newValue;\n\t\n\t return this;\n\t }\n\t\n\t if (newValue === null) {\n\t delete this.options.drop.accept;\n\t\n\t return this;\n\t }\n\t\n\t return this.options.drop.accept;\n\t },\n\t\n\t /* \\\n\t * Interactable.resizable\n\t [ method ]\n\t *\n\t * Gets or sets whether resize actions can be performed on the\n\t * Interactable\n\t *\n\t = (boolean) Indicates if this can be the target of resize elements\n\t | var isResizeable = interact('input[type=text]').resizable();\n\t * or\n\t - options (boolean | object) #optional true/false or An object with event listeners to be fired on resize events (object makes the Interactable resizable)\n\t = (object) This Interactable\n\t | interact(element).resizable({\n\t | onstart: function (event) {},\n\t | onmove : function (event) {},\n\t | onend : function (event) {},\n\t |\n\t | edges: {\n\t | top : true, // Use pointer coords to check for resize.\n\t | left : false, // Disable resizing from left edge.\n\t | bottom: '.resize-s',// Resize if pointer target matches selector\n\t | right : handleEl // Resize if pointer target is the given Element\n\t | },\n\t |\n\t | // Width and height can be adjusted independently. When `true`, width and\n\t | // height are adjusted at a 1:1 ratio.\n\t | square: false,\n\t |\n\t | // Width and height can be adjusted independently. When `true`, width and\n\t | // height maintain the aspect ratio they had when resizing started.\n\t | preserveAspectRatio: false,\n\t |\n\t | // a value of 'none' will limit the resize rect to a minimum of 0x0\n\t | // 'negate' will allow the rect to have negative width/height\n\t | // 'reposition' will keep the width/height positive by swapping\n\t | // the top and bottom edges and/or swapping the left and right edges\n\t | invert: 'none' || 'negate' || 'reposition'\n\t |\n\t | // limit multiple resizes.\n\t | // See the explanation in the @Interactable.draggable example\n\t | max: Infinity,\n\t | maxPerElement: 1,\n\t | });\n\t \\*/\n\t resizable: function resizable(options) {\n\t if (isObject(options)) {\n\t this.options.resize.enabled = options.enabled === false ? false : true;\n\t this.setPerAction('resize', options);\n\t this.setOnEvents('resize', options);\n\t\n\t if (/^x$|^y$|^xy$/.test(options.axis)) {\n\t this.options.resize.axis = options.axis;\n\t } else if (options.axis === null) {\n\t this.options.resize.axis = defaultOptions.resize.axis;\n\t }\n\t\n\t if (isBool(options.preserveAspectRatio)) {\n\t this.options.resize.preserveAspectRatio = options.preserveAspectRatio;\n\t } else if (isBool(options.square)) {\n\t this.options.resize.square = options.square;\n\t }\n\t\n\t return this;\n\t }\n\t if (isBool(options)) {\n\t this.options.resize.enabled = options;\n\t\n\t return this;\n\t }\n\t return this.options.resize;\n\t },\n\t\n\t /* \\\n\t * Interactable.squareResize\n\t [ method ]\n\t *\n\t * Deprecated. Add a `square: true || false` property to @Interactable.resizable instead\n\t *\n\t * Gets or sets whether resizing is forced 1:1 aspect\n\t *\n\t = (boolean) Current setting\n\t *\n\t * or\n\t *\n\t - newValue (boolean) #optional\n\t = (object) this Interactable\n\t \\*/\n\t squareResize: function squareResize(newValue) {\n\t if (isBool(newValue)) {\n\t this.options.resize.square = newValue;\n\t\n\t return this;\n\t }\n\t\n\t if (newValue === null) {\n\t delete this.options.resize.square;\n\t\n\t return this;\n\t }\n\t\n\t return this.options.resize.square;\n\t },\n\t\n\t /* \\\n\t * Interactable.gesturable\n\t [ method ]\n\t *\n\t * Gets or sets whether multitouch gestures can be performed on the\n\t * Interactable's element\n\t *\n\t = (boolean) Indicates if this can be the target of gesture events\n\t | var isGestureable = interact(element).gesturable();\n\t * or\n\t - options (boolean | object) #optional true/false or An object with event listeners to be fired on gesture events (makes the Interactable gesturable)\n\t = (object) this Interactable\n\t | interact(element).gesturable({\n\t | onstart: function (event) {},\n\t | onmove : function (event) {},\n\t | onend : function (event) {},\n\t |\n\t | // limit multiple gestures.\n\t | // See the explanation in @Interactable.draggable example\n\t | max: Infinity,\n\t | maxPerElement: 1,\n\t | });\n\t \\*/\n\t gesturable: function gesturable(options) {\n\t if (isObject(options)) {\n\t this.options.gesture.enabled = options.enabled === false ? false : true;\n\t this.setPerAction('gesture', options);\n\t this.setOnEvents('gesture', options);\n\t\n\t return this;\n\t }\n\t\n\t if (isBool(options)) {\n\t this.options.gesture.enabled = options;\n\t\n\t return this;\n\t }\n\t\n\t return this.options.gesture;\n\t },\n\t\n\t /* \\\n\t * Interactable.autoScroll\n\t [ method ]\n\t **\n\t * Deprecated. Add an `autoscroll` property to the options object\n\t * passed to @Interactable.draggable or @Interactable.resizable instead.\n\t *\n\t * Returns or sets whether dragging and resizing near the edges of the\n\t * window/container trigger autoScroll for this Interactable\n\t *\n\t = (object) Object with autoScroll properties\n\t *\n\t * or\n\t *\n\t - options (object | boolean) #optional\n\t * options can be:\n\t * - an object with margin, distance and interval properties,\n\t * - true or false to enable or disable autoScroll or\n\t = (Interactable) this Interactable\n\t \\*/\n\t autoScroll: function autoScroll(options) {\n\t if (isObject(options)) {\n\t options = extend({ actions: ['drag', 'resize'] }, options);\n\t } else if (isBool(options)) {\n\t options = { actions: ['drag', 'resize'], enabled: options };\n\t }\n\t\n\t return this.setOptions('autoScroll', options);\n\t },\n\t\n\t /* \\\n\t * Interactable.snap\n\t [ method ]\n\t **\n\t * Deprecated. Add a `snap` property to the options object passed\n\t * to @Interactable.draggable or @Interactable.resizable instead.\n\t *\n\t * Returns or sets if and how action coordinates are snapped. By\n\t * default, snapping is relative to the pointer coordinates. You can\n\t * change this by setting the\n\t * [`elementOrigin`](https://github.com/taye/interact.js/pull/72).\n\t **\n\t = (boolean | object) `false` if snap is disabled; object with snap properties if snap is enabled\n\t **\n\t * or\n\t **\n\t - options (object | boolean | null) #optional\n\t = (Interactable) this Interactable\n\t > Usage\n\t | interact(document.querySelector('#thing')).snap({\n\t | targets: [\n\t | // snap to this specific point\n\t | {\n\t | x: 100,\n\t | y: 100,\n\t | range: 25\n\t | },\n\t | // give this function the x and y page coords and snap to the object returned\n\t | function (x, y) {\n\t | return {\n\t | x: x,\n\t | y: (75 + 50 * Math.sin(x * 0.04)),\n\t | range: 40\n\t | };\n\t | },\n\t | // create a function that snaps to a grid\n\t | interact.createSnapGrid({\n\t | x: 50,\n\t | y: 50,\n\t | range: 10, // optional\n\t | offset: { x: 5, y: 10 } // optional\n\t | })\n\t | ],\n\t | // do not snap during normal movement.\n\t | // Instead, trigger only one snapped move event\n\t | // immediately before the end event.\n\t | endOnly: true,\n\t |\n\t | relativePoints: [\n\t | { x: 0, y: 0 }, // snap relative to the top left of the element\n\t | { x: 1, y: 1 }, // and also to the bottom right\n\t | ],\n\t |\n\t | // offset the snap target coordinates\n\t | // can be an object with x/y or 'startCoords'\n\t | offset: { x: 50, y: 50 }\n\t | }\n\t | });\n\t \\*/\n\t snap: function snap(options) {\n\t var ret = this.setOptions('snap', options);\n\t\n\t if (ret === this) {\n\t return this;\n\t }\n\t\n\t return ret.drag;\n\t },\n\t\n\t setOptions: function setOptions(option, options) {\n\t var actions = options && isArray(options.actions) ? options.actions : ['drag'];\n\t\n\t var i;\n\t\n\t if (isObject(options) || isBool(options)) {\n\t for (i = 0; i < actions.length; i++) {\n\t var action = /resize/.test(actions[i]) ? 'resize' : actions[i];\n\t\n\t if (!isObject(this.options[action])) {\n\t continue;\n\t }\n\t\n\t var thisOption = this.options[action][option];\n\t\n\t if (isObject(options)) {\n\t extend(thisOption, options);\n\t thisOption.enabled = options.enabled === false ? false : true;\n\t\n\t if (option === 'snap') {\n\t if (thisOption.mode === 'grid') {\n\t thisOption.targets = [interact.createSnapGrid(extend({\n\t offset: thisOption.gridOffset || { x: 0, y: 0 }\n\t }, thisOption.grid || {}))];\n\t } else if (thisOption.mode === 'anchor') {\n\t thisOption.targets = thisOption.anchors;\n\t } else if (thisOption.mode === 'path') {\n\t thisOption.targets = thisOption.paths;\n\t }\n\t\n\t if ('elementOrigin' in options) {\n\t thisOption.relativePoints = [options.elementOrigin];\n\t }\n\t }\n\t } else if (isBool(options)) {\n\t thisOption.enabled = options;\n\t }\n\t }\n\t\n\t return this;\n\t }\n\t\n\t var ret = {},\n\t allActions = ['drag', 'resize', 'gesture'];\n\t\n\t for (i = 0; i < allActions.length; i++) {\n\t if (option in defaultOptions[allActions[i]]) {\n\t ret[allActions[i]] = this.options[allActions[i]][option];\n\t }\n\t }\n\t\n\t return ret;\n\t },\n\t\n\t /* \\\n\t * Interactable.inertia\n\t [ method ]\n\t **\n\t * Deprecated. Add an `inertia` property to the options object passed\n\t * to @Interactable.draggable or @Interactable.resizable instead.\n\t *\n\t * Returns or sets if and how events continue to run after the pointer is released\n\t **\n\t = (boolean | object) `false` if inertia is disabled; `object` with inertia properties if inertia is enabled\n\t **\n\t * or\n\t **\n\t - options (object | boolean | null) #optional\n\t = (Interactable) this Interactable\n\t > Usage\n\t | // enable and use default settings\n\t | interact(element).inertia(true);\n\t |\n\t | // enable and use custom settings\n\t | interact(element).inertia({\n\t | // value greater than 0\n\t | // high values slow the object down more quickly\n\t | resistance : 16,\n\t |\n\t | // the minimum launch speed (pixels per second) that results in inertia start\n\t | minSpeed : 200,\n\t |\n\t | // inertia will stop when the object slows down to this speed\n\t | endSpeed : 20,\n\t |\n\t | // boolean; should actions be resumed when the pointer goes down during inertia\n\t | allowResume : true,\n\t |\n\t | // boolean; should the jump when resuming from inertia be ignored in event.dx/dy\n\t | zeroResumeDelta: false,\n\t |\n\t | // if snap/restrict are set to be endOnly and inertia is enabled, releasing\n\t | // the pointer without triggering inertia will animate from the release\n\t | // point to the snaped/restricted point in the given amount of time (ms)\n\t | smoothEndDuration: 300,\n\t |\n\t | // an array of action types that can have inertia (no gesture)\n\t | actions : ['drag', 'resize']\n\t | });\n\t |\n\t | // reset custom settings and use all defaults\n\t | interact(element).inertia(null);\n\t \\*/\n\t inertia: function inertia(options) {\n\t var ret = this.setOptions('inertia', options);\n\t\n\t if (ret === this) {\n\t return this;\n\t }\n\t\n\t return ret.drag;\n\t },\n\t\n\t getAction: function getAction(pointer, event, interaction, element) {\n\t var action = this.defaultActionChecker(pointer, interaction, element);\n\t\n\t if (this.options.actionChecker) {\n\t return this.options.actionChecker(pointer, event, action, this, element, interaction);\n\t }\n\t\n\t return action;\n\t },\n\t\n\t defaultActionChecker: defaultActionChecker,\n\t\n\t /* \\\n\t * Interactable.actionChecker\n\t [ method ]\n\t *\n\t * Gets or sets the function used to check action to be performed on\n\t * pointerDown\n\t *\n\t - checker (function | null) #optional A function which takes a pointer event, defaultAction string, interactable, element and interaction as parameters and returns an object with name property 'drag' 'resize' or 'gesture' and optionally an `edges` object with boolean 'top', 'left', 'bottom' and right props.\n\t = (Function | Interactable) The checker function or this Interactable\n\t *\n\t | interact('.resize-drag')\n\t | .resizable(true)\n\t | .draggable(true)\n\t | .actionChecker(function (pointer, event, action, interactable, element, interaction) {\n\t |\n\t | if (interact.matchesSelector(event.target, '.drag-handle') {\n\t | // force drag with handle target\n\t | action.name = drag;\n\t | }\n\t | else {\n\t | // resize from the top and right edges\n\t | action.name = 'resize';\n\t | action.edges = { top: true, right: true };\n\t | }\n\t |\n\t | return action;\n\t | });\n\t \\*/\n\t actionChecker: function actionChecker(checker) {\n\t if (isFunction(checker)) {\n\t this.options.actionChecker = checker;\n\t\n\t return this;\n\t }\n\t\n\t if (checker === null) {\n\t delete this.options.actionChecker;\n\t\n\t return this;\n\t }\n\t\n\t return this.options.actionChecker;\n\t },\n\t\n\t /* \\\n\t * Interactable.getRect\n\t [ method ]\n\t *\n\t * The default function to get an Interactables bounding rect. Can be\n\t * overridden using @Interactable.rectChecker.\n\t *\n\t - element (Element) #optional The element to measure.\n\t = (object) The object's bounding rectangle.\n\t o {\n\t o top : 0,\n\t o left : 0,\n\t o bottom: 0,\n\t o right : 0,\n\t o width : 0,\n\t o height: 0\n\t o }\n\t \\*/\n\t getRect: function rectCheck(element) {\n\t element = element || this._element;\n\t\n\t if (this.selector && !isElement(element)) {\n\t element = this._context.querySelector(this.selector);\n\t }\n\t\n\t return getElementRect(element);\n\t },\n\t\n\t /* \\\n\t * Interactable.rectChecker\n\t [ method ]\n\t *\n\t * Returns or sets the function used to calculate the interactable's\n\t * element's rectangle\n\t *\n\t - checker (function) #optional A function which returns this Interactable's bounding rectangle. See @Interactable.getRect\n\t = (function | object) The checker function or this Interactable\n\t \\*/\n\t rectChecker: function rectChecker(checker) {\n\t if (isFunction(checker)) {\n\t this.getRect = checker;\n\t\n\t return this;\n\t }\n\t\n\t if (checker === null) {\n\t delete this.options.getRect;\n\t\n\t return this;\n\t }\n\t\n\t return this.getRect;\n\t },\n\t\n\t /* \\\n\t * Interactable.styleCursor\n\t [ method ]\n\t *\n\t * Returns or sets whether the action that would be performed when the\n\t * mouse on the element are checked on `mousemove` so that the cursor\n\t * may be styled appropriately\n\t *\n\t - newValue (boolean) #optional\n\t = (boolean | Interactable) The current setting or this Interactable\n\t \\*/\n\t styleCursor: function styleCursor(newValue) {\n\t if (isBool(newValue)) {\n\t this.options.styleCursor = newValue;\n\t\n\t return this;\n\t }\n\t\n\t if (newValue === null) {\n\t delete this.options.styleCursor;\n\t\n\t return this;\n\t }\n\t\n\t return this.options.styleCursor;\n\t },\n\t\n\t /* \\\n\t * Interactable.preventDefault\n\t [ method ]\n\t *\n\t * Returns or sets whether to prevent the browser's default behaviour\n\t * in response to pointer events. Can be set to:\n\t * - `'always'` to always prevent\n\t * - `'never'` to never prevent\n\t * - `'auto'` to let interact.js try to determine what would be best\n\t *\n\t - newValue (string) #optional `true`, `false` or `'auto'`\n\t = (string | Interactable) The current setting or this Interactable\n\t \\*/\n\t preventDefault: function preventDefault(newValue) {\n\t if (/^(always|never|auto)$/.test(newValue)) {\n\t this.options.preventDefault = newValue;\n\t return this;\n\t }\n\t\n\t if (isBool(newValue)) {\n\t this.options.preventDefault = newValue ? 'always' : 'never';\n\t return this;\n\t }\n\t\n\t return this.options.preventDefault;\n\t },\n\t\n\t /* \\\n\t * Interactable.origin\n\t [ method ]\n\t *\n\t * Gets or sets the origin of the Interactable's element. The x and y\n\t * of the origin will be subtracted from action event coordinates.\n\t *\n\t - origin (object | string) #optional An object eg. { x: 0, y: 0 } or string 'parent', 'self' or any CSS selector\n\t * OR\n\t - origin (Element) #optional An HTML or SVG Element whose rect will be used\n\t **\n\t = (object) The current origin or this Interactable\n\t \\*/\n\t origin: function origin(newValue) {\n\t if (trySelector(newValue)) {\n\t this.options.origin = newValue;\n\t return this;\n\t } else if (isObject(newValue)) {\n\t this.options.origin = newValue;\n\t return this;\n\t }\n\t\n\t return this.options.origin;\n\t },\n\t\n\t /* \\\n\t * Interactable.deltaSource\n\t [ method ]\n\t *\n\t * Returns or sets the mouse coordinate types used to calculate the\n\t * movement of the pointer.\n\t *\n\t - newValue (string) #optional Use 'client' if you will be scrolling while interacting; Use 'page' if you want autoScroll to work\n\t = (string | object) The current deltaSource or this Interactable\n\t \\*/\n\t deltaSource: function deltaSource(newValue) {\n\t if (newValue === 'page' || newValue === 'client') {\n\t this.options.deltaSource = newValue;\n\t\n\t return this;\n\t }\n\t\n\t return this.options.deltaSource;\n\t },\n\t\n\t /* \\\n\t * Interactable.restrict\n\t [ method ]\n\t **\n\t * Deprecated. Add a `restrict` property to the options object passed to\n\t * @Interactable.draggable, @Interactable.resizable or @Interactable.gesturable instead.\n\t *\n\t * Returns or sets the rectangles within which actions on this\n\t * interactable (after snap calculations) are restricted. By default,\n\t * restricting is relative to the pointer coordinates. You can change\n\t * this by setting the\n\t * [`elementRect`](https://github.com/taye/interact.js/pull/72).\n\t **\n\t - options (object) #optional an object with keys drag, resize, and/or gesture whose values are rects, Elements, CSS selectors, or 'parent' or 'self'\n\t = (object) The current restrictions object or this Interactable\n\t **\n\t | interact(element).restrict({\n\t | // the rect will be `interact.getElementRect(element.parentNode)`\n\t | drag: element.parentNode,\n\t |\n\t | // x and y are relative to the the interactable's origin\n\t | resize: { x: 100, y: 100, width: 200, height: 200 }\n\t | })\n\t |\n\t | interact('.draggable').restrict({\n\t | // the rect will be the selected element's parent\n\t | drag: 'parent',\n\t |\n\t | // do not restrict during normal movement.\n\t | // Instead, trigger only one restricted move event\n\t | // immediately before the end event.\n\t | endOnly: true,\n\t |\n\t | // https://github.com/taye/interact.js/pull/72#issue-41813493\n\t | elementRect: { top: 0, left: 0, bottom: 1, right: 1 }\n\t | });\n\t \\*/\n\t restrict: function restrict(options) {\n\t if (!isObject(options)) {\n\t return this.setOptions('restrict', options);\n\t }\n\t\n\t var actions = ['drag', 'resize', 'gesture'],\n\t ret;\n\t\n\t for (var i = 0; i < actions.length; i++) {\n\t var action = actions[i];\n\t\n\t if (action in options) {\n\t var perAction = extend({\n\t actions: [action],\n\t restriction: options[action]\n\t }, options);\n\t\n\t ret = this.setOptions('restrict', perAction);\n\t }\n\t }\n\t\n\t return ret;\n\t },\n\t\n\t /* \\\n\t * Interactable.context\n\t [ method ]\n\t *\n\t * Gets the selector context Node of the Interactable. The default is `window.document`.\n\t *\n\t = (Node) The context Node of this Interactable\n\t **\n\t \\*/\n\t context: function context() {\n\t return this._context;\n\t },\n\t\n\t _context: document,\n\t\n\t /* \\\n\t * Interactable.ignoreFrom\n\t [ method ]\n\t *\n\t * If the target of the `mousedown`, `pointerdown` or `touchstart`\n\t * event or any of it's parents match the given CSS selector or\n\t * Element, no drag/resize/gesture is started.\n\t *\n\t - newValue (string | Element | null) #optional a CSS selector string, an Element or `null` to not ignore any elements\n\t = (string | Element | object) The current ignoreFrom value or this Interactable\n\t **\n\t | interact(element, { ignoreFrom: document.getElementById('no-action') });\n\t | // or\n\t | interact(element).ignoreFrom('input, textarea, a');\n\t \\*/\n\t ignoreFrom: function ignoreFrom(newValue) {\n\t if (trySelector(newValue)) {\n\t // CSS selector to match event.target\n\t this.options.ignoreFrom = newValue;\n\t return this;\n\t }\n\t\n\t if (isElement(newValue)) {\n\t // specific element\n\t this.options.ignoreFrom = newValue;\n\t return this;\n\t }\n\t\n\t return this.options.ignoreFrom;\n\t },\n\t\n\t /* \\\n\t * Interactable.allowFrom\n\t [ method ]\n\t *\n\t * A drag/resize/gesture is started only If the target of the\n\t * `mousedown`, `pointerdown` or `touchstart` event or any of it's\n\t * parents match the given CSS selector or Element.\n\t *\n\t - newValue (string | Element | null) #optional a CSS selector string, an Element or `null` to allow from any element\n\t = (string | Element | object) The current allowFrom value or this Interactable\n\t **\n\t | interact(element, { allowFrom: document.getElementById('drag-handle') });\n\t | // or\n\t | interact(element).allowFrom('.handle');\n\t \\*/\n\t allowFrom: function allowFrom(newValue) {\n\t if (trySelector(newValue)) {\n\t // CSS selector to match event.target\n\t this.options.allowFrom = newValue;\n\t return this;\n\t }\n\t\n\t if (isElement(newValue)) {\n\t // specific element\n\t this.options.allowFrom = newValue;\n\t return this;\n\t }\n\t\n\t return this.options.allowFrom;\n\t },\n\t\n\t /* \\\n\t * Interactable.element\n\t [ method ]\n\t *\n\t * If this is not a selector Interactable, it returns the element this\n\t * interactable represents\n\t *\n\t = (Element) HTML / SVG Element\n\t \\*/\n\t element: function element() {\n\t return this._element;\n\t },\n\t\n\t /* \\\n\t * Interactable.fire\n\t [ method ]\n\t *\n\t * Calls listeners for the given InteractEvent type bound globally\n\t * and directly to this Interactable\n\t *\n\t - iEvent (InteractEvent) The InteractEvent object to be fired on this Interactable\n\t = (Interactable) this Interactable\n\t \\*/\n\t fire: function fire(iEvent) {\n\t if (!(iEvent && iEvent.type) || !contains(eventTypes, iEvent.type)) {\n\t return this;\n\t }\n\t\n\t var listeners,\n\t i,\n\t len,\n\t onEvent = 'on' + iEvent.type,\n\t funcName = '';\n\t\n\t // Interactable#on() listeners\n\t if (iEvent.type in this._iEvents) {\n\t listeners = this._iEvents[iEvent.type];\n\t\n\t for (i = 0, len = listeners.length; i < len && !iEvent.immediatePropagationStopped; i++) {\n\t funcName = listeners[i].name;\n\t listeners[i](iEvent);\n\t }\n\t }\n\t\n\t // interactable.onevent listener\n\t if (isFunction(this[onEvent])) {\n\t funcName = this[onEvent].name;\n\t this[onEvent](iEvent);\n\t }\n\t\n\t // interact.on() listeners\n\t if (iEvent.type in globalEvents && (listeners = globalEvents[iEvent.type])) {\n\t for (i = 0, len = listeners.length; i < len && !iEvent.immediatePropagationStopped; i++) {\n\t funcName = listeners[i].name;\n\t listeners[i](iEvent);\n\t }\n\t }\n\t\n\t return this;\n\t },\n\t\n\t /* \\\n\t * Interactable.on\n\t [ method ]\n\t *\n\t * Binds a listener for an InteractEvent or DOM event.\n\t *\n\t - eventType (string | array | object) The types of events to listen for\n\t - listener (function) The function to be called on the given event(s)\n\t - useCapture (boolean) #optional useCapture flag for addEventListener\n\t = (object) This Interactable\n\t \\*/\n\t on: function on(eventType, listener, useCapture) {\n\t var i;\n\t\n\t if (isString(eventType) && eventType.search(' ') !== -1) {\n\t eventType = eventType.trim().split(/ +/);\n\t }\n\t\n\t if (isArray(eventType)) {\n\t for (i = 0; i < eventType.length; i++) {\n\t this.on(eventType[i], listener, useCapture);\n\t }\n\t\n\t return this;\n\t }\n\t\n\t if (isObject(eventType)) {\n\t for (var prop in eventType) {\n\t this.on(prop, eventType[prop], listener);\n\t }\n\t\n\t return this;\n\t }\n\t\n\t if (eventType === 'wheel') {\n\t eventType = wheelEvent;\n\t }\n\t\n\t // convert to boolean\n\t useCapture = useCapture ? true : false;\n\t\n\t if (contains(eventTypes, eventType)) {\n\t // if this type of event was never bound to this Interactable\n\t if (!(eventType in this._iEvents)) {\n\t this._iEvents[eventType] = [listener];\n\t } else {\n\t this._iEvents[eventType].push(listener);\n\t }\n\t }\n\t // delegated event for selector\n\t else if (this.selector) {\n\t if (!delegatedEvents[eventType]) {\n\t delegatedEvents[eventType] = {\n\t selectors: [],\n\t contexts: [],\n\t listeners: []\n\t };\n\t\n\t // add delegate listener functions\n\t for (i = 0; i < documents.length; i++) {\n\t events.add(documents[i], eventType, delegateListener);\n\t events.add(documents[i], eventType, delegateUseCapture, true);\n\t }\n\t }\n\t\n\t var delegated = delegatedEvents[eventType],\n\t index;\n\t\n\t for (index = delegated.selectors.length - 1; index >= 0; index--) {\n\t if (delegated.selectors[index] === this.selector && delegated.contexts[index] === this._context) {\n\t break;\n\t }\n\t }\n\t\n\t if (index === -1) {\n\t index = delegated.selectors.length;\n\t\n\t delegated.selectors.push(this.selector);\n\t delegated.contexts.push(this._context);\n\t delegated.listeners.push([]);\n\t }\n\t\n\t // keep listener and useCapture flag\n\t delegated.listeners[index].push([listener, useCapture]);\n\t } else {\n\t events.add(this._element, eventType, listener, useCapture);\n\t }\n\t\n\t return this;\n\t },\n\t\n\t /* \\\n\t * Interactable.off\n\t [ method ]\n\t *\n\t * Removes an InteractEvent or DOM event listener\n\t *\n\t - eventType (string | array | object) The types of events that were listened for\n\t - listener (function) The listener function to be removed\n\t - useCapture (boolean) #optional useCapture flag for removeEventListener\n\t = (object) This Interactable\n\t \\*/\n\t off: function off(eventType, listener, useCapture) {\n\t var i;\n\t\n\t if (isString(eventType) && eventType.search(' ') !== -1) {\n\t eventType = eventType.trim().split(/ +/);\n\t }\n\t\n\t if (isArray(eventType)) {\n\t for (i = 0; i < eventType.length; i++) {\n\t this.off(eventType[i], listener, useCapture);\n\t }\n\t\n\t return this;\n\t }\n\t\n\t if (isObject(eventType)) {\n\t for (var prop in eventType) {\n\t this.off(prop, eventType[prop], listener);\n\t }\n\t\n\t return this;\n\t }\n\t\n\t var eventList,\n\t index = -1;\n\t\n\t // convert to boolean\n\t useCapture = useCapture ? true : false;\n\t\n\t if (eventType === 'wheel') {\n\t eventType = wheelEvent;\n\t }\n\t\n\t // if it is an action event type\n\t if (contains(eventTypes, eventType)) {\n\t eventList = this._iEvents[eventType];\n\t\n\t if (eventList && (index = indexOf(eventList, listener)) !== -1) {\n\t this._iEvents[eventType].splice(index, 1);\n\t }\n\t }\n\t // delegated event\n\t else if (this.selector) {\n\t var delegated = delegatedEvents[eventType],\n\t matchFound = false;\n\t\n\t if (!delegated) {\n\t return this;\n\t }\n\t\n\t // count from last index of delegated to 0\n\t for (index = delegated.selectors.length - 1; index >= 0; index--) {\n\t // look for matching selector and context Node\n\t if (delegated.selectors[index] === this.selector && delegated.contexts[index] === this._context) {\n\t var listeners = delegated.listeners[index];\n\t\n\t // each item of the listeners array is an array: [function, useCaptureFlag]\n\t for (i = listeners.length - 1; i >= 0; i--) {\n\t var fn = listeners[i][0],\n\t useCap = listeners[i][1];\n\t\n\t // check if the listener functions and useCapture flags match\n\t if (fn === listener && useCap === useCapture) {\n\t // remove the listener from the array of listeners\n\t listeners.splice(i, 1);\n\t\n\t // if all listeners for this interactable have been removed\n\t // remove the interactable from the delegated arrays\n\t if (!listeners.length) {\n\t delegated.selectors.splice(index, 1);\n\t delegated.contexts.splice(index, 1);\n\t delegated.listeners.splice(index, 1);\n\t\n\t // remove delegate function from context\n\t events.remove(this._context, eventType, delegateListener);\n\t events.remove(this._context, eventType, delegateUseCapture, true);\n\t\n\t // remove the arrays if they are empty\n\t if (!delegated.selectors.length) {\n\t delegatedEvents[eventType] = null;\n\t }\n\t }\n\t\n\t // only remove one listener\n\t matchFound = true;\n\t break;\n\t }\n\t }\n\t\n\t if (matchFound) {\n\t break;\n\t }\n\t }\n\t }\n\t }\n\t // remove listener from this Interatable's element\n\t else {\n\t events.remove(this._element, eventType, listener, useCapture);\n\t }\n\t\n\t return this;\n\t },\n\t\n\t /* \\\n\t * Interactable.set\n\t [ method ]\n\t *\n\t * Reset the options of this Interactable\n\t - options (object) The new settings to apply\n\t = (object) This Interactable\n\t \\*/\n\t set: function set(options) {\n\t if (!isObject(options)) {\n\t options = {};\n\t }\n\t\n\t this.options = extend({}, defaultOptions.base);\n\t\n\t var i,\n\t actions = ['drag', 'drop', 'resize', 'gesture'],\n\t methods = ['draggable', 'dropzone', 'resizable', 'gesturable'],\n\t perActions = extend(extend({}, defaultOptions.perAction), options[action] || {});\n\t\n\t for (i = 0; i < actions.length; i++) {\n\t var action = actions[i];\n\t\n\t this.options[action] = extend({}, defaultOptions[action]);\n\t\n\t this.setPerAction(action, perActions);\n\t\n\t this[methods[i]](options[action]);\n\t }\n\t\n\t var settings = ['accept', 'actionChecker', 'allowFrom', 'deltaSource', 'dropChecker', 'ignoreFrom', 'origin', 'preventDefault', 'rectChecker', 'styleCursor'];\n\t\n\t for (i = 0, len = settings.length; i < len; i++) {\n\t var setting = settings[i];\n\t\n\t this.options[setting] = defaultOptions.base[setting];\n\t\n\t if (setting in options) {\n\t this[setting](options[setting]);\n\t }\n\t }\n\t\n\t return this;\n\t },\n\t\n\t /* \\\n\t * Interactable.unset\n\t [ method ]\n\t *\n\t * Remove this interactable from the list of interactables and remove\n\t * it's drag, drop, resize and gesture capabilities\n\t *\n\t = (object) @interact\n\t \\*/\n\t unset: function unset() {\n\t events.remove(this._element, 'all');\n\t\n\t if (!isString(this.selector)) {\n\t events.remove(this, 'all');\n\t if (this.options.styleCursor) {\n\t this._element.style.cursor = '';\n\t }\n\t } else {\n\t // remove delegated events\n\t for (var type in delegatedEvents) {\n\t var delegated = delegatedEvents[type];\n\t\n\t for (var i = 0; i < delegated.selectors.length; i++) {\n\t if (delegated.selectors[i] === this.selector && delegated.contexts[i] === this._context) {\n\t delegated.selectors.splice(i, 1);\n\t delegated.contexts.splice(i, 1);\n\t delegated.listeners.splice(i, 1);\n\t\n\t // remove the arrays if they are empty\n\t if (!delegated.selectors.length) {\n\t delegatedEvents[type] = null;\n\t }\n\t }\n\t\n\t events.remove(this._context, type, delegateListener);\n\t events.remove(this._context, type, delegateUseCapture, true);\n\t\n\t break;\n\t }\n\t }\n\t }\n\t\n\t this.dropzone(false);\n\t\n\t interactables.splice(indexOf(interactables, this), 1);\n\t\n\t return interact;\n\t }\n\t };\n\t\n\t function warnOnce(method, message) {\n\t var warned = false;\n\t\n\t return function () {\n\t if (!warned) {\n\t window.console.warn(message);\n\t warned = true;\n\t }\n\t\n\t return method.apply(this, arguments);\n\t };\n\t }\n\t\n\t Interactable.prototype.snap = warnOnce(Interactable.prototype.snap, 'Interactable#snap is deprecated. See the new documentation for snapping at http://interactjs.io/docs/snapping');\n\t Interactable.prototype.restrict = warnOnce(Interactable.prototype.restrict, 'Interactable#restrict is deprecated. See the new documentation for resticting at http://interactjs.io/docs/restriction');\n\t Interactable.prototype.inertia = warnOnce(Interactable.prototype.inertia, 'Interactable#inertia is deprecated. See the new documentation for inertia at http://interactjs.io/docs/inertia');\n\t Interactable.prototype.autoScroll = warnOnce(Interactable.prototype.autoScroll, 'Interactable#autoScroll is deprecated. See the new documentation for autoScroll at http://interactjs.io/docs/#autoscroll');\n\t Interactable.prototype.squareResize = warnOnce(Interactable.prototype.squareResize, 'Interactable#squareResize is deprecated. See http://interactjs.io/docs/#resize-square');\n\t\n\t Interactable.prototype.accept = warnOnce(Interactable.prototype.accept, 'Interactable#accept is deprecated. use Interactable#dropzone({ accept: target }) instead');\n\t Interactable.prototype.dropChecker = warnOnce(Interactable.prototype.dropChecker, 'Interactable#dropChecker is deprecated. use Interactable#dropzone({ dropChecker: checkerFunction }) instead');\n\t Interactable.prototype.context = warnOnce(Interactable.prototype.context, 'Interactable#context as a method is deprecated. It will soon be a DOM Node instead');\n\t\n\t /* \\\n\t * interact.isSet\n\t [ method ]\n\t *\n\t * Check if an element has been set\n\t - element (Element) The Element being searched for\n\t = (boolean) Indicates if the element or CSS selector was previously passed to interact\n\t \\*/\n\t interact.isSet = function (element, options) {\n\t return interactables.indexOfElement(element, options && options.context) !== -1;\n\t };\n\t\n\t /* \\\n\t * interact.on\n\t [ method ]\n\t *\n\t * Adds a global listener for an InteractEvent or adds a DOM event to\n\t * `document`\n\t *\n\t - type (string | array | object) The types of events to listen for\n\t - listener (function) The function to be called on the given event(s)\n\t - useCapture (boolean) #optional useCapture flag for addEventListener\n\t = (object) interact\n\t \\*/\n\t interact.on = function (type, listener, useCapture) {\n\t if (isString(type) && type.search(' ') !== -1) {\n\t type = type.trim().split(/ +/);\n\t }\n\t\n\t if (isArray(type)) {\n\t for (var i = 0; i < type.length; i++) {\n\t interact.on(type[i], listener, useCapture);\n\t }\n\t\n\t return interact;\n\t }\n\t\n\t if (isObject(type)) {\n\t for (var prop in type) {\n\t interact.on(prop, type[prop], listener);\n\t }\n\t\n\t return interact;\n\t }\n\t\n\t // if it is an InteractEvent type, add listener to globalEvents\n\t if (contains(eventTypes, type)) {\n\t // if this type of event was never bound\n\t if (!globalEvents[type]) {\n\t globalEvents[type] = [listener];\n\t } else {\n\t globalEvents[type].push(listener);\n\t }\n\t }\n\t // If non InteractEvent type, addEventListener to document\n\t else {\n\t events.add(document, type, listener, useCapture);\n\t }\n\t\n\t return interact;\n\t };\n\t\n\t /* \\\n\t * interact.off\n\t [ method ]\n\t *\n\t * Removes a global InteractEvent listener or DOM event from `document`\n\t *\n\t - type (string | array | object) The types of events that were listened for\n\t - listener (function) The listener function to be removed\n\t - useCapture (boolean) #optional useCapture flag for removeEventListener\n\t = (object) interact\n\t \\*/\n\t interact.off = function (type, listener, useCapture) {\n\t if (isString(type) && type.search(' ') !== -1) {\n\t type = type.trim().split(/ +/);\n\t }\n\t\n\t if (isArray(type)) {\n\t for (var i = 0; i < type.length; i++) {\n\t interact.off(type[i], listener, useCapture);\n\t }\n\t\n\t return interact;\n\t }\n\t\n\t if (isObject(type)) {\n\t for (var prop in type) {\n\t interact.off(prop, type[prop], listener);\n\t }\n\t\n\t return interact;\n\t }\n\t\n\t if (!contains(eventTypes, type)) {\n\t events.remove(document, type, listener, useCapture);\n\t } else {\n\t var index;\n\t\n\t if (type in globalEvents && (index = indexOf(globalEvents[type], listener)) !== -1) {\n\t globalEvents[type].splice(index, 1);\n\t }\n\t }\n\t\n\t return interact;\n\t };\n\t\n\t /* \\\n\t * interact.enableDragging\n\t [ method ]\n\t *\n\t * Deprecated.\n\t *\n\t * Returns or sets whether dragging is enabled for any Interactables\n\t *\n\t - newValue (boolean) #optional `true` to allow the action; `false` to disable action for all Interactables\n\t = (boolean | object) The current setting or interact\n\t \\*/\n\t interact.enableDragging = warnOnce(function (newValue) {\n\t if (newValue !== null && newValue !== undefined) {\n\t actionIsEnabled.drag = newValue;\n\t\n\t return interact;\n\t }\n\t return actionIsEnabled.drag;\n\t }, 'interact.enableDragging is deprecated and will soon be removed.');\n\t\n\t /* \\\n\t * interact.enableResizing\n\t [ method ]\n\t *\n\t * Deprecated.\n\t *\n\t * Returns or sets whether resizing is enabled for any Interactables\n\t *\n\t - newValue (boolean) #optional `true` to allow the action; `false` to disable action for all Interactables\n\t = (boolean | object) The current setting or interact\n\t \\*/\n\t interact.enableResizing = warnOnce(function (newValue) {\n\t if (newValue !== null && newValue !== undefined) {\n\t actionIsEnabled.resize = newValue;\n\t\n\t return interact;\n\t }\n\t return actionIsEnabled.resize;\n\t }, 'interact.enableResizing is deprecated and will soon be removed.');\n\t\n\t /* \\\n\t * interact.enableGesturing\n\t [ method ]\n\t *\n\t * Deprecated.\n\t *\n\t * Returns or sets whether gesturing is enabled for any Interactables\n\t *\n\t - newValue (boolean) #optional `true` to allow the action; `false` to disable action for all Interactables\n\t = (boolean | object) The current setting or interact\n\t \\*/\n\t interact.enableGesturing = warnOnce(function (newValue) {\n\t if (newValue !== null && newValue !== undefined) {\n\t actionIsEnabled.gesture = newValue;\n\t\n\t return interact;\n\t }\n\t return actionIsEnabled.gesture;\n\t }, 'interact.enableGesturing is deprecated and will soon be removed.');\n\t\n\t interact.eventTypes = eventTypes;\n\t\n\t /* \\\n\t * interact.debug\n\t [ method ]\n\t *\n\t * Returns debugging data\n\t = (object) An object with properties that outline the current state and expose internal functions and variables\n\t \\*/\n\t interact.debug = function () {\n\t var interaction = interactions[0] || new Interaction();\n\t\n\t return {\n\t interactions: interactions,\n\t target: interaction.target,\n\t dragging: interaction.dragging,\n\t resizing: interaction.resizing,\n\t gesturing: interaction.gesturing,\n\t prepared: interaction.prepared,\n\t matches: interaction.matches,\n\t matchElements: interaction.matchElements,\n\t\n\t prevCoords: interaction.prevCoords,\n\t startCoords: interaction.startCoords,\n\t\n\t pointerIds: interaction.pointerIds,\n\t pointers: interaction.pointers,\n\t addPointer: listeners.addPointer,\n\t removePointer: listeners.removePointer,\n\t recordPointer: listeners.recordPointer,\n\t\n\t snap: interaction.snapStatus,\n\t restrict: interaction.restrictStatus,\n\t inertia: interaction.inertiaStatus,\n\t\n\t downTime: interaction.downTimes[0],\n\t downEvent: interaction.downEvent,\n\t downPointer: interaction.downPointer,\n\t prevEvent: interaction.prevEvent,\n\t\n\t Interactable: Interactable,\n\t interactables: interactables,\n\t pointerIsDown: interaction.pointerIsDown,\n\t defaultOptions: defaultOptions,\n\t defaultActionChecker: defaultActionChecker,\n\t\n\t actionCursors: actionCursors,\n\t dragMove: listeners.dragMove,\n\t resizeMove: listeners.resizeMove,\n\t gestureMove: listeners.gestureMove,\n\t pointerUp: listeners.pointerUp,\n\t pointerDown: listeners.pointerDown,\n\t pointerMove: listeners.pointerMove,\n\t pointerHover: listeners.pointerHover,\n\t\n\t eventTypes: eventTypes,\n\t\n\t events: events,\n\t globalEvents: globalEvents,\n\t delegatedEvents: delegatedEvents,\n\t\n\t prefixedPropREs: prefixedPropREs\n\t };\n\t };\n\t\n\t // expose the functions used to calculate multi-touch properties\n\t interact.getPointerAverage = pointerAverage;\n\t interact.getTouchBBox = touchBBox;\n\t interact.getTouchDistance = touchDistance;\n\t interact.getTouchAngle = touchAngle;\n\t\n\t interact.getElementRect = getElementRect;\n\t interact.getElementClientRect = getElementClientRect;\n\t interact.matchesSelector = matchesSelector;\n\t interact.closest = closest;\n\t\n\t /* \\\n\t * interact.margin\n\t [ method ]\n\t *\n\t * Deprecated. Use `interact(target).resizable({ margin: number });` instead.\n\t * Returns or sets the margin for autocheck resizing used in\n\t * @Interactable.getAction. That is the distance from the bottom and right\n\t * edges of an element clicking in which will start resizing\n\t *\n\t - newValue (number) #optional\n\t = (number | interact) The current margin value or interact\n\t \\*/\n\t interact.margin = warnOnce(function (newvalue) {\n\t if (isNumber(newvalue)) {\n\t margin = newvalue;\n\t\n\t return interact;\n\t }\n\t return margin;\n\t }, 'interact.margin is deprecated. Use interact(target).resizable({ margin: number }); instead.');\n\t\n\t /* \\\n\t * interact.supportsTouch\n\t [ method ]\n\t *\n\t = (boolean) Whether or not the browser supports touch input\n\t \\*/\n\t interact.supportsTouch = function () {\n\t return supportsTouch;\n\t };\n\t\n\t /* \\\n\t * interact.supportsPointerEvent\n\t [ method ]\n\t *\n\t = (boolean) Whether or not the browser supports PointerEvents\n\t \\*/\n\t interact.supportsPointerEvent = function () {\n\t return supportsPointerEvent;\n\t };\n\t\n\t /* \\\n\t * interact.stop\n\t [ method ]\n\t *\n\t * Cancels all interactions (end events are not fired)\n\t *\n\t - event (Event) An event on which to call preventDefault()\n\t = (object) interact\n\t \\*/\n\t interact.stop = function (event) {\n\t for (var i = interactions.length - 1; i >= 0; i--) {\n\t interactions[i].stop(event);\n\t }\n\t\n\t return interact;\n\t };\n\t\n\t /* \\\n\t * interact.dynamicDrop\n\t [ method ]\n\t *\n\t * Returns or sets whether the dimensions of dropzone elements are\n\t * calculated on every dragmove or only on dragstart for the default\n\t * dropChecker\n\t *\n\t - newValue (boolean) #optional True to check on each move. False to check only before start\n\t = (boolean | interact) The current setting or interact\n\t \\*/\n\t interact.dynamicDrop = function (newValue) {\n\t if (isBool(newValue)) {\n\t // if (dragging && dynamicDrop !== newValue && !newValue) {\n\t // calcRects(dropzones);\n\t // }\n\t\n\t dynamicDrop = newValue;\n\t\n\t return interact;\n\t }\n\t return dynamicDrop;\n\t };\n\t\n\t /* \\\n\t * interact.pointerMoveTolerance\n\t [ method ]\n\t * Returns or sets the distance the pointer must be moved before an action\n\t * sequence occurs. This also affects tolerance for tap events.\n\t *\n\t - newValue (number) #optional The movement from the start position must be greater than this value\n\t = (number | Interactable) The current setting or interact\n\t \\*/\n\t interact.pointerMoveTolerance = function (newValue) {\n\t if (isNumber(newValue)) {\n\t pointerMoveTolerance = newValue;\n\t\n\t return this;\n\t }\n\t\n\t return pointerMoveTolerance;\n\t };\n\t\n\t /* \\\n\t * interact.maxInteractions\n\t [ method ]\n\t **\n\t * Returns or sets the maximum number of concurrent interactions allowed.\n\t * By default only 1 interaction is allowed at a time (for backwards\n\t * compatibility). To allow multiple interactions on the same Interactables\n\t * and elements, you need to enable it in the draggable, resizable and\n\t * gesturable `'max'` and `'maxPerElement'` options.\n\t **\n\t - newValue (number) #optional Any number. newValue <= 0 means no interactions.\n\t \\*/\n\t interact.maxInteractions = function (newValue) {\n\t if (isNumber(newValue)) {\n\t maxInteractions = newValue;\n\t\n\t return this;\n\t }\n\t\n\t return maxInteractions;\n\t };\n\t\n\t interact.createSnapGrid = function (grid) {\n\t return function (x, y) {\n\t var offsetX = 0,\n\t offsetY = 0;\n\t\n\t if (isObject(grid.offset)) {\n\t offsetX = grid.offset.x;\n\t offsetY = grid.offset.y;\n\t }\n\t\n\t var gridx = Math.round((x - offsetX) / grid.x),\n\t gridy = Math.round((y - offsetY) / grid.y),\n\t newX = gridx * grid.x + offsetX,\n\t newY = gridy * grid.y + offsetY;\n\t\n\t return {\n\t x: newX,\n\t y: newY,\n\t range: grid.range\n\t };\n\t };\n\t };\n\t\n\t function endAllInteractions(event) {\n\t for (var i = 0; i < interactions.length; i++) {\n\t interactions[i].pointerEnd(event, event);\n\t }\n\t }\n\t\n\t function listenToDocument(doc) {\n\t if (contains(documents, doc)) {\n\t return;\n\t }\n\t\n\t var win = doc.defaultView || doc.parentWindow;\n\t\n\t // add delegate event listener\n\t for (var eventType in delegatedEvents) {\n\t events.add(doc, eventType, delegateListener);\n\t events.add(doc, eventType, delegateUseCapture, true);\n\t }\n\t\n\t if (supportsPointerEvent) {\n\t if (PointerEvent === win.MSPointerEvent) {\n\t pEventTypes = {\n\t up: 'MSPointerUp', down: 'MSPointerDown', over: 'mouseover',\n\t out: 'mouseout', move: 'MSPointerMove', cancel: 'MSPointerCancel' };\n\t } else {\n\t pEventTypes = {\n\t up: 'pointerup', down: 'pointerdown', over: 'pointerover',\n\t out: 'pointerout', move: 'pointermove', cancel: 'pointercancel' };\n\t }\n\t\n\t events.add(doc, pEventTypes.down, listeners.selectorDown);\n\t events.add(doc, pEventTypes.move, listeners.pointerMove);\n\t events.add(doc, pEventTypes.over, listeners.pointerOver);\n\t events.add(doc, pEventTypes.out, listeners.pointerOut);\n\t events.add(doc, pEventTypes.up, listeners.pointerUp);\n\t events.add(doc, pEventTypes.cancel, listeners.pointerCancel);\n\t\n\t // autoscroll\n\t events.add(doc, pEventTypes.move, listeners.autoScrollMove);\n\t } else {\n\t events.add(doc, 'mousedown', listeners.selectorDown);\n\t events.add(doc, 'mousemove', listeners.pointerMove);\n\t events.add(doc, 'mouseup', listeners.pointerUp);\n\t events.add(doc, 'mouseover', listeners.pointerOver);\n\t events.add(doc, 'mouseout', listeners.pointerOut);\n\t\n\t events.add(doc, 'touchstart', listeners.selectorDown);\n\t events.add(doc, 'touchmove', listeners.pointerMove);\n\t events.add(doc, 'touchend', listeners.pointerUp);\n\t events.add(doc, 'touchcancel', listeners.pointerCancel);\n\t\n\t // autoscroll\n\t events.add(doc, 'mousemove', listeners.autoScrollMove);\n\t events.add(doc, 'touchmove', listeners.autoScrollMove);\n\t }\n\t\n\t events.add(win, 'blur', endAllInteractions);\n\t\n\t try {\n\t if (win.frameElement) {\n\t var parentDoc = win.frameElement.ownerDocument,\n\t parentWindow = parentDoc.defaultView;\n\t\n\t events.add(parentDoc, 'mouseup', listeners.pointerEnd);\n\t events.add(parentDoc, 'touchend', listeners.pointerEnd);\n\t events.add(parentDoc, 'touchcancel', listeners.pointerEnd);\n\t events.add(parentDoc, 'pointerup', listeners.pointerEnd);\n\t events.add(parentDoc, 'MSPointerUp', listeners.pointerEnd);\n\t events.add(parentWindow, 'blur', endAllInteractions);\n\t }\n\t } catch (error) {\n\t interact.windowParentError = error;\n\t }\n\t\n\t // prevent native HTML5 drag on interact.js target elements\n\t events.add(doc, 'dragstart', function (event) {\n\t for (var i = 0; i < interactions.length; i++) {\n\t var interaction = interactions[i];\n\t\n\t if (interaction.element && (interaction.element === event.target || nodeContains(interaction.element, event.target))) {\n\t interaction.checkAndPreventDefault(event, interaction.target, interaction.element);\n\t return;\n\t }\n\t }\n\t });\n\t\n\t if (events.useAttachEvent) {\n\t // For IE's lack of Event#preventDefault\n\t events.add(doc, 'selectstart', function (event) {\n\t var interaction = interactions[0];\n\t\n\t if (interaction.currentAction()) {\n\t interaction.checkAndPreventDefault(event);\n\t }\n\t });\n\t\n\t // For IE's bad dblclick event sequence\n\t events.add(doc, 'dblclick', doOnInteractions('ie8Dblclick'));\n\t }\n\t\n\t documents.push(doc);\n\t }\n\t\n\t listenToDocument(document);\n\t\n\t function indexOf(array, target) {\n\t for (var i = 0, len = array.length; i < len; i++) {\n\t if (array[i] === target) {\n\t return i;\n\t }\n\t }\n\t\n\t return -1;\n\t }\n\t\n\t function contains(array, target) {\n\t return indexOf(array, target) !== -1;\n\t }\n\t\n\t function matchesSelector(element, selector, nodeList) {\n\t if (ie8MatchesSelector) {\n\t return ie8MatchesSelector(element, selector, nodeList);\n\t }\n\t\n\t // remove /deep/ from selectors if shadowDOM polyfill is used\n\t if (window !== realWindow) {\n\t selector = selector.replace(/\\/deep\\//g, ' ');\n\t }\n\t\n\t return element[prefixedMatchesSelector](selector);\n\t }\n\t\n\t function matchesUpTo(element, selector, limit) {\n\t while (isElement(element)) {\n\t if (matchesSelector(element, selector)) {\n\t return true;\n\t }\n\t\n\t element = parentElement(element);\n\t\n\t if (element === limit) {\n\t return matchesSelector(element, selector);\n\t }\n\t }\n\t\n\t return false;\n\t }\n\t\n\t // For IE8's lack of an Element#matchesSelector\n\t // taken from http://tanalin.com/en/blog/2012/12/matches-selector-ie8/ and modified\n\t if (!(prefixedMatchesSelector in Element.prototype) || !isFunction(Element.prototype[prefixedMatchesSelector])) {\n\t ie8MatchesSelector = function ie8MatchesSelector(element, selector, elems) {\n\t elems = elems || element.parentNode.querySelectorAll(selector);\n\t\n\t for (var i = 0, len = elems.length; i < len; i++) {\n\t if (elems[i] === element) {\n\t return true;\n\t }\n\t }\n\t\n\t return false;\n\t };\n\t }\n\t\n\t // requestAnimationFrame polyfill\n\t (function () {\n\t var lastTime = 0,\n\t vendors = ['ms', 'moz', 'webkit', 'o'];\n\t\n\t for (var x = 0; x < vendors.length && !realWindow.requestAnimationFrame; ++x) {\n\t reqFrame = realWindow[vendors[x] + 'RequestAnimationFrame'];\n\t cancelFrame = realWindow[vendors[x] + 'CancelAnimationFrame'] || realWindow[vendors[x] + 'CancelRequestAnimationFrame'];\n\t }\n\t\n\t if (!reqFrame) {\n\t reqFrame = function reqFrame(callback) {\n\t var currTime = new Date().getTime(),\n\t timeToCall = Math.max(0, 16 - (currTime - lastTime)),\n\t id = setTimeout(function () {\n\t callback(currTime + timeToCall);\n\t }, timeToCall);\n\t lastTime = currTime + timeToCall;\n\t return id;\n\t };\n\t }\n\t\n\t if (!cancelFrame) {\n\t cancelFrame = function cancelFrame(id) {\n\t clearTimeout(id);\n\t };\n\t }\n\t })();\n\t\n\t /* global exports: true, module, define */\n\t\n\t // http://documentcloud.github.io/underscore/docs/underscore.html#section-11\n\t if (true) {\n\t if (typeof module !== 'undefined' && module.exports) {\n\t exports = module.exports = interact;\n\t }\n\t exports.interact = interact;\n\t }\n\t // AMD\n\t else if (typeof define === 'function' && define.amd) {\n\t define('interact', function () {\n\t return interact;\n\t });\n\t } else {\n\t realWindow.interact = interact;\n\t }\n\t})(typeof window === 'undefined' ? undefined : window);\n\n/***/ }),\n/* 6 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\texports.RowSelectionModel = exports.RowMoveManager = exports.HeaderMenu = exports.HeaderButtons = exports.CheckboxSelectColumn = exports.CellSelectionModel = exports.CellRangeSelector = exports.CellRangeDecorator = exports.CellCopyManager = exports.AutoTooltips = undefined;\n\t\n\tvar _slick = __webpack_require__(7);\n\t\n\tvar _slick2 = _interopRequireDefault(_slick);\n\t\n\tvar _slick3 = __webpack_require__(9);\n\t\n\tvar _slick4 = _interopRequireDefault(_slick3);\n\t\n\tvar _slick5 = __webpack_require__(11);\n\t\n\tvar _slick6 = _interopRequireDefault(_slick5);\n\t\n\tvar _slick7 = __webpack_require__(12);\n\t\n\tvar _slick8 = _interopRequireDefault(_slick7);\n\t\n\tvar _slick9 = __webpack_require__(13);\n\t\n\tvar _slick10 = _interopRequireDefault(_slick9);\n\t\n\tvar _slick11 = __webpack_require__(15);\n\t\n\tvar _slick12 = _interopRequireDefault(_slick11);\n\t\n\tvar _slick13 = __webpack_require__(17);\n\t\n\tvar _slick14 = _interopRequireDefault(_slick13);\n\t\n\tvar _slick15 = __webpack_require__(19);\n\t\n\tvar _slick16 = _interopRequireDefault(_slick15);\n\t\n\tvar _slick17 = __webpack_require__(21);\n\t\n\tvar _slick18 = _interopRequireDefault(_slick17);\n\t\n\tvar _slick19 = __webpack_require__(23);\n\t\n\tvar _slick20 = _interopRequireDefault(_slick19);\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\t\n\texports.AutoTooltips = _slick2.default;\n\texports.CellCopyManager = _slick4.default;\n\texports.CellRangeDecorator = _slick6.default;\n\texports.CellRangeSelector = _slick8.default;\n\texports.CellSelectionModel = _slick10.default;\n\texports.CheckboxSelectColumn = _slick12.default;\n\texports.HeaderButtons = _slick14.default;\n\texports.HeaderMenu = _slick16.default;\n\texports.RowMoveManager = _slick18.default;\n\texports.RowSelectionModel = _slick20.default;\n\n/***/ }),\n/* 7 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _slick = __webpack_require__(8);\n\t\n\tvar _slick2 = _interopRequireDefault(_slick);\n\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n\texports.default = _slick2.default;\n\n/***/ }),\n/* 8 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _jquery = __webpack_require__(2);\n\t\n\tvar _jquery2 = _interopRequireDefault(_jquery);\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\t\n\texports.default = AutoTooltips;\n\t\n\t/**\n\t * AutoTooltips plugin to show/hide tooltips when columns are too narrow to fit content.\n\t * @constructor\n\t * @param {boolean} [options.enableForCells=true] - Enable tooltip for grid cells\n\t * @param {boolean} [options.enableForHeaderCells=false] - Enable tooltip for header cells\n\t * @param {number} [options.maxToolTipLength=null] - The maximum length for a tooltip\n\t */\n\t\n\tfunction AutoTooltips(options) {\n\t var _grid = void 0;\n\t var _self = this;\n\t var _defaults = {\n\t enableForCells: true,\n\t enableForHeaderCells: false,\n\t maxToolTipLength: null\n\t };\n\t\n\t /**\n\t * Initialize plugin.\n\t */\n\t function init(grid) {\n\t options = Object.assign({}, _defaults, options);\n\t _grid = grid;\n\t if (options.enableForCells) _grid.onMouseEnter.subscribe(handleMouseEnter);\n\t if (options.enableForHeaderCells) _grid.onHeaderMouseEnter.subscribe(handleHeaderMouseEnter);\n\t }\n\t\n\t /**\n\t * Destroy plugin.\n\t */\n\t function destroy() {\n\t if (options.enableForCells) _grid.onMouseEnter.unsubscribe(handleMouseEnter);\n\t if (options.enableForHeaderCells) _grid.onHeaderMouseEnter.unsubscribe(handleHeaderMouseEnter);\n\t }\n\t\n\t /**\n\t * Handle mouse entering grid cell to add/remove tooltip.\n\t * @param {jQuery.Event} e - The event\n\t */\n\t function handleMouseEnter(e) {\n\t var cell = _grid.getCellFromEvent(e);\n\t if (cell) {\n\t var $node = (0, _jquery2.default)(_grid.getCellNode(cell.row, cell.cell));\n\t var text = void 0;\n\t if ($node.innerWidth() < $node[0].scrollWidth) {\n\t text = _jquery2.default.trim($node.text());\n\t if (options.maxToolTipLength && text.length > options.maxToolTipLength) {\n\t text = text.substr(0, options.maxToolTipLength - 3) + '...';\n\t }\n\t } else {\n\t text = '';\n\t }\n\t $node.attr('title', text);\n\t }\n\t }\n\t\n\t /**\n\t * Handle mouse entering header cell to add/remove tooltip.\n\t * @param {jQuery.Event} e - The event\n\t * @param {object} args.column - The column definition\n\t */\n\t function handleHeaderMouseEnter(e, args) {\n\t var column = args.column,\n\t $node = (0, _jquery2.default)(e.target).closest('.slick-header-column');\n\t if (column && !column.toolTip) {\n\t $node.attr('title', $node.innerWidth() < $node[0].scrollWidth ? column.name : '');\n\t }\n\t }\n\t\n\t // Public API\n\t Object.assign(this, {\n\t init: init,\n\t destroy: destroy\n\t });\n\t}\n\n/***/ }),\n/* 9 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _slick = __webpack_require__(10);\n\t\n\tvar _slick2 = _interopRequireDefault(_slick);\n\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n\texports.default = _slick2.default;\n\n/***/ }),\n/* 10 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _slick = __webpack_require__(1);\n\t\n\tvar _slick2 = _interopRequireDefault(_slick);\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\t\n\tvar keyCode = _slick2.default.keyCode;\n\texports.default = CellCopyManager;\n\t\n\t\n\tfunction CellCopyManager() {\n\t var _grid;\n\t var _self = this;\n\t var _copiedRanges;\n\t\n\t function init(grid) {\n\t _grid = grid;\n\t _grid.onKeyDown.subscribe(handleKeyDown);\n\t }\n\t\n\t function destroy() {\n\t _grid.onKeyDown.unsubscribe(handleKeyDown);\n\t }\n\t\n\t function handleKeyDown(e, args) {\n\t var ranges;\n\t if (!_grid.getEditorLock().isActive()) {\n\t if (e.which == keyCode.ESCAPE) {\n\t if (_copiedRanges) {\n\t e.preventDefault();\n\t clearCopySelection();\n\t _self.onCopyCancelled.notify({ ranges: _copiedRanges });\n\t _copiedRanges = null;\n\t }\n\t }\n\t\n\t if (e.which == 67 && (e.ctrlKey || e.metaKey)) {\n\t ranges = _grid.getSelectionModel().getSelectedRanges();\n\t if (ranges.length != 0) {\n\t e.preventDefault();\n\t _copiedRanges = ranges;\n\t markCopySelection(ranges);\n\t _self.onCopyCells.notify({ ranges: ranges });\n\t }\n\t }\n\t\n\t if (e.which == 86 && (e.ctrlKey || e.metaKey)) {\n\t if (_copiedRanges) {\n\t e.preventDefault();\n\t clearCopySelection();\n\t ranges = _grid.getSelectionModel().getSelectedRanges();\n\t _self.onPasteCells.notify({ from: _copiedRanges, to: ranges });\n\t _copiedRanges = null;\n\t }\n\t }\n\t }\n\t }\n\t\n\t function markCopySelection(ranges) {\n\t var columns = _grid.getColumns();\n\t var hash = {};\n\t for (var i = 0; i < ranges.length; i++) {\n\t for (var j = ranges[i].fromRow; j <= ranges[i].toRow; j++) {\n\t hash[j] = {};\n\t for (var k = ranges[i].fromCell; k <= ranges[i].toCell; k++) {\n\t hash[j][columns[k].id] = 'copied';\n\t }\n\t }\n\t }\n\t _grid.setCellCssStyles('copy-manager', hash);\n\t }\n\t\n\t function clearCopySelection() {\n\t _grid.removeCellCssStyles('copy-manager');\n\t }\n\t\n\t Object.assign(this, {\n\t init: init,\n\t destroy: destroy,\n\t clearCopySelection: clearCopySelection,\n\t\n\t onCopyCells: new _slick2.default.Event(),\n\t onCopyCancelled: new _slick2.default.Event(),\n\t onPasteCells: new _slick2.default.Event()\n\t });\n\t}\n\n/***/ }),\n/* 11 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _slick = __webpack_require__(3);\n\t\n\tvar _slick2 = _interopRequireDefault(_slick);\n\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n\texports.default = _slick2.default;\n\n/***/ }),\n/* 12 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _slick = __webpack_require__(4);\n\t\n\tvar _slick2 = _interopRequireDefault(_slick);\n\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n\texports.default = _slick2.default;\n\n/***/ }),\n/* 13 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _slick = __webpack_require__(14);\n\t\n\tvar _slick2 = _interopRequireDefault(_slick);\n\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n\texports.default = _slick2.default;\n\n/***/ }),\n/* 14 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _slick = __webpack_require__(1);\n\t\n\tvar _slick2 = _interopRequireDefault(_slick);\n\t\n\tvar _slick3 = __webpack_require__(4);\n\t\n\tvar _slick4 = _interopRequireDefault(_slick3);\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\t\n\texports.default = CellSelectionModel;\n\t\n\t\n\tfunction CellSelectionModel() {\n\t var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {\n\t selectActiveCell: true\n\t };\n\t\n\t var _grid = void 0;\n\t var _canvas = void 0;\n\t var _ranges = [];\n\t var _self = this;\n\t var _selector = new _slick4.default({\n\t selectionCss: {\n\t border: '2px solid black'\n\t }\n\t });\n\t var _options = void 0;\n\t var _defaults = {\n\t selectActiveCell: true\n\t };\n\t\n\t function init(grid) {\n\t _options = Object.assign({}, options);\n\t _grid = grid;\n\t _canvas = _grid.getCanvasNode();\n\t _grid.onActiveCellChanged.subscribe(handleActiveCellChange);\n\t _grid.onKeyDown.subscribe(handleKeyDown);\n\t grid.registerPlugin(_selector);\n\t _selector.onCellRangeSelected.subscribe(handleCellRangeSelected);\n\t _selector.onBeforeCellRangeSelected.subscribe(handleBeforeCellRangeSelected);\n\t }\n\t\n\t function destroy() {\n\t _grid.onActiveCellChanged.unsubscribe(handleActiveCellChange);\n\t _grid.onKeyDown.unsubscribe(handleKeyDown);\n\t _selector.onCellRangeSelected.unsubscribe(handleCellRangeSelected);\n\t _selector.onBeforeCellRangeSelected.unsubscribe(handleBeforeCellRangeSelected);\n\t _grid.unregisterPlugin(_selector);\n\t }\n\t\n\t function removeInvalidRanges(ranges) {\n\t var result = [];\n\t\n\t for (var i = 0; i < ranges.length; i++) {\n\t var r = ranges[i];\n\t if (_grid.canCellBeSelected(r.fromRow, r.fromCell) && _grid.canCellBeSelected(r.toRow, r.toCell)) {\n\t result.push(r);\n\t }\n\t }\n\t\n\t return result;\n\t }\n\t\n\t function setSelectedRanges(ranges) {\n\t // simle check for: empty selection didn't change, prevent firing onSelectedRangesChanged\n\t if ((!_ranges || _ranges.length === 0) && (!ranges || ranges.length === 0)) {\n\t return;\n\t }\n\t\n\t _ranges = removeInvalidRanges(ranges);\n\t _self.onSelectedRangesChanged.notify(_ranges);\n\t }\n\t\n\t function getSelectedRanges() {\n\t return _ranges;\n\t }\n\t\n\t function handleBeforeCellRangeSelected(e, args) {\n\t if (_grid.getEditorLock().isActive()) {\n\t e.stopPropagation();\n\t return false;\n\t }\n\t }\n\t\n\t function handleCellRangeSelected(e, args) {\n\t setSelectedRanges([args.range]);\n\t }\n\t\n\t function handleActiveCellChange(e, args) {\n\t if (_options.selectActiveCell && args.row != null && args.cell != null) {\n\t setSelectedRanges([new _slick2.default.Range(args.row, args.cell)]);\n\t }\n\t }\n\t\n\t function handleKeyDown(e) {\n\t /** *\n\t * Кey codes\n\t * 37 left\n\t * 38 up\n\t * 39 right\n\t * 40 down\n\t */\n\t var ranges = void 0,\n\t last = void 0;\n\t var active = _grid.getActiveCell();\n\t\n\t if (active && e.shiftKey && !e.ctrlKey && !e.altKey && (e.which == 37 || e.which == 39 || e.which == 38 || e.which == 40)) {\n\t ranges = getSelectedRanges();\n\t if (!ranges.length) ranges.push(new _slick2.default.Range(active.row, active.cell));\n\t\n\t // keyboard can work with last range only\n\t last = ranges.pop();\n\t\n\t // can't handle selection out of active cell\n\t if (!last.contains(active.row, active.cell)) last = new _slick2.default.Range(active.row, active.cell);\n\t\n\t var dRow = last.toRow - last.fromRow,\n\t dCell = last.toCell - last.fromCell,\n\t\n\t // walking direction\n\t dirRow = active.row == last.fromRow ? 1 : -1,\n\t dirCell = active.cell == last.fromCell ? 1 : -1;\n\t\n\t if (e.which == 37) {\n\t dCell -= dirCell;\n\t } else if (e.which == 39) {\n\t dCell += dirCell;\n\t } else if (e.which == 38) {\n\t dRow -= dirRow;\n\t } else if (e.which == 40) {\n\t dRow += dirRow;\n\t }\n\t\n\t // define new selection range\n\t var new_last = new _slick2.default.Range(active.row, active.cell, active.row + dirRow * dRow, active.cell + dirCell * dCell);\n\t if (removeInvalidRanges([new_last]).length) {\n\t ranges.push(new_last);\n\t var viewRow = dirRow > 0 ? new_last.toRow : new_last.fromRow;\n\t var viewCell = dirCell > 0 ? new_last.toCell : new_last.fromCell;\n\t _grid.scrollRowIntoView(viewRow);\n\t _grid.scrollCellIntoView(viewRow, viewCell);\n\t } else ranges.push(last);\n\t\n\t setSelectedRanges(ranges);\n\t\n\t e.preventDefault();\n\t e.stopPropagation();\n\t }\n\t }\n\t\n\t Object.assign(this, {\n\t getSelectedRanges: getSelectedRanges,\n\t setSelectedRanges: setSelectedRanges,\n\t\n\t init: init,\n\t destroy: destroy,\n\t\n\t onSelectedRangesChanged: new _slick2.default.Event()\n\t });\n\t}\n\n/***/ }),\n/* 15 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _slick = __webpack_require__(16);\n\t\n\tvar _slick2 = _interopRequireDefault(_slick);\n\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n\texports.default = _slick2.default;\n\n/***/ }),\n/* 16 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _jquery = __webpack_require__(2);\n\t\n\tvar _jquery2 = _interopRequireDefault(_jquery);\n\t\n\tvar _slick = __webpack_require__(1);\n\t\n\tvar _slick2 = _interopRequireDefault(_slick);\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\t\n\texports.default = CheckboxSelectColumn;\n\t\n\t\n\tfunction CheckboxSelectColumn(options) {\n\t var _grid = void 0;\n\t var _self = this;\n\t var _handler = new _slick2.default.EventHandler();\n\t var _selectedRowsLookup = {};\n\t var _defaults = {\n\t columnId: '_checkbox_selector',\n\t cssClass: null,\n\t toolTip: 'Select/Deselect All',\n\t width: 30\n\t };\n\t\n\t var _options = _jquery2.default.extend(true, {}, _defaults, options);\n\t\n\t function init(grid) {\n\t _grid = grid;\n\t _handler.subscribe(_grid.onSelectedRowsChanged, handleSelectedRowsChanged).subscribe(_grid.onClick, handleClick).subscribe(_grid.onHeaderClick, handleHeaderClick).subscribe(_grid.onKeyDown, handleKeyDown);\n\t }\n\t\n\t function destroy() {\n\t _handler.unsubscribeAll();\n\t }\n\t\n\t function handleSelectedRowsChanged(e, args) {\n\t var selectedRows = _grid.getSelectedRows();\n\t var lookup = {},\n\t row = void 0,\n\t i = void 0;\n\t for (i = 0; i < selectedRows.length; i++) {\n\t row = selectedRows[i];\n\t lookup[row] = true;\n\t if (lookup[row] !== _selectedRowsLookup[row]) {\n\t _grid.invalidateRow(row);\n\t delete _selectedRowsLookup[row];\n\t }\n\t }\n\t for (i in _selectedRowsLookup) {\n\t _grid.invalidateRow(i);\n\t }\n\t _selectedRowsLookup = lookup;\n\t _grid.render();\n\t\n\t if (selectedRows.length && selectedRows.length == _grid.getDataLength()) {\n\t _grid.updateColumnHeader(_options.columnId, \"\", _options.toolTip);\n\t } else {\n\t _grid.updateColumnHeader(_options.columnId, \"\", _options.toolTip);\n\t }\n\t }\n\t\n\t function handleKeyDown(e, args) {\n\t if (e.which == 32) {\n\t if (_grid.getColumns()[args.cell].id === _options.columnId) {\n\t // if editing, try to commit\n\t if (!_grid.getEditorLock().isActive() || _grid.getEditorLock().commitCurrentEdit()) {\n\t toggleRowSelection(args.row);\n\t }\n\t e.preventDefault();\n\t e.stopImmediatePropagation();\n\t }\n\t }\n\t }\n\t\n\t function handleClick(e, args) {\n\t // clicking on a row select checkbox\n\t if (_grid.getColumns()[args.cell].id === _options.columnId && (0, _jquery2.default)(e.target).is(':checkbox')) {\n\t // if editing, try to commit\n\t if (_grid.getEditorLock().isActive() && !_grid.getEditorLock().commitCurrentEdit()) {\n\t e.preventDefault();\n\t e.stopImmediatePropagation();\n\t return;\n\t }\n\t\n\t toggleRowSelection(args.row);\n\t e.stopPropagation();\n\t e.stopImmediatePropagation();\n\t }\n\t }\n\t\n\t function toggleRowSelection(row) {\n\t if (_selectedRowsLookup[row]) {\n\t _grid.setSelectedRows(_jquery2.default.grep(_grid.getSelectedRows(), function (n) {\n\t return n != row;\n\t }));\n\t } else {\n\t _grid.setSelectedRows(_grid.getSelectedRows().concat(row));\n\t }\n\t }\n\t\n\t function handleHeaderClick(e, args) {\n\t if (args.column.id == _options.columnId && (0, _jquery2.default)(e.target).is(':checkbox')) {\n\t // if editing, try to commit\n\t if (_grid.getEditorLock().isActive() && !_grid.getEditorLock().commitCurrentEdit()) {\n\t e.preventDefault();\n\t e.stopImmediatePropagation();\n\t return;\n\t }\n\t\n\t if ((0, _jquery2.default)(e.target).is(':checked')) {\n\t var rows = [];\n\t for (var i = 0; i < _grid.getDataLength(); i++) {\n\t rows.push(i);\n\t }\n\t _grid.setSelectedRows(rows);\n\t } else {\n\t _grid.setSelectedRows([]);\n\t }\n\t e.stopPropagation();\n\t e.stopImmediatePropagation();\n\t }\n\t }\n\t\n\t function getColumnDefinition() {\n\t return {\n\t id: _options.columnId,\n\t name: \"\",\n\t toolTip: _options.toolTip,\n\t field: 'sel',\n\t width: _options.width,\n\t resizable: false,\n\t sortable: false,\n\t cssClass: _options.cssClass,\n\t formatter: checkboxSelectionFormatter\n\t };\n\t }\n\t\n\t function checkboxSelectionFormatter(row, cell, value, columnDef, dataContext) {\n\t if (dataContext) {\n\t return _selectedRowsLookup[row] ? \"\" : \"\";\n\t }\n\t return null;\n\t }\n\t\n\t Object.assign(this, {\n\t init: init,\n\t destroy: destroy,\n\t\n\t getColumnDefinition: getColumnDefinition\n\t });\n\t}\n\n/***/ }),\n/* 17 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _slick = __webpack_require__(18);\n\t\n\tvar _slick2 = _interopRequireDefault(_slick);\n\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n\texports.default = _slick2.default;\n\n/***/ }),\n/* 18 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _jquery = __webpack_require__(2);\n\t\n\tvar _jquery2 = _interopRequireDefault(_jquery);\n\t\n\tvar _slick = __webpack_require__(1);\n\t\n\tvar _slick2 = _interopRequireDefault(_slick);\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\t\n\texports.default = HeaderButtons;\n\t/** *\n\t * A plugin to add custom buttons to column headers.\n\t *\n\t * USAGE:\n\t *\n\t * Add the plugin .js & .css files and register it with the grid.\n\t *\n\t * To specify a custom button in a column header, extend the column definition like so:\n\t *\n\t * var columns = [\n\t * {\n\t * id: 'myColumn',\n\t * name: 'My column',\n\t *\n\t * // This is the relevant part\n\t * header: {\n\t * buttons: [\n\t * {\n\t * // button options\n\t * },\n\t * {\n\t * // button options\n\t * }\n\t * ]\n\t * }\n\t * }\n\t * ];\n\t *\n\t * Available button options:\n\t * cssClass: CSS class to add to the button.\n\t * image: Relative button image path.\n\t * tooltip: Button tooltip.\n\t * showOnHover: Only show the button on hover.\n\t * handler: Button click handler.\n\t * command: A command identifier to be passed to the onCommand event handlers.\n\t *\n\t * The plugin exposes the following events:\n\t * onCommand: Fired on button click for buttons with 'command' specified.\n\t * Event args:\n\t * grid: Reference to the grid.\n\t * column: Column definition.\n\t * command: Button command identified.\n\t * button: Button options. Note that you can change the button options in your\n\t * event handler, and the column header will be automatically updated to\n\t * reflect them. This is useful if you want to implement something like a\n\t * toggle button.\n\t *\n\t *\n\t * @param options {Object} Options:\n\t * buttonCssClass: a CSS class to use for buttons (default 'slick-header-button')\n\t * @class Slick.Plugins.HeaderButtons\n\t * @constructor\n\t */\n\t\n\tfunction HeaderButtons(options) {\n\t var _grid;\n\t var _self = this;\n\t var _handler = new _slick2.default.EventHandler();\n\t var _defaults = {\n\t buttonCssClass: 'slick-header-button'\n\t };\n\t\n\t function init(grid) {\n\t options = Object.assign({}, _defaults, options);\n\t _grid = grid;\n\t _handler.subscribe(_grid.onHeaderCellRendered, handleHeaderCellRendered).subscribe(_grid.onBeforeHeaderCellDestroy, handleBeforeHeaderCellDestroy);\n\t\n\t // Force the grid to re-render the header now that the events are hooked up.\n\t _grid.setColumns(_grid.getColumns());\n\t }\n\t\n\t function destroy() {\n\t _handler.unsubscribeAll();\n\t }\n\t\n\t function handleHeaderCellRendered(e, args) {\n\t var column = args.column;\n\t\n\t if (column.header && column.header.buttons) {\n\t // Append buttons in reverse order since they are floated to the right.\n\t var i = column.header.buttons.length;\n\t while (i--) {\n\t var button = column.header.buttons[i];\n\t var btn = (0, _jquery2.default)('').addClass(options.buttonCssClass).data('column', column).data('button', button);\n\t\n\t if (button.showOnHover) {\n\t btn.addClass('slick-header-button-hidden');\n\t }\n\t\n\t if (button.image) {\n\t btn.css('backgroundImage', 'url(' + button.image + ')');\n\t }\n\t\n\t if (button.cssClass) {\n\t btn.addClass(button.cssClass);\n\t }\n\t\n\t if (button.tooltip) {\n\t btn.attr('title', button.tooltip);\n\t }\n\t\n\t if (button.command) {\n\t btn.data('command', button.command);\n\t }\n\t\n\t if (button.handler) {\n\t btn.bind('click', button.handler);\n\t }\n\t\n\t btn.bind('click', handleButtonClick).appendTo(args.node);\n\t args.node.classList.add('has-buttons');\n\t }\n\t }\n\t }\n\t\n\t function handleBeforeHeaderCellDestroy(e, args) {\n\t var column = args.column;\n\t\n\t if (column.header && column.header.buttons) {\n\t // Removing buttons via jQuery will also clean up any event handlers and data.\n\t // NOTE: If you attach event handlers directly or using a different framework,\n\t // you must also clean them up here to avoid memory leaks.\n\t (0, _jquery2.default)(args.node).find('.' + options.buttonCssClass).remove();\n\t }\n\t }\n\t\n\t function handleButtonClick(e) {\n\t var command = (0, _jquery2.default)(this).data('command');\n\t var columnDef = (0, _jquery2.default)(this).data('column');\n\t var button = (0, _jquery2.default)(this).data('button');\n\t\n\t if (command != null) {\n\t _self.onCommand.notify({\n\t 'grid': _grid,\n\t 'column': columnDef,\n\t 'command': command,\n\t 'button': button\n\t }, e, _self);\n\t\n\t // Update the header in case the user updated the button definition in the handler.\n\t _grid.updateColumnHeader(columnDef.id);\n\t }\n\t\n\t // Stop propagation so that it doesn't register as a header click event.\n\t e.preventDefault();\n\t e.stopPropagation();\n\t }\n\t\n\t Object.assign(this, {\n\t init: init,\n\t destroy: destroy,\n\t\n\t 'onCommand': new _slick2.default.Event()\n\t });\n\t}\n\n/***/ }),\n/* 19 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _slick = __webpack_require__(20);\n\t\n\tvar _slick2 = _interopRequireDefault(_slick);\n\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n\texports.default = _slick2.default;\n\n/***/ }),\n/* 20 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _jquery = __webpack_require__(2);\n\t\n\tvar _jquery2 = _interopRequireDefault(_jquery);\n\t\n\tvar _slick = __webpack_require__(1);\n\t\n\tvar _slick2 = _interopRequireDefault(_slick);\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\t\n\t// import './slick.headermenu.css';\n\t\n\texports.default = HeaderMenu;\n\t\n\t/** *\n\t * A plugin to add drop-down menus to column headers.\n\t *\n\t * USAGE:\n\t *\n\t * Add the plugin .js & .css files and register it with the grid.\n\t *\n\t * To specify a menu in a column header, extend the column definition like so:\n\t *\n\t * const columns = [\n\t * {\n\t * id: 'myColumn',\n\t * name: 'My column',\n\t *\n\t * // This is the relevant part\n\t * header: {\n\t * menu: {\n\t * items: [\n\t * {\n\t * // menu item options\n\t * },\n\t * {\n\t * // menu item options\n\t * }\n\t * ]\n\t * }\n\t * }\n\t * }\n\t * ];\n\t *\n\t *\n\t * Available menu options:\n\t * tooltip: Menu button tooltip.\n\t *\n\t *\n\t * Available menu item options:\n\t * title: Menu item text.\n\t * disabled: Whether the item is disabled.\n\t * tooltip: Item tooltip.\n\t * command: A command identifier to be passed to the onCommand event handlers.\n\t * iconCssClass: A CSS class to be added to the menu item icon.\n\t * iconImage: A url to the icon image.\n\t *\n\t *\n\t * The plugin exposes the following events:\n\t * onBeforeMenuShow: Fired before the menu is shown. You can customize the menu or dismiss it by returning false.\n\t * Event args:\n\t * grid: Reference to the grid.\n\t * column: Column definition.\n\t * menu: Menu options. Note that you can change the menu items here.\n\t *\n\t * onCommand: Fired on menu item click for buttons with 'command' specified.\n\t * Event args:\n\t * grid: Reference to the grid.\n\t * column: Column definition.\n\t * command: Button command identified.\n\t * button: Button options. Note that you can change the button options in your\n\t * event handler, and the column header will be automatically updated to\n\t * reflect them. This is useful if you want to implement something like a\n\t * toggle button.\n\t *\n\t *\n\t * @param options {Object} Options:\n\t * buttonCssClass: an extra CSS class to add to the menu button\n\t * buttonImage: a url to the menu button image (default '../images/down.gif')\n\t * @class Slick.Plugins.HeaderButtons\n\t * @constructor\n\t */\n\t\n\tfunction HeaderMenu(options) {\n\t var _grid = void 0;\n\t var _self = this;\n\t var _handler = new _slick2.default.EventHandler();\n\t var _defaults = {\n\t buttonCssClass: null,\n\t buttonImage: null\n\t };\n\t\n\t var $menu = void 0;\n\t var $activeHeaderColumn = void 0;\n\t\n\t function init(grid) {\n\t options = Object.assign({}, _defaults, options);\n\t _grid = grid;\n\t _handler.subscribe(_grid.onHeaderCellRendered, handleHeaderCellRendered).subscribe(_grid.onBeforeHeaderCellDestroy, handleBeforeHeaderCellDestroy);\n\t\n\t // Force the grid to re-render the header now that the events are hooked up.\n\t _grid.setColumns(_grid.getColumns());\n\t\n\t // Hide the menu on outside click.\n\t (0, _jquery2.default)(document.body).bind('mousedown', handleBodyMouseDown);\n\t }\n\t\n\t function destroy() {\n\t _handler.unsubscribeAll();\n\t (0, _jquery2.default)(document.body).unbind('mousedown', handleBodyMouseDown);\n\t }\n\t\n\t function handleBodyMouseDown(e) {\n\t if ($menu && $menu[0] != e.target && !_jquery2.default.contains($menu[0], e.target)) {\n\t hideMenu();\n\t }\n\t }\n\t\n\t function hideMenu() {\n\t if ($menu) {\n\t $menu.remove();\n\t $menu = null;\n\t $activeHeaderColumn.removeClass('slick-header-column-active');\n\t }\n\t }\n\t\n\t function handleHeaderCellRendered(e, args) {\n\t var column = args.column;\n\t var menu = column.header && column.header.menu;\n\t\n\t if (menu) {\n\t var $el = (0, _jquery2.default)('').addClass('slick-header-menubutton').data('column', column).data('menu', menu);\n\t\n\t if (options.buttonCssClass) {\n\t $el.addClass(options.buttonCssClass);\n\t }\n\t\n\t if (options.buttonImage) {\n\t $el.css('background-image', 'url(' + options.buttonImage + ')');\n\t }\n\t\n\t if (menu.tooltip) {\n\t $el.attr('title', menu.tooltip);\n\t }\n\t\n\t $el.bind('click', showMenu).appendTo(args.node);\n\t }\n\t }\n\t\n\t function handleBeforeHeaderCellDestroy(e, args) {\n\t var column = args.column;\n\t\n\t if (column.header && column.header.menu) {\n\t (0, _jquery2.default)(args.node).find('.slick-header-menubutton').remove();\n\t }\n\t }\n\t\n\t function showMenu(e) {\n\t var $menuButton = (0, _jquery2.default)(this);\n\t var menu = $menuButton.data('menu');\n\t var columnDef = $menuButton.data('column');\n\t\n\t // Let the user modify the menu or cancel altogether,\n\t // or provide alternative menu implementation.\n\t if (_self.onBeforeMenuShow.notify({\n\t 'grid': _grid,\n\t 'column': columnDef,\n\t 'menu': menu\n\t }, e, _self) == false) {\n\t return;\n\t }\n\t\n\t if (!$menu) {\n\t $menu = (0, _jquery2.default)(\"\").appendTo(_grid.getContainerNode());\n\t }\n\t $menu.empty();\n\t\n\t // Construct the menu items.\n\t for (var i = 0; i < menu.items.length; i++) {\n\t var item = menu.items[i];\n\t\n\t var $li = (0, _jquery2.default)(\"\").data('command', item.command || '').data('column', columnDef).data('item', item).bind('click', handleMenuItemClick).appendTo($menu);\n\t\n\t if (item.disabled) {\n\t $li.addClass('slick-header-menuitem-disabled');\n\t }\n\t\n\t if (item.tooltip) {\n\t $li.attr('title', item.tooltip);\n\t }\n\t\n\t var $icon = (0, _jquery2.default)(\"\").appendTo($li);\n\t\n\t if (item.iconCssClass) {\n\t $icon.addClass(item.iconCssClass);\n\t }\n\t\n\t if (item.iconImage) {\n\t $icon.css('background-image', 'url(' + item.iconImage + ')');\n\t }\n\t\n\t (0, _jquery2.default)(\"\").text(item.title).appendTo($li);\n\t }\n\t\n\t // Position the menu.\n\t $menu.offset({ top: (0, _jquery2.default)(this).offset().top + (0, _jquery2.default)(this).height(), left: (0, _jquery2.default)(this).offset().left });\n\t\n\t // Mark the header as active to keep the highlighting.\n\t $activeHeaderColumn = $menuButton.closest('.slick-header-column');\n\t $activeHeaderColumn.addClass('slick-header-column-active');\n\t\n\t // Stop propagation so that it doesn't register as a header click event.\n\t e.preventDefault();\n\t e.stopPropagation();\n\t }\n\t\n\t function handleMenuItemClick(e) {\n\t var command = (0, _jquery2.default)(this).data('command');\n\t var columnDef = (0, _jquery2.default)(this).data('column');\n\t var item = (0, _jquery2.default)(this).data('item');\n\t\n\t if (item.disabled) {\n\t return;\n\t }\n\t\n\t hideMenu();\n\t\n\t if (command != null && command != '') {\n\t _self.onCommand.notify({\n\t 'grid': _grid,\n\t 'column': columnDef,\n\t 'command': command,\n\t 'item': item\n\t }, e, _self);\n\t }\n\t\n\t // Stop propagation so that it doesn't register as a header click event.\n\t e.preventDefault();\n\t e.stopPropagation();\n\t }\n\t\n\t Object.assign(this, {\n\t init: init,\n\t destroy: destroy,\n\t\n\t 'onBeforeMenuShow': new _slick2.default.Event(),\n\t 'onCommand': new _slick2.default.Event()\n\t });\n\t}\n\n/***/ }),\n/* 21 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _slick = __webpack_require__(22);\n\t\n\tvar _slick2 = _interopRequireDefault(_slick);\n\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n\texports.default = _slick2.default;\n\n/***/ }),\n/* 22 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _slick = __webpack_require__(1);\n\t\n\tvar _slick2 = _interopRequireDefault(_slick);\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\t\n\texports.default = RowMoveManager;\n\t\n\t\n\tfunction RowMoveManager(options) {\n\t var _grid = void 0;\n\t var _canvas = void 0;\n\t var _dragging = void 0;\n\t var _self = this;\n\t var _handler = new _slick2.default.EventHandler();\n\t var _defaults = {\n\t cancelEditOnDrag: false\n\t };\n\t\n\t function init(grid) {\n\t options = Object.assign({}, _defaults, options);\n\t _grid = grid;\n\t _canvas = _grid.getCanvasNode();\n\t _handler.subscribe(_grid.onDragInit, handleDragInit).subscribe(_grid.onDragStart, handleDragStart).subscribe(_grid.onDrag, handleDrag).subscribe(_grid.onDragEnd, handleDragEnd);\n\t }\n\t\n\t function destroy() {\n\t _handler.unsubscribeAll();\n\t }\n\t\n\t function handleDragInit(e, dd) {\n\t // prevent the grid from cancelling drag'n'drop by default\n\t e.stopImmediatePropagation();\n\t }\n\t\n\t function handleDragStart(e, dd) {\n\t var cell = _grid.getCellFromEvent(e);\n\t\n\t if (options.cancelEditOnDrag && _grid.getEditorLock().isActive()) {\n\t _grid.getEditorLock().cancelCurrentEdit();\n\t }\n\t\n\t if (_grid.getEditorLock().isActive() || !/move|selectAndMove/.test(_grid.getColumns()[cell.cell].behavior)) {\n\t return false;\n\t }\n\t\n\t _dragging = true;\n\t e.stopImmediatePropagation();\n\t\n\t var selectedRows = _grid.getSelectedRows();\n\t\n\t if (selectedRows.length == 0 || $.inArray(cell.row, selectedRows) == -1) {\n\t selectedRows = [cell.row];\n\t _grid.setSelectedRows(selectedRows);\n\t }\n\t\n\t var rowHeight = _grid.getOptions().rowHeight;\n\t\n\t dd.selectedRows = selectedRows;\n\t\n\t dd.selectionProxy = $(\"\").css('position', 'absolute').css('zIndex', '99999').css('width', $(_canvas).innerWidth()).css('height', rowHeight * selectedRows.length).appendTo(_canvas);\n\t\n\t dd.guide = $(\"\").css('position', 'absolute').css('zIndex', '99998').css('width', $(_canvas).innerWidth()).css('top', -1000).appendTo(_canvas);\n\t\n\t dd.insertBefore = -1;\n\t }\n\t\n\t function handleDrag(e, dd) {\n\t if (!_dragging) {\n\t return;\n\t }\n\t\n\t e.stopImmediatePropagation();\n\t\n\t var top = e.pageY - $(_canvas).offset().top;\n\t dd.selectionProxy.css('top', top - 5);\n\t\n\t var insertBefore = Math.max(0, Math.min(Math.round(top / _grid.getOptions().rowHeight), _grid.getDataLength()));\n\t if (insertBefore !== dd.insertBefore) {\n\t var eventData = {\n\t 'rows': dd.selectedRows,\n\t 'insertBefore': insertBefore\n\t };\n\t\n\t if (_self.onBeforeMoveRows.notify(eventData) === false) {\n\t dd.guide.css('top', -1000);\n\t dd.canMove = false;\n\t } else {\n\t dd.guide.css('top', insertBefore * _grid.getOptions().rowHeight);\n\t dd.canMove = true;\n\t }\n\t\n\t dd.insertBefore = insertBefore;\n\t }\n\t }\n\t\n\t function handleDragEnd(e, dd) {\n\t if (!_dragging) {\n\t return;\n\t }\n\t _dragging = false;\n\t e.stopImmediatePropagation();\n\t\n\t dd.guide.remove();\n\t dd.selectionProxy.remove();\n\t\n\t if (dd.canMove) {\n\t var eventData = {\n\t 'rows': dd.selectedRows,\n\t 'insertBefore': dd.insertBefore\n\t };\n\t // TODO: _grid.remapCellCssClasses ?\n\t _self.onMoveRows.notify(eventData);\n\t }\n\t }\n\t\n\t Object.assign(this, {\n\t 'onBeforeMoveRows': new _slick2.default.Event(),\n\t 'onMoveRows': new _slick2.default.Event(),\n\t init: init,\n\t destroy: destroy\n\t });\n\t}\n\n/***/ }),\n/* 23 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _slick = __webpack_require__(24);\n\t\n\tvar _slick2 = _interopRequireDefault(_slick);\n\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n\texports.default = _slick2.default;\n\n/***/ }),\n/* 24 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _jquery = __webpack_require__(2);\n\t\n\tvar _jquery2 = _interopRequireDefault(_jquery);\n\t\n\tvar _slick = __webpack_require__(1);\n\t\n\tvar _slick2 = _interopRequireDefault(_slick);\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\t\n\texports.default = RowSelectionModel;\n\t\n\t\n\tfunction RowSelectionModel(options) {\n\t var _grid = void 0;\n\t var _ranges = [];\n\t var _self = this;\n\t var _handler = new _slick2.default.EventHandler();\n\t var _inHandler = void 0;\n\t var _options = void 0;\n\t var _defaults = {\n\t selectActiveRow: true\n\t };\n\t\n\t function init(grid) {\n\t _options = Object.assign({}, _defaults, options);\n\t _grid = grid;\n\t _handler.subscribe(_grid.onActiveCellChanged, wrapHandler(handleActiveCellChange));\n\t _handler.subscribe(_grid.onKeyDown, wrapHandler(handleKeyDown));\n\t _handler.subscribe(_grid.onClick, wrapHandler(handleClick));\n\t }\n\t\n\t function destroy() {\n\t _handler.unsubscribeAll();\n\t }\n\t\n\t function wrapHandler(handler) {\n\t return function () {\n\t if (!_inHandler) {\n\t _inHandler = true;\n\t handler.apply(this, arguments);\n\t _inHandler = false;\n\t }\n\t };\n\t }\n\t\n\t function rangesToRows(ranges) {\n\t var rows = [];\n\t for (var i = 0; i < ranges.length; i++) {\n\t for (var j = ranges[i].fromRow; j <= ranges[i].toRow; j++) {\n\t rows.push(j);\n\t }\n\t }\n\t return rows;\n\t }\n\t\n\t function rowsToRanges(rows) {\n\t var ranges = [];\n\t var lastCell = _grid.getColumns().length - 1;\n\t for (var i = 0; i < rows.length; i++) {\n\t ranges.push(new _slick2.default.Range(rows[i], 0, rows[i], lastCell));\n\t }\n\t return ranges;\n\t }\n\t\n\t function getRowsRange(from, to) {\n\t var i = void 0;\n\t var rows = [];\n\t for (i = from; i <= to; i++) {\n\t rows.push(i);\n\t }\n\t for (i = to; i < from; i++) {\n\t rows.push(i);\n\t }\n\t return rows;\n\t }\n\t\n\t function getSelectedRows() {\n\t return rangesToRows(_ranges);\n\t }\n\t\n\t function setSelectedRows(rows) {\n\t setSelectedRanges(rowsToRanges(rows));\n\t }\n\t\n\t function setSelectedRanges(ranges) {\n\t // simle check for: empty selection didn't change, prevent firing onSelectedRangesChanged\n\t if ((!_ranges || _ranges.length === 0) && (!ranges || ranges.length === 0)) {\n\t return;\n\t }\n\t _ranges = ranges;\n\t _self.onSelectedRangesChanged.notify(_ranges);\n\t }\n\t\n\t function getSelectedRanges() {\n\t return _ranges;\n\t }\n\t\n\t function handleActiveCellChange(e, data) {\n\t if (_options.selectActiveRow && data.row != null) {\n\t setSelectedRanges([new _slick2.default.Range(data.row, 0, data.row, _grid.getColumns().length - 1)]);\n\t }\n\t }\n\t\n\t function handleKeyDown(e) {\n\t var activeRow = _grid.getActiveCell();\n\t if (activeRow && e.shiftKey && !e.ctrlKey && !e.altKey && !e.metaKey && (e.which == 38 || e.which == 40)) {\n\t var selectedRows = getSelectedRows();\n\t selectedRows.sort(function (x, y) {\n\t return x - y;\n\t });\n\t\n\t if (!selectedRows.length) {\n\t selectedRows = [activeRow.row];\n\t }\n\t\n\t var top = selectedRows[0];\n\t var bottom = selectedRows[selectedRows.length - 1];\n\t var active = void 0;\n\t\n\t if (e.which == 40) {\n\t active = activeRow.row < bottom || top == bottom ? ++bottom : ++top;\n\t } else {\n\t active = activeRow.row < bottom ? --bottom : --top;\n\t }\n\t\n\t if (active >= 0 && active < _grid.getDataLength()) {\n\t _grid.scrollRowIntoView(active);\n\t _ranges = rowsToRanges(getRowsRange(top, bottom));\n\t setSelectedRanges(_ranges);\n\t }\n\t\n\t e.preventDefault();\n\t e.stopPropagation();\n\t }\n\t }\n\t\n\t function handleClick(e) {\n\t var cell = _grid.getCellFromEvent(e);\n\t if (!cell || !_grid.canCellBeActive(cell.row, cell.cell)) {\n\t return false;\n\t }\n\t\n\t if (!_grid.getOptions().multiSelect || !e.ctrlKey && !e.shiftKey && !e.metaKey) {\n\t return false;\n\t }\n\t\n\t var selection = rangesToRows(_ranges);\n\t var idx = _jquery2.default.inArray(cell.row, selection);\n\t\n\t if (idx === -1 && (e.ctrlKey || e.metaKey)) {\n\t selection.push(cell.row);\n\t _grid.setActiveCell(cell.row, cell.cell);\n\t } else if (idx !== -1 && (e.ctrlKey || e.metaKey)) {\n\t selection = _jquery2.default.grep(selection, function (o, i) {\n\t return o !== cell.row;\n\t });\n\t _grid.setActiveCell(cell.row, cell.cell);\n\t } else if (selection.length && e.shiftKey) {\n\t var last = selection.pop();\n\t var from = Math.min(cell.row, last);\n\t var to = Math.max(cell.row, last);\n\t selection = [];\n\t for (var i = from; i <= to; i++) {\n\t if (i !== last) {\n\t selection.push(i);\n\t }\n\t }\n\t selection.push(last);\n\t _grid.setActiveCell(cell.row, cell.cell);\n\t }\n\t\n\t _ranges = rowsToRanges(selection);\n\t setSelectedRanges(_ranges);\n\t e.stopImmediatePropagation();\n\t\n\t return true;\n\t }\n\t\n\t Object.assign(this, {\n\t getSelectedRows: getSelectedRows,\n\t setSelectedRows: setSelectedRows,\n\t\n\t getSelectedRanges: getSelectedRanges,\n\t setSelectedRanges: setSelectedRanges,\n\t\n\t init: init,\n\t destroy: destroy,\n\t\n\t 'onSelectedRangesChanged': new _slick2.default.Event()\n\t });\n\t}\n\n/***/ }),\n/* 25 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\texports.Plugins = exports.FrozenGrid = exports.Grid = exports.Data = exports.Formatters = exports.Editors = exports.Slick = undefined;\n\t\n\tvar _slick = __webpack_require__(1);\n\t\n\tvar _slick2 = _interopRequireDefault(_slick);\n\t\n\tvar _slick3 = __webpack_require__(28);\n\t\n\tvar _slick4 = _interopRequireDefault(_slick3);\n\t\n\tvar _slick5 = __webpack_require__(27);\n\t\n\tvar _slick6 = _interopRequireDefault(_slick5);\n\t\n\tvar _slick7 = __webpack_require__(30);\n\t\n\tvar _slick8 = _interopRequireDefault(_slick7);\n\t\n\tvar _slickFrozen = __webpack_require__(26);\n\t\n\tvar _slickFrozen2 = _interopRequireDefault(_slickFrozen);\n\t\n\tvar _slick9 = __webpack_require__(29);\n\t\n\tvar _slick10 = _interopRequireDefault(_slick9);\n\t\n\tvar _plugins = __webpack_require__(6);\n\t\n\tvar Plugins = _interopRequireWildcard(_plugins);\n\t\n\tfunction _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\t\n\texports.Slick = _slick2.default;\n\texports.Editors = _slick4.default;\n\texports.Formatters = _slick10.default;\n\texports.Data = _slick6.default;\n\texports.Grid = _slick8.default;\n\texports.FrozenGrid = _slickFrozen2.default;\n\texports.Plugins = Plugins;\n\n/***/ }),\n/* 26 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _jquery = __webpack_require__(2);\n\t\n\tvar _jquery2 = _interopRequireDefault(_jquery);\n\t\n\tvar _interact = __webpack_require__(5);\n\t\n\tvar _interact2 = _interopRequireDefault(_interact);\n\t\n\tvar _slick = __webpack_require__(1);\n\t\n\tvar _slick2 = _interopRequireDefault(_slick);\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\t\n\t// Slick.Grid globals pretense\n\t_slick2.default.FrozenGrid = SlickGrid; /**\n\t * @license\n\t * (c) 2009-2013 Michael Leibman\n\t * michael{dot}leibman{at}gmail{dot}com\n\t * http://github.com/mleibman/slickgrid\n\t *\n\t * Distributed under MIT license.\n\t * All rights reserved.\n\t *\n\t * SlickGrid v2.2\n\t *\n\t * NOTES:\n\t * Cell/row DOM manipulations are done directly bypassing jQuery's DOM manipulation methods.\n\t * This increases the speed dramatically, but can only be done safely because there are no event handlers\n\t * or data associated with any cell/row DOM nodes. Cell editors must make sure they implement .destroy()\n\t * and do proper cleanup.\n\t */\n\t\n\texports.default = SlickGrid;\n\t\n\t// shared across all grids on the page\n\t\n\tvar scrollbarDimensions;\n\tvar maxSupportedCssHeight; // browser's breaking point\n\t\n\t//////////////////////////////////////////////////////////////////////////////////////////////\n\t// SlickGrid class implementation (available as Slick.Grid)\n\t\n\t/**\n\t * Creates a new instance of the grid.\n\t * @class SlickGrid\n\t * @constructor\n\t * @param {Node} container Container node to create the grid in.\n\t * @param {Array,Object} data An array of objects for databinding.\n\t * @param {Array} columns An array of column definitions.\n\t * @param {Object} options Grid options.\n\t **/\n\tfunction SlickGrid(container, data, columns, options) {\n\t // settings\n\t var defaults = {\n\t explicitInitialization: false,\n\t rowHeight: 25,\n\t defaultColumnWidth: 80,\n\t enableAddRow: false,\n\t leaveSpaceForNewRows: false,\n\t editable: false,\n\t autoEdit: true,\n\t enableCellNavigation: true,\n\t enableColumnReorder: true,\n\t asyncEditorLoading: false,\n\t asyncEditorLoadDelay: 100,\n\t forceFitColumns: false,\n\t enableAsyncPostRender: false,\n\t asyncPostRenderDelay: 50,\n\t autoHeight: false,\n\t editorLock: _slick2.default.GlobalEditorLock,\n\t showHeaderRow: false,\n\t headerRowHeight: 25,\n\t showFooterRow: false,\n\t footerRowHeight: 25,\n\t showTopPanel: false,\n\t topPanelHeight: 25,\n\t formatterFactory: null,\n\t editorFactory: null,\n\t cellFlashingCssClass: \"flashing\",\n\t selectedCellCssClass: \"selected\",\n\t multiSelect: true,\n\t enableTextSelectionOnCells: false,\n\t dataItemColumnValueExtractor: null,\n\t frozenBottom: false,\n\t frozenColumn: -1,\n\t frozenRow: -1,\n\t fullWidthRows: false,\n\t multiColumnSort: false,\n\t defaultFormatter: defaultFormatter,\n\t forceSyncScrolling: false,\n\t addNewRowCssClass: \"new-row\"\n\t };\n\t\n\t var columnDefaults = {\n\t name: \"\",\n\t resizable: true,\n\t sortable: false,\n\t minWidth: 30,\n\t rerenderOnResize: false,\n\t headerCssClass: null,\n\t defaultSortAsc: true,\n\t focusable: true,\n\t selectable: true\n\t };\n\t\n\t // scroller\n\t var th; // virtual height\n\t var h; // real scrollable height\n\t var ph; // page height\n\t var n; // number of pages\n\t var cj; // \"jumpiness\" coefficient\n\t\n\t var page = 0; // current page\n\t var offset = 0; // current page offset\n\t var vScrollDir = 1;\n\t\n\t // private\n\t var initialized = false;\n\t var $container;\n\t var uid = \"slickgrid_\" + Math.round(1000000 * Math.random());\n\t var self = this;\n\t var $focusSink, $focusSink2;\n\t var $groupHeaders = (0, _jquery2.default)();\n\t var $headerScroller;\n\t var $headers;\n\t var $headerRow, $headerRowScroller, $headerRowSpacerL, $headerRowSpacerR;\n\t var $footerRow, $footerRowScroller, $footerRowSpacerL, $footerRowSpacerR;\n\t var $topPanelScroller;\n\t var $topPanel;\n\t var $viewport;\n\t var $canvas;\n\t var $style;\n\t var $boundAncestors;\n\t var treeColumns;\n\t var stylesheet, columnCssRulesL, columnCssRulesR;\n\t var viewportH, viewportW;\n\t var canvasWidth, canvasWidthL, canvasWidthR;\n\t var headersWidth, headersWidthL, headersWidthR;\n\t var viewportHasHScroll, viewportHasVScroll;\n\t var headerColumnWidthDiff = 0,\n\t headerColumnHeightDiff = 0,\n\t // border+padding\n\t cellWidthDiff = 0,\n\t cellHeightDiff = 0;\n\t var absoluteColumnMinWidth;\n\t var hasFrozenRows = false;\n\t var frozenRowsHeight = 0;\n\t var actualFrozenRow = -1;\n\t var paneTopH = 0;\n\t var paneBottomH = 0;\n\t var viewportTopH = 0;\n\t var viewportBottomH = 0;\n\t var topPanelH = 0;\n\t var headerRowH = 0;\n\t var footerRowH = 0;\n\t\n\t var tabbingDirection = 1;\n\t var $activeCanvasNode;\n\t var $activeViewportNode;\n\t var activePosX;\n\t var activeRow, activeCell;\n\t var activeCellNode = null;\n\t var currentEditor = null;\n\t var serializedEditorValue;\n\t var editController;\n\t\n\t var rowsCache = {};\n\t var renderedRows = 0;\n\t var numVisibleRows = 0;\n\t var prevScrollTop = 0;\n\t var scrollTop = 0;\n\t var lastRenderedScrollTop = 0;\n\t var lastRenderedScrollLeft = 0;\n\t var prevScrollLeft = 0;\n\t var scrollLeft = 0;\n\t\n\t var selectionModel;\n\t var selectedRows = [];\n\t\n\t var plugins = [];\n\t var cellCssClasses = {};\n\t\n\t var columnsById = {};\n\t var sortColumns = [];\n\t var columnPosLeft = [];\n\t var columnPosRight = [];\n\t\n\t // async call handles\n\t var h_editorLoader = null;\n\t var h_render = null;\n\t var h_postrender = null;\n\t var postProcessedRows = {};\n\t var postProcessToRow = null;\n\t var postProcessFromRow = null;\n\t\n\t // perf counters\n\t var counter_rows_rendered = 0;\n\t var counter_rows_removed = 0;\n\t\n\t // These two variables work around a bug with inertial scrolling in Webkit/Blink on Mac.\n\t // See http://crbug.com/312427.\n\t var rowNodeFromLastMouseWheelEvent; // this node must not be deleted while inertial scrolling\n\t var zombieRowNodeFromLastMouseWheelEvent; // node that was hidden instead of getting deleted\n\t\n\t var $paneHeaderL;\n\t var $paneHeaderR;\n\t var $paneTopL;\n\t var $paneTopR;\n\t var $paneBottomL;\n\t var $paneBottomR;\n\t\n\t var $headerScrollerL;\n\t var $headerScrollerR;\n\t\n\t var $headerL;\n\t var $headerR;\n\t\n\t var $groupHeadersL;\n\t var $groupHeadersR;\n\t\n\t var $headerRowScrollerL;\n\t var $headerRowScrollerR;\n\t\n\t var $footerRowScrollerL;\n\t var $footerRowScrollerR;\n\t\n\t var $headerRowL;\n\t var $headerRowR;\n\t\n\t var $footerRowL;\n\t var $footerRowR;\n\t\n\t var $topPanelScrollerL;\n\t var $topPanelScrollerR;\n\t\n\t var $topPanelL;\n\t var $topPanelR;\n\t\n\t var $viewportTopL;\n\t var $viewportTopR;\n\t var $viewportBottomL;\n\t var $viewportBottomR;\n\t\n\t var $canvasTopL;\n\t var $canvasTopR;\n\t var $canvasBottomL;\n\t var $canvasBottomR;\n\t\n\t var $viewportScrollContainerX;\n\t var $viewportScrollContainerY;\n\t var $headerScrollContainer;\n\t var $headerRowScrollContainer;\n\t var $footerRowScrollContainer;\n\t\n\t //////////////////////////////////////////////////////////////////////////////////////////////\n\t // Initialization\n\t\n\t function init() {\n\t $container = (0, _jquery2.default)(container);\n\t if ($container.length < 1) {\n\t throw new Error(\"SlickGrid requires a valid container, \" + container + \" does not exist in the DOM.\");\n\t }\n\t\n\t // calculate these only once and share between grid instances\n\t maxSupportedCssHeight = maxSupportedCssHeight || getMaxSupportedCssHeight();\n\t scrollbarDimensions = scrollbarDimensions || measureScrollbar();\n\t\n\t options = _jquery2.default.extend({}, defaults, options);\n\t validateAndEnforceOptions();\n\t columnDefaults.width = options.defaultColumnWidth;\n\t\n\t treeColumns = new _slick2.default.TreeColumns(columns);\n\t columns = treeColumns.extractColumns();\n\t\n\t columnsById = {};\n\t for (var i = 0; i < columns.length; i++) {\n\t var m = columns[i] = _jquery2.default.extend({}, columnDefaults, columns[i]);\n\t columnsById[m.id] = i;\n\t if (m.minWidth && m.width < m.minWidth) {\n\t m.width = m.minWidth;\n\t }\n\t if (m.maxWidth && m.width > m.maxWidth) {\n\t m.width = m.maxWidth;\n\t }\n\t }\n\t\n\t editController = {\n\t \"commitCurrentEdit\": commitCurrentEdit,\n\t \"cancelCurrentEdit\": cancelCurrentEdit\n\t };\n\t\n\t $container.empty().css(\"overflow\", \"hidden\").css(\"outline\", 0).addClass(uid).addClass(\"ui-widget\");\n\t\n\t // set up a positioning container if needed\n\t if (!/relative|absolute|fixed/.test($container.css(\"position\"))) {\n\t $container.css(\"position\", \"relative\");\n\t }\n\t\n\t $focusSink = (0, _jquery2.default)(\"\").appendTo($container);\n\t\n\t // Containers used for scrolling frozen columns and rows\n\t $paneHeaderL = (0, _jquery2.default)(\"\").appendTo($container);\n\t $paneHeaderR = (0, _jquery2.default)(\"\").appendTo($container);\n\t $paneTopL = (0, _jquery2.default)(\"\").appendTo($container);\n\t $paneTopR = (0, _jquery2.default)(\"\").appendTo($container);\n\t $paneBottomL = (0, _jquery2.default)(\"\").appendTo($container);\n\t $paneBottomR = (0, _jquery2.default)(\"\").appendTo($container);\n\t\n\t // Append the header scroller containers\n\t $headerScrollerL = (0, _jquery2.default)(\"\").appendTo($paneHeaderL);\n\t $headerScrollerR = (0, _jquery2.default)(\"\").appendTo($paneHeaderR);\n\t\n\t // Cache the header scroller containers\n\t $headerScroller = (0, _jquery2.default)().add($headerScrollerL).add($headerScrollerR);\n\t\n\t if (treeColumns.hasDepth()) {\n\t $groupHeadersL = [], $groupHeadersR = [];\n\t for (var index = 0; index < treeColumns.getDepth() - 1; index++) {\n\t $groupHeadersL[index] = (0, _jquery2.default)(\"\").appendTo($headerScrollerL);\n\t $groupHeadersR[index] = (0, _jquery2.default)(\"\").appendTo($headerScrollerR);\n\t }\n\t\n\t $groupHeaders = (0, _jquery2.default)().add($groupHeadersL).add($groupHeadersR);\n\t }\n\t\n\t // Append the columnn containers to the headers\n\t $headerL = (0, _jquery2.default)(\"\").appendTo($headerScrollerL);\n\t $headerR = (0, _jquery2.default)(\"\").appendTo($headerScrollerR);\n\t\n\t // Cache the header columns\n\t $headers = (0, _jquery2.default)().add($headerL).add($headerR);\n\t\n\t $headerRowScrollerL = (0, _jquery2.default)(\"\").appendTo($paneTopL);\n\t $headerRowScrollerR = (0, _jquery2.default)(\"\").appendTo($paneTopR);\n\t\n\t $headerRowScroller = (0, _jquery2.default)().add($headerRowScrollerL).add($headerRowScrollerR);\n\t\n\t $headerRowSpacerL = (0, _jquery2.default)(\"\").css(\"width\", getCanvasWidth() + scrollbarDimensions.width + \"px\").appendTo($headerRowScrollerL);\n\t $headerRowSpacerR = (0, _jquery2.default)(\"\").css(\"width\", getCanvasWidth() + scrollbarDimensions.width + \"px\").appendTo($headerRowScrollerR);\n\t\n\t $headerRowL = (0, _jquery2.default)(\"\").appendTo($headerRowScrollerL);\n\t $headerRowR = (0, _jquery2.default)(\"\").appendTo($headerRowScrollerR);\n\t\n\t $headerRow = (0, _jquery2.default)().add($headerRowL).add($headerRowR);\n\t\n\t // Append the top panel scroller\n\t $topPanelScrollerL = (0, _jquery2.default)(\"\").appendTo($paneTopL);\n\t $topPanelScrollerR = (0, _jquery2.default)(\"\").appendTo($paneTopR);\n\t\n\t $topPanelScroller = (0, _jquery2.default)().add($topPanelScrollerL).add($topPanelScrollerR);\n\t\n\t // Append the top panel\n\t $topPanelL = (0, _jquery2.default)(\"\").appendTo($topPanelScrollerL);\n\t $topPanelR = (0, _jquery2.default)(\"\").appendTo($topPanelScrollerR);\n\t\n\t $topPanel = (0, _jquery2.default)().add($topPanelL).add($topPanelR);\n\t\n\t if (!options.showTopPanel) {\n\t $topPanelScroller.hide();\n\t }\n\t\n\t if (!options.showHeaderRow) {\n\t $headerRowScroller.hide();\n\t }\n\t\n\t // Append the viewport containers\n\t $viewportTopL = (0, _jquery2.default)(\"\").appendTo($paneTopL);\n\t $viewportTopR = (0, _jquery2.default)(\"\").appendTo($paneTopR);\n\t $viewportBottomL = (0, _jquery2.default)(\"\").appendTo($paneBottomL);\n\t $viewportBottomR = (0, _jquery2.default)(\"\").appendTo($paneBottomR);\n\t\n\t // Cache the viewports\n\t $viewport = (0, _jquery2.default)().add($viewportTopL).add($viewportTopR).add($viewportBottomL).add($viewportBottomR);\n\t\n\t // Default the active viewport to the top left\n\t $activeViewportNode = $viewportTopL;\n\t\n\t // Append the canvas containers\n\t $canvasTopL = (0, _jquery2.default)(\"\").appendTo($viewportTopL);\n\t $canvasTopR = (0, _jquery2.default)(\"\").appendTo($viewportTopR);\n\t $canvasBottomL = (0, _jquery2.default)(\"\").appendTo($viewportBottomL);\n\t $canvasBottomR = (0, _jquery2.default)(\"\").appendTo($viewportBottomR);\n\t\n\t // Cache the canvases\n\t $canvas = (0, _jquery2.default)().add($canvasTopL).add($canvasTopR).add($canvasBottomL).add($canvasBottomR);\n\t\n\t // Default the active canvas to the top left\n\t $activeCanvasNode = $canvasTopL;\n\t\n\t // footer Row\n\t $footerRowScrollerR = (0, _jquery2.default)(\"\").appendTo($paneTopR);\n\t $footerRowScrollerL = (0, _jquery2.default)(\"\").appendTo($paneTopL);\n\t\n\t $footerRowScroller = (0, _jquery2.default)().add($footerRowScrollerL).add($footerRowScrollerR);\n\t\n\t $footerRowSpacerL = (0, _jquery2.default)(\"\").css(\"width\", getCanvasWidth() + scrollbarDimensions.width + \"px\").appendTo($footerRowScrollerL);\n\t $footerRowSpacerR = (0, _jquery2.default)(\"\").css(\"width\", getCanvasWidth() + scrollbarDimensions.width + \"px\").appendTo($footerRowScrollerR);\n\t\n\t $footerRowL = (0, _jquery2.default)(\"\").appendTo($footerRowScrollerL);\n\t $footerRowR = (0, _jquery2.default)(\"\").appendTo($footerRowScrollerR);\n\t\n\t $footerRow = (0, _jquery2.default)().add($footerRowL).add($footerRowR);\n\t\n\t if (!options.showFooterRow) {\n\t $footerRowScroller.hide();\n\t }\n\t\n\t $focusSink2 = $focusSink.clone().appendTo($container);\n\t\n\t if (!options.explicitInitialization) {\n\t finishInitialization();\n\t }\n\t }\n\t\n\t function finishInitialization() {\n\t if (!initialized) {\n\t initialized = true;\n\t\n\t getViewportWidth();\n\t getViewportHeight();\n\t\n\t // header columns and cells may have different padding/border skewing width calculations (box-sizing, hello?)\n\t // calculate the diff so we can set consistent sizes\n\t measureCellPaddingAndBorder();\n\t\n\t // for usability reasons, all text selection in SlickGrid is disabled\n\t // with the exception of input and textarea elements (selection must\n\t // be enabled there so that editors work as expected); note that\n\t // selection in grid cells (grid body) is already unavailable in\n\t // all browsers except IE\n\t disableSelection($headers); // disable all text selection in header (including input and textarea)\n\t\n\t if (!options.enableTextSelectionOnCells) {\n\t // disable text selection in grid cells except in input and textarea elements\n\t // (this is IE-specific, because selectstart event will only fire in IE)\n\t $viewport.bind(\"selectstart.ui\", function (event) {\n\t return (0, _jquery2.default)(event.target).is(\"input,textarea\");\n\t });\n\t }\n\t\n\t setFrozenOptions();\n\t setPaneVisibility();\n\t setScroller();\n\t setOverflow();\n\t\n\t updateColumnCaches();\n\t createColumnHeaders();\n\t createColumnGroupHeaders();\n\t createColumnFooter();\n\t setupColumnSort();\n\t createCssRules();\n\t resizeCanvas();\n\t bindAncestorScrollEvents();\n\t\n\t $container.bind(\"resize.slickgrid\", resizeCanvas);\n\t $viewport.on(\"scroll\", handleScroll);\n\t\n\t if (_jquery2.default.fn.mousewheel && (options.frozenColumn > -1 || hasFrozenRows)) {\n\t $viewport.on(\"mousewheel\", handleMouseWheel);\n\t }\n\t\n\t $headerScroller.bind(\"contextmenu\", handleHeaderContextMenu).bind(\"click\", handleHeaderClick).delegate(\".slick-header-column\", \"mouseenter\", handleHeaderMouseEnter).delegate(\".slick-header-column\", \"mouseleave\", handleHeaderMouseLeave);\n\t $headerRowScroller.bind(\"scroll\", handleHeaderRowScroll);\n\t\n\t $footerRowScroller.bind(\"scroll\", handleFooterRowScroll);\n\t\n\t $focusSink.add($focusSink2).bind(\"keydown\", handleKeyDown);\n\t $canvas.bind(\"keydown\", handleKeyDown).bind(\"click\", handleClick).bind(\"dblclick\", handleDblClick).bind(\"contextmenu\", handleContextMenu).delegate(\".slick-cell\", \"mouseenter\", handleMouseEnter).delegate(\".slick-cell\", \"mouseleave\", handleMouseLeave);\n\t\n\t // legacy support for drag events\n\t (0, _interact2.default)($canvas[0]).allowFrom('div.slick-cell').draggable({\n\t onmove: handleDrag,\n\t onstart: handleDragStart,\n\t onend: handleDragEnd\n\t }).styleCursor(false);\n\t\n\t // Work around http://crbug.com/312427.\n\t if (navigator.userAgent.toLowerCase().match(/webkit/) && navigator.userAgent.toLowerCase().match(/macintosh/)) {\n\t $canvas.on(\"mousewheel\", handleMouseWheel);\n\t }\n\t }\n\t }\n\t\n\t function hasFrozenColumns() {\n\t return options.frozenColumn > -1;\n\t }\n\t\n\t function registerPlugin(plugin) {\n\t plugins.unshift(plugin);\n\t plugin.init(self);\n\t }\n\t\n\t function unregisterPlugin(plugin) {\n\t for (var i = plugins.length; i >= 0; i--) {\n\t if (plugins[i] === plugin) {\n\t if (plugins[i].destroy) {\n\t plugins[i].destroy();\n\t }\n\t plugins.splice(i, 1);\n\t break;\n\t }\n\t }\n\t }\n\t\n\t function setSelectionModel(model) {\n\t if (selectionModel) {\n\t selectionModel.onSelectedRangesChanged.unsubscribe(handleSelectedRangesChanged);\n\t if (selectionModel.destroy) {\n\t selectionModel.destroy();\n\t }\n\t }\n\t\n\t selectionModel = model;\n\t if (selectionModel) {\n\t selectionModel.init(self);\n\t selectionModel.onSelectedRangesChanged.subscribe(handleSelectedRangesChanged);\n\t }\n\t }\n\t\n\t function getSelectionModel() {\n\t return selectionModel;\n\t }\n\t\n\t function getCanvasNode() {\n\t return $canvas[0];\n\t }\n\t\n\t function getActiveCanvasNode(element) {\n\t setActiveCanvasNode(element);\n\t\n\t return $activeCanvasNode[0];\n\t }\n\t\n\t function getCanvases() {\n\t return $canvas;\n\t }\n\t\n\t function setActiveCanvasNode(element) {\n\t if (element) {\n\t $activeCanvasNode = (0, _jquery2.default)(element.target).closest('.grid-canvas');\n\t }\n\t }\n\t\n\t function getViewportNode() {\n\t return $viewport[0];\n\t }\n\t\n\t function getActiveViewportNode(element) {\n\t setActiveViewPortNode(element);\n\t\n\t return $activeViewportNode[0];\n\t }\n\t\n\t function setActiveViewportNode(element) {\n\t if (element) {\n\t $activeViewportNode = (0, _jquery2.default)(element.target).closest('.slick-viewport');\n\t }\n\t }\n\t\n\t function measureScrollbar() {\n\t var $c = (0, _jquery2.default)(\"\").appendTo(document.body);\n\t var dim = {\n\t width: $c.width() - $c[0].clientWidth,\n\t height: $c.height() - $c[0].clientHeight\n\t };\n\t $c.remove();\n\t return dim;\n\t }\n\t\n\t function getHeadersWidth() {\n\t headersWidth = headersWidthL = headersWidthR = 0;\n\t\n\t for (var i = 0, ii = columns.length; i < ii; i++) {\n\t var width = columns[i].width;\n\t\n\t if (options.frozenColumn > -1 && i > options.frozenColumn) {\n\t headersWidthR += width;\n\t } else {\n\t headersWidthL += width;\n\t }\n\t }\n\t\n\t if (hasFrozenColumns()) {\n\t headersWidthL = headersWidthL + 1000;\n\t\n\t headersWidthR = Math.max(headersWidthR, viewportW) + headersWidthL;\n\t headersWidthR += scrollbarDimensions.width;\n\t } else {\n\t headersWidthL += scrollbarDimensions.width;\n\t headersWidthL = Math.max(headersWidthL, viewportW) + 1000;\n\t }\n\t\n\t headersWidth = headersWidthL + headersWidthR;\n\t }\n\t\n\t function getHeadersWidthL() {\n\t headersWidthL = 0;\n\t\n\t columns.forEach(function (column, i) {\n\t if (!(options.frozenColumn > -1 && i > options.frozenColumn)) headersWidthL += column.width;\n\t });\n\t\n\t if (hasFrozenColumns()) {\n\t headersWidthL += 1000;\n\t } else {\n\t headersWidthL += scrollbarDimensions.width;\n\t headersWidthL = Math.max(headersWidthL, viewportW) + 1000;\n\t }\n\t\n\t return headersWidthL;\n\t }\n\t\n\t function getHeadersWidthR() {\n\t headersWidthR = 0;\n\t\n\t columns.forEach(function (column, i) {\n\t if (options.frozenColumn > -1 && i > options.frozenColumn) headersWidthR += column.width;\n\t });\n\t\n\t if (hasFrozenColumns()) {\n\t headersWidthR = Math.max(headersWidthR, viewportW) + getHeadersWidthL();\n\t headersWidthR += scrollbarDimensions.width;\n\t }\n\t\n\t return headersWidthR;\n\t }\n\t\n\t function getCanvasWidth() {\n\t var availableWidth = viewportHasVScroll ? viewportW - scrollbarDimensions.width : viewportW;\n\t\n\t var i = columns.length;\n\t\n\t canvasWidthL = canvasWidthR = 0;\n\t\n\t while (i--) {\n\t if (hasFrozenColumns() && i > options.frozenColumn) {\n\t canvasWidthR += columns[i].width;\n\t } else {\n\t canvasWidthL += columns[i].width;\n\t }\n\t }\n\t\n\t var totalRowWidth = canvasWidthL + canvasWidthR;\n\t\n\t return options.fullWidthRows ? Math.max(totalRowWidth, availableWidth) : totalRowWidth;\n\t }\n\t\n\t function updateCanvasWidth(forceColumnWidthsUpdate) {\n\t var oldCanvasWidth = canvasWidth;\n\t var oldCanvasWidthL = canvasWidthL;\n\t var oldCanvasWidthR = canvasWidthR;\n\t var widthChanged;\n\t canvasWidth = getCanvasWidth();\n\t\n\t widthChanged = canvasWidth !== oldCanvasWidth || canvasWidthL !== oldCanvasWidthL || canvasWidthR !== oldCanvasWidthR;\n\t\n\t if (widthChanged || hasFrozenColumns() || hasFrozenRows) {\n\t $canvasTopL.width(canvasWidthL);\n\t\n\t getHeadersWidth();\n\t\n\t $headerL.width(headersWidthL);\n\t $headerR.width(headersWidthR);\n\t\n\t if (hasFrozenColumns()) {\n\t $canvasTopR.width(canvasWidthR);\n\t\n\t $paneHeaderL.width(canvasWidthL);\n\t $paneHeaderR.css('left', canvasWidthL);\n\t $paneHeaderR.css('width', viewportW - canvasWidthL);\n\t\n\t $paneTopL.width(canvasWidthL);\n\t $paneTopR.css('left', canvasWidthL);\n\t $paneTopR.css('width', viewportW - canvasWidthL);\n\t\n\t $headerRowScrollerL.width(canvasWidthL);\n\t $headerRowScrollerR.width(viewportW - canvasWidthL);\n\t\n\t $headerRowL.width(canvasWidthL);\n\t $headerRowR.width(canvasWidthR);\n\t\n\t $footerRowScrollerL.width(canvasWidthL);\n\t $footerRowScrollerR.width(viewportW - canvasWidthL);\n\t\n\t $footerRowL.width(canvasWidthL);\n\t $footerRowR.width(canvasWidthR);\n\t\n\t $viewportTopL.width(canvasWidthL);\n\t $viewportTopR.width(viewportW - canvasWidthL);\n\t\n\t if (hasFrozenRows) {\n\t $paneBottomL.width(canvasWidthL);\n\t $paneBottomR.css('left', canvasWidthL);\n\t\n\t $viewportBottomL.width(canvasWidthL);\n\t $viewportBottomR.width(viewportW - canvasWidthL);\n\t\n\t $canvasBottomL.width(canvasWidthL);\n\t $canvasBottomR.width(canvasWidthR);\n\t }\n\t } else {\n\t $paneHeaderL.width('100%');\n\t\n\t $paneTopL.width('100%');\n\t\n\t $headerRowScrollerL.width('100%');\n\t\n\t $headerRowL.width(canvasWidth);\n\t\n\t $footerRowScrollerL.width('100%');\n\t\n\t $footerRowL.width(canvasWidth);\n\t\n\t $viewportTopL.width('100%');\n\t\n\t if (hasFrozenRows) {\n\t $viewportBottomL.width('100%');\n\t $canvasBottomL.width(canvasWidthL);\n\t }\n\t }\n\t\n\t viewportHasHScroll = canvasWidth > viewportW - scrollbarDimensions.width;\n\t }\n\t\n\t $headerRowSpacerL.width(canvasWidth + (viewportHasVScroll ? scrollbarDimensions.width : 0));\n\t $headerRowSpacerR.width(canvasWidth + (viewportHasVScroll ? scrollbarDimensions.width : 0));\n\t\n\t $footerRowSpacerL.width(canvasWidth + (viewportHasVScroll ? scrollbarDimensions.width : 0));\n\t $footerRowSpacerR.width(canvasWidth + (viewportHasVScroll ? scrollbarDimensions.width : 0));\n\t\n\t if (widthChanged || forceColumnWidthsUpdate) {\n\t applyColumnWidths();\n\t }\n\t }\n\t\n\t function disableSelection($target) {\n\t if ($target && $target.jquery) {\n\t $target.attr(\"unselectable\", \"on\").css(\"MozUserSelect\", \"none\").bind(\"selectstart.ui\", function () {\n\t return false;\n\t }); // from jquery:ui.core.js 1.7.2\n\t }\n\t }\n\t\n\t function getMaxSupportedCssHeight() {\n\t var supportedHeight = 1000000;\n\t // FF reports the height back but still renders blank after ~6M px\n\t var testUpTo = navigator.userAgent.toLowerCase().match(/firefox/) ? 6000000 : 1000000000;\n\t var div = (0, _jquery2.default)(\"\").appendTo(document.body);\n\t\n\t while (true) {\n\t var test = supportedHeight * 2;\n\t div.css(\"height\", test);\n\t if (test > testUpTo || div.height() !== test) {\n\t break;\n\t } else {\n\t supportedHeight = test;\n\t }\n\t }\n\t\n\t div.remove();\n\t return supportedHeight;\n\t }\n\t\n\t // TODO: this is static. need to handle page mutation.\n\t function bindAncestorScrollEvents() {\n\t var elem = hasFrozenRows && !options.frozenBottom ? $canvasBottomL[0] : $canvasTopL[0];\n\t while ((elem = elem.parentNode) != document.body && elem != null) {\n\t // bind to scroll containers only\n\t if (elem == $viewportTopL[0] || elem.scrollWidth != elem.clientWidth || elem.scrollHeight != elem.clientHeight) {\n\t var $elem = (0, _jquery2.default)(elem);\n\t if (!$boundAncestors) {\n\t $boundAncestors = $elem;\n\t } else {\n\t $boundAncestors = $boundAncestors.add($elem);\n\t }\n\t $elem.bind(\"scroll.\" + uid, handleActiveCellPositionChange);\n\t }\n\t }\n\t }\n\t\n\t function unbindAncestorScrollEvents() {\n\t if (!$boundAncestors) {\n\t return;\n\t }\n\t $boundAncestors.unbind(\"scroll.\" + uid);\n\t $boundAncestors = null;\n\t }\n\t\n\t function updateColumnHeader(columnId, title, toolTip) {\n\t if (!initialized) {\n\t return;\n\t }\n\t var idx = getColumnIndex(columnId);\n\t if (idx == null) {\n\t return;\n\t }\n\t\n\t var columnDef = columns[idx];\n\t var $header = $headers.children().eq(idx);\n\t if ($header) {\n\t if (title !== undefined) {\n\t columns[idx].name = title;\n\t }\n\t if (toolTip !== undefined) {\n\t columns[idx].toolTip = toolTip;\n\t }\n\t\n\t trigger(self.onBeforeHeaderCellDestroy, {\n\t \"node\": $header[0],\n\t \"column\": columnDef\n\t });\n\t\n\t $header.attr(\"title\", toolTip || \"\").children().eq(0).html(title);\n\t\n\t trigger(self.onHeaderCellRendered, {\n\t \"node\": $header[0],\n\t \"column\": columnDef\n\t });\n\t }\n\t }\n\t\n\t function getHeaderRow() {\n\t return hasFrozenColumns() ? $headerRow : $headerRow[0];\n\t }\n\t\n\t function getHeaderRowColumn(columnId) {\n\t var idx = getColumnIndex(columnId);\n\t\n\t var $headerRowTarget;\n\t\n\t if (hasFrozenColumns()) {\n\t if (idx <= options.frozenColumn) {\n\t $headerRowTarget = $headerRowL;\n\t } else {\n\t $headerRowTarget = $headerRowR;\n\t\n\t idx -= options.frozenColumn + 1;\n\t }\n\t } else {\n\t $headerRowTarget = $headerRowL;\n\t }\n\t\n\t var $header = $headerRowTarget.children().eq(idx);\n\t return $header && $header[0];\n\t }\n\t\n\t function getFooterRow() {\n\t return hasFrozenColumns() ? $footerRow : $footerRow[0];\n\t }\n\t\n\t function getFooterRowColumn(columnId) {\n\t var idx = getColumnIndex(columnId);\n\t\n\t var $footerRowTarget;\n\t\n\t if (hasFrozenColumns()) {\n\t if (idx <= options.frozenColumn) {\n\t $footerRowTarget = $footerRowL;\n\t } else {\n\t $footerRowTarget = $footerRowR;\n\t\n\t idx -= options.frozenColumn + 1;\n\t }\n\t } else {\n\t $footerRowTarget = $footerRowL;\n\t }\n\t\n\t var $footer = $footerRowTarget.children().eq(idx);\n\t return $footer && $footer[0];\n\t }\n\t\n\t function createColumnFooter() {\n\t $footerRow.find(\".slick-footerrow-column\").each(function () {\n\t var columnDef = (0, _jquery2.default)(this).data(\"column\");\n\t if (columnDef) {\n\t trigger(self.onBeforeFooterRowCellDestroy, {\n\t \"node\": this,\n\t \"column\": columnDef\n\t });\n\t }\n\t });\n\t\n\t $footerRowL.empty();\n\t $footerRowR.empty();\n\t\n\t for (var i = 0; i < columns.length; i++) {\n\t var m = columns[i];\n\t\n\t var footerRowCell = (0, _jquery2.default)(\"\").data(\"column\", m).addClass(hasFrozenColumns() && i <= options.frozenColumn ? 'frozen' : '').appendTo(hasFrozenColumns() && i > options.frozenColumn ? $footerRowR : $footerRowL);\n\t\n\t trigger(self.onFooterRowCellRendered, {\n\t \"node\": footerRowCell[0],\n\t \"column\": m\n\t });\n\t }\n\t }\n\t\n\t function createColumnGroupHeaders() {\n\t var columnsLength = 0;\n\t var frozenColumnsValid = false;\n\t\n\t if (!treeColumns.hasDepth()) return;\n\t\n\t for (var index = 0; index < $groupHeadersL.length; index++) {\n\t\n\t $groupHeadersL[index].empty();\n\t $groupHeadersR[index].empty();\n\t\n\t var groupColumns = treeColumns.getColumnsInDepth(index);\n\t\n\t for (var indexGroup in groupColumns) {\n\t var m = groupColumns[indexGroup];\n\t\n\t columnsLength += m.extractColumns().length;\n\t\n\t if (hasFrozenColumns() && index == 0 && columnsLength - 1 === options.frozenColumn) frozenColumnsValid = true;\n\t\n\t (0, _jquery2.default)(\"\").html(\"\" + m.name + \"\").attr(\"id\", \"\" + uid + m.id).attr(\"title\", m.toolTip || \"\").data(\"column\", m).addClass(m.headerCssClass || \"\").addClass(hasFrozenColumns() && columnsLength - 1 <= options.frozenColumn ? 'frozen' : '').appendTo(hasFrozenColumns() && columnsLength - 1 > options.frozenColumn ? $groupHeadersR[index] : $groupHeadersL[index]);\n\t }\n\t\n\t if (hasFrozenColumns() && index == 0 && !frozenColumnsValid) {\n\t $groupHeadersL[index].empty();\n\t $groupHeadersR[index].empty();\n\t alert(\"All columns of group should to be grouped!\");\n\t break;\n\t }\n\t }\n\t\n\t applyColumnGroupHeaderWidths();\n\t }\n\t\n\t function createColumnHeaders() {\n\t function onMouseEnter() {\n\t (0, _jquery2.default)(this).addClass(\"ui-state-hover\");\n\t }\n\t\n\t function onMouseLeave() {\n\t (0, _jquery2.default)(this).removeClass(\"ui-state-hover\");\n\t }\n\t\n\t $headers.find(\".slick-header-column\").each(function () {\n\t var columnDef = (0, _jquery2.default)(this).data(\"column\");\n\t if (columnDef) {\n\t trigger(self.onBeforeHeaderCellDestroy, {\n\t \"node\": this,\n\t \"column\": columnDef\n\t });\n\t }\n\t });\n\t\n\t $headerL.empty();\n\t $headerR.empty();\n\t\n\t getHeadersWidth();\n\t\n\t $headerL.width(headersWidthL);\n\t $headerR.width(headersWidthR);\n\t\n\t $headerRow.find(\".slick-headerrow-column\").each(function () {\n\t var columnDef = (0, _jquery2.default)(this).data(\"column\");\n\t if (columnDef) {\n\t trigger(self.onBeforeHeaderRowCellDestroy, {\n\t \"node\": this,\n\t \"column\": columnDef\n\t });\n\t }\n\t });\n\t\n\t $headerRowL.empty();\n\t $headerRowR.empty();\n\t\n\t for (var i = 0; i < columns.length; i++) {\n\t var m = columns[i];\n\t\n\t var $headerTarget = hasFrozenColumns() ? i <= options.frozenColumn ? $headerL : $headerR : $headerL;\n\t var $headerRowTarget = hasFrozenColumns() ? i <= options.frozenColumn ? $headerRowL : $headerRowR : $headerRowL;\n\t\n\t var header = (0, _jquery2.default)(\"\").html(\"\" + m.name + \"\").width(m.width - headerColumnWidthDiff).attr(\"id\", \"\" + uid + m.id).attr(\"title\", m.toolTip || \"\").data(\"column\", m).addClass(m.headerCssClass || \"\").addClass(hasFrozenColumns() && i <= options.frozenColumn ? 'frozen' : '').appendTo($headerTarget);\n\t\n\t if (options.enableColumnReorder || m.sortable) {\n\t header.on('mouseenter', onMouseEnter).on('mouseleave', onMouseLeave);\n\t }\n\t\n\t if (m.sortable) {\n\t header.addClass(\"slick-header-sortable\");\n\t header.append(\"\");\n\t }\n\t\n\t trigger(self.onHeaderCellRendered, {\n\t \"node\": header[0],\n\t \"column\": m\n\t });\n\t\n\t if (options.showHeaderRow) {\n\t var headerRowCell = (0, _jquery2.default)(\"\").data(\"column\", m).appendTo($headerRowTarget);\n\t\n\t trigger(self.onHeaderRowCellRendered, {\n\t \"node\": headerRowCell[0],\n\t \"column\": m\n\t });\n\t }\n\t }\n\t\n\t setSortColumns(sortColumns);\n\t setupColumnResize();\n\t if (options.enableColumnReorder) {\n\t setupColumnReorder();\n\t }\n\t }\n\t\n\t function setupColumnSort() {\n\t $headers.click(function (e) {\n\t // temporary workaround for a bug in jQuery 1.7.1 (http://bugs.jquery.com/ticket/11328)\n\t e.metaKey = e.metaKey || e.ctrlKey;\n\t\n\t if ((0, _jquery2.default)(e.target).hasClass(\"slick-resizable-handle\")) {\n\t return;\n\t }\n\t\n\t var $col = (0, _jquery2.default)(e.target).closest(\".slick-header-column\");\n\t if (!$col.length) {\n\t return;\n\t }\n\t\n\t var column = $col.data(\"column\");\n\t if (column.sortable) {\n\t if (!getEditorLock().commitCurrentEdit()) {\n\t return;\n\t }\n\t\n\t var sortOpts = null;\n\t var i = 0;\n\t for (; i < sortColumns.length; i++) {\n\t if (sortColumns[i].columnId == column.id) {\n\t sortOpts = sortColumns[i];\n\t sortOpts.sortAsc = !sortOpts.sortAsc;\n\t break;\n\t }\n\t }\n\t\n\t if (e.metaKey && options.multiColumnSort) {\n\t if (sortOpts) {\n\t sortColumns.splice(i, 1);\n\t }\n\t } else {\n\t if (!e.shiftKey && !e.metaKey || !options.multiColumnSort) {\n\t sortColumns = [];\n\t }\n\t\n\t if (!sortOpts) {\n\t sortOpts = {\n\t columnId: column.id,\n\t sortAsc: column.defaultSortAsc\n\t };\n\t sortColumns.push(sortOpts);\n\t } else if (sortColumns.length == 0) {\n\t sortColumns.push(sortOpts);\n\t }\n\t }\n\t\n\t setSortColumns(sortColumns);\n\t\n\t if (!options.multiColumnSort) {\n\t trigger(self.onSort, {\n\t multiColumnSort: false,\n\t sortCol: column,\n\t sortAsc: sortOpts.sortAsc\n\t }, e);\n\t } else {\n\t trigger(self.onSort, {\n\t multiColumnSort: true,\n\t sortCols: _jquery2.default.map(sortColumns, function (col) {\n\t return {\n\t sortCol: columns[getColumnIndex(col.columnId)],\n\t sortAsc: col.sortAsc\n\t };\n\t })\n\t }, e);\n\t }\n\t }\n\t });\n\t }\n\t\n\t function currentPositionInHeader(id) {\n\t var currentPosition = 0;\n\t $headers.find('.slick-header-column').each(function (i) {\n\t if (this.id == id) {\n\t currentPosition = i;\n\t return false;\n\t }\n\t });\n\t\n\t return currentPosition;\n\t }\n\t\n\t function limitPositionInGroup(idColumn) {\n\t var groupColumnOfPreviousPosition,\n\t startLimit = 0,\n\t endLimit = 0;\n\t\n\t treeColumns.getColumnsInDepth($groupHeadersL.length - 1).some(function (groupColumn) {\n\t startLimit = endLimit;\n\t endLimit += groupColumn.columns.length;\n\t\n\t groupColumn.columns.some(function (column) {\n\t\n\t if (column.id === idColumn) groupColumnOfPreviousPosition = groupColumn;\n\t\n\t return groupColumnOfPreviousPosition;\n\t });\n\t\n\t return groupColumnOfPreviousPosition;\n\t });\n\t\n\t endLimit--;\n\t\n\t return {\n\t start: startLimit,\n\t end: endLimit,\n\t group: groupColumnOfPreviousPosition\n\t };\n\t }\n\t\n\t function remove(arr, elem) {\n\t var index = arr.lastIndexOf(elem);\n\t if (index > -1) {\n\t arr.splice(index, 1);\n\t remove(arr, elem);\n\t }\n\t }\n\t\n\t function columnPositionValidInGroup($item) {\n\t var currentPosition = currentPositionInHeader($item[0].id);\n\t var limit = limitPositionInGroup($item.data('column').id);\n\t var positionValid = limit.start <= currentPosition && currentPosition <= limit.end;\n\t\n\t return {\n\t limit: limit,\n\t valid: positionValid,\n\t message: positionValid ? '' : 'Column \"'.concat($item.text(), '\" can be reordered only within the \"', limit.group.name, '\" group!')\n\t };\n\t }\n\t\n\t function setupColumnReorder() {\n\t var x = 0;\n\t var delta = 0;\n\t var placeholder = document.createElement('div');\n\t\n\t placeholder.className = 'interact-placeholder';\n\t\n\t (0, _interact2.default)('.slick-header-column').ignoreFrom('.slick-resizable-handle').draggable({\n\t inertia: true,\n\t // keep the element within the area of it's parent\n\t restrict: {\n\t restriction: 'parent',\n\t endOnly: true,\n\t elementRect: { top: 0, left: 0, bottom: 0, right: 0 }\n\t },\n\t // enable autoScroll\n\t autoScroll: true,\n\t axis: 'x',\n\t onstart: function onstart(event) {\n\t x = 0;\n\t delta = event.target.offsetWidth;\n\t\n\t // get old order\n\t $headers.find('.slick-header-column').each(function (index) {\n\t (0, _jquery2.default)(this).data('index', index);\n\t });\n\t\n\t placeholder.style.height = event.target.offsetHeight + 'px';\n\t placeholder.style.width = delta + 'px';\n\t\n\t (0, _jquery2.default)(event.target).after(placeholder).css({\n\t position: 'absolute',\n\t zIndex: 1000,\n\t marginLeft: (0, _jquery2.default)(event.target).position().left - 1000\n\t });\n\t },\n\t\n\t onmove: function onmove(event) {\n\t x += event.dx;\n\t event.target.style.transform = 'translate3d(' + x + 'px, -3px, 100px)';\n\t // event.target.style.marginLeft = x + 'px';\n\t },\n\t\n\t onend: function onend(event) {\n\t x = 0;\n\t delta = 0;\n\t\n\t if (treeColumns.hasDepth()) {\n\t var validPositionInGroup = columnPositionValidInGroup((0, _jquery2.default)(event.target));\n\t var limit = validPositionInGroup.limit;\n\t\n\t var cancel = !validPositionInGroup.valid;\n\t\n\t if (cancel) alert(validPositionInGroup.message);\n\t }\n\t\n\t placeholder.parentNode.removeChild(placeholder);\n\t\n\t if (cancel) {\n\t event.target.style.transform = 'none';\n\t setColumns(getColumns());\n\t return;\n\t }\n\t\n\t (0, _jquery2.default)(event.target).css({\n\t position: 'relative',\n\t zIndex: '',\n\t marginLeft: 0,\n\t transform: 'none'\n\t });\n\t\n\t var newColumns = [];\n\t $headers.find('.slick-header-column').each(function (index) {\n\t newColumns.push(columns[(0, _jquery2.default)(this).data('index')]);\n\t (0, _jquery2.default)(this).removeData('index');\n\t });\n\t\n\t setColumns(newColumns);\n\t\n\t trigger(self.onColumnsReordered, { impactedColumns: getImpactedColumns(limit), grid: self });\n\t setupColumnResize();\n\t }\n\t }).dropzone({\n\t accept: '.slick-header-column',\n\t\n\t ondragenter: function ondragenter(event) {\n\t event.target.classList.add('interact-drop-active');\n\t event.relatedTarget.classList.add('interact-can-drop');\n\t },\n\t\n\t ondragleave: function ondragleave(event) {\n\t event.target.classList.remove('interact-drop-active');\n\t event.relatedTarget.classList.remove('interact-can-drop');\n\t },\n\t\n\t ondrop: function ondrop(event) {\n\t event.target.classList.remove('interact-drop-active');\n\t event.relatedTarget.classList.remove('interact-can-drop');\n\t (0, _jquery2.default)(event.target)[x > 0 ? 'after' : 'before'](event.relatedTarget);\n\t }\n\t }).styleCursor(false);\n\t }\n\t\n\t function getImpactedColumns(limit) {\n\t var impactedColumns = [];\n\t\n\t if (limit != undefined) {\n\t\n\t for (var i = limit.start; i <= limit.end; i++) {\n\t impactedColumns.push(columns[i]);\n\t }\n\t } else {\n\t\n\t impactedColumns = columns;\n\t }\n\t\n\t return impactedColumns;\n\t }\n\t\n\t function setupColumnResize() {\n\t var $col, j, c, pageX, columnElements, minPageX, maxPageX, firstResizable, lastResizable;\n\t columnElements = $headers.children();\n\t columnElements.find('.slick-resizable-handle').remove();\n\t columnElements.each(function (i, e) {\n\t if (columns[i].resizable) {\n\t if (firstResizable === undefined) {\n\t firstResizable = i;\n\t }\n\t lastResizable = i;\n\t }\n\t });\n\t if (firstResizable === undefined) {\n\t return;\n\t }\n\t columnElements.each(function (i, element) {\n\t if (i < firstResizable || options.forceFitColumns && i >= lastResizable) {\n\t return;\n\t }\n\t $col = (0, _jquery2.default)(element);\n\t\n\t var $handle = (0, _jquery2.default)(\"\");\n\t $handle.appendTo(element);\n\t\n\t if ($col.data('resizable')) return;\n\t\n\t var activeColumn = columns[i];\n\t if (activeColumn.resizable) {\n\t $col.data('resizable', true);\n\t (0, _interact2.default)(element).resizable({\n\t preserveAspectRatio: false,\n\t edges: { left: true, right: true, bottom: false, top: false }\n\t }).on('resizestart', function (event) {\n\t if (!getEditorLock().commitCurrentEdit()) {\n\t return false;\n\t }\n\t activeColumn.previousWidth = event.rect.width;\n\t event.target.classList.add('slick-header-column-active');\n\t }).on('resizemove', function (event) {\n\t var x = event.dx;\n\t var width = activeColumn.width += x;\n\t\n\t if (activeColumn.minWidth > 0 && activeColumn.minWidth > width) width = activeColumn.minWidth;else if (activeColumn.maxWidth > 0 && activeColumn.maxWidth < width) width = activeColumn.maxWidth;\n\t\n\t activeColumn.width = width;\n\t\n\t if (options.forceFitColumns) {\n\t autosizeColumns();\n\t }\n\t applyColumnHeaderWidths();\n\t if (options.syncColumnCellResize) {\n\t applyColumnWidths();\n\t }\n\t }).on('resizeend', function (event) {\n\t event.target.classList.remove('slick-header-column-active');\n\t if (treeColumns.hasDepth()) createColumnGroupHeaders();\n\t\n\t invalidateAllRows();\n\t updateCanvasWidth(true);\n\t render();\n\t trigger(self.onColumnsResized, { grid: self });\n\t });\n\t }\n\t });\n\t }\n\t\n\t function getVBoxDelta($el) {\n\t var p = [\"borderTopWidth\", \"borderBottomWidth\", \"paddingTop\", \"paddingBottom\"];\n\t var delta = 0;\n\t _jquery2.default.each(p, function (n, val) {\n\t delta += parseFloat($el.css(val)) || 0;\n\t });\n\t return delta;\n\t }\n\t\n\t function setFrozenOptions() {\n\t options.frozenColumn = options.frozenColumn >= 0 && options.frozenColumn < columns.length ? parseInt(options.frozenColumn) : -1;\n\t\n\t options.frozenRow = options.frozenRow >= 0 && options.frozenRow < numVisibleRows ? parseInt(options.frozenRow) : -1;\n\t\n\t if (options.frozenRow > -1) {\n\t hasFrozenRows = true;\n\t frozenRowsHeight = options.frozenRow * options.rowHeight;\n\t\n\t var dataLength = getDataLength() || this.data.length;\n\t\n\t actualFrozenRow = options.frozenBottom ? dataLength - options.frozenRow : options.frozenRow;\n\t } else {\n\t hasFrozenRows = false;\n\t }\n\t }\n\t\n\t function setPaneVisibility() {\n\t if (hasFrozenColumns()) {\n\t $paneHeaderR.show();\n\t $paneTopR.show();\n\t\n\t if (hasFrozenRows) {\n\t $paneBottomL.show();\n\t $paneBottomR.show();\n\t } else {\n\t $paneBottomR.hide();\n\t $paneBottomL.hide();\n\t }\n\t } else {\n\t $paneHeaderR.hide();\n\t $paneTopR.hide();\n\t $paneBottomR.hide();\n\t\n\t if (hasFrozenRows) {\n\t $paneBottomL.show();\n\t } else {\n\t $paneBottomR.hide();\n\t $paneBottomL.hide();\n\t }\n\t }\n\t }\n\t\n\t function setOverflow() {\n\t $viewportTopL.css({\n\t 'overflow-x': hasFrozenColumns() ? hasFrozenRows ? 'hidden' : 'scroll' : hasFrozenRows ? 'hidden' : 'auto',\n\t 'overflow-y': hasFrozenColumns() ? hasFrozenRows ? 'hidden' : 'hidden' : hasFrozenRows ? 'scroll' : 'auto'\n\t });\n\t\n\t $viewportTopR.css({\n\t 'overflow-x': hasFrozenColumns() ? hasFrozenRows ? 'hidden' : 'scroll' : hasFrozenRows ? 'hidden' : 'auto',\n\t 'overflow-y': hasFrozenColumns() ? hasFrozenRows ? 'scroll' : 'auto' : hasFrozenRows ? 'scroll' : 'auto'\n\t });\n\t\n\t $viewportBottomL.css({\n\t 'overflow-x': hasFrozenColumns() ? hasFrozenRows ? 'scroll' : 'auto' : hasFrozenRows ? 'auto' : 'auto',\n\t 'overflow-y': hasFrozenColumns() ? hasFrozenRows ? 'hidden' : 'hidden' : hasFrozenRows ? 'scroll' : 'auto'\n\t });\n\t\n\t $viewportBottomR.css({\n\t 'overflow-x': hasFrozenColumns() ? hasFrozenRows ? 'scroll' : 'auto' : hasFrozenRows ? 'auto' : 'auto',\n\t 'overflow-y': hasFrozenColumns() ? hasFrozenRows ? 'auto' : 'auto' : hasFrozenRows ? 'auto' : 'auto'\n\t });\n\t }\n\t\n\t function setScroller() {\n\t if (hasFrozenColumns()) {\n\t $headerScrollContainer = $headerScrollerR;\n\t $headerRowScrollContainer = $headerRowScrollerR;\n\t $footerRowScrollContainer = $footerRowScrollerR;\n\t\n\t if (hasFrozenRows) {\n\t if (options.frozenBottom) {\n\t $viewportScrollContainerX = $viewportBottomR;\n\t $viewportScrollContainerY = $viewportTopR;\n\t } else {\n\t $viewportScrollContainerX = $viewportScrollContainerY = $viewportBottomR;\n\t }\n\t } else {\n\t $viewportScrollContainerX = $viewportScrollContainerY = $viewportTopR;\n\t }\n\t } else {\n\t $headerScrollContainer = $headerScrollerL;\n\t $headerRowScrollContainer = $headerRowScrollerL;\n\t $footerRowScrollContainer = $footerRowScrollerL;\n\t\n\t if (hasFrozenRows) {\n\t if (options.frozenBottom) {\n\t $viewportScrollContainerX = $viewportBottomL;\n\t $viewportScrollContainerY = $viewportTopL;\n\t } else {\n\t $viewportScrollContainerX = $viewportScrollContainerY = $viewportBottomL;\n\t }\n\t } else {\n\t $viewportScrollContainerX = $viewportScrollContainerY = $viewportTopL;\n\t }\n\t }\n\t }\n\t\n\t function measureCellPaddingAndBorder() {\n\t var el;\n\t var h = [\"borderLeftWidth\", \"borderRightWidth\", \"paddingLeft\", \"paddingRight\"];\n\t var v = [\"borderTopWidth\", \"borderBottomWidth\", \"paddingTop\", \"paddingBottom\"];\n\t\n\t el = (0, _jquery2.default)(\"
-
\").appendTo($headers);\n\t headerColumnWidthDiff = headerColumnHeightDiff = 0;\n\t if (el.css(\"box-sizing\") != \"border-box\" && el.css(\"-moz-box-sizing\") != \"border-box\" && el.css(\"-webkit-box-sizing\") != \"border-box\") {\n\t _jquery2.default.each(h, function (n, val) {\n\t headerColumnWidthDiff += parseFloat(el.css(val)) || 0;\n\t });\n\t _jquery2.default.each(v, function (n, val) {\n\t headerColumnHeightDiff += parseFloat(el.css(val)) || 0;\n\t });\n\t }\n\t el.remove();\n\t\n\t var r = (0, _jquery2.default)(\"\").appendTo($canvas);\n\t el = (0, _jquery2.default)(\"
-
\").appendTo(r);\n\t cellWidthDiff = cellHeightDiff = 0;\n\t if (el.css(\"box-sizing\") != \"border-box\" && el.css(\"-moz-box-sizing\") != \"border-box\" && el.css(\"-webkit-box-sizing\") != \"border-box\") {\n\t _jquery2.default.each(h, function (n, val) {\n\t cellWidthDiff += parseFloat(el.css(val)) || 0;\n\t });\n\t _jquery2.default.each(v, function (n, val) {\n\t cellHeightDiff += parseFloat(el.css(val)) || 0;\n\t });\n\t }\n\t r.remove();\n\t\n\t absoluteColumnMinWidth = Math.max(headerColumnWidthDiff, cellWidthDiff);\n\t }\n\t\n\t function createCssRules() {\n\t $style = (0, _jquery2.default)(\"\").appendTo((0, _jquery2.default)(\"head\"));\n\t var rowHeight = options.rowHeight - cellHeightDiff;\n\t var rules = [\".\" + uid + \" .slick-group-header-column { left: 1000px; }\", \".\" + uid + \" .slick-header-column { left: 1000px; }\", \".\" + uid + \" .slick-top-panel { height:\" + options.topPanelHeight + \"px; }\", \".\" + uid + \" .slick-headerrow-columns { height:\" + options.headerRowHeight + \"px; }\", \".\" + uid + \" .slick-cell { height:\" + rowHeight + \"px; }\", \".\" + uid + \" .slick-row { height:\" + options.rowHeight + \"px; }\", \".\" + uid + \" .slick-footerrow-columns { height:\" + options.footerRowHeight + \"px; }\"];\n\t\n\t for (var i = 0; i < columns.length; i++) {\n\t rules.push(\".\" + uid + \" .l\" + i + \" { }\");\n\t rules.push(\".\" + uid + \" .r\" + i + \" { }\");\n\t }\n\t\n\t if ($style[0].styleSheet) {\n\t // IE\n\t $style[0].styleSheet.cssText = rules.join(\" \");\n\t } else {\n\t $style[0].appendChild(document.createTextNode(rules.join(\" \")));\n\t }\n\t }\n\t\n\t function getColumnCssRules(idx) {\n\t if (!stylesheet) {\n\t var sheets = document.styleSheets;\n\t for (var i = 0; i < sheets.length; i++) {\n\t if ((sheets[i].ownerNode || sheets[i].owningElement) == $style[0]) {\n\t stylesheet = sheets[i];\n\t break;\n\t }\n\t }\n\t\n\t if (!stylesheet) {\n\t throw new Error(\"Cannot find stylesheet.\");\n\t }\n\t\n\t // find and cache column CSS rules\n\t columnCssRulesL = [];\n\t columnCssRulesR = [];\n\t var cssRules = stylesheet.cssRules || stylesheet.rules;\n\t var matches, columnIdx;\n\t for (var i = 0; i < cssRules.length; i++) {\n\t var selector = cssRules[i].selectorText;\n\t if (matches = /\\.l\\d+/.exec(selector)) {\n\t columnIdx = parseInt(matches[0].substr(2, matches[0].length - 2), 10);\n\t columnCssRulesL[columnIdx] = cssRules[i];\n\t } else if (matches = /\\.r\\d+/.exec(selector)) {\n\t columnIdx = parseInt(matches[0].substr(2, matches[0].length - 2), 10);\n\t columnCssRulesR[columnIdx] = cssRules[i];\n\t }\n\t }\n\t }\n\t\n\t return {\n\t \"left\": columnCssRulesL[idx],\n\t \"right\": columnCssRulesR[idx]\n\t };\n\t }\n\t\n\t function removeCssRules() {\n\t $style.remove();\n\t stylesheet = null;\n\t }\n\t\n\t function destroy() {\n\t getEditorLock().cancelCurrentEdit();\n\t\n\t trigger(self.onBeforeDestroy, {});\n\t\n\t var i = plugins.length;\n\t while (i--) {\n\t unregisterPlugin(plugins[i]);\n\t }\n\t\n\t unbindAncestorScrollEvents();\n\t $container.unbind(\".slickgrid\");\n\t removeCssRules();\n\t\n\t $container.empty().removeClass(uid);\n\t }\n\t\n\t //////////////////////////////////////////////////////////////////////////////////////////////\n\t // General\n\t\n\t function trigger(evt, args, e) {\n\t e = e || new _slick2.default.EventData();\n\t args = args || {};\n\t args.grid = self;\n\t return evt.notify(args, e, self);\n\t }\n\t\n\t function getEditorLock() {\n\t return options.editorLock;\n\t }\n\t\n\t function getEditController() {\n\t return editController;\n\t }\n\t\n\t function getColumnIndex(id) {\n\t return columnsById[id];\n\t }\n\t\n\t function autosizeColumns() {\n\t var i,\n\t c,\n\t widths = [],\n\t shrinkLeeway = 0,\n\t total = 0,\n\t prevTotal,\n\t availWidth = viewportHasVScroll ? viewportW - scrollbarDimensions.width : viewportW;\n\t\n\t for (i = 0; i < columns.length; i++) {\n\t c = columns[i];\n\t widths.push(c.width);\n\t total += c.width;\n\t if (c.resizable) {\n\t shrinkLeeway += c.width - Math.max(c.minWidth, absoluteColumnMinWidth);\n\t }\n\t }\n\t\n\t // shrink\n\t prevTotal = total;\n\t while (total > availWidth && shrinkLeeway) {\n\t var shrinkProportion = (total - availWidth) / shrinkLeeway;\n\t for (i = 0; i < columns.length && total > availWidth; i++) {\n\t c = columns[i];\n\t var width = widths[i];\n\t if (!c.resizable || width <= c.minWidth || width <= absoluteColumnMinWidth) {\n\t continue;\n\t }\n\t var absMinWidth = Math.max(c.minWidth, absoluteColumnMinWidth);\n\t var shrinkSize = Math.floor(shrinkProportion * (width - absMinWidth)) || 1;\n\t shrinkSize = Math.min(shrinkSize, width - absMinWidth);\n\t total -= shrinkSize;\n\t shrinkLeeway -= shrinkSize;\n\t widths[i] -= shrinkSize;\n\t }\n\t if (prevTotal <= total) {\n\t // avoid infinite loop\n\t break;\n\t }\n\t prevTotal = total;\n\t }\n\t\n\t // grow\n\t prevTotal = total;\n\t while (total < availWidth) {\n\t var growProportion = availWidth / total;\n\t for (i = 0; i < columns.length && total < availWidth; i++) {\n\t c = columns[i];\n\t var currentWidth = widths[i];\n\t var growSize;\n\t\n\t if (!c.resizable || c.maxWidth <= currentWidth) {\n\t growSize = 0;\n\t } else {\n\t growSize = Math.min(Math.floor(growProportion * currentWidth) - currentWidth, c.maxWidth - currentWidth || 1000000) || 1;\n\t }\n\t total += growSize;\n\t widths[i] += growSize;\n\t }\n\t if (prevTotal >= total) {\n\t // avoid infinite loop\n\t break;\n\t }\n\t prevTotal = total;\n\t }\n\t\n\t var reRender = false;\n\t for (i = 0; i < columns.length; i++) {\n\t if (columns[i].rerenderOnResize && columns[i].width != widths[i]) {\n\t reRender = true;\n\t }\n\t columns[i].width = widths[i];\n\t }\n\t\n\t applyColumnHeaderWidths();\n\t applyColumnGroupHeaderWidths();\n\t updateCanvasWidth(true);\n\t if (reRender) {\n\t invalidateAllRows();\n\t render();\n\t }\n\t }\n\t\n\t function applyColumnGroupHeaderWidths() {\n\t if (!treeColumns.hasDepth()) return;\n\t\n\t for (var depth = $groupHeadersL.length - 1; depth >= 0; depth--) {\n\t\n\t var groupColumns = treeColumns.getColumnsInDepth(depth);\n\t\n\t (0, _jquery2.default)().add($groupHeadersL[depth]).add($groupHeadersR[depth]).each(function (i) {\n\t var $groupHeader = (0, _jquery2.default)(this),\n\t currentColumnIndex = 0;\n\t\n\t $groupHeader.width(i == 0 ? getHeadersWidthL() : getHeadersWidthR());\n\t\n\t $groupHeader.children().each(function () {\n\t var $groupHeaderColumn = (0, _jquery2.default)(this);\n\t\n\t var m = (0, _jquery2.default)(this).data('column');\n\t\n\t m.width = 0;\n\t\n\t m.columns.forEach(function () {\n\t var $headerColumn = $groupHeader.next().children(':eq(' + currentColumnIndex++ + ')');\n\t m.width += $headerColumn.outerWidth();\n\t });\n\t\n\t $groupHeaderColumn.width(m.width - headerColumnWidthDiff);\n\t });\n\t });\n\t }\n\t }\n\t\n\t function applyColumnHeaderWidths() {\n\t if (!initialized) {\n\t return;\n\t }\n\t var h;\n\t for (var i = 0, headers = $headers.children(), ii = headers.length; i < ii; i++) {\n\t h = (0, _jquery2.default)(headers[i]);\n\t if (h.width() !== columns[i].width - headerColumnWidthDiff) {\n\t h.width(columns[i].width - headerColumnWidthDiff);\n\t }\n\t }\n\t\n\t updateColumnCaches();\n\t }\n\t\n\t function applyColumnWidths() {\n\t var x = 0,\n\t w,\n\t rule;\n\t for (var i = 0; i < columns.length; i++) {\n\t w = columns[i].width;\n\t\n\t rule = getColumnCssRules(i);\n\t rule.left.style.left = x + \"px\";\n\t rule.right.style.right = (options.frozenColumn != -1 && i > options.frozenColumn ? canvasWidthR : canvasWidthL) - x - w + \"px\";\n\t\n\t // If this column is frozen, reset the css left value since the\n\t // column starts in a new viewport.\n\t if (options.frozenColumn == i) {\n\t x = 0;\n\t } else {\n\t x += columns[i].width;\n\t }\n\t }\n\t }\n\t\n\t function setSortColumn(columnId, ascending) {\n\t setSortColumns([{\n\t columnId: columnId,\n\t sortAsc: ascending\n\t }]);\n\t }\n\t\n\t function setSortColumns(cols) {\n\t sortColumns = cols;\n\t\n\t var headerColumnEls = $headers.children();\n\t headerColumnEls.removeClass(\"slick-header-column-sorted\").find(\".slick-sort-indicator\").removeClass(\"slick-sort-indicator-asc slick-sort-indicator-desc\");\n\t\n\t _jquery2.default.each(sortColumns, function (i, col) {\n\t if (col.sortAsc == null) {\n\t col.sortAsc = true;\n\t }\n\t var columnIndex = getColumnIndex(col.columnId);\n\t if (columnIndex != null) {\n\t headerColumnEls.eq(columnIndex).addClass(\"slick-header-column-sorted\").find(\".slick-sort-indicator\").addClass(col.sortAsc ? \"slick-sort-indicator-asc\" : \"slick-sort-indicator-desc\");\n\t }\n\t });\n\t }\n\t\n\t function getSortColumns() {\n\t return sortColumns;\n\t }\n\t\n\t function handleSelectedRangesChanged(e, ranges) {\n\t selectedRows = [];\n\t var hash = {};\n\t for (var i = 0; i < ranges.length; i++) {\n\t for (var j = ranges[i].fromRow; j <= ranges[i].toRow; j++) {\n\t if (!hash[j]) {\n\t // prevent duplicates\n\t selectedRows.push(j);\n\t hash[j] = {};\n\t }\n\t for (var k = ranges[i].fromCell; k <= ranges[i].toCell; k++) {\n\t if (canCellBeSelected(j, k)) {\n\t hash[j][columns[k].id] = options.selectedCellCssClass;\n\t }\n\t }\n\t }\n\t }\n\t\n\t setCellCssStyles(options.selectedCellCssClass, hash);\n\t\n\t trigger(self.onSelectedRowsChanged, {\n\t rows: getSelectedRows()\n\t }, e);\n\t }\n\t\n\t function getColumns() {\n\t return columns;\n\t }\n\t\n\t function updateColumnCaches() {\n\t // Pre-calculate cell boundaries.\n\t columnPosLeft = [];\n\t columnPosRight = [];\n\t var x = 0;\n\t for (var i = 0, ii = columns.length; i < ii; i++) {\n\t columnPosLeft[i] = x;\n\t columnPosRight[i] = x + columns[i].width;\n\t\n\t if (options.frozenColumn == i) {\n\t x = 0;\n\t } else {\n\t x += columns[i].width;\n\t }\n\t }\n\t }\n\t\n\t function setColumns(columnDefinitions) {\n\t var _treeColumns = new _slick2.default.TreeColumns(columnDefinitions);\n\t if (_treeColumns.hasDepth()) {\n\t treeColumns = _treeColumns;\n\t columns = treeColumns.extractColumns();\n\t } else {\n\t columns = columnDefinitions;\n\t }\n\t\n\t columnsById = {};\n\t for (var i = 0; i < columns.length; i++) {\n\t var m = columns[i] = _jquery2.default.extend({}, columnDefaults, columns[i]);\n\t columnsById[m.id] = i;\n\t if (m.minWidth && m.width < m.minWidth) {\n\t m.width = m.minWidth;\n\t }\n\t if (m.maxWidth && m.width > m.maxWidth) {\n\t m.width = m.maxWidth;\n\t }\n\t }\n\t\n\t updateColumnCaches();\n\t\n\t if (initialized) {\n\t setPaneVisibility();\n\t setOverflow();\n\t\n\t invalidateAllRows();\n\t createColumnHeaders();\n\t createColumnGroupHeaders();\n\t createColumnFooter();\n\t removeCssRules();\n\t createCssRules();\n\t resizeCanvas();\n\t updateCanvasWidth();\n\t applyColumnWidths();\n\t handleScroll();\n\t }\n\t }\n\t\n\t function getOptions() {\n\t return options;\n\t }\n\t\n\t function setOptions(args) {\n\t if (!getEditorLock().commitCurrentEdit()) {\n\t return;\n\t }\n\t\n\t makeActiveCellNormal();\n\t\n\t if (options.enableAddRow !== args.enableAddRow) {\n\t invalidateRow(getDataLength());\n\t }\n\t\n\t options = _jquery2.default.extend(options, args);\n\t validateAndEnforceOptions();\n\t\n\t setFrozenOptions();\n\t setScroller();\n\t zombieRowNodeFromLastMouseWheelEvent = null;\n\t\n\t setColumns(treeColumns.extractColumns());\n\t render();\n\t }\n\t\n\t function validateAndEnforceOptions() {\n\t if (options.autoHeight) {\n\t options.leaveSpaceForNewRows = false;\n\t }\n\t }\n\t\n\t function setData(newData, scrollToTop) {\n\t data = newData;\n\t invalidateAllRows();\n\t updateRowCount();\n\t if (scrollToTop) {\n\t scrollTo(0);\n\t }\n\t }\n\t\n\t function getData() {\n\t return data;\n\t }\n\t\n\t function getDataLength() {\n\t if (data.getLength) {\n\t return data.getLength();\n\t } else {\n\t return data.length;\n\t }\n\t }\n\t\n\t function getDataLengthIncludingAddNew() {\n\t return getDataLength() + (options.enableAddRow ? 1 : 0);\n\t }\n\t\n\t function getDataItem(i) {\n\t if (data.getItem) {\n\t return data.getItem(i);\n\t } else {\n\t return data[i];\n\t }\n\t }\n\t\n\t function getTopPanel() {\n\t return $topPanel[0];\n\t }\n\t\n\t function setTopPanelVisibility(visible) {\n\t if (options.showTopPanel != visible) {\n\t options.showTopPanel = visible;\n\t if (visible) {\n\t $topPanelScroller.slideDown(\"fast\", resizeCanvas);\n\t } else {\n\t $topPanelScroller.slideUp(\"fast\", resizeCanvas);\n\t }\n\t }\n\t }\n\t\n\t function setHeaderRowVisibility(visible) {\n\t if (options.showHeaderRow != visible) {\n\t options.showHeaderRow = visible;\n\t if (visible) {\n\t $headerRowScroller.slideDown(\"fast\", resizeCanvas);\n\t } else {\n\t $headerRowScroller.slideUp(\"fast\", resizeCanvas);\n\t }\n\t }\n\t }\n\t\n\t function setFooterRowVisibility(visible) {\n\t if (options.showFooterRow != visible) {\n\t options.showFooterRow = visible;\n\t if (visible) {\n\t $footerRowScroller.fadeIn(\"fast\", resizeCanvas);\n\t } else {\n\t $footerRowScroller.slideDown(\"fast\", resizeCanvas);\n\t }\n\t }\n\t }\n\t\n\t function getContainerNode() {\n\t return $container.get(0);\n\t }\n\t\n\t //////////////////////////////////////////////////////////////////////////////////////////////\n\t // Rendering / Scrolling\n\t\n\t function getRowTop(row) {\n\t return options.rowHeight * row - offset;\n\t }\n\t\n\t function getRowFromPosition(y) {\n\t return Math.floor((y + offset) / options.rowHeight);\n\t }\n\t\n\t function scrollTo(y) {\n\t y = Math.max(y, 0);\n\t y = Math.min(y, th - $viewportScrollContainerY.height() + (viewportHasHScroll || hasFrozenColumns() ? scrollbarDimensions.height : 0));\n\t\n\t var oldOffset = offset;\n\t\n\t page = Math.min(n - 1, Math.floor(y / ph));\n\t offset = Math.round(page * cj);\n\t var newScrollTop = y - offset;\n\t\n\t if (offset != oldOffset) {\n\t var range = getVisibleRange(newScrollTop);\n\t cleanupRows(range);\n\t updateRowPositions();\n\t }\n\t\n\t if (prevScrollTop != newScrollTop) {\n\t vScrollDir = prevScrollTop + oldOffset < newScrollTop + offset ? 1 : -1;\n\t\n\t lastRenderedScrollTop = scrollTop = prevScrollTop = newScrollTop;\n\t\n\t if (hasFrozenColumns()) {\n\t $viewportTopL[0].scrollTop = newScrollTop;\n\t }\n\t\n\t if (hasFrozenRows) {\n\t $viewportBottomL[0].scrollTop = $viewportBottomR[0].scrollTop = newScrollTop;\n\t }\n\t\n\t $viewportScrollContainerY[0].scrollTop = newScrollTop;\n\t\n\t trigger(self.onViewportChanged, {});\n\t }\n\t }\n\t\n\t function defaultFormatter(row, cell, value, columnDef, dataContext) {\n\t if (value == null) {\n\t return \"\";\n\t } else {\n\t return (value + \"\").replace(/&/g, \"&\").replace(//g, \">\");\n\t }\n\t }\n\t\n\t function getFormatter(row, column) {\n\t var rowMetadata = data.getItemMetadata && data.getItemMetadata(row);\n\t\n\t // look up by id, then index\n\t var columnOverrides = rowMetadata && rowMetadata.columns && (rowMetadata.columns[column.id] || rowMetadata.columns[getColumnIndex(column.id)]);\n\t\n\t return columnOverrides && columnOverrides.formatter || rowMetadata && rowMetadata.formatter || column.formatter || options.formatterFactory && options.formatterFactory.getFormatter(column) || options.defaultFormatter;\n\t }\n\t\n\t function callFormatter(row, cell, value, m, item) {\n\t\n\t var result;\n\t\n\t // pass metadata to formatter\n\t var metadata = data.getItemMetadata && data.getItemMetadata(row);\n\t metadata = metadata && metadata.columns;\n\t\n\t if (metadata) {\n\t var columnData = metadata[m.id] || metadata[cell];\n\t result = getFormatter(row, m)(row, cell, value, m, item, columnData);\n\t } else {\n\t result = getFormatter(row, m)(row, cell, value, m, item);\n\t }\n\t\n\t return result;\n\t }\n\t\n\t function getEditor(row, cell) {\n\t var column = columns[cell];\n\t var rowMetadata = data.getItemMetadata && data.getItemMetadata(row);\n\t var columnMetadata = rowMetadata && rowMetadata.columns;\n\t\n\t if (columnMetadata && columnMetadata[column.id] && columnMetadata[column.id].editor !== undefined) {\n\t return columnMetadata[column.id].editor;\n\t }\n\t if (columnMetadata && columnMetadata[cell] && columnMetadata[cell].editor !== undefined) {\n\t return columnMetadata[cell].editor;\n\t }\n\t\n\t return column.editor || options.editorFactory && options.editorFactory.getEditor(column);\n\t }\n\t\n\t function getDataItemValueForColumn(item, columnDef) {\n\t if (options.dataItemColumnValueExtractor) {\n\t return options.dataItemColumnValueExtractor(item, columnDef);\n\t }\n\t return item[columnDef.field];\n\t }\n\t\n\t function appendRowHtml(stringArrayL, stringArrayR, row, range, dataLength) {\n\t var d = getDataItem(row);\n\t var dataLoading = row < dataLength && !d;\n\t var rowCss = \"slick-row\" + (hasFrozenRows && row < options.frozenRow ? ' frozen' : '') + (dataLoading ? \" loading\" : \"\") + (row === activeRow ? \" active\" : \"\") + (row % 2 == 1 ? \" odd\" : \" even\");\n\t\n\t if (!d) {\n\t rowCss += \" \" + options.addNewRowCssClass;\n\t }\n\t\n\t var metadata = data.getItemMetadata && data.getItemMetadata(row);\n\t\n\t if (metadata && metadata.cssClasses) {\n\t rowCss += \" \" + metadata.cssClasses;\n\t }\n\t\n\t var frozenRowOffset = getFrozenRowOffset(row);\n\t\n\t var rowHtml = \"
\";\n\t\n\t stringArrayL.push(rowHtml);\n\t\n\t if (hasFrozenColumns()) {\n\t stringArrayR.push(rowHtml);\n\t }\n\t\n\t var colspan, m;\n\t for (var i = 0, ii = columns.length; i < ii; i++) {\n\t m = columns[i];\n\t colspan = 1;\n\t if (metadata && metadata.columns) {\n\t var columnData = metadata.columns[m.id] || metadata.columns[i];\n\t colspan = columnData && columnData.colspan || 1;\n\t if (colspan === \"*\") {\n\t colspan = ii - i;\n\t }\n\t }\n\t\n\t // Do not render cells outside of the viewport.\n\t if (columnPosRight[Math.min(ii - 1, i + colspan - 1)] > range.leftPx) {\n\t if (columnPosLeft[i] > range.rightPx) {\n\t // All columns to the right are outside the range.\n\t break;\n\t }\n\t\n\t if (hasFrozenColumns() && i > options.frozenColumn) {\n\t appendCellHtml(stringArrayR, row, i, colspan, d);\n\t } else {\n\t appendCellHtml(stringArrayL, row, i, colspan, d);\n\t }\n\t } else if (hasFrozenColumns() && i <= options.frozenColumn) {\n\t appendCellHtml(stringArrayL, row, i, colspan, d);\n\t }\n\t\n\t if (colspan > 1) {\n\t i += colspan - 1;\n\t }\n\t }\n\t\n\t stringArrayL.push(\"
\");\n\t\n\t if (hasFrozenColumns()) {\n\t stringArrayR.push(\"\");\n\t }\n\t }\n\t\n\t function appendCellHtml(stringArray, row, cell, colspan, item) {\n\t var m = columns[cell];\n\t var cellCss = \"slick-cell l\" + cell + \" r\" + Math.min(columns.length - 1, cell + colspan - 1) + (m.cssClass ? \" \" + m.cssClass : \"\");\n\t\n\t if (hasFrozenColumns() && cell <= options.frozenColumn) cellCss += ' frozen';\n\t\n\t if (row === activeRow && cell === activeCell) cellCss += \" active\";\n\t\n\t // TODO: merge them together in the setter\n\t for (var key in cellCssClasses) {\n\t if (cellCssClasses[key][row] && cellCssClasses[key][row][m.id]) {\n\t cellCss += \" \" + cellCssClasses[key][row][m.id];\n\t }\n\t }\n\t\n\t stringArray.push(\"
\");\n\t\n\t // if there is a corresponding row (if not, this is the Add New row or this data hasn't been loaded yet)\n\t if (item) {\n\t var value = getDataItemValueForColumn(item, m);\n\t stringArray.push(callFormatter(row, cell, value, m, item));\n\t }\n\t\n\t stringArray.push(\"
\");\n\t\n\t rowsCache[row].cellRenderQueue.push(cell);\n\t rowsCache[row].cellColSpans[cell] = colspan;\n\t }\n\t\n\t function cleanupRows(rangeToKeep) {\n\t for (var i in rowsCache) {\n\t var removeFrozenRow = true;\n\t\n\t if (hasFrozenRows && (options.frozenBottom && i >= actualFrozenRow || // Frozen bottom rows\n\t !options.frozenBottom && i <= actualFrozenRow // Frozen top rows\n\t )) {\n\t removeFrozenRow = false;\n\t }\n\t\n\t if ((i = parseInt(i, 10)) !== activeRow && (i < rangeToKeep.top || i > rangeToKeep.bottom) && removeFrozenRow) {\n\t removeRowFromCache(i);\n\t }\n\t }\n\t }\n\t\n\t function invalidate() {\n\t updateRowCount();\n\t invalidateAllRows();\n\t render();\n\t }\n\t\n\t function invalidateAllRows() {\n\t if (currentEditor) {\n\t makeActiveCellNormal();\n\t }\n\t for (var row in rowsCache) {\n\t removeRowFromCache(row);\n\t }\n\t }\n\t\n\t function removeRowFromCache(row) {\n\t var cacheEntry = rowsCache[row];\n\t if (!cacheEntry) {\n\t return;\n\t }\n\t\n\t if (rowNodeFromLastMouseWheelEvent == cacheEntry.rowNode[0] || hasFrozenColumns() && rowNodeFromLastMouseWheelEvent == cacheEntry.rowNode[1]) {\n\t\n\t cacheEntry.rowNode.hide();\n\t\n\t zombieRowNodeFromLastMouseWheelEvent = cacheEntry.rowNode;\n\t } else {\n\t\n\t cacheEntry.rowNode.each(function () {\n\t this.parentElement.removeChild(this);\n\t });\n\t }\n\t\n\t delete rowsCache[row];\n\t delete postProcessedRows[row];\n\t renderedRows--;\n\t counter_rows_removed++;\n\t }\n\t\n\t function invalidateRows(rows) {\n\t var i, rl;\n\t if (!rows || !rows.length) {\n\t return;\n\t }\n\t vScrollDir = 0;\n\t for (i = 0, rl = rows.length; i < rl; i++) {\n\t if (currentEditor && activeRow === rows[i]) {\n\t makeActiveCellNormal();\n\t }\n\t if (rowsCache[rows[i]]) {\n\t removeRowFromCache(rows[i]);\n\t }\n\t }\n\t }\n\t\n\t function invalidateRow(row) {\n\t invalidateRows([row]);\n\t }\n\t\n\t function updateCell(row, cell) {\n\t var cellNode = getCellNode(row, cell);\n\t if (!cellNode) {\n\t return;\n\t }\n\t\n\t var m = columns[cell],\n\t d = getDataItem(row);\n\t if (currentEditor && activeRow === row && activeCell === cell) {\n\t currentEditor.loadValue(d);\n\t } else {\n\t cellNode.innerHTML = d ? callFormatter(row, cell, getDataItemValueForColumn(d, m), m, d) : \"\";\n\t invalidatePostProcessingResults(row);\n\t }\n\t }\n\t\n\t function updateRow(row) {\n\t var cacheEntry = rowsCache[row];\n\t if (!cacheEntry) {\n\t return;\n\t }\n\t\n\t ensureCellNodesInRowsCache(row);\n\t\n\t var d = getDataItem(row);\n\t\n\t for (var columnIdx in cacheEntry.cellNodesByColumnIdx) {\n\t if (!cacheEntry.cellNodesByColumnIdx.hasOwnProperty(columnIdx)) {\n\t continue;\n\t }\n\t\n\t columnIdx = columnIdx | 0;\n\t var m = columns[columnIdx],\n\t node = cacheEntry.cellNodesByColumnIdx[columnIdx][0];\n\t\n\t if (row === activeRow && columnIdx === activeCell && currentEditor) {\n\t currentEditor.loadValue(d);\n\t } else if (d) {\n\t node.innerHTML = callFormatter(row, columnIdx, getDataItemValueForColumn(d, m), m, d);\n\t } else {\n\t node.innerHTML = \"\";\n\t }\n\t }\n\t\n\t invalidatePostProcessingResults(row);\n\t }\n\t\n\t function getViewportHeight() {\n\t if (options.autoHeight) {\n\t viewportH = options.rowHeight * getDataLengthIncludingAddNew() + (options.frozenColumn == -1 ? $headers.outerHeight() : 0);\n\t } else {\n\t topPanelH = options.showTopPanel ? options.topPanelHeight + getVBoxDelta($topPanelScroller) : 0;\n\t\n\t headerRowH = options.showHeaderRow ? options.headerRowHeight + getVBoxDelta($headerRowScroller) : 0;\n\t\n\t footerRowH = options.showFooterRow ? options.footerRowHeight + getVBoxDelta($footerRowScroller) : 0;\n\t\n\t viewportH = parseFloat(_jquery2.default.css($container[0], \"height\", true)) - parseFloat(_jquery2.default.css($container[0], \"paddingTop\", true)) - parseFloat(_jquery2.default.css($container[0], \"paddingBottom\", true)) - parseFloat(_jquery2.default.css($headerScroller[0], \"height\")) - getVBoxDelta($headerScroller) - topPanelH - headerRowH - footerRowH;\n\t }\n\t\n\t numVisibleRows = Math.ceil(viewportH / options.rowHeight);\n\t }\n\t\n\t function getViewportWidth() {\n\t viewportW = parseFloat(_jquery2.default.css($container[0], \"width\", true));\n\t }\n\t\n\t function resizeCanvas() {\n\t if (!initialized) {\n\t return;\n\t }\n\t\n\t paneTopH = 0;\n\t paneBottomH = 0;\n\t viewportTopH = 0;\n\t viewportBottomH = 0;\n\t\n\t getViewportWidth();\n\t getViewportHeight();\n\t\n\t // Account for Frozen Rows\n\t if (hasFrozenRows) {\n\t if (options.frozenBottom) {\n\t paneTopH = viewportH - frozenRowsHeight - scrollbarDimensions.height;\n\t\n\t paneBottomH = frozenRowsHeight + scrollbarDimensions.height;\n\t } else {\n\t paneTopH = frozenRowsHeight;\n\t paneBottomH = viewportH - frozenRowsHeight;\n\t }\n\t } else {\n\t paneTopH = viewportH;\n\t }\n\t\n\t // The top pane includes the top panel and the header row\n\t paneTopH += topPanelH + headerRowH + footerRowH;\n\t\n\t if (hasFrozenColumns() && options.autoHeight) {\n\t paneTopH += scrollbarDimensions.height;\n\t }\n\t\n\t // The top viewport does not contain the top panel or header row\n\t viewportTopH = paneTopH - topPanelH - headerRowH - footerRowH;\n\t\n\t if (options.autoHeight) {\n\t if (hasFrozenColumns()) {\n\t $container.height(paneTopH + parseFloat(_jquery2.default.css($headerScrollerL[0], \"height\")));\n\t }\n\t\n\t $paneTopL.css('position', 'relative');\n\t }\n\t\n\t $paneTopL.css({\n\t 'top': $paneHeaderL.height(),\n\t 'height': paneTopH\n\t });\n\t\n\t var paneBottomTop = $paneTopL.position().top + paneTopH;\n\t\n\t $viewportTopL.height(viewportTopH);\n\t\n\t if (hasFrozenColumns()) {\n\t $paneTopR.css({\n\t 'top': $paneHeaderL.height(),\n\t 'height': paneTopH\n\t });\n\t\n\t $viewportTopR.height(viewportTopH);\n\t\n\t if (hasFrozenRows) {\n\t $paneBottomL.css({\n\t 'top': paneBottomTop,\n\t 'height': paneBottomH\n\t });\n\t\n\t $paneBottomR.css({\n\t 'top': paneBottomTop,\n\t 'height': paneBottomH\n\t });\n\t\n\t $viewportBottomR.height(paneBottomH);\n\t }\n\t } else {\n\t if (hasFrozenRows) {\n\t $paneBottomL.css({\n\t 'width': '100%',\n\t 'height': paneBottomH\n\t });\n\t\n\t $paneBottomL.css('top', paneBottomTop);\n\t }\n\t }\n\t\n\t if (hasFrozenRows) {\n\t $viewportBottomL.height(paneBottomH);\n\t\n\t if (options.frozenBottom) {\n\t $canvasBottomL.height(frozenRowsHeight);\n\t\n\t if (hasFrozenColumns()) {\n\t $canvasBottomR.height(frozenRowsHeight);\n\t }\n\t } else {\n\t $canvasTopL.height(frozenRowsHeight);\n\t\n\t if (hasFrozenColumns()) {\n\t $canvasTopR.height(frozenRowsHeight);\n\t }\n\t }\n\t } else {\n\t $viewportTopR.height(viewportTopH);\n\t }\n\t\n\t if (options.forceFitColumns) {\n\t autosizeColumns();\n\t }\n\t\n\t updateRowCount();\n\t handleScroll();\n\t // Since the width has changed, force the render() to reevaluate virtually rendered cells.\n\t lastRenderedScrollLeft = -1;\n\t render();\n\t }\n\t\n\t function updateRowCount() {\n\t if (!initialized) {\n\t return;\n\t }\n\t\n\t var dataLengthIncludingAddNew = getDataLengthIncludingAddNew();\n\t var numberOfRows = 0;\n\t var oldH = hasFrozenRows && !options.frozenBottom ? $canvasBottomL.height() : $canvasTopL.height();\n\t\n\t if (hasFrozenRows) {\n\t var numberOfRows = getDataLength() - options.frozenRow;\n\t } else {\n\t var numberOfRows = dataLengthIncludingAddNew + (options.leaveSpaceForNewRows ? numVisibleRows - 1 : 0);\n\t }\n\t\n\t var tempViewportH = $viewportScrollContainerY.height();\n\t var oldViewportHasVScroll = viewportHasVScroll;\n\t // with autoHeight, we do not need to accommodate the vertical scroll bar\n\t viewportHasVScroll = !options.autoHeight && numberOfRows * options.rowHeight > tempViewportH;\n\t\n\t makeActiveCellNormal();\n\t\n\t // remove the rows that are now outside of the data range\n\t // this helps avoid redundant calls to .removeRow() when the size of the data decreased by thousands of rows\n\t var l = dataLengthIncludingAddNew - 1;\n\t for (var i in rowsCache) {\n\t if (i >= l) {\n\t removeRowFromCache(i);\n\t }\n\t }\n\t\n\t th = Math.max(options.rowHeight * numberOfRows, tempViewportH - scrollbarDimensions.height);\n\t\n\t if (activeCellNode && activeRow > l) {\n\t resetActiveCell();\n\t }\n\t\n\t if (th < maxSupportedCssHeight) {\n\t // just one page\n\t h = ph = th;\n\t n = 1;\n\t cj = 0;\n\t } else {\n\t // break into pages\n\t h = maxSupportedCssHeight;\n\t ph = h / 100;\n\t n = Math.floor(th / ph);\n\t cj = (th - h) / (n - 1);\n\t }\n\t\n\t if (h !== oldH) {\n\t if (hasFrozenRows && !options.frozenBottom) {\n\t $canvasBottomL.css(\"height\", h);\n\t\n\t if (hasFrozenColumns()) {\n\t $canvasBottomR.css(\"height\", h);\n\t }\n\t } else {\n\t $canvasTopL.css(\"height\", h);\n\t $canvasTopR.css(\"height\", h);\n\t }\n\t\n\t scrollTop = $viewportScrollContainerY[0].scrollTop;\n\t }\n\t\n\t var oldScrollTopInRange = scrollTop + offset <= th - tempViewportH;\n\t\n\t if (th == 0 || scrollTop == 0) {\n\t page = offset = 0;\n\t } else if (oldScrollTopInRange) {\n\t // maintain virtual position\n\t scrollTo(scrollTop + offset);\n\t } else {\n\t // scroll to bottom\n\t scrollTo(th - tempViewportH);\n\t }\n\t\n\t if (h != oldH && options.autoHeight) {\n\t resizeCanvas();\n\t }\n\t\n\t if (options.forceFitColumns && oldViewportHasVScroll != viewportHasVScroll) {\n\t autosizeColumns();\n\t }\n\t updateCanvasWidth(false);\n\t }\n\t\n\t function getVisibleRange(viewportTop, viewportLeft) {\n\t if (viewportTop == null) {\n\t viewportTop = scrollTop;\n\t }\n\t if (viewportLeft == null) {\n\t viewportLeft = scrollLeft;\n\t }\n\t\n\t return {\n\t top: getRowFromPosition(viewportTop),\n\t bottom: getRowFromPosition(viewportTop + viewportH) + 1,\n\t leftPx: viewportLeft,\n\t rightPx: viewportLeft + viewportW\n\t };\n\t }\n\t\n\t function getRenderedRange(viewportTop, viewportLeft) {\n\t var range = getVisibleRange(viewportTop, viewportLeft);\n\t var buffer = Math.round(viewportH / options.rowHeight);\n\t var minBuffer = 3;\n\t\n\t if (vScrollDir == -1) {\n\t range.top -= buffer;\n\t range.bottom += minBuffer;\n\t } else if (vScrollDir == 1) {\n\t range.top -= minBuffer;\n\t range.bottom += buffer;\n\t } else {\n\t range.top -= minBuffer;\n\t range.bottom += minBuffer;\n\t }\n\t\n\t range.top = Math.max(0, range.top);\n\t range.bottom = Math.min(getDataLengthIncludingAddNew() - 1, range.bottom);\n\t\n\t range.leftPx -= viewportW;\n\t range.rightPx += viewportW;\n\t\n\t range.leftPx = Math.max(0, range.leftPx);\n\t range.rightPx = Math.min(canvasWidth, range.rightPx);\n\t\n\t return range;\n\t }\n\t\n\t function ensureCellNodesInRowsCache(row) {\n\t var cacheEntry = rowsCache[row];\n\t if (cacheEntry) {\n\t if (cacheEntry.cellRenderQueue.length) {\n\t var $lastNode = cacheEntry.rowNode.children().last();\n\t while (cacheEntry.cellRenderQueue.length) {\n\t var columnIdx = cacheEntry.cellRenderQueue.pop();\n\t\n\t cacheEntry.cellNodesByColumnIdx[columnIdx] = $lastNode;\n\t $lastNode = $lastNode.prev();\n\t\n\t // Hack to retrieve the frozen columns because\n\t if ($lastNode.length == 0) {\n\t $lastNode = (0, _jquery2.default)(cacheEntry.rowNode[0]).children().last();\n\t }\n\t }\n\t }\n\t }\n\t }\n\t\n\t function cleanUpCells(range, row) {\n\t // Ignore frozen rows\n\t if (hasFrozenRows && (options.frozenBottom && row > actualFrozenRow || // Frozen bottom rows\n\t row <= actualFrozenRow // Frozen top rows\n\t )) {\n\t return;\n\t }\n\t\n\t var totalCellsRemoved = 0;\n\t var cacheEntry = rowsCache[row];\n\t\n\t // Remove cells outside the range.\n\t var cellsToRemove = [];\n\t for (var i in cacheEntry.cellNodesByColumnIdx) {\n\t // I really hate it when people mess with Array.prototype.\n\t if (!cacheEntry.cellNodesByColumnIdx.hasOwnProperty(i)) {\n\t continue;\n\t }\n\t\n\t // This is a string, so it needs to be cast back to a number.\n\t i = i | 0;\n\t\n\t // Ignore frozen columns\n\t if (i <= options.frozenColumn) {\n\t continue;\n\t }\n\t\n\t var colspan = cacheEntry.cellColSpans[i];\n\t if (columnPosLeft[i] > range.rightPx || columnPosRight[Math.min(columns.length - 1, i + colspan - 1)] < range.leftPx) {\n\t if (!(row == activeRow && i == activeCell)) {\n\t cellsToRemove.push(i);\n\t }\n\t }\n\t }\n\t\n\t var cellToRemove;\n\t while ((cellToRemove = cellsToRemove.pop()) != null) {\n\t cacheEntry.cellNodesByColumnIdx[cellToRemove][0].parentElement.removeChild(cacheEntry.cellNodesByColumnIdx[cellToRemove][0]);\n\t delete cacheEntry.cellColSpans[cellToRemove];\n\t delete cacheEntry.cellNodesByColumnIdx[cellToRemove];\n\t if (postProcessedRows[row]) {\n\t delete postProcessedRows[row][cellToRemove];\n\t }\n\t totalCellsRemoved++;\n\t }\n\t }\n\t\n\t function cleanUpAndRenderCells(range) {\n\t var cacheEntry;\n\t var stringArray = [];\n\t var processedRows = [];\n\t var cellsAdded;\n\t var totalCellsAdded = 0;\n\t var colspan;\n\t\n\t for (var row = range.top, btm = range.bottom; row <= btm; row++) {\n\t cacheEntry = rowsCache[row];\n\t if (!cacheEntry) {\n\t continue;\n\t }\n\t\n\t // cellRenderQueue populated in renderRows() needs to be cleared first\n\t ensureCellNodesInRowsCache(row);\n\t\n\t cleanUpCells(range, row);\n\t\n\t // Render missing cells.\n\t cellsAdded = 0;\n\t\n\t var metadata = data.getItemMetadata && data.getItemMetadata(row);\n\t metadata = metadata && metadata.columns;\n\t\n\t var d = getDataItem(row);\n\t\n\t // TODO: shorten this loop (index? heuristics? binary search?)\n\t for (var i = 0, ii = columns.length; i < ii; i++) {\n\t // Cells to the right are outside the range.\n\t if (columnPosLeft[i] > range.rightPx) {\n\t break;\n\t }\n\t\n\t // Already rendered.\n\t if ((colspan = cacheEntry.cellColSpans[i]) != null) {\n\t i += colspan > 1 ? colspan - 1 : 0;\n\t continue;\n\t }\n\t\n\t colspan = 1;\n\t if (metadata) {\n\t var columnData = metadata[columns[i].id] || metadata[i];\n\t colspan = columnData && columnData.colspan || 1;\n\t if (colspan === \"*\") {\n\t colspan = ii - i;\n\t }\n\t }\n\t\n\t if (columnPosRight[Math.min(ii - 1, i + colspan - 1)] > range.leftPx) {\n\t appendCellHtml(stringArray, row, i, colspan, d);\n\t cellsAdded++;\n\t }\n\t\n\t i += colspan > 1 ? colspan - 1 : 0;\n\t }\n\t\n\t if (cellsAdded) {\n\t totalCellsAdded += cellsAdded;\n\t processedRows.push(row);\n\t }\n\t }\n\t\n\t if (!stringArray.length) {\n\t return;\n\t }\n\t\n\t var x = document.createElement(\"div\");\n\t x.innerHTML = stringArray.join(\"\");\n\t\n\t var processedRow;\n\t var $node;\n\t while ((processedRow = processedRows.pop()) != null) {\n\t cacheEntry = rowsCache[processedRow];\n\t var columnIdx;\n\t while ((columnIdx = cacheEntry.cellRenderQueue.pop()) != null) {\n\t $node = (0, _jquery2.default)(x).children().last();\n\t\n\t if (hasFrozenColumns() && columnIdx > options.frozenColumn) {\n\t (0, _jquery2.default)(cacheEntry.rowNode[1]).append($node);\n\t } else {\n\t (0, _jquery2.default)(cacheEntry.rowNode[0]).append($node);\n\t }\n\t\n\t cacheEntry.cellNodesByColumnIdx[columnIdx] = $node;\n\t }\n\t }\n\t }\n\t\n\t function renderRows(range) {\n\t var stringArrayL = [],\n\t stringArrayR = [],\n\t rows = [],\n\t needToReselectCell = false,\n\t dataLength = getDataLength();\n\t\n\t for (var i = range.top, ii = range.bottom; i <= ii; i++) {\n\t if (rowsCache[i] || hasFrozenRows && options.frozenBottom && i == getDataLength()) {\n\t continue;\n\t }\n\t renderedRows++;\n\t rows.push(i);\n\t\n\t // Create an entry right away so that appendRowHtml() can\n\t // start populatating it.\n\t rowsCache[i] = {\n\t \"rowNode\": null,\n\t\n\t // ColSpans of rendered cells (by column idx).\n\t // Can also be used for checking whether a cell has been rendered.\n\t \"cellColSpans\": [],\n\t\n\t // Cell nodes (by column idx). Lazy-populated by ensureCellNodesInRowsCache().\n\t \"cellNodesByColumnIdx\": [],\n\t\n\t // Column indices of cell nodes that have been rendered, but not yet indexed in\n\t // cellNodesByColumnIdx. These are in the same order as cell nodes added at the\n\t // end of the row.\n\t \"cellRenderQueue\": []\n\t };\n\t\n\t appendRowHtml(stringArrayL, stringArrayR, i, range, dataLength);\n\t if (activeCellNode && activeRow === i) {\n\t needToReselectCell = true;\n\t }\n\t counter_rows_rendered++;\n\t }\n\t\n\t if (!rows.length) {\n\t return;\n\t }\n\t\n\t var x = document.createElement(\"div\"),\n\t xRight = document.createElement(\"div\");\n\t\n\t x.innerHTML = stringArrayL.join(\"\");\n\t xRight.innerHTML = stringArrayR.join(\"\");\n\t\n\t for (var i = 0, ii = rows.length; i < ii; i++) {\n\t if (hasFrozenRows && rows[i] >= actualFrozenRow) {\n\t if (hasFrozenColumns()) {\n\t rowsCache[rows[i]].rowNode = (0, _jquery2.default)().add((0, _jquery2.default)(x.firstChild).appendTo($canvasBottomL)).add((0, _jquery2.default)(xRight.firstChild).appendTo($canvasBottomR));\n\t } else {\n\t rowsCache[rows[i]].rowNode = (0, _jquery2.default)().add((0, _jquery2.default)(x.firstChild).appendTo($canvasBottomL));\n\t }\n\t } else if (hasFrozenColumns()) {\n\t rowsCache[rows[i]].rowNode = (0, _jquery2.default)().add((0, _jquery2.default)(x.firstChild).appendTo($canvasTopL)).add((0, _jquery2.default)(xRight.firstChild).appendTo($canvasTopR));\n\t } else {\n\t rowsCache[rows[i]].rowNode = (0, _jquery2.default)().add((0, _jquery2.default)(x.firstChild).appendTo($canvasTopL));\n\t }\n\t }\n\t\n\t if (needToReselectCell) {\n\t activeCellNode = getCellNode(activeRow, activeCell);\n\t }\n\t }\n\t\n\t function startPostProcessing() {\n\t if (!options.enableAsyncPostRender) {\n\t return;\n\t }\n\t clearTimeout(h_postrender);\n\t h_postrender = setTimeout(asyncPostProcessRows, options.asyncPostRenderDelay);\n\t }\n\t\n\t function invalidatePostProcessingResults(row) {\n\t delete postProcessedRows[row];\n\t postProcessFromRow = Math.min(postProcessFromRow, row);\n\t postProcessToRow = Math.max(postProcessToRow, row);\n\t startPostProcessing();\n\t }\n\t\n\t function updateRowPositions() {\n\t for (var row in rowsCache) {\n\t rowsCache[row].rowNode.css('top', getRowTop(row) + \"px\");\n\t }\n\t }\n\t\n\t function render() {\n\t if (!initialized) {\n\t return;\n\t }\n\t var visible = getVisibleRange();\n\t var rendered = getRenderedRange();\n\t\n\t // remove rows no longer in the viewport\n\t cleanupRows(rendered);\n\t\n\t // add new rows & missing cells in existing rows\n\t if (lastRenderedScrollLeft != scrollLeft) {\n\t\n\t if (hasFrozenRows) {\n\t\n\t var renderedFrozenRows = _jquery2.default.extend(true, {}, rendered);\n\t\n\t if (options.frozenBottom) {\n\t\n\t renderedFrozenRows.top = actualFrozenRow;\n\t renderedFrozenRows.bottom = getDataLength();\n\t } else {\n\t\n\t renderedFrozenRows.top = 0;\n\t renderedFrozenRows.bottom = options.frozenRow;\n\t }\n\t\n\t cleanUpAndRenderCells(renderedFrozenRows);\n\t }\n\t\n\t cleanUpAndRenderCells(rendered);\n\t }\n\t\n\t // render missing rows\n\t renderRows(rendered);\n\t\n\t // Render frozen rows\n\t if (hasFrozenRows) {\n\t if (options.frozenBottom) {\n\t renderRows({\n\t top: actualFrozenRow,\n\t bottom: getDataLength() - 1,\n\t leftPx: rendered.leftPx,\n\t rightPx: rendered.rightPx\n\t });\n\t } else {\n\t renderRows({\n\t top: 0,\n\t bottom: options.frozenRow - 1,\n\t leftPx: rendered.leftPx,\n\t rightPx: rendered.rightPx\n\t });\n\t }\n\t }\n\t\n\t postProcessFromRow = visible.top;\n\t postProcessToRow = Math.min(getDataLengthIncludingAddNew() - 1, visible.bottom);\n\t startPostProcessing();\n\t\n\t lastRenderedScrollTop = scrollTop;\n\t lastRenderedScrollLeft = scrollLeft;\n\t h_render = null;\n\t }\n\t\n\t function handleHeaderRowScroll() {\n\t var scrollLeft = $headerRowScrollContainer[0].scrollLeft;\n\t if (scrollLeft != $viewportScrollContainerX[0].scrollLeft) {\n\t $viewportScrollContainerX[0].scrollLeft = scrollLeft;\n\t }\n\t }\n\t\n\t function handleFooterRowScroll() {\n\t var scrollLeft = $footerRowScrollContainer[0].scrollLeft;\n\t if (scrollLeft != $viewportScrollContainerX[0].scrollLeft) {\n\t $viewportScrollContainerX[0].scrollLeft = scrollLeft;\n\t }\n\t }\n\t\n\t function handleMouseWheel(e, delta, deltaX, deltaY) {\n\t var $rowNode = (0, _jquery2.default)(e.target).closest(\".slick-row\");\n\t var rowNode = $rowNode[0];\n\t\n\t if (rowNode != rowNodeFromLastMouseWheelEvent) {\n\t\n\t var $gridCanvas = $rowNode.parents('.grid-canvas');\n\t var left = $gridCanvas.hasClass('grid-canvas-left');\n\t\n\t if (zombieRowNodeFromLastMouseWheelEvent && zombieRowNodeFromLastMouseWheelEvent[left ? 0 : 1] != rowNode) {\n\t var zombieRow = zombieRowNodeFromLastMouseWheelEvent[left || zombieRowNodeFromLastMouseWheelEvent.length == 1 ? 0 : 1];\n\t zombieRow.parentElement.removeChild(zombieRow);\n\t\n\t zombieRowNodeFromLastMouseWheelEvent = null;\n\t }\n\t\n\t rowNodeFromLastMouseWheelEvent = rowNode;\n\t }\n\t\n\t scrollTop = Math.max(0, $viewportScrollContainerY[0].scrollTop - deltaY * options.rowHeight);\n\t scrollLeft = $viewportScrollContainerX[0].scrollLeft + deltaX * 10;\n\t var handled = _handleScroll(true);\n\t if (handled) e.preventDefault();\n\t }\n\t\n\t function handleScroll() {\n\t scrollTop = $viewportScrollContainerY[0].scrollTop;\n\t scrollLeft = $viewportScrollContainerX[0].scrollLeft;\n\t return _handleScroll(false);\n\t }\n\t\n\t function _handleScroll(isMouseWheel) {\n\t var maxScrollDistanceY = $viewportScrollContainerY[0].scrollHeight - $viewportScrollContainerY[0].clientHeight;\n\t var maxScrollDistanceX = $viewportScrollContainerY[0].scrollWidth - $viewportScrollContainerY[0].clientWidth;\n\t var hasFrozenCols = hasFrozenColumns();\n\t\n\t // Ceiling the max scroll values\n\t if (scrollTop > maxScrollDistanceY) {\n\t scrollTop = maxScrollDistanceY;\n\t }\n\t if (scrollLeft > maxScrollDistanceX) {\n\t scrollLeft = maxScrollDistanceX;\n\t }\n\t\n\t var vScrollDist = Math.abs(scrollTop - prevScrollTop);\n\t var hScrollDist = Math.abs(scrollLeft - prevScrollLeft);\n\t\n\t if (hScrollDist) {\n\t prevScrollLeft = scrollLeft;\n\t\n\t $viewportScrollContainerX[0].scrollLeft = scrollLeft;\n\t $headerScrollContainer[0].scrollLeft = scrollLeft;\n\t $topPanelScroller[0].scrollLeft = scrollLeft;\n\t $headerRowScrollContainer[0].scrollLeft = scrollLeft;\n\t $footerRowScrollContainer[0].scrollLeft = scrollLeft;\n\t\n\t if (hasFrozenCols) {\n\t if (hasFrozenRows) {\n\t $viewportTopR[0].scrollLeft = scrollLeft;\n\t }\n\t } else {\n\t if (hasFrozenRows) {\n\t $viewportTopL[0].scrollLeft = scrollLeft;\n\t }\n\t }\n\t }\n\t\n\t if (vScrollDist) {\n\t vScrollDir = prevScrollTop < scrollTop ? 1 : -1;\n\t prevScrollTop = scrollTop;\n\t\n\t if (isMouseWheel) {\n\t $viewportScrollContainerY[0].scrollTop = scrollTop;\n\t }\n\t\n\t if (hasFrozenCols) {\n\t if (hasFrozenRows && !options.frozenBottom) {\n\t $viewportBottomL[0].scrollTop = scrollTop;\n\t } else {\n\t $viewportTopL[0].scrollTop = scrollTop;\n\t }\n\t }\n\t\n\t // switch virtual pages if needed\n\t if (vScrollDist < viewportH) {\n\t scrollTo(scrollTop + offset);\n\t } else {\n\t var oldOffset = offset;\n\t if (h == viewportH) {\n\t page = 0;\n\t } else {\n\t page = Math.min(n - 1, Math.floor(scrollTop * ((th - viewportH) / (h - viewportH)) * (1 / ph)));\n\t }\n\t offset = Math.round(page * cj);\n\t if (oldOffset != offset) {\n\t invalidateAllRows();\n\t }\n\t }\n\t }\n\t\n\t if (hScrollDist || vScrollDist) {\n\t if (h_render) {\n\t clearTimeout(h_render);\n\t }\n\t\n\t if (Math.abs(lastRenderedScrollTop - scrollTop) > 20 || Math.abs(lastRenderedScrollLeft - scrollLeft) > 20) {\n\t if (options.forceSyncScrolling || Math.abs(lastRenderedScrollTop - scrollTop) < viewportH && Math.abs(lastRenderedScrollLeft - scrollLeft) < viewportW) {\n\t render();\n\t } else {\n\t h_render = setTimeout(render, 50);\n\t }\n\t\n\t trigger(self.onViewportChanged, {});\n\t }\n\t }\n\t\n\t trigger(self.onScroll, {\n\t scrollLeft: scrollLeft,\n\t scrollTop: scrollTop\n\t });\n\t\n\t if (hScrollDist || vScrollDist) return true;\n\t return false;\n\t }\n\t\n\t function asyncPostProcessRows() {\n\t var dataLength = getDataLength();\n\t while (postProcessFromRow <= postProcessToRow) {\n\t var row = vScrollDir >= 0 ? postProcessFromRow++ : postProcessToRow--;\n\t var cacheEntry = rowsCache[row];\n\t if (!cacheEntry || row >= dataLength) {\n\t continue;\n\t }\n\t\n\t if (!postProcessedRows[row]) {\n\t postProcessedRows[row] = {};\n\t }\n\t\n\t ensureCellNodesInRowsCache(row);\n\t for (var columnIdx in cacheEntry.cellNodesByColumnIdx) {\n\t if (!cacheEntry.cellNodesByColumnIdx.hasOwnProperty(columnIdx)) {\n\t continue;\n\t }\n\t\n\t columnIdx = columnIdx | 0;\n\t\n\t var m = columns[columnIdx];\n\t if (m.asyncPostRender && !postProcessedRows[row][columnIdx]) {\n\t var node = cacheEntry.cellNodesByColumnIdx[columnIdx];\n\t if (node) {\n\t m.asyncPostRender(node, row, getDataItem(row), m);\n\t }\n\t postProcessedRows[row][columnIdx] = true;\n\t }\n\t }\n\t\n\t h_postrender = setTimeout(asyncPostProcessRows, options.asyncPostRenderDelay);\n\t return;\n\t }\n\t }\n\t\n\t function updateCellCssStylesOnRenderedRows(addedHash, removedHash) {\n\t var node, columnId, addedRowHash, removedRowHash;\n\t for (var row in rowsCache) {\n\t removedRowHash = removedHash && removedHash[row];\n\t addedRowHash = addedHash && addedHash[row];\n\t\n\t if (removedRowHash) {\n\t for (columnId in removedRowHash) {\n\t if (!addedRowHash || removedRowHash[columnId] != addedRowHash[columnId]) {\n\t node = getCellNode(row, getColumnIndex(columnId));\n\t if (node) {\n\t (0, _jquery2.default)(node).removeClass(removedRowHash[columnId]);\n\t }\n\t }\n\t }\n\t }\n\t\n\t if (addedRowHash) {\n\t for (columnId in addedRowHash) {\n\t if (!removedRowHash || removedRowHash[columnId] != addedRowHash[columnId]) {\n\t node = getCellNode(row, getColumnIndex(columnId));\n\t if (node) {\n\t (0, _jquery2.default)(node).addClass(addedRowHash[columnId]);\n\t }\n\t }\n\t }\n\t }\n\t }\n\t }\n\t\n\t function addCellCssStyles(key, hash) {\n\t if (cellCssClasses[key]) {\n\t throw \"addCellCssStyles: cell CSS hash with key '\" + key + \"' already exists.\";\n\t }\n\t\n\t cellCssClasses[key] = hash;\n\t updateCellCssStylesOnRenderedRows(hash, null);\n\t\n\t trigger(self.onCellCssStylesChanged, {\n\t \"key\": key,\n\t \"hash\": hash\n\t });\n\t }\n\t\n\t function removeCellCssStyles(key) {\n\t if (!cellCssClasses[key]) {\n\t return;\n\t }\n\t\n\t updateCellCssStylesOnRenderedRows(null, cellCssClasses[key]);\n\t delete cellCssClasses[key];\n\t\n\t trigger(self.onCellCssStylesChanged, {\n\t \"key\": key,\n\t \"hash\": null\n\t });\n\t }\n\t\n\t function setCellCssStyles(key, hash) {\n\t var prevHash = cellCssClasses[key];\n\t\n\t cellCssClasses[key] = hash;\n\t updateCellCssStylesOnRenderedRows(hash, prevHash);\n\t\n\t trigger(self.onCellCssStylesChanged, {\n\t \"key\": key,\n\t \"hash\": hash\n\t });\n\t }\n\t\n\t function getCellCssStyles(key) {\n\t return cellCssClasses[key];\n\t }\n\t\n\t function flashCell(row, cell, speed) {\n\t speed = speed || 100;\n\t if (rowsCache[row]) {\n\t var toggleCellClass = function toggleCellClass(times) {\n\t if (!times) {\n\t return;\n\t }\n\t setTimeout(function () {\n\t $cell.queue(function () {\n\t $cell.toggleClass(options.cellFlashingCssClass).dequeue();\n\t toggleCellClass(times - 1);\n\t });\n\t }, speed);\n\t };\n\t\n\t var $cell = (0, _jquery2.default)(getCellNode(row, cell));\n\t\n\t toggleCellClass(4);\n\t }\n\t }\n\t\n\t //////////////////////////////////////////////////////////////////////////////////////////////\n\t // Interactivity\n\t\n\t function handleDragInit(e, dd) {\n\t var cell = getCellFromEvent(e);\n\t if (!cell || !cellExists(cell.row, cell.cell)) {\n\t return false;\n\t }\n\t\n\t var retval = trigger(self.onDragInit, dd, e);\n\t if (e.isImmediatePropagationStopped()) {\n\t return retval;\n\t }\n\t\n\t // if nobody claims to be handling drag'n'drop by stopping immediate propagation,\n\t // cancel out of it\n\t return false;\n\t }\n\t\n\t function handleDragStart(interactEvent) {\n\t var event = _jquery2.default.Event(interactEvent.originalEvent.type, interactEvent.originalEvent);\n\t var cell = getCellFromEvent(event);\n\t if (!cell || !cellExists(cell.row, cell.cell)) {\n\t return false;\n\t }\n\t\n\t var retval = trigger(self.onDragStart, interactEvent, event);\n\t if (event.isImmediatePropagationStopped()) {\n\t return retval;\n\t }\n\t\n\t return false;\n\t }\n\t\n\t function handleDrag(interactEvent) {\n\t var event = _jquery2.default.Event(interactEvent.originalEvent.type, interactEvent.originalEvent);\n\t return trigger(self.onDrag, interactEvent, event);\n\t }\n\t\n\t function handleDragEnd(interactEvent) {\n\t trigger(self.onDragEnd, interactEvent, _jquery2.default.Event('mousedown'));\n\t }\n\t\n\t function handleKeyDown(e) {\n\t trigger(self.onKeyDown, {\n\t row: activeRow,\n\t cell: activeCell\n\t }, e);\n\t var handled = e.isImmediatePropagationStopped();\n\t\n\t if (!handled) {\n\t if (!e.shiftKey && !e.altKey && !e.ctrlKey) {\n\t if (e.which == 27) {\n\t if (!getEditorLock().isActive()) {\n\t return; // no editing mode to cancel, allow bubbling and default processing (exit without cancelling the event)\n\t }\n\t cancelEditAndSetFocus();\n\t } else if (e.which == 34) {\n\t navigatePageDown();\n\t handled = true;\n\t } else if (e.which == 33) {\n\t navigatePageUp();\n\t handled = true;\n\t } else if (e.which == 37) {\n\t handled = navigateLeft();\n\t } else if (e.which == 39) {\n\t handled = navigateRight();\n\t } else if (e.which == 38) {\n\t handled = navigateUp();\n\t } else if (e.which == 40) {\n\t handled = navigateDown();\n\t } else if (e.which == 9) {\n\t handled = navigateNext();\n\t } else if (e.which == 13) {\n\t if (options.editable) {\n\t if (currentEditor) {\n\t // adding new row\n\t if (activeRow === getDataLength()) {\n\t navigateDown();\n\t } else {\n\t commitEditAndSetFocus();\n\t }\n\t } else {\n\t if (getEditorLock().commitCurrentEdit()) {\n\t makeActiveCellEditable();\n\t }\n\t }\n\t }\n\t handled = true;\n\t }\n\t } else if (e.which == 9 && e.shiftKey && !e.ctrlKey && !e.altKey) {\n\t handled = navigatePrev();\n\t }\n\t }\n\t\n\t if (handled) {\n\t // the event has been handled so don't let parent element (bubbling/propagation) or browser (default) handle it\n\t e.stopPropagation();\n\t e.preventDefault();\n\t try {\n\t e.originalEvent.keyCode = 0; // prevent default behaviour for special keys in IE browsers (F3, F5, etc.)\n\t }\n\t // ignore exceptions - setting the original event's keycode throws access denied exception for \"Ctrl\"\n\t // (hitting control key only, nothing else), \"Shift\" (maybe others)\n\t catch (error) {}\n\t }\n\t }\n\t\n\t function handleClick(e) {\n\t if (!currentEditor) {\n\t // if this click resulted in some cell child node getting focus,\n\t // don't steal it back - keyboard events will still bubble up\n\t // IE9+ seems to default DIVs to tabIndex=0 instead of -1, so check for cell clicks directly.\n\t if (e.target != document.activeElement || (0, _jquery2.default)(e.target).hasClass(\"slick-cell\")) {\n\t setFocus();\n\t }\n\t }\n\t\n\t var cell = getCellFromEvent(e);\n\t if (!cell || currentEditor !== null && activeRow == cell.row && activeCell == cell.cell) {\n\t return;\n\t }\n\t\n\t trigger(self.onClick, {\n\t row: cell.row,\n\t cell: cell.cell\n\t }, e);\n\t if (e.isImmediatePropagationStopped()) {\n\t return;\n\t }\n\t\n\t if ((activeCell != cell.cell || activeRow != cell.row) && canCellBeActive(cell.row, cell.cell)) {\n\t if (!getEditorLock().isActive() || getEditorLock().commitCurrentEdit()) {\n\t\n\t scrollRowIntoView(cell.row, false);\n\t setActiveCellInternal(getCellNode(cell.row, cell.cell));\n\t }\n\t }\n\t }\n\t\n\t function handleContextMenu(e) {\n\t var $cell = (0, _jquery2.default)(e.target).closest(\".slick-cell\", $canvas);\n\t if ($cell.length === 0) {\n\t return;\n\t }\n\t\n\t // are we editing this cell?\n\t if (activeCellNode === $cell[0] && currentEditor !== null) {\n\t return;\n\t }\n\t\n\t trigger(self.onContextMenu, {}, e);\n\t }\n\t\n\t function handleDblClick(e) {\n\t var cell = getCellFromEvent(e);\n\t if (!cell || currentEditor !== null && activeRow == cell.row && activeCell == cell.cell) {\n\t return;\n\t }\n\t\n\t trigger(self.onDblClick, {\n\t row: cell.row,\n\t cell: cell.cell\n\t }, e);\n\t if (e.isImmediatePropagationStopped()) {\n\t return;\n\t }\n\t\n\t if (options.editable) {\n\t gotoCell(cell.row, cell.cell, true);\n\t }\n\t }\n\t\n\t function handleHeaderMouseEnter(e) {\n\t trigger(self.onHeaderMouseEnter, {\n\t \"column\": (0, _jquery2.default)(this).data(\"column\")\n\t }, e);\n\t }\n\t\n\t function handleHeaderMouseLeave(e) {\n\t trigger(self.onHeaderMouseLeave, {\n\t \"column\": (0, _jquery2.default)(this).data(\"column\")\n\t }, e);\n\t }\n\t\n\t function handleHeaderContextMenu(e) {\n\t var $header = (0, _jquery2.default)(e.target).closest(\".slick-header-column\", \".slick-header-columns\");\n\t var column = $header && $header.data(\"column\");\n\t trigger(self.onHeaderContextMenu, {\n\t column: column\n\t }, e);\n\t }\n\t\n\t function handleHeaderClick(e) {\n\t var $header = (0, _jquery2.default)(e.target).closest(\".slick-header-column\", \".slick-header-columns\");\n\t var column = $header && $header.data(\"column\");\n\t if (column) {\n\t trigger(self.onHeaderClick, {\n\t column: column\n\t }, e);\n\t }\n\t }\n\t\n\t function handleMouseEnter(e) {\n\t trigger(self.onMouseEnter, {}, e);\n\t }\n\t\n\t function handleMouseLeave(e) {\n\t trigger(self.onMouseLeave, {}, e);\n\t }\n\t\n\t function cellExists(row, cell) {\n\t return !(row < 0 || row >= getDataLength() || cell < 0 || cell >= columns.length);\n\t }\n\t\n\t function getCellFromPoint(x, y) {\n\t var row = getRowFromPosition(y);\n\t var cell = 0;\n\t\n\t var w = 0;\n\t for (var i = 0; i < columns.length && w < x; i++) {\n\t w += columns[i].width;\n\t cell++;\n\t }\n\t\n\t if (cell < 0) {\n\t cell = 0;\n\t }\n\t\n\t return {\n\t row: row,\n\t cell: cell - 1\n\t };\n\t }\n\t\n\t function getCellFromNode(cellNode) {\n\t // read column number from .l CSS class\n\t var cls = /l\\d+/.exec(cellNode.className);\n\t if (!cls) {\n\t throw \"getCellFromNode: cannot get cell - \" + cellNode.className;\n\t }\n\t return parseInt(cls[0].substr(1, cls[0].length - 1), 10);\n\t }\n\t\n\t function getRowFromNode(rowNode) {\n\t for (var row in rowsCache) {\n\t for (var i in rowsCache[row].rowNode) {\n\t if (rowsCache[row].rowNode[i] === rowNode) return row | 0;\n\t }\n\t }return null;\n\t }\n\t\n\t function getFrozenRowOffset(row) {\n\t var offset = hasFrozenRows ? options.frozenBottom ? row >= actualFrozenRow ? h < viewportTopH ? actualFrozenRow * options.rowHeight : h : 0 : row >= actualFrozenRow ? frozenRowsHeight : 0 : 0;\n\t\n\t return offset;\n\t }\n\t\n\t function getCellFromEvent(e) {\n\t var row, cell;\n\t var $cell = (0, _jquery2.default)(e.target).closest(\".slick-cell\", $canvas);\n\t if (!$cell.length) {\n\t return null;\n\t }\n\t\n\t row = getRowFromNode($cell[0].parentNode);\n\t\n\t if (hasFrozenRows) {\n\t\n\t var c = $cell.parents('.grid-canvas').offset();\n\t\n\t var rowOffset = 0;\n\t var isBottom = $cell.parents('.grid-canvas-bottom').length;\n\t\n\t if (isBottom) {\n\t rowOffset = options.frozenBottom ? $canvasTopL.height() : frozenRowsHeight;\n\t }\n\t\n\t row = getCellFromPoint(e.clientX - c.left, e.clientY - c.top + rowOffset + (0, _jquery2.default)(document).scrollTop()).row;\n\t }\n\t\n\t cell = getCellFromNode($cell[0]);\n\t\n\t if (row == null || cell == null) {\n\t return null;\n\t } else {\n\t return {\n\t \"row\": row,\n\t \"cell\": cell\n\t };\n\t }\n\t }\n\t\n\t function getCellNodeBox(row, cell) {\n\t if (!cellExists(row, cell)) {\n\t return null;\n\t }\n\t\n\t var frozenRowOffset = getFrozenRowOffset(row);\n\t\n\t var y1 = getRowTop(row) - frozenRowOffset;\n\t var y2 = y1 + options.rowHeight - 1;\n\t var x1 = 0;\n\t for (var i = 0; i < cell; i++) {\n\t x1 += columns[i].width;\n\t\n\t if (options.frozenColumn == i) {\n\t x1 = 0;\n\t }\n\t }\n\t var x2 = x1 + columns[cell].width;\n\t\n\t return {\n\t top: y1,\n\t left: x1,\n\t bottom: y2,\n\t right: x2\n\t };\n\t }\n\t\n\t //////////////////////////////////////////////////////////////////////////////////////////////\n\t // Cell switching\n\t\n\t function resetActiveCell() {\n\t setActiveCellInternal(null, false);\n\t }\n\t\n\t function setFocus() {\n\t if (tabbingDirection == -1) {\n\t $focusSink[0].focus();\n\t } else {\n\t $focusSink2[0].focus();\n\t }\n\t }\n\t\n\t function scrollCellIntoView(row, cell, doPaging) {\n\t // Don't scroll to frozen cells\n\t if (cell <= options.frozenColumn) {\n\t return;\n\t }\n\t\n\t if (row < actualFrozenRow) {\n\t scrollRowIntoView(row, doPaging);\n\t }\n\t\n\t var colspan = getColspan(row, cell);\n\t var left = columnPosLeft[cell],\n\t right = columnPosRight[cell + (colspan > 1 ? colspan - 1 : 0)],\n\t scrollRight = scrollLeft + $viewportScrollContainerX.width();\n\t\n\t if (left < scrollLeft) {\n\t $viewportScrollContainerX.scrollLeft(left);\n\t handleScroll();\n\t render();\n\t } else if (right > scrollRight) {\n\t $viewportScrollContainerX.scrollLeft(Math.min(left, right - $viewportScrollContainerX[0].clientWidth));\n\t handleScroll();\n\t render();\n\t }\n\t }\n\t\n\t function setActiveCellInternal(newCell, opt_editMode) {\n\t if (activeCellNode !== null) {\n\t makeActiveCellNormal();\n\t (0, _jquery2.default)(activeCellNode).removeClass(\"active\");\n\t if (rowsCache[activeRow]) {\n\t (0, _jquery2.default)(rowsCache[activeRow].rowNode).removeClass(\"active\");\n\t }\n\t }\n\t\n\t var activeCellChanged = activeCellNode !== newCell;\n\t activeCellNode = newCell;\n\t\n\t if (activeCellNode != null) {\n\t var $activeCellNode = (0, _jquery2.default)(activeCellNode);\n\t var $activeCellOffset = $activeCellNode.offset();\n\t\n\t var rowOffset = Math.floor($activeCellNode.parents('.grid-canvas').offset().top);\n\t var isBottom = $activeCellNode.parents('.grid-canvas-bottom').length;\n\t\n\t if (hasFrozenRows && isBottom) {\n\t rowOffset -= options.frozenBottom ? $canvasTopL.height() : frozenRowsHeight;\n\t }\n\t\n\t var cell = getCellFromPoint($activeCellOffset.left, Math.ceil($activeCellOffset.top) - rowOffset);\n\t\n\t activeRow = cell.row;\n\t activeCell = activePosX = activeCell = activePosX = getCellFromNode(activeCellNode[0]);\n\t\n\t $activeCellNode.addClass(\"active\");\n\t if (rowsCache[activeRow]) {\n\t (0, _jquery2.default)(rowsCache[activeRow].rowNode).addClass('active');\n\t }\n\t\n\t if (opt_editMode == null) {\n\t opt_editMode = activeRow == getDataLength() || options.autoEdit;\n\t }\n\t\n\t if (options.editable && opt_editMode && isCellPotentiallyEditable(activeRow, activeCell)) {\n\t clearTimeout(h_editorLoader);\n\t\n\t if (options.asyncEditorLoading) {\n\t h_editorLoader = setTimeout(function () {\n\t makeActiveCellEditable();\n\t }, options.asyncEditorLoadDelay);\n\t } else {\n\t makeActiveCellEditable();\n\t }\n\t }\n\t } else {\n\t activeRow = activeCell = null;\n\t }\n\t\n\t if (activeCellChanged) {\n\t setTimeout(scrollActiveCellIntoView, 50);\n\t trigger(self.onActiveCellChanged, getActiveCell());\n\t }\n\t }\n\t\n\t function clearTextSelection() {\n\t if (document.selection && document.selection.empty) {\n\t try {\n\t //IE fails here if selected element is not in dom\n\t document.selection.empty();\n\t } catch (e) {}\n\t } else if (window.getSelection) {\n\t var sel = window.getSelection();\n\t if (sel && sel.removeAllRanges) {\n\t sel.removeAllRanges();\n\t }\n\t }\n\t }\n\t\n\t function isCellPotentiallyEditable(row, cell) {\n\t var dataLength = getDataLength();\n\t // is the data for this row loaded?\n\t if (row < dataLength && !getDataItem(row)) {\n\t return false;\n\t }\n\t\n\t // are we in the Add New row? can we create new from this cell?\n\t if (columns[cell].cannotTriggerInsert && row >= dataLength) {\n\t return false;\n\t }\n\t\n\t // does this cell have an editor?\n\t if (!getEditor(row, cell)) {\n\t return false;\n\t }\n\t\n\t return true;\n\t }\n\t\n\t function makeActiveCellNormal() {\n\t if (!currentEditor) {\n\t return;\n\t }\n\t trigger(self.onBeforeCellEditorDestroy, {\n\t editor: currentEditor\n\t });\n\t currentEditor.destroy();\n\t currentEditor = null;\n\t\n\t if (activeCellNode) {\n\t var d = getDataItem(activeRow);\n\t (0, _jquery2.default)(activeCellNode).removeClass(\"editable invalid\");\n\t if (d) {\n\t var column = columns[activeCell];\n\t activeCellNode[0].innerHTML = callFormatter(activeRow, activeCell, getDataItemValueForColumn(d, column), column, d);\n\t invalidatePostProcessingResults(activeRow);\n\t }\n\t }\n\t\n\t // if there previously was text selected on a page (such as selected text in the edit cell just removed),\n\t // IE can't set focus to anything else correctly\n\t if (navigator.userAgent.toLowerCase().match(/msie/)) {\n\t clearTextSelection();\n\t }\n\t\n\t getEditorLock().deactivate(editController);\n\t }\n\t\n\t function makeActiveCellEditable(editor) {\n\t if (!activeCellNode) {\n\t return;\n\t }\n\t if (!options.editable) {\n\t throw \"Grid : makeActiveCellEditable : should never get called when options.editable is false\";\n\t }\n\t\n\t // cancel pending async call if there is one\n\t clearTimeout(h_editorLoader);\n\t\n\t if (!isCellPotentiallyEditable(activeRow, activeCell)) {\n\t return;\n\t }\n\t\n\t var columnDef = columns[activeCell];\n\t var item = getDataItem(activeRow);\n\t\n\t if (trigger(self.onBeforeEditCell, {\n\t row: activeRow,\n\t cell: activeCell,\n\t item: item,\n\t column: columnDef\n\t }) === false) {\n\t setFocus();\n\t return;\n\t }\n\t\n\t getEditorLock().activate(editController);\n\t (0, _jquery2.default)(activeCellNode).addClass(\"editable\");\n\t\n\t // don't clear the cell if a custom editor is passed through\n\t if (!editor) {\n\t activeCellNode[0].innerHTML = \"\";\n\t }\n\t\n\t currentEditor = new (editor || getEditor(activeRow, activeCell))({\n\t grid: self,\n\t gridPosition: absBox($container[0]),\n\t position: absBox(activeCellNode[0]),\n\t container: activeCellNode,\n\t column: columnDef,\n\t item: item || {},\n\t commitChanges: commitEditAndSetFocus,\n\t cancelChanges: cancelEditAndSetFocus\n\t });\n\t\n\t if (item) {\n\t currentEditor.loadValue(item);\n\t }\n\t\n\t serializedEditorValue = currentEditor.serializeValue();\n\t\n\t if (currentEditor.position) {\n\t handleActiveCellPositionChange();\n\t }\n\t }\n\t\n\t function commitEditAndSetFocus() {\n\t // if the commit fails, it would do so due to a validation error\n\t // if so, do not steal the focus from the editor\n\t if (getEditorLock().commitCurrentEdit()) {\n\t setFocus();\n\t if (options.autoEdit) {\n\t navigateDown();\n\t }\n\t }\n\t }\n\t\n\t function cancelEditAndSetFocus() {\n\t if (getEditorLock().cancelCurrentEdit()) {\n\t setFocus();\n\t }\n\t }\n\t\n\t function absBox(elem) {\n\t var box = {\n\t top: elem.offsetTop,\n\t left: elem.offsetLeft,\n\t bottom: 0,\n\t right: 0,\n\t width: (0, _jquery2.default)(elem).outerWidth(),\n\t height: (0, _jquery2.default)(elem).outerHeight(),\n\t visible: true\n\t };\n\t box.bottom = box.top + box.height;\n\t box.right = box.left + box.width;\n\t\n\t // walk up the tree\n\t var offsetParent = elem.offsetParent;\n\t while ((elem = elem.parentNode) != document.body) {\n\t if (box.visible && elem.scrollHeight != elem.offsetHeight && (0, _jquery2.default)(elem).css(\"overflowY\") != \"visible\") {\n\t box.visible = box.bottom > elem.scrollTop && box.top < elem.scrollTop + elem.clientHeight;\n\t }\n\t\n\t if (box.visible && elem.scrollWidth != elem.offsetWidth && (0, _jquery2.default)(elem).css(\"overflowX\") != \"visible\") {\n\t box.visible = box.right > elem.scrollLeft && box.left < elem.scrollLeft + elem.clientWidth;\n\t }\n\t\n\t box.left -= elem.scrollLeft;\n\t box.top -= elem.scrollTop;\n\t\n\t if (elem === offsetParent) {\n\t box.left += elem.offsetLeft;\n\t box.top += elem.offsetTop;\n\t offsetParent = elem.offsetParent;\n\t }\n\t\n\t box.bottom = box.top + box.height;\n\t box.right = box.left + box.width;\n\t }\n\t\n\t return box;\n\t }\n\t\n\t function getActiveCellPosition() {\n\t return absBox(activeCellNode[0]);\n\t }\n\t\n\t function getGridPosition() {\n\t return absBox($container[0]);\n\t }\n\t\n\t function handleActiveCellPositionChange() {\n\t if (!activeCellNode) {\n\t return;\n\t }\n\t\n\t trigger(self.onActiveCellPositionChanged, {});\n\t\n\t if (currentEditor) {\n\t var cellBox = getActiveCellPosition();\n\t if (currentEditor.show && currentEditor.hide) {\n\t if (!cellBox.visible) {\n\t currentEditor.hide();\n\t } else {\n\t currentEditor.show();\n\t }\n\t }\n\t\n\t if (currentEditor.position) {\n\t currentEditor.position(cellBox);\n\t }\n\t }\n\t }\n\t\n\t function getCellEditor() {\n\t return currentEditor;\n\t }\n\t\n\t function getActiveCell() {\n\t if (!activeCellNode) {\n\t return null;\n\t } else {\n\t return {\n\t row: activeRow,\n\t cell: activeCell\n\t };\n\t }\n\t }\n\t\n\t function getActiveCellNode() {\n\t return activeCellNode;\n\t }\n\t\n\t function scrollActiveCellIntoView() {\n\t if (activeRow != null && activeCell != null) {\n\t scrollCellIntoView(activeRow, activeCell);\n\t }\n\t }\n\t\n\t function scrollRowIntoView(row, doPaging) {\n\t\n\t if (!hasFrozenRows || !options.frozenBottom && row > actualFrozenRow - 1 || options.frozenBottom && row < actualFrozenRow - 1) {\n\t\n\t var viewportScrollH = $viewportScrollContainerY.height();\n\t\n\t var rowAtTop = row * options.rowHeight;\n\t var rowAtBottom = (row + 1) * options.rowHeight - viewportScrollH + (viewportHasHScroll ? scrollbarDimensions.height : 0);\n\t\n\t // need to page down?\n\t if ((row + 1) * options.rowHeight > scrollTop + viewportScrollH + offset) {\n\t scrollTo(doPaging ? rowAtTop : rowAtBottom);\n\t render();\n\t }\n\t // or page up?\n\t else if (row * options.rowHeight < scrollTop + offset) {\n\t scrollTo(doPaging ? rowAtBottom : rowAtTop);\n\t render();\n\t }\n\t }\n\t }\n\t\n\t function scrollRowToTop(row) {\n\t scrollTo(row * options.rowHeight);\n\t render();\n\t }\n\t\n\t function scrollPage(dir) {\n\t var deltaRows = dir * numVisibleRows;\n\t scrollTo((getRowFromPosition(scrollTop) + deltaRows) * options.rowHeight);\n\t render();\n\t\n\t if (options.enableCellNavigation && activeRow != null) {\n\t var row = activeRow + deltaRows;\n\t var dataLengthIncludingAddNew = getDataLengthIncludingAddNew();\n\t if (row >= dataLengthIncludingAddNew) {\n\t row = dataLengthIncludingAddNew - 1;\n\t }\n\t if (row < 0) {\n\t row = 0;\n\t }\n\t\n\t var cell = 0,\n\t prevCell = null;\n\t var prevActivePosX = activePosX;\n\t while (cell <= activePosX) {\n\t if (canCellBeActive(row, cell)) {\n\t prevCell = cell;\n\t }\n\t cell += getColspan(row, cell);\n\t }\n\t\n\t if (prevCell !== null) {\n\t setActiveCellInternal(getCellNode(row, prevCell));\n\t activePosX = prevActivePosX;\n\t } else {\n\t resetActiveCell();\n\t }\n\t }\n\t }\n\t\n\t function navigatePageDown() {\n\t scrollPage(1);\n\t }\n\t\n\t function navigatePageUp() {\n\t scrollPage(-1);\n\t }\n\t\n\t function getColspan(row, cell) {\n\t var metadata = data.getItemMetadata && data.getItemMetadata(row);\n\t if (!metadata || !metadata.columns) {\n\t return 1;\n\t }\n\t\n\t var columnData = columns[cell] && (metadata.columns[columns[cell].id] || metadata.columns[cell]);\n\t var colspan = columnData && columnData.colspan;\n\t if (colspan === \"*\") {\n\t colspan = columns.length - cell;\n\t } else {\n\t colspan = colspan || 1;\n\t }\n\t\n\t return colspan;\n\t }\n\t\n\t function findFirstFocusableCell(row) {\n\t var cell = 0;\n\t while (cell < columns.length) {\n\t if (canCellBeActive(row, cell)) {\n\t return cell;\n\t }\n\t cell += getColspan(row, cell);\n\t }\n\t return null;\n\t }\n\t\n\t function findLastFocusableCell(row) {\n\t var cell = 0;\n\t var lastFocusableCell = null;\n\t while (cell < columns.length) {\n\t if (canCellBeActive(row, cell)) {\n\t lastFocusableCell = cell;\n\t }\n\t cell += getColspan(row, cell);\n\t }\n\t return lastFocusableCell;\n\t }\n\t\n\t function gotoRight(row, cell, posX) {\n\t if (cell >= columns.length) {\n\t return null;\n\t }\n\t\n\t do {\n\t cell += getColspan(row, cell);\n\t } while (cell < columns.length && !canCellBeActive(row, cell));\n\t\n\t if (cell < columns.length) {\n\t return {\n\t \"row\": row,\n\t \"cell\": cell,\n\t \"posX\": cell\n\t };\n\t }\n\t return null;\n\t }\n\t\n\t function gotoLeft(row, cell, posX) {\n\t if (cell <= 0) {\n\t return null;\n\t }\n\t\n\t var firstFocusableCell = findFirstFocusableCell(row);\n\t if (firstFocusableCell === null || firstFocusableCell >= cell) {\n\t return null;\n\t }\n\t\n\t var prev = {\n\t \"row\": row,\n\t \"cell\": firstFocusableCell,\n\t \"posX\": firstFocusableCell\n\t };\n\t var pos;\n\t while (true) {\n\t pos = gotoRight(prev.row, prev.cell, prev.posX);\n\t if (!pos) {\n\t return null;\n\t }\n\t if (pos.cell >= cell) {\n\t return prev;\n\t }\n\t prev = pos;\n\t }\n\t }\n\t\n\t function gotoDown(row, cell, posX) {\n\t var prevCell;\n\t var dataLengthIncludingAddNew = getDataLengthIncludingAddNew();\n\t while (true) {\n\t if (++row >= dataLengthIncludingAddNew) {\n\t return null;\n\t }\n\t\n\t prevCell = cell = 0;\n\t while (cell <= posX) {\n\t prevCell = cell;\n\t cell += getColspan(row, cell);\n\t }\n\t\n\t if (canCellBeActive(row, prevCell)) {\n\t return {\n\t \"row\": row,\n\t \"cell\": prevCell,\n\t \"posX\": posX\n\t };\n\t }\n\t }\n\t }\n\t\n\t function gotoUp(row, cell, posX) {\n\t var prevCell;\n\t while (true) {\n\t if (--row < 0) {\n\t return null;\n\t }\n\t\n\t prevCell = cell = 0;\n\t while (cell <= posX) {\n\t prevCell = cell;\n\t cell += getColspan(row, cell);\n\t }\n\t\n\t if (canCellBeActive(row, prevCell)) {\n\t return {\n\t \"row\": row,\n\t \"cell\": prevCell,\n\t \"posX\": posX\n\t };\n\t }\n\t }\n\t }\n\t\n\t function gotoNext(row, cell, posX) {\n\t if (row == null && cell == null) {\n\t row = cell = posX = 0;\n\t if (canCellBeActive(row, cell)) {\n\t return {\n\t \"row\": row,\n\t \"cell\": cell,\n\t \"posX\": cell\n\t };\n\t }\n\t }\n\t\n\t var pos = gotoRight(row, cell, posX);\n\t if (pos) {\n\t return pos;\n\t }\n\t\n\t var firstFocusableCell = null;\n\t var dataLengthIncludingAddNew = getDataLengthIncludingAddNew();\n\t while (++row < dataLengthIncludingAddNew) {\n\t firstFocusableCell = findFirstFocusableCell(row);\n\t if (firstFocusableCell !== null) {\n\t return {\n\t \"row\": row,\n\t \"cell\": firstFocusableCell,\n\t \"posX\": firstFocusableCell\n\t };\n\t }\n\t }\n\t return null;\n\t }\n\t\n\t function gotoPrev(row, cell, posX) {\n\t if (row == null && cell == null) {\n\t row = getDataLengthIncludingAddNew() - 1;\n\t cell = posX = columns.length - 1;\n\t if (canCellBeActive(row, cell)) {\n\t return {\n\t \"row\": row,\n\t \"cell\": cell,\n\t \"posX\": cell\n\t };\n\t }\n\t }\n\t\n\t var pos;\n\t var lastSelectableCell;\n\t while (!pos) {\n\t pos = gotoLeft(row, cell, posX);\n\t if (pos) {\n\t break;\n\t }\n\t if (--row < 0) {\n\t return null;\n\t }\n\t\n\t cell = 0;\n\t lastSelectableCell = findLastFocusableCell(row);\n\t if (lastSelectableCell !== null) {\n\t pos = {\n\t \"row\": row,\n\t \"cell\": lastSelectableCell,\n\t \"posX\": lastSelectableCell\n\t };\n\t }\n\t }\n\t return pos;\n\t }\n\t\n\t function navigateRight() {\n\t return navigate(\"right\");\n\t }\n\t\n\t function navigateLeft() {\n\t return navigate(\"left\");\n\t }\n\t\n\t function navigateDown() {\n\t return navigate(\"down\");\n\t }\n\t\n\t function navigateUp() {\n\t return navigate(\"up\");\n\t }\n\t\n\t function navigateNext() {\n\t return navigate(\"next\");\n\t }\n\t\n\t function navigatePrev() {\n\t return navigate(\"prev\");\n\t }\n\t\n\t /**\n\t * @param {string} dir Navigation direction.\n\t * @return {boolean} Whether navigation resulted in a change of active cell.\n\t */\n\t function navigate(dir) {\n\t if (!options.enableCellNavigation) {\n\t return false;\n\t }\n\t\n\t if (!activeCellNode && dir != \"prev\" && dir != \"next\") {\n\t return false;\n\t }\n\t\n\t if (!getEditorLock().commitCurrentEdit()) {\n\t return true;\n\t }\n\t setFocus();\n\t\n\t var tabbingDirections = {\n\t \"up\": -1,\n\t \"down\": 1,\n\t \"left\": -1,\n\t \"right\": 1,\n\t \"prev\": -1,\n\t \"next\": 1\n\t };\n\t tabbingDirection = tabbingDirections[dir];\n\t\n\t var stepFunctions = {\n\t \"up\": gotoUp,\n\t \"down\": gotoDown,\n\t \"left\": gotoLeft,\n\t \"right\": gotoRight,\n\t \"prev\": gotoPrev,\n\t \"next\": gotoNext\n\t };\n\t var stepFn = stepFunctions[dir];\n\t var pos = stepFn(activeRow, activeCell, activePosX);\n\t if (pos) {\n\t if (hasFrozenRows && options.frozenBottom & pos.row == getDataLength()) {\n\t return;\n\t }\n\t\n\t var isAddNewRow = pos.row == getDataLength();\n\t\n\t if (!options.frozenBottom && pos.row >= actualFrozenRow || options.frozenBottom && pos.row < actualFrozenRow) {\n\t scrollCellIntoView(pos.row, pos.cell, !isAddNewRow);\n\t }\n\t\n\t setActiveCellInternal(getCellNode(pos.row, pos.cell));\n\t activePosX = pos.posX;\n\t return true;\n\t } else {\n\t setActiveCellInternal(getCellNode(activeRow, activeCell));\n\t return false;\n\t }\n\t }\n\t\n\t function getCellNode(row, cell) {\n\t if (rowsCache[row]) {\n\t ensureCellNodesInRowsCache(row);\n\t return rowsCache[row].cellNodesByColumnIdx[cell];\n\t }\n\t return null;\n\t }\n\t\n\t function setActiveCell(row, cell) {\n\t if (!initialized) {\n\t return;\n\t }\n\t if (row > getDataLength() || row < 0 || cell >= columns.length || cell < 0) {\n\t return;\n\t }\n\t\n\t if (!options.enableCellNavigation) {\n\t return;\n\t }\n\t\n\t scrollCellIntoView(row, cell, false);\n\t setActiveCellInternal(getCellNode(row, cell), false);\n\t }\n\t\n\t function canCellBeActive(row, cell) {\n\t if (!options.enableCellNavigation || row >= getDataLengthIncludingAddNew() || row < 0 || cell >= columns.length || cell < 0) {\n\t return false;\n\t }\n\t\n\t var rowMetadata = data.getItemMetadata && data.getItemMetadata(row);\n\t if (rowMetadata && typeof rowMetadata.focusable === \"boolean\") {\n\t return rowMetadata.focusable;\n\t }\n\t\n\t var columnMetadata = rowMetadata && rowMetadata.columns;\n\t if (columnMetadata && columns[cell] && columnMetadata[columns[cell].id] && typeof columnMetadata[columns[cell].id].focusable === \"boolean\") {\n\t return columnMetadata[columns[cell].id].focusable;\n\t }\n\t if (columnMetadata && columnMetadata[cell] && typeof columnMetadata[cell].focusable === \"boolean\") {\n\t return columnMetadata[cell].focusable;\n\t }\n\t\n\t return columns[cell] && columns[cell].focusable;\n\t }\n\t\n\t function canCellBeSelected(row, cell) {\n\t if (row >= getDataLength() || row < 0 || cell >= columns.length || cell < 0) {\n\t return false;\n\t }\n\t\n\t var rowMetadata = data.getItemMetadata && data.getItemMetadata(row);\n\t if (rowMetadata && typeof rowMetadata.selectable === \"boolean\") {\n\t return rowMetadata.selectable;\n\t }\n\t\n\t var columnMetadata = rowMetadata && rowMetadata.columns && (rowMetadata.columns[columns[cell].id] || rowMetadata.columns[cell]);\n\t if (columnMetadata && typeof columnMetadata.selectable === \"boolean\") {\n\t return columnMetadata.selectable;\n\t }\n\t\n\t return columns[cell].selectable;\n\t }\n\t\n\t function gotoCell(row, cell, forceEdit) {\n\t if (!initialized) {\n\t return;\n\t }\n\t if (!canCellBeActive(row, cell)) {\n\t return;\n\t }\n\t\n\t if (!getEditorLock().commitCurrentEdit()) {\n\t return;\n\t }\n\t\n\t scrollCellIntoView(row, cell, false);\n\t\n\t var newCell = getCellNode(row, cell);\n\t\n\t // if selecting the 'add new' row, start editing right away\n\t setActiveCellInternal(newCell, forceEdit || row === getDataLength() || options.autoEdit);\n\t\n\t // if no editor was created, set the focus back on the grid\n\t if (!currentEditor) {\n\t setFocus();\n\t }\n\t }\n\t\n\t //////////////////////////////////////////////////////////////////////////////////////////////\n\t // IEditor implementation for the editor lock\n\t\n\t function commitCurrentEdit() {\n\t var item = getDataItem(activeRow);\n\t var column = columns[activeCell];\n\t\n\t if (currentEditor) {\n\t if (currentEditor.isValueChanged()) {\n\t var validationResults = currentEditor.validate();\n\t\n\t if (validationResults.valid) {\n\t if (activeRow < getDataLength()) {\n\t var editCommand = {\n\t row: activeRow,\n\t cell: activeCell,\n\t editor: currentEditor,\n\t serializedValue: currentEditor.serializeValue(),\n\t prevSerializedValue: serializedEditorValue,\n\t execute: function execute() {\n\t this.editor.applyValue(item, this.serializedValue);\n\t updateRow(this.row);\n\t trigger(self.onCellChange, {\n\t row: activeRow,\n\t cell: activeCell,\n\t item: item\n\t });\n\t },\n\t undo: function undo() {\n\t this.editor.applyValue(item, this.prevSerializedValue);\n\t updateRow(this.row);\n\t trigger(self.onCellChange, {\n\t row: activeRow,\n\t cell: activeCell,\n\t item: item\n\t });\n\t }\n\t };\n\t\n\t if (options.editCommandHandler) {\n\t makeActiveCellNormal();\n\t options.editCommandHandler(item, column, editCommand);\n\t } else {\n\t editCommand.execute();\n\t makeActiveCellNormal();\n\t }\n\t } else {\n\t var newItem = {};\n\t currentEditor.applyValue(newItem, currentEditor.serializeValue());\n\t makeActiveCellNormal();\n\t trigger(self.onAddNewRow, {\n\t item: newItem,\n\t column: column\n\t });\n\t }\n\t\n\t // check whether the lock has been re-acquired by event handlers\n\t return !getEditorLock().isActive();\n\t } else {\n\t // Re-add the CSS class to trigger transitions, if any.\n\t (0, _jquery2.default)(activeCellNode).removeClass(\"invalid\");\n\t (0, _jquery2.default)(activeCellNode).width(); // force layout\n\t (0, _jquery2.default)(activeCellNode).addClass(\"invalid\");\n\t\n\t trigger(self.onValidationError, {\n\t editor: currentEditor,\n\t cellNode: activeCellNode,\n\t validationResults: validationResults,\n\t row: activeRow,\n\t cell: activeCell,\n\t column: column\n\t });\n\t\n\t currentEditor.focus();\n\t return false;\n\t }\n\t }\n\t\n\t makeActiveCellNormal();\n\t }\n\t return true;\n\t }\n\t\n\t function cancelCurrentEdit() {\n\t makeActiveCellNormal();\n\t return true;\n\t }\n\t\n\t function rowsToRanges(rows) {\n\t var ranges = [];\n\t var lastCell = columns.length - 1;\n\t for (var i = 0; i < rows.length; i++) {\n\t ranges.push(new _slick2.default.Range(rows[i], 0, rows[i], lastCell));\n\t }\n\t return ranges;\n\t }\n\t\n\t function getSelectedRows() {\n\t if (!selectionModel) {\n\t throw \"Selection model is not set\";\n\t }\n\t return selectedRows;\n\t }\n\t\n\t function setSelectedRows(rows) {\n\t if (!selectionModel) {\n\t throw \"Selection model is not set\";\n\t }\n\t selectionModel.setSelectedRanges(rowsToRanges(rows));\n\t }\n\t\n\t //////////////////////////////////////////////////////////////////////////////////////////////\n\t // Debug\n\t\n\t this.debug = function () {\n\t var s = \"\";\n\t\n\t s += \"\\n\" + \"counter_rows_rendered: \" + counter_rows_rendered;\n\t s += \"\\n\" + \"counter_rows_removed: \" + counter_rows_removed;\n\t s += \"\\n\" + \"renderedRows: \" + renderedRows;\n\t s += \"\\n\" + \"numVisibleRows: \" + numVisibleRows;\n\t s += \"\\n\" + \"maxSupportedCssHeight: \" + maxSupportedCssHeight;\n\t s += \"\\n\" + \"n(umber of pages): \" + n;\n\t s += \"\\n\" + \"(current) page: \" + page;\n\t s += \"\\n\" + \"page height (ph): \" + ph;\n\t s += \"\\n\" + \"vScrollDir: \" + vScrollDir;\n\t\n\t alert(s);\n\t };\n\t\n\t // a debug helper to be able to access private members\n\t this.eval = function (expr) {\n\t return eval(expr);\n\t };\n\t\n\t //////////////////////////////////////////////////////////////////////////////////////////////\n\t // Public API\n\t\n\t _jquery2.default.extend(this, {\n\t \"slickGridVersion\": \"2.1\",\n\t\n\t // Events\n\t \"onScroll\": new _slick2.default.Event(),\n\t \"onSort\": new _slick2.default.Event(),\n\t \"onHeaderMouseEnter\": new _slick2.default.Event(),\n\t \"onHeaderMouseLeave\": new _slick2.default.Event(),\n\t \"onHeaderContextMenu\": new _slick2.default.Event(),\n\t \"onHeaderClick\": new _slick2.default.Event(),\n\t \"onHeaderCellRendered\": new _slick2.default.Event(),\n\t \"onBeforeHeaderCellDestroy\": new _slick2.default.Event(),\n\t \"onHeaderRowCellRendered\": new _slick2.default.Event(),\n\t \"onFooterRowCellRendered\": new _slick2.default.Event(),\n\t \"onBeforeHeaderRowCellDestroy\": new _slick2.default.Event(),\n\t \"onBeforeFooterRowCellDestroy\": new _slick2.default.Event(),\n\t \"onMouseEnter\": new _slick2.default.Event(),\n\t \"onMouseLeave\": new _slick2.default.Event(),\n\t \"onClick\": new _slick2.default.Event(),\n\t \"onDblClick\": new _slick2.default.Event(),\n\t \"onContextMenu\": new _slick2.default.Event(),\n\t \"onKeyDown\": new _slick2.default.Event(),\n\t \"onAddNewRow\": new _slick2.default.Event(),\n\t \"onValidationError\": new _slick2.default.Event(),\n\t \"onViewportChanged\": new _slick2.default.Event(),\n\t \"onColumnsReordered\": new _slick2.default.Event(),\n\t \"onColumnsResized\": new _slick2.default.Event(),\n\t \"onCellChange\": new _slick2.default.Event(),\n\t \"onBeforeEditCell\": new _slick2.default.Event(),\n\t \"onBeforeCellEditorDestroy\": new _slick2.default.Event(),\n\t \"onBeforeDestroy\": new _slick2.default.Event(),\n\t \"onActiveCellChanged\": new _slick2.default.Event(),\n\t \"onActiveCellPositionChanged\": new _slick2.default.Event(),\n\t \"onDragInit\": new _slick2.default.Event(),\n\t \"onDragStart\": new _slick2.default.Event(),\n\t \"onDrag\": new _slick2.default.Event(),\n\t \"onDragEnd\": new _slick2.default.Event(),\n\t \"onSelectedRowsChanged\": new _slick2.default.Event(),\n\t \"onCellCssStylesChanged\": new _slick2.default.Event(),\n\t\n\t // Methods\n\t \"registerPlugin\": registerPlugin,\n\t \"unregisterPlugin\": unregisterPlugin,\n\t \"getColumns\": getColumns,\n\t \"setColumns\": setColumns,\n\t \"getColumnIndex\": getColumnIndex,\n\t \"updateColumnHeader\": updateColumnHeader,\n\t \"setSortColumn\": setSortColumn,\n\t \"setSortColumns\": setSortColumns,\n\t \"getSortColumns\": getSortColumns,\n\t \"autosizeColumns\": autosizeColumns,\n\t \"getOptions\": getOptions,\n\t \"setOptions\": setOptions,\n\t \"getData\": getData,\n\t \"getDataLength\": getDataLength,\n\t \"getDataItem\": getDataItem,\n\t \"setData\": setData,\n\t \"getSelectionModel\": getSelectionModel,\n\t \"setSelectionModel\": setSelectionModel,\n\t \"getSelectedRows\": getSelectedRows,\n\t \"setSelectedRows\": setSelectedRows,\n\t \"getContainerNode\": getContainerNode,\n\t\n\t \"render\": render,\n\t \"invalidate\": invalidate,\n\t \"invalidateRow\": invalidateRow,\n\t \"invalidateRows\": invalidateRows,\n\t \"invalidateAllRows\": invalidateAllRows,\n\t \"updateCell\": updateCell,\n\t \"updateRow\": updateRow,\n\t \"getViewport\": getVisibleRange,\n\t \"getRenderedRange\": getRenderedRange,\n\t \"resizeCanvas\": resizeCanvas,\n\t \"updateRowCount\": updateRowCount,\n\t \"scrollRowIntoView\": scrollRowIntoView,\n\t \"scrollRowToTop\": scrollRowToTop,\n\t \"scrollCellIntoView\": scrollCellIntoView,\n\t \"getCanvasNode\": getCanvasNode,\n\t \"getCanvases\": getCanvases,\n\t \"getActiveCanvasNode\": getActiveCanvasNode,\n\t \"setActiveCanvasNode\": setActiveCanvasNode,\n\t \"getViewportNode\": getViewportNode,\n\t \"getActiveViewportNode\": getActiveViewportNode,\n\t \"setActiveViewportNode\": setActiveViewportNode,\n\t \"focus\": setFocus,\n\t\n\t \"getCellFromPoint\": getCellFromPoint,\n\t \"getCellFromEvent\": getCellFromEvent,\n\t \"getActiveCell\": getActiveCell,\n\t \"setActiveCell\": setActiveCell,\n\t \"getActiveCellNode\": getActiveCellNode,\n\t \"getActiveCellPosition\": getActiveCellPosition,\n\t \"resetActiveCell\": resetActiveCell,\n\t \"editActiveCell\": makeActiveCellEditable,\n\t \"getCellEditor\": getCellEditor,\n\t \"getCellNode\": getCellNode,\n\t \"getCellNodeBox\": getCellNodeBox,\n\t \"canCellBeSelected\": canCellBeSelected,\n\t \"canCellBeActive\": canCellBeActive,\n\t \"navigatePrev\": navigatePrev,\n\t \"navigateNext\": navigateNext,\n\t \"navigateUp\": navigateUp,\n\t \"navigateDown\": navigateDown,\n\t \"navigateLeft\": navigateLeft,\n\t \"navigateRight\": navigateRight,\n\t \"navigatePageUp\": navigatePageUp,\n\t \"navigatePageDown\": navigatePageDown,\n\t \"gotoCell\": gotoCell,\n\t \"getTopPanel\": getTopPanel,\n\t \"setTopPanelVisibility\": setTopPanelVisibility,\n\t \"setHeaderRowVisibility\": setHeaderRowVisibility,\n\t \"getHeaderRow\": getHeaderRow,\n\t \"getHeaderRowColumn\": getHeaderRowColumn,\n\t \"setFooterRowVisibility\": setFooterRowVisibility,\n\t \"getFooterRow\": getFooterRow,\n\t \"getFooterRowColumn\": getFooterRowColumn,\n\t \"getGridPosition\": getGridPosition,\n\t \"flashCell\": flashCell,\n\t \"addCellCssStyles\": addCellCssStyles,\n\t \"setCellCssStyles\": setCellCssStyles,\n\t \"removeCellCssStyles\": removeCellCssStyles,\n\t \"getCellCssStyles\": getCellCssStyles,\n\t \"getFrozenRowOffset\": getFrozenRowOffset,\n\t\n\t \"init\": finishInitialization,\n\t \"destroy\": destroy,\n\t\n\t // IEditor implementation\n\t \"getEditorLock\": getEditorLock,\n\t \"getEditController\": getEditController\n\t });\n\t\n\t init();\n\t}\n\n/***/ }),\n/* 27 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _slick = __webpack_require__(1);\n\t\n\tvar _slick2 = _interopRequireDefault(_slick);\n\t\n\tvar _jquery = __webpack_require__(2);\n\t\n\tvar _jquery2 = _interopRequireDefault(_jquery);\n\t\n\tvar _slick3 = __webpack_require__(31);\n\t\n\tvar _slick4 = _interopRequireDefault(_slick3);\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\t\n\tvar Aggregators = {\n\t Avg: AvgAggregator,\n\t Min: MinAggregator,\n\t Max: MaxAggregator,\n\t Sum: SumAggregator\n\t};\n\t\n\tvar Data = {\n\t DataView: DataView,\n\t GroupMetaDataProvider: _slick4.default,\n\t Aggregators: Aggregators\n\t};\n\t\n\texports.default = Data;\n\t\n\t/** *\n\t * A sample Model implementation.\n\t * Provides a filtered view of the underlying data.\n\t *\n\t * Relies on the data item having an \"id\" property uniquely identifying it.\n\t */\n\t\n\tfunction DataView(options) {\n\t var self = this;\n\t\n\t var defaults = {\n\t groupItemMetadataProvider: null,\n\t inlineFilters: false\n\t };\n\t\n\t // private\n\t var idProperty = 'id'; // property holding a unique row id\n\t var items = []; // data by index\n\t var rows = []; // data by row\n\t var idxById = {}; // indexes by id\n\t var rowsById = null; // rows by id; lazy-calculated\n\t var filter = null; // filter function\n\t var updated = null; // updated item ids\n\t var suspend = false; // suspends the recalculation\n\t var sortAsc = true;\n\t var fastSortField = void 0;\n\t var sortComparer = void 0;\n\t var refreshHints = {};\n\t var prevRefreshHints = {};\n\t var filterArgs = void 0;\n\t var filteredItems = [];\n\t var compiledFilter = void 0;\n\t var compiledFilterWithCaching = void 0;\n\t var filterCache = [];\n\t\n\t // grouping\n\t var groupingInfoDefaults = {\n\t getter: null,\n\t formatter: null,\n\t comparer: function comparer(a, b) {\n\t return a.value === b.value ? 0 : a.value > b.value ? 1 : -1;\n\t },\n\t predefinedValues: [],\n\t aggregators: [],\n\t aggregateEmpty: false,\n\t aggregateCollapsed: false,\n\t aggregateChildGroups: false,\n\t collapsed: false,\n\t displayTotalsRow: true,\n\t lazyTotalsCalculation: false\n\t };\n\t var groupingInfos = [];\n\t var groups = [];\n\t var toggledGroupsByLevel = [];\n\t var groupingDelimiter = ':|:';\n\t\n\t var pagesize = 0;\n\t var pagenum = 0;\n\t var totalRows = 0;\n\t\n\t // events\n\t var onRowCountChanged = new _slick2.default.Event();\n\t var onRowsChanged = new _slick2.default.Event();\n\t var onPagingInfoChanged = new _slick2.default.Event();\n\t\n\t options = _jquery2.default.extend(true, {}, defaults, options);\n\t\n\t function beginUpdate() {\n\t suspend = true;\n\t }\n\t\n\t function endUpdate() {\n\t suspend = false;\n\t refresh();\n\t }\n\t\n\t function setRefreshHints(hints) {\n\t refreshHints = hints;\n\t }\n\t\n\t function setFilterArgs(args) {\n\t filterArgs = args;\n\t }\n\t\n\t function updateIdxById(startingIndex) {\n\t startingIndex = startingIndex || 0;\n\t var id = void 0;\n\t for (var i = startingIndex, l = items.length; i < l; i++) {\n\t id = items[i][idProperty];\n\t if (id === undefined) {\n\t throw \"Each data element must implement a unique 'id' property\";\n\t }\n\t idxById[id] = i;\n\t }\n\t }\n\t\n\t function ensureIdUniqueness() {\n\t var id = void 0;\n\t for (var i = 0, l = items.length; i < l; i++) {\n\t id = items[i][idProperty];\n\t if (id === undefined || idxById[id] !== i) {\n\t throw \"Each data element must implement a unique 'id' property\";\n\t }\n\t }\n\t }\n\t\n\t function getItems() {\n\t return items;\n\t }\n\t\n\t function setItems(data, objectIdProperty) {\n\t if (objectIdProperty !== undefined) {\n\t idProperty = objectIdProperty;\n\t }\n\t items = filteredItems = data;\n\t idxById = {};\n\t updateIdxById();\n\t ensureIdUniqueness();\n\t refresh();\n\t }\n\t\n\t function setPagingOptions(args) {\n\t if (args.pageSize != undefined) {\n\t pagesize = args.pageSize;\n\t pagenum = pagesize ? Math.min(pagenum, Math.max(0, Math.ceil(totalRows / pagesize) - 1)) : 0;\n\t }\n\t\n\t if (args.pageNum != undefined) {\n\t pagenum = Math.min(args.pageNum, Math.max(0, Math.ceil(totalRows / pagesize) - 1));\n\t }\n\t\n\t onPagingInfoChanged.notify(getPagingInfo(), null, self);\n\t\n\t refresh();\n\t }\n\t\n\t function getPagingInfo() {\n\t var totalPages = pagesize ? Math.max(1, Math.ceil(totalRows / pagesize)) : 1;\n\t return { pageSize: pagesize, pageNum: pagenum, totalRows: totalRows, totalPages: totalPages, dataView: self };\n\t }\n\t\n\t function sort(comparer, ascending) {\n\t sortAsc = ascending;\n\t sortComparer = comparer;\n\t fastSortField = null;\n\t if (ascending === false) {\n\t items.reverse();\n\t }\n\t items.sort(comparer);\n\t if (ascending === false) {\n\t items.reverse();\n\t }\n\t idxById = {};\n\t updateIdxById();\n\t refresh();\n\t }\n\t\n\t /** *\n\t * Provides a workaround for the extremely slow sorting in IE.\n\t * Does a [lexicographic] sort on a give column by temporarily overriding Object.prototype.toString\n\t * to return the value of that field and then doing a native Array.sort().\n\t */\n\t function fastSort(field, ascending) {\n\t sortAsc = ascending;\n\t fastSortField = field;\n\t sortComparer = null;\n\t var oldToString = Object.prototype.toString;\n\t Object.prototype.toString = typeof field == 'function' ? field : function () {\n\t return this[field];\n\t };\n\t // an extra reversal for descending sort keeps the sort stable\n\t // (assuming a stable native sort implementation, which isn't true in some cases)\n\t if (ascending === false) {\n\t items.reverse();\n\t }\n\t items.sort();\n\t Object.prototype.toString = oldToString;\n\t if (ascending === false) {\n\t items.reverse();\n\t }\n\t idxById = {};\n\t updateIdxById();\n\t refresh();\n\t }\n\t\n\t function reSort() {\n\t if (sortComparer) {\n\t sort(sortComparer, sortAsc);\n\t } else if (fastSortField) {\n\t fastSort(fastSortField, sortAsc);\n\t }\n\t }\n\t\n\t function setFilter(filterFn) {\n\t filter = filterFn;\n\t if (options.inlineFilters) {\n\t compiledFilter = compileFilter();\n\t compiledFilterWithCaching = compileFilterWithCaching();\n\t }\n\t refresh();\n\t }\n\t\n\t function getGrouping() {\n\t return groupingInfos;\n\t }\n\t\n\t function setGrouping(groupingInfo) {\n\t if (!options.groupItemMetadataProvider) {\n\t options.groupItemMetadataProvider = new Data.GroupItemMetadataProvider();\n\t }\n\t\n\t groups = [];\n\t toggledGroupsByLevel = [];\n\t groupingInfo = groupingInfo || [];\n\t groupingInfos = groupingInfo instanceof Array ? groupingInfo : [groupingInfo];\n\t\n\t for (var i = 0; i < groupingInfos.length; i++) {\n\t var gi = groupingInfos[i] = _jquery2.default.extend(true, {}, groupingInfoDefaults, groupingInfos[i]);\n\t gi.getterIsAFn = typeof gi.getter === 'function';\n\t\n\t // pre-compile accumulator loops\n\t gi.compiledAccumulators = [];\n\t var idx = gi.aggregators.length;\n\t while (idx--) {\n\t gi.compiledAccumulators[idx] = compileAccumulatorLoop(gi.aggregators[idx]);\n\t }\n\t\n\t toggledGroupsByLevel[i] = {};\n\t }\n\t\n\t refresh();\n\t }\n\t\n\t /**\n\t * @deprecated Please use {@link setGrouping}.\n\t */\n\t function groupBy(valueGetter, valueFormatter, sortComparer) {\n\t if (valueGetter == null) {\n\t setGrouping([]);\n\t return;\n\t }\n\t\n\t setGrouping({\n\t getter: valueGetter,\n\t formatter: valueFormatter,\n\t comparer: sortComparer\n\t });\n\t }\n\t\n\t /**\n\t * @deprecated Please use {@link setGrouping}.\n\t */\n\t function setAggregators(groupAggregators, includeCollapsed) {\n\t if (!groupingInfos.length) {\n\t throw new Error('At least one grouping must be specified before calling setAggregators().');\n\t }\n\t\n\t groupingInfos[0].aggregators = groupAggregators;\n\t groupingInfos[0].aggregateCollapsed = includeCollapsed;\n\t\n\t setGrouping(groupingInfos);\n\t }\n\t\n\t function getItemByIdx(i) {\n\t return items[i];\n\t }\n\t\n\t function getIdxById(id) {\n\t return idxById[id];\n\t }\n\t\n\t function ensureRowsByIdCache() {\n\t if (!rowsById) {\n\t rowsById = {};\n\t for (var i = 0, l = rows.length; i < l; i++) {\n\t rowsById[rows[i][idProperty]] = i;\n\t }\n\t }\n\t }\n\t\n\t function getRowById(id) {\n\t ensureRowsByIdCache();\n\t return rowsById[id];\n\t }\n\t\n\t function getItemById(id) {\n\t return items[idxById[id]];\n\t }\n\t\n\t function mapIdsToRows(idArray) {\n\t var rows = [];\n\t ensureRowsByIdCache();\n\t for (var i = 0, l = idArray.length; i < l; i++) {\n\t var row = rowsById[idArray[i]];\n\t if (row != null) {\n\t rows[rows.length] = row;\n\t }\n\t }\n\t return rows;\n\t }\n\t\n\t function mapRowsToIds(rowArray) {\n\t var ids = [];\n\t for (var i = 0, l = rowArray.length; i < l; i++) {\n\t if (rowArray[i] < rows.length) {\n\t ids[ids.length] = rows[rowArray[i]][idProperty];\n\t }\n\t }\n\t return ids;\n\t }\n\t\n\t function updateItem(id, item) {\n\t if (idxById[id] === undefined || id !== item[idProperty]) {\n\t throw 'Invalid or non-matching id';\n\t }\n\t items[idxById[id]] = item;\n\t if (!updated) {\n\t updated = {};\n\t }\n\t updated[id] = true;\n\t refresh();\n\t }\n\t\n\t function insertItem(insertBefore, item) {\n\t items.splice(insertBefore, 0, item);\n\t updateIdxById(insertBefore);\n\t refresh();\n\t }\n\t\n\t function addItem(item) {\n\t items.push(item);\n\t updateIdxById(items.length - 1);\n\t refresh();\n\t }\n\t\n\t function deleteItem(id) {\n\t var idx = idxById[id];\n\t if (idx === undefined) {\n\t throw 'Invalid id';\n\t }\n\t delete idxById[id];\n\t items.splice(idx, 1);\n\t updateIdxById(idx);\n\t refresh();\n\t }\n\t\n\t function getLength() {\n\t return rows.length;\n\t }\n\t\n\t function getItem(i) {\n\t var item = rows[i];\n\t\n\t // if this is a group row, make sure totals are calculated and update the title\n\t if (item && item.__group && item.totals && !item.totals.initialized) {\n\t var gi = groupingInfos[item.level];\n\t if (!gi.displayTotalsRow) {\n\t calculateTotals(item.totals);\n\t item.title = gi.formatter ? gi.formatter(item) : item.value;\n\t }\n\t }\n\t // if this is a totals row, make sure it's calculated\n\t else if (item && item.__groupTotals && !item.initialized) {\n\t calculateTotals(item);\n\t }\n\t\n\t return item;\n\t }\n\t\n\t function getItemMetadata(i) {\n\t var item = rows[i];\n\t if (item === undefined) {\n\t return null;\n\t }\n\t\n\t // overrides for grouping rows\n\t if (item.__group) {\n\t return options.groupItemMetadataProvider.getGroupRowMetadata(item);\n\t }\n\t\n\t // overrides for totals rows\n\t if (item.__groupTotals) {\n\t return options.groupItemMetadataProvider.getTotalsRowMetadata(item);\n\t }\n\t\n\t return null;\n\t }\n\t\n\t function expandCollapseAllGroups(level, collapse) {\n\t if (level == null) {\n\t for (var i = 0; i < groupingInfos.length; i++) {\n\t toggledGroupsByLevel[i] = {};\n\t groupingInfos[i].collapsed = collapse;\n\t }\n\t } else {\n\t toggledGroupsByLevel[level] = {};\n\t groupingInfos[level].collapsed = collapse;\n\t }\n\t refresh();\n\t }\n\t\n\t /**\n\t * @param level {Number} Optional level to collapse. If not specified, applies to all levels.\n\t */\n\t function collapseAllGroups(level) {\n\t expandCollapseAllGroups(level, true);\n\t }\n\t\n\t /**\n\t * @param level {Number} Optional level to expand. If not specified, applies to all levels.\n\t */\n\t function expandAllGroups(level) {\n\t expandCollapseAllGroups(level, false);\n\t }\n\t\n\t function expandCollapseGroup(level, groupingKey, collapse) {\n\t toggledGroupsByLevel[level][groupingKey] = groupingInfos[level].collapsed ^ collapse;\n\t refresh();\n\t }\n\t\n\t /**\n\t * @param letArgs Either a Slick.Group's \"groupingKey\" property, or a\n\t * letiable argument list of grouping values denoting a unique path to the row. For\n\t * example, calling collapseGroup('high', '10%') will collapse the '10%' subgroup of\n\t * the 'high' group.\n\t */\n\t function collapseGroup(letArgs) {\n\t var args = Array.prototype.slice.call(arguments);\n\t var arg0 = args[0];\n\t if (args.length == 1 && arg0.indexOf(groupingDelimiter) != -1) {\n\t expandCollapseGroup(arg0.split(groupingDelimiter).length - 1, arg0, true);\n\t } else {\n\t expandCollapseGroup(args.length - 1, args.join(groupingDelimiter), true);\n\t }\n\t }\n\t\n\t /**\n\t * @param letArgs Either a Slick.Group's \"groupingKey\" property, or a\n\t * letiable argument list of grouping values denoting a unique path to the row. For\n\t * example, calling expandGroup('high', '10%') will expand the '10%' subgroup of\n\t * the 'high' group.\n\t */\n\t function expandGroup(letArgs) {\n\t var args = Array.prototype.slice.call(arguments);\n\t var arg0 = args[0];\n\t if (args.length == 1 && arg0.indexOf(groupingDelimiter) != -1) {\n\t expandCollapseGroup(arg0.split(groupingDelimiter).length - 1, arg0, false);\n\t } else {\n\t expandCollapseGroup(args.length - 1, args.join(groupingDelimiter), false);\n\t }\n\t }\n\t\n\t function getGroups() {\n\t return groups;\n\t }\n\t\n\t function extractGroups(rows, parentGroup) {\n\t var group = void 0;\n\t var val = void 0;\n\t var groups = [];\n\t var groupsByVal = {};\n\t var r = void 0;\n\t var level = parentGroup ? parentGroup.level + 1 : 0;\n\t var gi = groupingInfos[level];\n\t\n\t for (var i = 0, l = gi.predefinedValues.length; i < l; i++) {\n\t val = gi.predefinedValues[i];\n\t group = groupsByVal[val];\n\t if (!group) {\n\t group = new _slick2.default.Group();\n\t group.value = val;\n\t group.level = level;\n\t group.groupingKey = (parentGroup ? parentGroup.groupingKey + groupingDelimiter : '') + val;\n\t groups[groups.length] = group;\n\t groupsByVal[val] = group;\n\t }\n\t }\n\t\n\t for (var _i = 0, _l = rows.length; _i < _l; _i++) {\n\t r = rows[_i];\n\t val = gi.getterIsAFn ? gi.getter(r) : r[gi.getter];\n\t group = groupsByVal[val];\n\t if (!group) {\n\t group = new _slick2.default.Group();\n\t group.value = val;\n\t group.level = level;\n\t group.groupingKey = (parentGroup ? parentGroup.groupingKey + groupingDelimiter : '') + val;\n\t groups[groups.length] = group;\n\t groupsByVal[val] = group;\n\t }\n\t\n\t group.rows[group.count++] = r;\n\t }\n\t\n\t if (level < groupingInfos.length - 1) {\n\t for (var _i2 = 0; _i2 < groups.length; _i2++) {\n\t group = groups[_i2];\n\t group.groups = extractGroups(group.rows, group);\n\t }\n\t }\n\t\n\t groups.sort(groupingInfos[level].comparer);\n\t\n\t return groups;\n\t }\n\t\n\t function calculateTotals(totals) {\n\t var group = totals.group;\n\t var gi = groupingInfos[group.level];\n\t var isLeafLevel = group.level == groupingInfos.length;\n\t var agg = void 0,\n\t idx = gi.aggregators.length;\n\t\n\t if (!isLeafLevel && gi.aggregateChildGroups) {\n\t // make sure all the subgroups are calculated\n\t var i = group.groups.length;\n\t while (i--) {\n\t if (!group.groups[i].totals.initialized) {\n\t calculateTotals(group.groups[i].totals);\n\t }\n\t }\n\t }\n\t\n\t while (idx--) {\n\t agg = gi.aggregators[idx];\n\t agg.init();\n\t if (!isLeafLevel && gi.aggregateChildGroups) {\n\t gi.compiledAccumulators[idx].call(agg, group.groups);\n\t } else {\n\t gi.compiledAccumulators[idx].call(agg, group.rows);\n\t }\n\t agg.storeResult(totals);\n\t }\n\t totals.initialized = true;\n\t }\n\t\n\t function addGroupTotals(group) {\n\t var gi = groupingInfos[group.level];\n\t var totals = new _slick2.default.GroupTotals();\n\t totals.group = group;\n\t group.totals = totals;\n\t if (!gi.lazyTotalsCalculation) {\n\t calculateTotals(totals);\n\t }\n\t }\n\t\n\t function addTotals(groups, level) {\n\t level = level || 0;\n\t var gi = groupingInfos[level];\n\t var groupCollapsed = gi.collapsed;\n\t var toggledGroups = toggledGroupsByLevel[level];\n\t var idx = groups.length,\n\t g = void 0;\n\t while (idx--) {\n\t g = groups[idx];\n\t\n\t if (g.collapsed && !gi.aggregateCollapsed) {\n\t continue;\n\t }\n\t\n\t // Do a depth-first aggregation so that parent group aggregators can access subgroup totals.\n\t if (g.groups) {\n\t addTotals(g.groups, level + 1);\n\t }\n\t\n\t if (gi.aggregators.length && (gi.aggregateEmpty || g.rows.length || g.groups && g.groups.length)) {\n\t addGroupTotals(g);\n\t }\n\t\n\t g.collapsed = groupCollapsed ^ toggledGroups[g.groupingKey];\n\t g.title = gi.formatter ? gi.formatter(g) : g.value;\n\t }\n\t }\n\t\n\t function flattenGroupedRows(groups, level) {\n\t level = level || 0;\n\t var gi = groupingInfos[level];\n\t var groupedRows = [],\n\t rows = void 0,\n\t gl = 0,\n\t g = void 0;\n\t for (var i = 0, l = groups.length; i < l; i++) {\n\t g = groups[i];\n\t groupedRows[gl++] = g;\n\t\n\t if (!g.collapsed) {\n\t rows = g.groups ? flattenGroupedRows(g.groups, level + 1) : g.rows;\n\t for (var j = 0, jj = rows.length; j < jj; j++) {\n\t groupedRows[gl++] = rows[j];\n\t }\n\t }\n\t\n\t if (g.totals && gi.displayTotalsRow && (!g.collapsed || gi.aggregateCollapsed)) {\n\t groupedRows[gl++] = g.totals;\n\t }\n\t }\n\t return groupedRows;\n\t }\n\t\n\t function getFunctionInfo(fn) {\n\t var fnRegex = /^function[^(]*\\(([^)]*)\\)\\s*{([\\s\\S]*)}$/;\n\t var matches = fn.toString().match(fnRegex);\n\t return {\n\t params: matches[1].split(','),\n\t body: matches[2]\n\t };\n\t }\n\t\n\t function compileAccumulatorLoop(aggregator) {\n\t var accumulatorInfo = getFunctionInfo(aggregator.accumulate);\n\t var fn = new Function('_items', 'for (let ' + accumulatorInfo.params[0] + ', _i=0, _il=_items.length; _i<_il; _i++) {' + accumulatorInfo.params[0] + ' = _items[_i]; ' + accumulatorInfo.body + '}');\n\t fn.displayName = 'compiledAccumulatorLoop';\n\t return fn;\n\t }\n\t\n\t function compileFilter() {\n\t var filterInfo = getFunctionInfo(filter);\n\t\n\t var filterPath1 = '{ continue _coreloop; }$1';\n\t var filterPath2 = '{ _retval[_idx++] = $item$; continue _coreloop; }$1';\n\t // make some allowances for minification - there's only so far we can go with RegEx\n\t var filterBody = filterInfo.body.replace(/return false\\s*([;}]|\\}|$)/gi, filterPath1).replace(/return!1([;}]|\\}|$)/gi, filterPath1).replace(/return true\\s*([;}]|\\}|$)/gi, filterPath2).replace(/return!0([;}]|\\}|$)/gi, filterPath2).replace(/return ([^;}]+?)\\s*([;}]|$)/gi, '{ if ($1) { _retval[_idx++] = $item$; }; continue _coreloop; }$2');\n\t\n\t // This preserves the function template code after JS compression,\n\t // so that replace() commands still work as expected.\n\t var tpl = [\n\t // \"function(_items, _args) { \",\n\t 'let _retval = [], _idx = 0; ', 'let $item$, $args$ = _args; ', '_coreloop: ', 'for (let _i = 0, _il = _items.length; _i < _il; _i++) { ', '$item$ = _items[_i]; ', '$filter$; ', '} ', 'return _retval; '\n\t // \"}\"\n\t ].join('');\n\t tpl = tpl.replace(/\\$filter\\$/gi, filterBody);\n\t tpl = tpl.replace(/\\$item\\$/gi, filterInfo.params[0]);\n\t tpl = tpl.replace(/\\$args\\$/gi, filterInfo.params[1]);\n\t\n\t var fn = new Function('_items,_args', tpl);\n\t fn.displayName = 'compiledFilter';\n\t\n\t return fn;\n\t }\n\t\n\t function compileFilterWithCaching() {\n\t var filterInfo = getFunctionInfo(filter);\n\t\n\t var filterPath1 = '{ continue _coreloop; }$1';\n\t var filterPath2 = '{ _cache[_i] = true;_retval[_idx++] = $item$; continue _coreloop; }$1';\n\t // make some allowances for minification - there's only so far we can go with RegEx\n\t var filterBody = filterInfo.body.replace(/return false\\s*([;}]|\\}|$)/gi, filterPath1).replace(/return!1([;}]|\\}|$)/gi, filterPath1).replace(/return true\\s*([;}]|\\}|$)/gi, filterPath2).replace(/return!0([;}]|\\}|$)/gi, filterPath2).replace(/return ([^;}]+?)\\s*([;}]|$)/gi, '{ if ((_cache[_i] = $1)) { _retval[_idx++] = $item$; }; continue _coreloop; }$2');\n\t\n\t // This preserves the function template code after JS compression,\n\t // so that replace() commands still work as expected.\n\t var tpl = [\n\t // \"function(_items, _args, _cache) { \",\n\t 'let _retval = [], _idx = 0; ', 'let $item$, $args$ = _args; ', '_coreloop: ', 'for (let _i = 0, _il = _items.length; _i < _il; _i++) { ', '$item$ = _items[_i]; ', 'if (_cache[_i]) { ', '_retval[_idx++] = $item$; ', 'continue _coreloop; ', '} ', '$filter$; ', '} ', 'return _retval; '\n\t // \"}\"\n\t ].join('');\n\t tpl = tpl.replace(/\\$filter\\$/gi, filterBody);\n\t tpl = tpl.replace(/\\$item\\$/gi, filterInfo.params[0]);\n\t tpl = tpl.replace(/\\$args\\$/gi, filterInfo.params[1]);\n\t\n\t var fn = new Function('_items,_args,_cache', tpl);\n\t fn.displayName = 'compiledFilterWithCaching';\n\t return fn;\n\t }\n\t\n\t function uncompiledFilter(items, args) {\n\t var retval = [],\n\t idx = 0;\n\t\n\t for (var i = 0, ii = items.length; i < ii; i++) {\n\t if (filter(items[i], args)) {\n\t retval[idx++] = items[i];\n\t }\n\t }\n\t\n\t return retval;\n\t }\n\t\n\t function uncompiledFilterWithCaching(items, args, cache) {\n\t var retval = [],\n\t idx = 0,\n\t item = void 0;\n\t\n\t for (var i = 0, ii = items.length; i < ii; i++) {\n\t item = items[i];\n\t if (cache[i]) {\n\t retval[idx++] = item;\n\t } else if (filter(item, args)) {\n\t retval[idx++] = item;\n\t cache[i] = true;\n\t }\n\t }\n\t\n\t return retval;\n\t }\n\t\n\t function getFilteredAndPagedItems(items) {\n\t if (filter) {\n\t var batchFilter = options.inlineFilters ? compiledFilter : uncompiledFilter;\n\t var batchFilterWithCaching = options.inlineFilters ? compiledFilterWithCaching : uncompiledFilterWithCaching;\n\t\n\t if (refreshHints.isFilterNarrowing) {\n\t filteredItems = batchFilter(filteredItems, filterArgs);\n\t } else if (refreshHints.isFilterExpanding) {\n\t filteredItems = batchFilterWithCaching(items, filterArgs, filterCache);\n\t } else if (!refreshHints.isFilterUnchanged) {\n\t filteredItems = batchFilter(items, filterArgs);\n\t }\n\t } else {\n\t // special case: if not filtering and not paging, the resulting\n\t // rows collection needs to be a copy so that changes due to sort\n\t // can be caught\n\t filteredItems = pagesize ? items : items.concat();\n\t }\n\t\n\t // get the current page\n\t var paged = void 0;\n\t if (pagesize) {\n\t if (filteredItems.length < pagenum * pagesize) {\n\t pagenum = Math.floor(filteredItems.length / pagesize);\n\t }\n\t paged = filteredItems.slice(pagesize * pagenum, pagesize * pagenum + pagesize);\n\t } else {\n\t paged = filteredItems;\n\t }\n\t\n\t return { totalRows: filteredItems.length, rows: paged };\n\t }\n\t\n\t function getRowDiffs(rows, newRows) {\n\t var item = void 0,\n\t r = void 0,\n\t eitherIsNonData = void 0,\n\t diff = [];\n\t var from = 0,\n\t to = newRows.length;\n\t\n\t if (refreshHints && refreshHints.ignoreDiffsBefore) {\n\t from = Math.max(0, Math.min(newRows.length, refreshHints.ignoreDiffsBefore));\n\t }\n\t\n\t if (refreshHints && refreshHints.ignoreDiffsAfter) {\n\t to = Math.min(newRows.length, Math.max(0, refreshHints.ignoreDiffsAfter));\n\t }\n\t\n\t for (var i = from, rl = rows.length; i < to; i++) {\n\t if (i >= rl) {\n\t diff[diff.length] = i;\n\t } else {\n\t item = newRows[i];\n\t r = rows[i];\n\t\n\t if (groupingInfos.length && (eitherIsNonData = item.__nonDataRow || r.__nonDataRow) && item.__group !== r.__group || item.__group && !item.equals(r) || eitherIsNonData && (\n\t // no good way to compare totals since they are arbitrary DTOs\n\t // deep object comparison is pretty expensive\n\t // always considering them 'dirty' seems easier for the time being\n\t item.__groupTotals || r.__groupTotals) || item[idProperty] != r[idProperty] || updated && updated[item[idProperty]]) {\n\t diff[diff.length] = i;\n\t }\n\t }\n\t }\n\t return diff;\n\t }\n\t\n\t function recalc(_items) {\n\t rowsById = null;\n\t\n\t if (refreshHints.isFilterNarrowing != prevRefreshHints.isFilterNarrowing || refreshHints.isFilterExpanding != prevRefreshHints.isFilterExpanding) {\n\t filterCache = [];\n\t }\n\t\n\t var filteredItems = getFilteredAndPagedItems(_items);\n\t totalRows = filteredItems.totalRows;\n\t var newRows = filteredItems.rows;\n\t\n\t groups = [];\n\t if (groupingInfos.length) {\n\t groups = extractGroups(newRows);\n\t if (groups.length) {\n\t addTotals(groups);\n\t newRows = flattenGroupedRows(groups);\n\t }\n\t }\n\t\n\t var diff = getRowDiffs(rows, newRows);\n\t\n\t rows = newRows;\n\t\n\t return diff;\n\t }\n\t\n\t function refresh() {\n\t if (suspend) {\n\t return;\n\t }\n\t\n\t var countBefore = rows.length;\n\t var totalRowsBefore = totalRows;\n\t\n\t var diff = recalc(items, filter); // pass as direct refs to avoid closure perf hit\n\t\n\t // if the current page is no longer valid, go to last page and recalc\n\t // we suffer a performance penalty here, but the main loop (recalc) remains highly optimized\n\t if (pagesize && totalRows < pagenum * pagesize) {\n\t pagenum = Math.max(0, Math.ceil(totalRows / pagesize) - 1);\n\t diff = recalc(items, filter);\n\t }\n\t\n\t updated = null;\n\t prevRefreshHints = refreshHints;\n\t refreshHints = {};\n\t\n\t if (totalRowsBefore !== totalRows) {\n\t onPagingInfoChanged.notify(getPagingInfo(), null, self);\n\t }\n\t if (countBefore !== rows.length) {\n\t onRowCountChanged.notify({ previous: countBefore, current: rows.length, dataView: self }, null, self);\n\t }\n\t if (diff.length > 0) {\n\t onRowsChanged.notify({ rows: diff, dataView: self }, null, self);\n\t }\n\t }\n\t\n\t /** *\n\t * Wires the grid and the DataView together to keep row selection tied to item ids.\n\t * This is useful since, without it, the grid only knows about rows, so if the items\n\t * move around, the same rows stay selected instead of the selection moving along\n\t * with the items.\n\t *\n\t * NOTE: This doesn't work with cell selection model.\n\t *\n\t * @param grid {Slick.Grid} The grid to sync selection with.\n\t * @param preserveHidden {Boolean} Whether to keep selected items that go out of the\n\t * view due to them getting filtered out.\n\t * @param preserveHiddenOnSelectionChange {Boolean} Whether to keep selected items\n\t * that are currently out of the view (see preserveHidden) as selected when selection\n\t * changes.\n\t * @return {Slick.Event} An event that notifies when an internal list of selected row ids\n\t * changes. This is useful since, in combination with the above two options, it allows\n\t * access to the full list selected row ids, and not just the ones visible to the grid.\n\t * @method syncGridSelection\n\t */\n\t function syncGridSelection(grid, preserveHidden, preserveHiddenOnSelectionChange) {\n\t var self = this;\n\t var inHandler = void 0;\n\t var selectedRowIds = self.mapRowsToIds(grid.getSelectedRows());\n\t var onSelectedRowIdsChanged = new _slick2.default.Event();\n\t\n\t function setSelectedRowIds(rowIds) {\n\t if (selectedRowIds.join(',') == rowIds.join(',')) {\n\t return;\n\t }\n\t\n\t selectedRowIds = rowIds;\n\t\n\t onSelectedRowIdsChanged.notify({\n\t 'grid': grid,\n\t 'ids': selectedRowIds,\n\t 'dataView': self\n\t }, new _slick2.default.EventData(), self);\n\t }\n\t\n\t function update() {\n\t if (selectedRowIds.length > 0) {\n\t inHandler = true;\n\t var selectedRows = self.mapIdsToRows(selectedRowIds);\n\t if (!preserveHidden) {\n\t setSelectedRowIds(self.mapRowsToIds(selectedRows));\n\t }\n\t grid.setSelectedRows(selectedRows);\n\t inHandler = false;\n\t }\n\t }\n\t\n\t grid.onSelectedRowsChanged.subscribe(function (e, args) {\n\t if (inHandler) {\n\t return;\n\t }\n\t var newSelectedRowIds = self.mapRowsToIds(grid.getSelectedRows());\n\t if (!preserveHiddenOnSelectionChange || !grid.getOptions().multiSelect) {\n\t setSelectedRowIds(newSelectedRowIds);\n\t } else {\n\t // keep the ones that are hidden\n\t var existing = _jquery2.default.grep(selectedRowIds, function (id) {\n\t return self.getRowById(id) === undefined;\n\t });\n\t // add the newly selected ones\n\t setSelectedRowIds(existing.concat(newSelectedRowIds));\n\t }\n\t });\n\t\n\t this.onRowsChanged.subscribe(update);\n\t\n\t this.onRowCountChanged.subscribe(update);\n\t\n\t return onSelectedRowIdsChanged;\n\t }\n\t\n\t function syncGridCellCssStyles(grid, key) {\n\t var hashById = void 0;\n\t var inHandler = void 0;\n\t\n\t // since this method can be called after the cell styles have been set,\n\t // get the existing ones right away\n\t storeCellCssStyles(grid.getCellCssStyles(key));\n\t\n\t function storeCellCssStyles(hash) {\n\t hashById = {};\n\t for (var row in hash) {\n\t var id = rows[row][idProperty];\n\t hashById[id] = hash[row];\n\t }\n\t }\n\t\n\t function update() {\n\t if (hashById) {\n\t inHandler = true;\n\t ensureRowsByIdCache();\n\t var newHash = {};\n\t for (var id in hashById) {\n\t var row = rowsById[id];\n\t if (row != undefined) {\n\t newHash[row] = hashById[id];\n\t }\n\t }\n\t grid.setCellCssStyles(key, newHash);\n\t inHandler = false;\n\t }\n\t }\n\t\n\t grid.onCellCssStylesChanged.subscribe(function (e, args) {\n\t if (inHandler) {\n\t return;\n\t }\n\t if (key != args.key) {\n\t return;\n\t }\n\t if (args.hash) {\n\t storeCellCssStyles(args.hash);\n\t }\n\t });\n\t\n\t this.onRowsChanged.subscribe(update);\n\t\n\t this.onRowCountChanged.subscribe(update);\n\t }\n\t\n\t _jquery2.default.extend(this, {\n\t // methods\n\t 'beginUpdate': beginUpdate,\n\t 'endUpdate': endUpdate,\n\t 'setPagingOptions': setPagingOptions,\n\t 'getPagingInfo': getPagingInfo,\n\t 'getItems': getItems,\n\t 'setItems': setItems,\n\t 'setFilter': setFilter,\n\t 'sort': sort,\n\t 'fastSort': fastSort,\n\t 'reSort': reSort,\n\t 'setGrouping': setGrouping,\n\t 'getGrouping': getGrouping,\n\t 'groupBy': groupBy,\n\t 'setAggregators': setAggregators,\n\t 'collapseAllGroups': collapseAllGroups,\n\t 'expandAllGroups': expandAllGroups,\n\t 'collapseGroup': collapseGroup,\n\t 'expandGroup': expandGroup,\n\t 'getGroups': getGroups,\n\t 'getIdxById': getIdxById,\n\t 'getRowById': getRowById,\n\t 'getItemById': getItemById,\n\t 'getItemByIdx': getItemByIdx,\n\t 'mapRowsToIds': mapRowsToIds,\n\t 'mapIdsToRows': mapIdsToRows,\n\t 'setRefreshHints': setRefreshHints,\n\t 'setFilterArgs': setFilterArgs,\n\t 'refresh': refresh,\n\t 'updateItem': updateItem,\n\t 'insertItem': insertItem,\n\t 'addItem': addItem,\n\t 'deleteItem': deleteItem,\n\t 'syncGridSelection': syncGridSelection,\n\t 'syncGridCellCssStyles': syncGridCellCssStyles,\n\t\n\t // data provider methods\n\t 'getLength': getLength,\n\t 'getItem': getItem,\n\t 'getItemMetadata': getItemMetadata,\n\t\n\t // events\n\t 'onRowCountChanged': onRowCountChanged,\n\t 'onRowsChanged': onRowsChanged,\n\t 'onPagingInfoChanged': onPagingInfoChanged\n\t });\n\t}\n\t\n\tfunction AvgAggregator(field) {\n\t this.field_ = field;\n\t\n\t this.init = function () {\n\t this.count_ = 0;\n\t this.nonNullCount_ = 0;\n\t this.sum_ = 0;\n\t };\n\t\n\t this.accumulate = function (item) {\n\t var val = item[this.field_];\n\t this.count_++;\n\t if (val != null && val !== '' && !isNaN(val)) {\n\t this.nonNullCount_++;\n\t this.sum_ += parseFloat(val);\n\t }\n\t };\n\t\n\t this.storeResult = function (groupTotals) {\n\t if (!groupTotals.avg) {\n\t groupTotals.avg = {};\n\t }\n\t if (this.nonNullCount_ != 0) {\n\t groupTotals.avg[this.field_] = this.sum_ / this.nonNullCount_;\n\t }\n\t };\n\t}\n\t\n\tfunction MinAggregator(field) {\n\t this.field_ = field;\n\t\n\t this.init = function () {\n\t this.min_ = null;\n\t };\n\t\n\t this.accumulate = function (item) {\n\t var val = item[this.field_];\n\t if (val != null && val !== '' && !isNaN(val)) {\n\t if (this.min_ == null || val < this.min_) {\n\t this.min_ = val;\n\t }\n\t }\n\t };\n\t\n\t this.storeResult = function (groupTotals) {\n\t if (!groupTotals.min) {\n\t groupTotals.min = {};\n\t }\n\t groupTotals.min[this.field_] = this.min_;\n\t };\n\t}\n\t\n\tfunction MaxAggregator(field) {\n\t this.field_ = field;\n\t\n\t this.init = function () {\n\t this.max_ = null;\n\t };\n\t\n\t this.accumulate = function (item) {\n\t var val = item[this.field_];\n\t if (val != null && val !== '' && !isNaN(val)) {\n\t if (this.max_ == null || val > this.max_) {\n\t this.max_ = val;\n\t }\n\t }\n\t };\n\t\n\t this.storeResult = function (groupTotals) {\n\t if (!groupTotals.max) {\n\t groupTotals.max = {};\n\t }\n\t groupTotals.max[this.field_] = this.max_;\n\t };\n\t}\n\t\n\tfunction SumAggregator(field) {\n\t this.field_ = field;\n\t\n\t this.init = function () {\n\t this.sum_ = null;\n\t };\n\t\n\t this.accumulate = function (item) {\n\t var val = item[this.field_];\n\t if (val != null && val !== '' && !isNaN(val)) {\n\t this.sum_ += parseFloat(val);\n\t }\n\t };\n\t\n\t this.storeResult = function (groupTotals) {\n\t if (!groupTotals.sum) {\n\t groupTotals.sum = {};\n\t }\n\t groupTotals.sum[this.field_] = this.sum_;\n\t };\n\t}\n\n/***/ }),\n/* 28 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _slick = __webpack_require__(1);\n\t\n\tvar _slick2 = _interopRequireDefault(_slick);\n\t\n\tvar _flatpickr = __webpack_require__(32);\n\t\n\tvar _flatpickr2 = _interopRequireDefault(_flatpickr);\n\t\n\tvar _jquery = __webpack_require__(2);\n\t\n\tvar _jquery2 = _interopRequireDefault(_jquery);\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\t\n\tvar keyCode = _slick2.default.keyCode;\n\t\n\t/** *\n\t * Contains basic SlickGrid editors.\n\t * @module Editors\n\t * @namespace Slick\n\t */\n\t\n\t//import 'flatpickr/dist/flatpickr.min.css';\n\t\n\tvar Editors = {\n\t Text: TextEditor,\n\t Integer: IntegerEditor,\n\t Float: FloatEditor,\n\t Date: DateEditor,\n\t YesNoSelect: YesNoSelectEditor,\n\t Checkbox: CheckboxEditor,\n\t LongText: LongTextEditor\n\t};\n\t\n\t_slick2.default.Editors = Editors;\n\texports.default = Editors;\n\t\n\t\n\tfunction TextEditor(args) {\n\t var $input = void 0;\n\t var defaultValue = void 0;\n\t\n\t this.init = function () {\n\t $input = (0, _jquery2.default)(\"\").appendTo(args.container).bind('keydown.nav', function (e) {\n\t if (e.keyCode === keyCode.LEFT || e.keyCode === keyCode.RIGHT) {\n\t e.stopImmediatePropagation();\n\t }\n\t }).focus().select();\n\t };\n\t\n\t this.destroy = function () {\n\t $input.remove();\n\t };\n\t\n\t this.focus = function () {\n\t $input.focus();\n\t };\n\t\n\t this.getValue = function () {\n\t return $input.val();\n\t };\n\t\n\t this.setValue = function (val) {\n\t $input.val(val);\n\t };\n\t\n\t this.loadValue = function (item) {\n\t defaultValue = item[args.column.field] || '';\n\t $input.val(defaultValue);\n\t $input[0].defaultValue = defaultValue;\n\t $input.select();\n\t };\n\t\n\t this.serializeValue = function () {\n\t return $input.val();\n\t };\n\t\n\t this.applyValue = function (item, state) {\n\t item[args.column.field] = state;\n\t };\n\t\n\t this.isValueChanged = function () {\n\t return !($input.val() == '' && defaultValue == null) && $input.val() != defaultValue;\n\t };\n\t\n\t this.validate = function () {\n\t var valid = true;\n\t var msg = null;\n\t if (args.column.validator) {\n\t var validationResults = args.column.validator($input.val(), args);\n\t valid = validationResults.valid;\n\t msg = validationResults.msg;\n\t }\n\t\n\t return {\n\t valid: true,\n\t msg: null\n\t };\n\t };\n\t\n\t this.init();\n\t}\n\t\n\tfunction IntegerEditor(args) {\n\t var $input = void 0;\n\t var defaultValue = void 0;\n\t\n\t this.init = function () {\n\t $input = (0, _jquery2.default)(\"\");\n\t\n\t $input.bind('keydown.nav', function (e) {\n\t if (e.keyCode === keyCode.LEFT || e.keyCode === keyCode.RIGHT) {\n\t e.stopImmediatePropagation();\n\t }\n\t });\n\t\n\t $input.appendTo(args.container);\n\t $input.focus().select();\n\t };\n\t\n\t this.destroy = function () {\n\t $input.remove();\n\t };\n\t\n\t this.focus = function () {\n\t $input.focus();\n\t };\n\t\n\t this.loadValue = function (item) {\n\t defaultValue = item[args.column.field];\n\t $input.val(defaultValue);\n\t $input[0].defaultValue = defaultValue;\n\t $input.select();\n\t };\n\t\n\t this.serializeValue = function () {\n\t return parseInt($input.val(), 10) || 0;\n\t };\n\t\n\t this.applyValue = function (item, state) {\n\t item[args.column.field] = state;\n\t };\n\t\n\t this.isValueChanged = function () {\n\t return !($input.val() == '' && defaultValue == null) && $input.val() != defaultValue;\n\t };\n\t\n\t this.validate = function () {\n\t if (isNaN($input.val())) {\n\t return {\n\t valid: false,\n\t msg: 'Please enter a valid integer'\n\t };\n\t }\n\t\n\t if (args.column.validator) {\n\t var validationResults = args.column.validator($input.val());\n\t if (!validationResults.valid) {\n\t return validationResults;\n\t }\n\t }\n\t\n\t return {\n\t valid: true,\n\t msg: null\n\t };\n\t };\n\t\n\t this.init();\n\t}\n\t\n\tfunction FloatEditor(args) {\n\t var $input = void 0;\n\t var defaultValue = void 0;\n\t var scope = this;\n\t\n\t this.init = function () {\n\t $input = (0, _jquery2.default)(\"\");\n\t\n\t $input.bind('keydown.nav', function (e) {\n\t if (e.keyCode === keyCode.LEFT || e.keyCode === keyCode.RIGHT) {\n\t e.stopImmediatePropagation();\n\t }\n\t });\n\t\n\t $input.appendTo(args.container);\n\t $input.focus().select();\n\t };\n\t\n\t this.destroy = function () {\n\t $input.remove();\n\t };\n\t\n\t this.focus = function () {\n\t $input.focus();\n\t };\n\t\n\t function getDecimalPlaces() {\n\t // returns the number of fixed decimal places or null\n\t var rtn = args.column.editorFixedDecimalPlaces;\n\t if (typeof rtn == 'undefined') {\n\t rtn = FloatEditor.DefaultDecimalPlaces;\n\t }\n\t return !rtn && rtn !== 0 ? null : rtn;\n\t }\n\t\n\t this.loadValue = function (item) {\n\t defaultValue = item[args.column.field];\n\t\n\t var decPlaces = getDecimalPlaces();\n\t if (decPlaces !== null && (defaultValue || defaultValue === 0) && defaultValue.toFixed) {\n\t defaultValue = defaultValue.toFixed(decPlaces);\n\t }\n\t\n\t $input.val(defaultValue);\n\t $input[0].defaultValue = defaultValue;\n\t $input.select();\n\t };\n\t\n\t this.serializeValue = function () {\n\t var rtn = parseFloat($input.val()) || 0;\n\t\n\t var decPlaces = getDecimalPlaces();\n\t if (decPlaces !== null && (rtn || rtn === 0) && rtn.toFixed) {\n\t rtn = parseFloat(rtn.toFixed(decPlaces));\n\t }\n\t\n\t return rtn;\n\t };\n\t\n\t this.applyValue = function (item, state) {\n\t item[args.column.field] = state;\n\t };\n\t\n\t this.isValueChanged = function () {\n\t return !($input.val() == '' && defaultValue == null) && $input.val() != defaultValue;\n\t };\n\t\n\t this.validate = function () {\n\t if (isNaN($input.val())) {\n\t return {\n\t valid: false,\n\t msg: 'Please enter a valid number'\n\t };\n\t }\n\t\n\t if (args.column.validator) {\n\t var validationResults = args.column.validator($input.val(), args);\n\t if (!validationResults.valid) {\n\t return validationResults;\n\t }\n\t }\n\t\n\t return {\n\t valid: true,\n\t msg: null\n\t };\n\t };\n\t\n\t this.init();\n\t}\n\t\n\tFloatEditor.DefaultDecimalPlaces = null;\n\t\n\t/**\n\t * see https://chmln.github.io/flatpickr/#options - pass as column.options.date = {}\n\t * @param args\n\t * @constructor\n\t */\n\tfunction DateEditor(args) {\n\t var $input = void 0,\n\t flatInstance = void 0,\n\t defaultDate = void 0,\n\t options = args.column.options && args.column.options.date ? args.column.options.date : {};\n\t\n\t this.init = function () {\n\t defaultDate = options.defaultDate = args.item[args.column.field];\n\t\n\t $input = (0, _jquery2.default)('');\n\t $input.appendTo(args.container);\n\t $input.focus().val(defaultDate).select();\n\t flatInstance = (0, _flatpickr2.default)($input[0], options);\n\t };\n\t\n\t this.destroy = function () {\n\t flatInstance.destroy();\n\t $input.remove();\n\t };\n\t\n\t this.show = function () {\n\t flatInstance.open();\n\t flatInstance.positionCalendar();\n\t };\n\t\n\t this.hide = function () {\n\t flatInstance.close();\n\t };\n\t\n\t this.position = function (position) {\n\t //todo: fix how scrolling is affected\n\t flatInstance.positionCalendar();\n\t };\n\t\n\t this.focus = function () {\n\t $input.focus();\n\t };\n\t\n\t this.loadValue = function (item) {\n\t defaultDate = item[args.column.field];\n\t $input.val(defaultDate);\n\t $input.select();\n\t };\n\t\n\t this.serializeValue = function () {\n\t return $input.val();\n\t };\n\t\n\t this.applyValue = function (item, state) {\n\t item[args.column.field] = state;\n\t };\n\t\n\t this.isValueChanged = function () {\n\t return !($input.val() == '' && defaultDate == null) && $input.val() != defaultDate;\n\t };\n\t\n\t this.validate = function () {\n\t if (args.column.validator) {\n\t var validationResults = args.column.validator($input.val(), args);\n\t if (!validationResults.valid) {\n\t return validationResults;\n\t }\n\t }\n\t\n\t return {\n\t valid: true,\n\t msg: null\n\t };\n\t };\n\t\n\t this.init();\n\t}\n\t\n\tfunction YesNoSelectEditor(args) {\n\t var $select = void 0;\n\t var defaultValue = void 0;\n\t var scope = this;\n\t\n\t this.init = function () {\n\t $select = (0, _jquery2.default)(\"\");\n\t $select.appendTo(args.container);\n\t $select.focus();\n\t };\n\t\n\t this.destroy = function () {\n\t $select.remove();\n\t };\n\t\n\t this.focus = function () {\n\t $select.focus();\n\t };\n\t\n\t this.loadValue = function (item) {\n\t $select.val((defaultValue = item[args.column.field]) ? 'yes' : 'no');\n\t $select.select();\n\t };\n\t\n\t this.serializeValue = function () {\n\t return $select.val() == 'yes';\n\t };\n\t\n\t this.applyValue = function (item, state) {\n\t item[args.column.field] = state;\n\t };\n\t\n\t this.isValueChanged = function () {\n\t return $select.val() != defaultValue;\n\t };\n\t\n\t this.validate = function () {\n\t var valid = true;\n\t var msg = null;\n\t if (args.column.validator) {\n\t var validationResults = args.column.validator($select.val(), args);\n\t valid = validationResults.valid;\n\t msg = validationResults.msg;\n\t }\n\t\n\t return {\n\t valid: true,\n\t msg: null\n\t };\n\t };\n\t\n\t this.init();\n\t}\n\t\n\tfunction CheckboxEditor(args) {\n\t var $select = void 0;\n\t var defaultValue = void 0;\n\t var scope = this;\n\t\n\t this.init = function () {\n\t $select = (0, _jquery2.default)(\"\");\n\t $select.appendTo(args.container);\n\t $select.focus();\n\t };\n\t\n\t this.destroy = function () {\n\t $select.remove();\n\t };\n\t\n\t this.focus = function () {\n\t $select.focus();\n\t };\n\t\n\t this.loadValue = function (item) {\n\t defaultValue = !!item[args.column.field];\n\t if (defaultValue) {\n\t $select.prop('checked', true);\n\t } else {\n\t $select.prop('checked', false);\n\t }\n\t };\n\t\n\t this.serializeValue = function () {\n\t return $select.prop('checked');\n\t };\n\t\n\t this.applyValue = function (item, state) {\n\t item[args.column.field] = state;\n\t };\n\t\n\t this.isValueChanged = function () {\n\t return this.serializeValue() !== defaultValue;\n\t };\n\t\n\t this.validate = function () {\n\t var valid = true;\n\t var msg = null;\n\t if (args.column.validator) {\n\t var validationResults = args.column.validator($select.val(), args);\n\t valid = validationResults.valid;\n\t msg = validationResults.msg;\n\t }\n\t\n\t return {\n\t valid: true,\n\t msg: null\n\t };\n\t };\n\t\n\t this.init();\n\t}\n\t\n\tfunction PercentCompleteEditor(args) {\n\t console.error('PercentCompleteEditor is derecated');\n\t}\n\t\n\t/*\n\t * An example of a \"detached\" editor.\n\t * The UI is added onto document BODY and .position(), .show() and .hide() are implemented.\n\t * KeyDown events are also handled to provide handling for Tab, Shift-Tab, Esc and Ctrl-Enter.\n\t */\n\tfunction LongTextEditor(args) {\n\t var $input = void 0,\n\t $wrapper = void 0;\n\t var defaultValue = void 0;\n\t var scope = this;\n\t\n\t this.init = function () {\n\t var $container = (0, _jquery2.default)('body');\n\t\n\t $wrapper = (0, _jquery2.default)(\"\").appendTo($container);\n\t $input = (0, _jquery2.default)(\"\").appendTo($wrapper);\n\t\n\t (0, _jquery2.default)(\"
\").appendTo($wrapper);\n\t\n\t $wrapper.find('button:first').bind('click', this.save);\n\t $wrapper.find('button:last').bind('click', this.cancel);\n\t $input.bind('keydown', this.handleKeyDown);\n\t\n\t scope.position(args.position);\n\t $input.focus().select();\n\t };\n\t\n\t this.handleKeyDown = function (e) {\n\t if (e.which == keyCode.ENTER && e.ctrlKey) {\n\t scope.save();\n\t } else if (e.which == keyCode.ESCAPE) {\n\t e.preventDefault();\n\t scope.cancel();\n\t } else if (e.which == keyCode.TAB && e.shiftKey) {\n\t e.preventDefault();\n\t args.grid.navigatePrev();\n\t } else if (e.which == keyCode.TAB) {\n\t e.preventDefault();\n\t args.grid.navigateNext();\n\t }\n\t };\n\t\n\t this.save = function () {\n\t args.commitChanges();\n\t };\n\t\n\t this.cancel = function () {\n\t $input.val(defaultValue);\n\t args.cancelChanges();\n\t };\n\t\n\t this.hide = function () {\n\t $wrapper.hide();\n\t };\n\t\n\t this.show = function () {\n\t $wrapper.show();\n\t };\n\t\n\t this.position = function (position) {\n\t $wrapper.css('top', position.top - 5).css('left', position.left - 5);\n\t };\n\t\n\t this.destroy = function () {\n\t $wrapper.remove();\n\t };\n\t\n\t this.focus = function () {\n\t $input.focus();\n\t };\n\t\n\t this.loadValue = function (item) {\n\t $input.val(defaultValue = item[args.column.field]);\n\t $input.select();\n\t };\n\t\n\t this.serializeValue = function () {\n\t return $input.val();\n\t };\n\t\n\t this.applyValue = function (item, state) {\n\t item[args.column.field] = state;\n\t };\n\t\n\t this.isValueChanged = function () {\n\t return !($input.val() == '' && defaultValue == null) && $input.val() != defaultValue;\n\t };\n\t\n\t this.validate = function () {\n\t var valid = true;\n\t var msg = null;\n\t if (args.column.validator) {\n\t var validationResults = args.column.validator($select.val(), args);\n\t valid = validationResults.valid;\n\t msg = validationResults.msg;\n\t }\n\t\n\t return {\n\t valid: true,\n\t msg: null\n\t };\n\t };\n\t\n\t this.init();\n\t}\n\n/***/ }),\n/* 29 */\n/***/ (function(module, exports) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\tfunction PercentCompleteFormatter(row, cell, value, columnDef, dataContext) {\n\t if (value == null || value === '') {\n\t return '-';\n\t } else if (value < 50) {\n\t return '' + value + '%';\n\t } else {\n\t return '' + value + '%';\n\t }\n\t}\n\t\n\tfunction PercentCompleteBarFormatter(row, cell, value, columnDef, dataContext) {\n\t if (value == null || value === '') {\n\t return '';\n\t }\n\t\n\t var color = void 0;\n\t\n\t if (value < 30) {\n\t color = 'red';\n\t } else if (value < 70) {\n\t color = 'silver';\n\t } else {\n\t color = 'green';\n\t }\n\t\n\t return \"\";\n\t}\n\t\n\tfunction YesNoFormatter(row, cell, value, columnDef, dataContext) {\n\t return value ? 'Yes' : 'No';\n\t}\n\t\n\tfunction CheckmarkFormatter(row, cell, value, columnDef, dataContext) {\n\t return value ? '✔' : '';\n\t}\n\t\n\texports.default = {\n\t PercentComplete: PercentCompleteFormatter,\n\t PercentCompleteBar: PercentCompleteBarFormatter,\n\t YesNo: YesNoFormatter,\n\t Checkmark: CheckmarkFormatter\n\t};\n\n/***/ }),\n/* 30 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _jquery = __webpack_require__(2);\n\t\n\tvar _jquery2 = _interopRequireDefault(_jquery);\n\t\n\tvar _interact = __webpack_require__(5);\n\t\n\tvar _interact2 = _interopRequireDefault(_interact);\n\t\n\tvar _slick = __webpack_require__(1);\n\t\n\tvar _slick2 = _interopRequireDefault(_slick);\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\t\n\t// Slick.Grid globals pretense\n\t_slick2.default.Grid = SlickGrid; /**\n\t * @license\n\t * (c) 2009-2013 Michael Leibman\n\t * michael{dot}leibman{at}gmail{dot}com\n\t * http://github.com/mleibman/slickgrid\n\t *\n\t * Distributed under MIT license.\n\t * All rights reserved.\n\t *\n\t * SlickGrid v2.2\n\t *\n\t * NOTES:\n\t * Cell/row DOM manipulations are done directly bypassing jQuery's DOM manipulation methods.\n\t * This increases the speed dramatically, but can only be done safely because there are no event handlers\n\t * or data associated with any cell/row DOM nodes. Cell editors must make sure they implement .destroy()\n\t * and do proper cleanup.\n\t */\n\t\n\texports.default = SlickGrid;\n\t\n\t// shared across all grids on the page\n\t\n\tvar scrollbarDimensions;\n\tvar maxSupportedCssHeight; // browser's breaking point\n\t\n\t// ////////////////////////////////////////////////////////////////////////////////////////////\n\t// SlickGrid class implementation (available as Slick.Grid)\n\t\n\t/**\n\t * Creates a new instance of the grid.\n\t * @class SlickGrid\n\t * @constructor\n\t * @param {Node} container Container node to create the grid in.\n\t * @param {Array,Object} data An array of objects for databinding.\n\t * @param {Array} columns An array of column definitions.\n\t * @param {Object} options Grid options.\n\t **/\n\tfunction SlickGrid(container, data, columns, options) {\n\t // settings\n\t var defaults = {\n\t explicitInitialization: false,\n\t rowHeight: 25,\n\t defaultColumnWidth: 80,\n\t enableAddRow: false,\n\t leaveSpaceForNewRows: false,\n\t editable: false,\n\t autoEdit: true,\n\t enableCellNavigation: true,\n\t enableColumnReorder: true,\n\t asyncEditorLoading: false,\n\t asyncEditorLoadDelay: 100,\n\t forceFitColumns: false,\n\t enableAsyncPostRender: false,\n\t asyncPostRenderDelay: 50,\n\t enableAsyncPostRenderCleanup: false,\n\t asyncPostRenderCleanupDelay: 40,\n\t autoHeight: false,\n\t editorLock: _slick2.default.GlobalEditorLock,\n\t showHeaderRow: false,\n\t headerRowHeight: 25,\n\t createFooterRow: false,\n\t showFooterRow: false,\n\t footerRowHeight: 25,\n\t showTopPanel: false,\n\t topPanelHeight: 25,\n\t formatterFactory: null,\n\t editorFactory: null,\n\t cellFlashingCssClass: 'flashing',\n\t selectedCellCssClass: 'selected',\n\t multiSelect: true,\n\t enableTextSelectionOnCells: false,\n\t dataItemColumnValueExtractor: null,\n\t fullWidthRows: false,\n\t multiColumnSort: false,\n\t defaultFormatter: defaultFormatter,\n\t forceSyncScrolling: false,\n\t addNewRowCssClass: 'new-row'\n\t };\n\t\n\t var columnDefaults = {\n\t name: '',\n\t resizable: true,\n\t sortable: false,\n\t minWidth: 30,\n\t rerenderOnResize: false,\n\t headerCssClass: null,\n\t defaultSortAsc: true,\n\t focusable: true,\n\t selectable: true\n\t };\n\t\n\t // scroller\n\t var th; // virtual height\n\t var h; // real scrollable height\n\t var ph; // page height\n\t var n; // number of pages\n\t var cj; // \"jumpiness\" coefficient\n\t\n\t var page = 0; // current page\n\t var offset = 0; // current page offset\n\t var vScrollDir = 1;\n\t\n\t // private\n\t var initialized = false;\n\t var $container;\n\t var uid = 'slickgrid_' + Math.round(1000000 * Math.random());\n\t var self = this;\n\t var $focusSink, $focusSink2;\n\t var $headerScroller;\n\t var $headers;\n\t var $headerRow, $headerRowScroller, $headerRowSpacer;\n\t var $footerRow, $footerRowScroller, $footerRowSpacer;\n\t var $topPanelScroller;\n\t var $topPanel;\n\t var $viewport;\n\t var $canvas;\n\t var $style;\n\t var $boundAncestors;\n\t var stylesheet, columnCssRulesL, columnCssRulesR;\n\t var viewportH, viewportW;\n\t var canvasWidth;\n\t var viewportHasHScroll, viewportHasVScroll;\n\t var headerColumnWidthDiff = 0,\n\t headerColumnHeightDiff = 0,\n\t // border+padding\n\t cellWidthDiff = 0,\n\t cellHeightDiff = 0,\n\t jQueryNewWidthBehaviour = false;\n\t var absoluteColumnMinWidth;\n\t\n\t var tabbingDirection = 1;\n\t var activePosX;\n\t var activeRow, activeCell;\n\t var activeCellNode = null;\n\t var currentEditor = null;\n\t var serializedEditorValue;\n\t var editController;\n\t\n\t var rowsCache = {};\n\t var renderedRows = 0;\n\t var numVisibleRows;\n\t var prevScrollTop = 0;\n\t var scrollTop = 0;\n\t var lastRenderedScrollTop = 0;\n\t var lastRenderedScrollLeft = 0;\n\t var prevScrollLeft = 0;\n\t var scrollLeft = 0;\n\t\n\t var selectionModel;\n\t var selectedRows = [];\n\t\n\t var plugins = [];\n\t var cellCssClasses = {};\n\t\n\t var columnsById = {};\n\t var sortColumns = [];\n\t var columnPosLeft = [];\n\t var columnPosRight = [];\n\t\n\t // async call handles\n\t var h_editorLoader = null;\n\t var h_render = null;\n\t var h_postrender = null;\n\t var h_postrenderCleanup = null;\n\t var postProcessedRows = {};\n\t var postProcessToRow = null;\n\t var postProcessFromRow = null;\n\t var postProcessedCleanupQueue = [];\n\t var postProcessgroupId = 0;\n\t\n\t // perf counters\n\t var counter_rows_rendered = 0;\n\t var counter_rows_removed = 0;\n\t\n\t // These two variables work around a bug with inertial scrolling in Webkit/Blink on Mac.\n\t // See http://crbug.com/312427.\n\t var rowNodeFromLastMouseWheelEvent; // this node must not be deleted while inertial scrolling\n\t var zombieRowNodeFromLastMouseWheelEvent; // node that was hidden instead of getting deleted\n\t var zombieRowCacheFromLastMouseWheelEvent; // row cache for above node\n\t var zombieRowPostProcessedFromLastMouseWheelEvent; // post processing references for above node\n\t\n\t // store css attributes if display:none is active in container or parent\n\t var cssShow = { position: 'absolute', visibility: 'hidden', display: 'block' };\n\t var $hiddenParents;\n\t var oldProps = [];\n\t\n\t // ////////////////////////////////////////////////////////////////////////////////////////////\n\t // Initialization\n\t\n\t function init() {\n\t $container = (0, _jquery2.default)(container);\n\t if ($container.length < 1) {\n\t throw new Error('SlickGrid requires a valid container, ' + container + ' does not exist in the DOM.');\n\t }\n\t\n\t cacheCssForHiddenInit();\n\t\n\t // calculate these only once and share between grid instances\n\t maxSupportedCssHeight = maxSupportedCssHeight || getMaxSupportedCssHeight();\n\t scrollbarDimensions = scrollbarDimensions || measureScrollbar();\n\t\n\t options = _jquery2.default.extend({}, defaults, options);\n\t validateAndEnforceOptions();\n\t columnDefaults.width = options.defaultColumnWidth;\n\t\n\t columnsById = {};\n\t for (var i = 0; i < columns.length; i++) {\n\t var m = columns[i] = _jquery2.default.extend({}, columnDefaults, columns[i]);\n\t columnsById[m.id] = i;\n\t if (m.minWidth && m.width < m.minWidth) {\n\t m.width = m.minWidth;\n\t }\n\t if (m.maxWidth && m.width > m.maxWidth) {\n\t m.width = m.maxWidth;\n\t }\n\t }\n\t\n\t editController = {\n\t 'commitCurrentEdit': commitCurrentEdit,\n\t 'cancelCurrentEdit': cancelCurrentEdit\n\t };\n\t\n\t $container.empty().css('overflow', 'hidden').css('outline', 0).addClass(uid).addClass('ui-widget');\n\t\n\t // set up a positioning container if needed\n\t if (!/relative|absolute|fixed/.test($container.css('position'))) {\n\t $container.css('position', 'relative');\n\t }\n\t\n\t $focusSink = (0, _jquery2.default)(\"\").appendTo($container);\n\t\n\t $headerScroller = (0, _jquery2.default)(\"\").appendTo($container);\n\t $headers = (0, _jquery2.default)(\"\").appendTo($headerScroller);\n\t $headers.width(getHeadersWidth());\n\t\n\t $headerRowScroller = (0, _jquery2.default)(\"\").appendTo($container);\n\t $headerRow = (0, _jquery2.default)(\"\").appendTo($headerRowScroller);\n\t $headerRowSpacer = (0, _jquery2.default)(\"\").css('width', getCanvasWidth() + scrollbarDimensions.width + 'px').appendTo($headerRowScroller);\n\t\n\t $topPanelScroller = (0, _jquery2.default)(\"\").appendTo($container);\n\t $topPanel = (0, _jquery2.default)(\"\").appendTo($topPanelScroller);\n\t\n\t if (!options.showTopPanel) {\n\t $topPanelScroller.hide();\n\t }\n\t\n\t if (!options.showHeaderRow) {\n\t $headerRowScroller.hide();\n\t }\n\t\n\t $viewport = (0, _jquery2.default)(\"
\").appendTo($container);\n\t $viewport.css('overflow-y', options.autoHeight ? 'hidden' : 'auto');\n\t\n\t $canvas = (0, _jquery2.default)(\"\").appendTo($viewport);\n\t\n\t if (options.createFooterRow) {\n\t $footerRowScroller = (0, _jquery2.default)(\"\").appendTo($container);\n\t $footerRow = (0, _jquery2.default)(\"\").appendTo($footerRowScroller);\n\t $footerRowSpacer = (0, _jquery2.default)(\"\").css('width', getCanvasWidth() + scrollbarDimensions.width + 'px').appendTo($footerRowScroller);\n\t\n\t if (!options.showFooterRow) {\n\t $footerRowScroller.hide();\n\t }\n\t }\n\t\n\t $focusSink2 = $focusSink.clone().appendTo($container);\n\t\n\t if (!options.explicitInitialization) {\n\t finishInitialization();\n\t }\n\t }\n\t\n\t function finishInitialization() {\n\t if (!initialized) {\n\t initialized = true;\n\t\n\t viewportW = parseFloat(_jquery2.default.css($container[0], 'width', true));\n\t\n\t // header columns and cells may have different padding/border skewing width calculations (box-sizing, hello?)\n\t // calculate the diff so we can set consistent sizes\n\t measureCellPaddingAndBorder();\n\t\n\t // for usability reasons, all text selection in SlickGrid is disabled\n\t // with the exception of input and textarea elements (selection must\n\t // be enabled there so that editors work as expected); note that\n\t // selection in grid cells (grid body) is already unavailable in\n\t // all browsers except IE\n\t disableSelection($headers); // disable all text selection in header (including input and textarea)\n\t\n\t if (!options.enableTextSelectionOnCells) {\n\t // disable text selection in grid cells except in input and textarea elements\n\t // (this is IE-specific, because selectstart event will only fire in IE)\n\t $viewport.bind('selectstart.ui', function (event) {\n\t return (0, _jquery2.default)(event.target).is('input,textarea');\n\t });\n\t }\n\t\n\t updateColumnCaches();\n\t createColumnHeaders();\n\t setupColumnSort();\n\t createCssRules();\n\t resizeCanvas();\n\t bindAncestorScrollEvents();\n\t\n\t $container.bind('resize.slickgrid', resizeCanvas);\n\t $viewport\n\t // .bind(\"click\", handleClick)\n\t .bind('scroll', handleScroll);\n\t $headerScroller.bind('contextmenu', handleHeaderContextMenu).bind('click', handleHeaderClick).delegate('.slick-header-column', 'mouseenter', handleHeaderMouseEnter).delegate('.slick-header-column', 'mouseleave', handleHeaderMouseLeave);\n\t $headerRowScroller.bind('scroll', handleHeaderRowScroll);\n\t\n\t if (options.createFooterRow) {\n\t $footerRowScroller.bind('scroll', handleFooterRowScroll);\n\t }\n\t\n\t $focusSink.add($focusSink2).bind('keydown', handleKeyDown);\n\t $canvas.bind('keydown', handleKeyDown).bind('click', handleClick).bind('dblclick', handleDblClick).bind('contextmenu', handleContextMenu).delegate('.slick-cell', 'mouseenter', handleMouseEnter).delegate('.slick-cell', 'mouseleave', handleMouseLeave);\n\t\n\t // legacy support for drag events\n\t (0, _interact2.default)($canvas[0]).allowFrom('div.slick-cell').draggable({\n\t onmove: handleDrag,\n\t onstart: handleDragStart,\n\t onend: handleDragEnd\n\t }).styleCursor(false);\n\t\n\t // Work around http://crbug.com/312427.\n\t if (navigator.userAgent.toLowerCase().match(/webkit/) && navigator.userAgent.toLowerCase().match(/macintosh/)) {\n\t $canvas.bind('mousewheel', handleMouseWheel);\n\t }\n\t restoreCssFromHiddenInit();\n\t }\n\t }\n\t\n\t function cacheCssForHiddenInit() {\n\t // handle display:none on container or container parents\n\t $hiddenParents = $container.parents().addBack().not(':visible');\n\t $hiddenParents.each(function () {\n\t var old = {};\n\t for (var name in cssShow) {\n\t old[name] = this.style[name];\n\t this.style[name] = cssShow[name];\n\t }\n\t oldProps.push(old);\n\t });\n\t }\n\t\n\t function restoreCssFromHiddenInit() {\n\t // finish handle display:none on container or container parents\n\t // - put values back the way they were\n\t $hiddenParents.each(function (i) {\n\t var old = oldProps[i];\n\t for (var name in cssShow) {\n\t this.style[name] = old[name];\n\t }\n\t });\n\t }\n\t\n\t function registerPlugin(plugin) {\n\t plugins.unshift(plugin);\n\t plugin.init(self);\n\t }\n\t\n\t function unregisterPlugin(plugin) {\n\t for (var i = plugins.length; i >= 0; i--) {\n\t if (plugins[i] === plugin) {\n\t if (plugins[i].destroy) {\n\t plugins[i].destroy();\n\t }\n\t plugins.splice(i, 1);\n\t break;\n\t }\n\t }\n\t }\n\t\n\t function setSelectionModel(model) {\n\t if (selectionModel) {\n\t selectionModel.onSelectedRangesChanged.unsubscribe(handleSelectedRangesChanged);\n\t if (selectionModel.destroy) {\n\t selectionModel.destroy();\n\t }\n\t }\n\t\n\t selectionModel = model;\n\t if (selectionModel) {\n\t selectionModel.init(self);\n\t selectionModel.onSelectedRangesChanged.subscribe(handleSelectedRangesChanged);\n\t }\n\t }\n\t\n\t function getSelectionModel() {\n\t return selectionModel;\n\t }\n\t\n\t function getCanvasNode() {\n\t return $canvas[0];\n\t }\n\t\n\t function measureScrollbar() {\n\t var $c = (0, _jquery2.default)(\"\").appendTo('body');\n\t var dim = {\n\t width: $c.width() - $c[0].clientWidth,\n\t height: $c.height() - $c[0].clientHeight\n\t };\n\t $c.remove();\n\t return dim;\n\t }\n\t\n\t function getHeadersWidth() {\n\t var headersWidth = 0;\n\t for (var i = 0, ii = columns.length; i < ii; i++) {\n\t var width = columns[i].width;\n\t headersWidth += width;\n\t }\n\t headersWidth += scrollbarDimensions.width;\n\t return Math.max(headersWidth, viewportW) + 1000;\n\t }\n\t\n\t function getCanvasWidth() {\n\t var availableWidth = viewportHasVScroll ? viewportW - scrollbarDimensions.width : viewportW;\n\t var rowWidth = 0;\n\t var i = columns.length;\n\t while (i--) {\n\t rowWidth += columns[i].width;\n\t }\n\t return options.fullWidthRows ? Math.max(rowWidth, availableWidth) : rowWidth;\n\t }\n\t\n\t function updateCanvasWidth(forceColumnWidthsUpdate) {\n\t var oldCanvasWidth = canvasWidth;\n\t canvasWidth = getCanvasWidth();\n\t\n\t if (canvasWidth != oldCanvasWidth) {\n\t $canvas.width(canvasWidth);\n\t $headerRow.width(canvasWidth);\n\t if (options.createFooterRow) {\n\t $footerRow.width(canvasWidth);\n\t }\n\t $headers.width(getHeadersWidth());\n\t viewportHasHScroll = canvasWidth > viewportW - scrollbarDimensions.width;\n\t }\n\t\n\t var w = canvasWidth + (viewportHasVScroll ? scrollbarDimensions.width : 0);\n\t $headerRowSpacer.width(w);\n\t if (options.createFooterRow) {\n\t $footerRowSpacer.width(w);\n\t }\n\t\n\t if (canvasWidth != oldCanvasWidth || forceColumnWidthsUpdate) {\n\t applyColumnWidths();\n\t }\n\t }\n\t\n\t function disableSelection($target) {\n\t if ($target && $target.jquery) {\n\t $target.attr('unselectable', 'on').css('MozUserSelect', 'none').bind('selectstart.ui', function () {\n\t return false;\n\t }); // from jquery:ui.core.js 1.7.2\n\t }\n\t }\n\t\n\t function getMaxSupportedCssHeight() {\n\t var supportedHeight = 1000000;\n\t // FF reports the height back but still renders blank after ~6M px\n\t var testUpTo = navigator.userAgent.toLowerCase().match(/firefox/) ? 6000000 : 1000000000;\n\t var div = (0, _jquery2.default)(\"\").appendTo(document.body);\n\t\n\t while (true) {\n\t var test = supportedHeight * 2;\n\t div.css('height', test);\n\t if (test > testUpTo || div.height() !== test) {\n\t break;\n\t } else {\n\t supportedHeight = test;\n\t }\n\t }\n\t\n\t div.remove();\n\t return supportedHeight;\n\t }\n\t\n\t // TODO: this is static. need to handle page mutation.\n\t function bindAncestorScrollEvents() {\n\t var elem = $canvas[0];\n\t while ((elem = elem.parentNode) != document.body && elem != null) {\n\t // bind to scroll containers only\n\t if (elem == $viewport[0] || elem.scrollWidth != elem.clientWidth || elem.scrollHeight != elem.clientHeight) {\n\t var $elem = (0, _jquery2.default)(elem);\n\t if (!$boundAncestors) {\n\t $boundAncestors = $elem;\n\t } else {\n\t $boundAncestors = $boundAncestors.add($elem);\n\t }\n\t $elem.bind('scroll.' + uid, handleActiveCellPositionChange);\n\t }\n\t }\n\t }\n\t\n\t function unbindAncestorScrollEvents() {\n\t if (!$boundAncestors) {\n\t return;\n\t }\n\t $boundAncestors.unbind('scroll.' + uid);\n\t $boundAncestors = null;\n\t }\n\t\n\t function updateColumnHeader(columnId, title, toolTip) {\n\t if (!initialized) {\n\t return;\n\t }\n\t var idx = getColumnIndex(columnId);\n\t if (idx == null) {\n\t return;\n\t }\n\t\n\t var columnDef = columns[idx];\n\t var $header = $headers.children().eq(idx);\n\t if ($header) {\n\t if (title !== undefined) {\n\t columns[idx].name = title;\n\t }\n\t if (toolTip !== undefined) {\n\t columns[idx].toolTip = toolTip;\n\t }\n\t\n\t trigger(self.onBeforeHeaderCellDestroy, {\n\t 'node': $header[0],\n\t 'column': columnDef,\n\t 'grid': self\n\t });\n\t\n\t $header.attr('title', toolTip || '').children().eq(0).html(title);\n\t\n\t trigger(self.onHeaderCellRendered, {\n\t 'node': $header[0],\n\t 'column': columnDef,\n\t 'grid': self\n\t });\n\t }\n\t }\n\t\n\t function getHeaderRow() {\n\t return $headerRow[0];\n\t }\n\t\n\t function getFooterRow() {\n\t return $footerRow[0];\n\t }\n\t\n\t function getHeaderRowColumn(columnId) {\n\t var idx = getColumnIndex(columnId);\n\t var $header = $headerRow.children().eq(idx);\n\t return $header && $header[0];\n\t }\n\t\n\t function getFooterRowColumn(columnId) {\n\t var idx = getColumnIndex(columnId);\n\t var $footer = $footerRow.children().eq(idx);\n\t return $footer && $footer[0];\n\t }\n\t\n\t function createColumnHeaders() {\n\t function onMouseEnter() {\n\t (0, _jquery2.default)(this).addClass('ui-state-hover');\n\t }\n\t\n\t function onMouseLeave() {\n\t (0, _jquery2.default)(this).removeClass('ui-state-hover');\n\t }\n\t\n\t $headers.find('.slick-header-column').each(function () {\n\t var columnDef = (0, _jquery2.default)(this).data('column');\n\t if (columnDef) {\n\t trigger(self.onBeforeHeaderCellDestroy, {\n\t 'node': this,\n\t 'column': columnDef,\n\t 'grid': self\n\t });\n\t }\n\t });\n\t $headers.empty();\n\t $headers.width(getHeadersWidth());\n\t\n\t $headerRow.find('.slick-headerrow-column').each(function () {\n\t var columnDef = (0, _jquery2.default)(this).data('column');\n\t if (columnDef) {\n\t trigger(self.onBeforeHeaderRowCellDestroy, {\n\t 'node': this,\n\t 'column': columnDef,\n\t 'grid': self\n\t });\n\t }\n\t });\n\t $headerRow.empty();\n\t\n\t if (options.createFooterRow) {\n\t $footerRow.find('.slick-footerrow-column').each(function () {\n\t var columnDef = (0, _jquery2.default)(this).data('column');\n\t if (columnDef) {\n\t trigger(self.onBeforeFooterRowCellDestroy, {\n\t 'node': this,\n\t 'column': columnDef\n\t });\n\t }\n\t });\n\t $footerRow.empty();\n\t }\n\t\n\t for (var i = 0; i < columns.length; i++) {\n\t var m = columns[i];\n\t\n\t var header = (0, _jquery2.default)(\"\").html(\"\" + m.name + '').width(m.width - headerColumnWidthDiff).attr('id', '' + uid + m.id).attr('title', m.toolTip || '').data('column', m).addClass(m.headerCssClass || '').appendTo($headers);\n\t\n\t if (options.enableColumnReorder || m.sortable) {\n\t header.on('mouseenter', onMouseEnter).on('mouseleave', onMouseLeave);\n\t }\n\t\n\t if (m.sortable) {\n\t header.addClass('slick-header-sortable');\n\t header.append(\"\");\n\t }\n\t\n\t trigger(self.onHeaderCellRendered, {\n\t 'node': header[0],\n\t 'column': m,\n\t 'grid': self\n\t });\n\t\n\t if (options.showHeaderRow) {\n\t var headerRowCell = (0, _jquery2.default)(\"\").data('column', m).appendTo($headerRow);\n\t\n\t trigger(self.onHeaderRowCellRendered, {\n\t 'node': headerRowCell[0],\n\t 'column': m,\n\t 'grid': self\n\t });\n\t }\n\t if (options.createFooterRow && options.showFooterRow) {\n\t var footerRowCell = (0, _jquery2.default)(\"\").data('column', m).appendTo($footerRow);\n\t\n\t trigger(self.onFooterRowCellRendered, {\n\t 'node': footerRowCell[0],\n\t 'column': m\n\t });\n\t }\n\t }\n\t\n\t setSortColumns(sortColumns);\n\t setupColumnResize();\n\t if (options.enableColumnReorder) {\n\t setupColumnReorder();\n\t }\n\t }\n\t\n\t function setupColumnSort() {\n\t $headers.click(function (e) {\n\t // temporary workaround for a bug in jQuery 1.7.1 (http://bugs.jquery.com/ticket/11328)\n\t e.metaKey = e.metaKey || e.ctrlKey;\n\t\n\t if ((0, _jquery2.default)(e.target).hasClass('slick-resizable-handle')) {\n\t return;\n\t }\n\t\n\t var $col = (0, _jquery2.default)(e.target).closest('.slick-header-column');\n\t if (!$col.length) {\n\t return;\n\t }\n\t\n\t var column = $col.data('column');\n\t if (column.sortable) {\n\t if (!getEditorLock().commitCurrentEdit()) {\n\t return;\n\t }\n\t\n\t var sortOpts = null;\n\t var i = 0;\n\t for (; i < sortColumns.length; i++) {\n\t if (sortColumns[i].columnId == column.id) {\n\t sortOpts = sortColumns[i];\n\t sortOpts.sortAsc = !sortOpts.sortAsc;\n\t break;\n\t }\n\t }\n\t\n\t if (e.metaKey && options.multiColumnSort) {\n\t if (sortOpts) {\n\t sortColumns.splice(i, 1);\n\t }\n\t } else {\n\t if (!e.shiftKey && !e.metaKey || !options.multiColumnSort) {\n\t sortColumns = [];\n\t }\n\t\n\t if (!sortOpts) {\n\t sortOpts = { columnId: column.id, sortAsc: column.defaultSortAsc };\n\t sortColumns.push(sortOpts);\n\t } else if (sortColumns.length == 0) {\n\t sortColumns.push(sortOpts);\n\t }\n\t }\n\t\n\t setSortColumns(sortColumns);\n\t\n\t if (!options.multiColumnSort) {\n\t trigger(self.onSort, {\n\t multiColumnSort: false,\n\t sortCol: column,\n\t sortAsc: sortOpts.sortAsc,\n\t grid: self\n\t }, e);\n\t } else {\n\t trigger(self.onSort, {\n\t multiColumnSort: true,\n\t sortCols: _jquery2.default.map(sortColumns, function (col) {\n\t return { sortCol: columns[getColumnIndex(col.columnId)], sortAsc: col.sortAsc };\n\t }),\n\t grid: self\n\t }, e);\n\t }\n\t }\n\t });\n\t }\n\t\n\t /**\n\t * Refactored to use interactjs\n\t */\n\t function setupColumnReorder() {\n\t var x = 0;\n\t var delta = 0;\n\t var placeholder = document.createElement('div');\n\t\n\t placeholder.className = 'interact-placeholder';\n\t\n\t (0, _interact2.default)('.slick-header-column').ignoreFrom('.slick-resizable-handle').draggable({\n\t inertia: true,\n\t // keep the element within the area of it's parent\n\t restrict: {\n\t restriction: 'parent',\n\t endOnly: true,\n\t elementRect: { top: 0, left: 0, bottom: 0, right: 0 }\n\t },\n\t // enable autoScroll\n\t autoScroll: true,\n\t axis: 'x',\n\t onstart: function onstart(event) {\n\t x = 0;\n\t delta = event.target.offsetWidth;\n\t\n\t // get old order\n\t $headers.find('.slick-header-column').each(function (index) {\n\t (0, _jquery2.default)(this).data('index', index);\n\t });\n\t\n\t placeholder.style.height = event.target.offsetHeight + 'px';\n\t placeholder.style.width = delta + 'px';\n\t\n\t (0, _jquery2.default)(event.target).after(placeholder).css({\n\t position: 'absolute',\n\t zIndex: 1000,\n\t marginLeft: (0, _jquery2.default)(event.target).position().left\n\t });\n\t },\n\t\n\t onmove: function onmove(event) {\n\t x += event.dx;\n\t event.target.style.transform = 'translate3d(' + x + 'px, -3px, 100px)';\n\t // event.target.style.marginLeft = x + 'px';\n\t },\n\t\n\t onend: function onend(event) {\n\t x = 0;\n\t delta = 0;\n\t (0, _jquery2.default)(event.target).css({\n\t position: 'relative',\n\t zIndex: '',\n\t marginLeft: 0,\n\t transform: 'none'\n\t });\n\t\n\t placeholder.parentNode.removeChild(placeholder);\n\t var newColumns = [];\n\t\n\t $headers.find('.slick-header-column').each(function (index) {\n\t newColumns.push(columns[(0, _jquery2.default)(this).data('index')]);\n\t (0, _jquery2.default)(this).removeData('index');\n\t });\n\t\n\t setColumns(newColumns);\n\t trigger(self.onColumnsReordered, { grid: self });\n\t setupColumnResize();\n\t }\n\t }).dropzone({\n\t accept: '.slick-header-column',\n\t\n\t ondragenter: function ondragenter(event) {\n\t event.target.classList.add('interact-drop-active');\n\t event.relatedTarget.classList.add('interact-can-drop');\n\t },\n\t\n\t ondragleave: function ondragleave(event) {\n\t event.target.classList.remove('interact-drop-active');\n\t event.relatedTarget.classList.remove('interact-can-drop');\n\t },\n\t\n\t ondrop: function ondrop(event) {\n\t event.target.classList.remove('interact-drop-active');\n\t event.relatedTarget.classList.remove('interact-can-drop');\n\t (0, _jquery2.default)(event.target)[x > 0 ? 'after' : 'before'](event.relatedTarget);\n\t }\n\t }).styleCursor(false);\n\t }\n\t\n\t function setupColumnResize() {\n\t var $col, j, c, pageX, columnElements, minPageX, maxPageX, firstResizable, lastResizable;\n\t columnElements = $headers.children();\n\t columnElements.find('.slick-resizable-handle').remove();\n\t columnElements.each(function (i, e) {\n\t if (columns[i].resizable) {\n\t if (firstResizable === undefined) {\n\t firstResizable = i;\n\t }\n\t lastResizable = i;\n\t }\n\t });\n\t if (firstResizable === undefined) {\n\t return;\n\t }\n\t columnElements.each(function (i, element) {\n\t if (i < firstResizable || options.forceFitColumns && i >= lastResizable) {\n\t return;\n\t }\n\t $col = (0, _jquery2.default)(element);\n\t\n\t var $handle = (0, _jquery2.default)(\"\");\n\t $handle.appendTo(element);\n\t\n\t if ($col.data('resizable')) return;\n\t\n\t var activeColumn = columns[i];\n\t if (activeColumn.resizable) {\n\t $col.data('resizable', true);\n\t (0, _interact2.default)(element).resizable({\n\t preserveAspectRatio: false,\n\t edges: { left: true, right: true, bottom: false, top: false }\n\t }).on('resizestart', function (event) {\n\t if (!getEditorLock().commitCurrentEdit()) {\n\t return false;\n\t }\n\t activeColumn.previousWidth = event.rect.width;\n\t event.target.classList.add('slick-header-column-active');\n\t }).on('resizemove', function (event) {\n\t var x = event.dx;\n\t var width = activeColumn.width += x;\n\t\n\t if (activeColumn.minWidth > 0 && activeColumn.minWidth > width) width = activeColumn.minWidth;else if (activeColumn.maxWidth > 0 && activeColumn.maxWidth < width) width = activeColumn.maxWidth;\n\t\n\t activeColumn.width = width;\n\t\n\t if (options.forceFitColumns) {\n\t autosizeColumns();\n\t }\n\t applyColumnHeaderWidths();\n\t if (options.syncColumnCellResize) {\n\t applyColumnWidths();\n\t }\n\t }).on('resizeend', function (event) {\n\t event.target.classList.remove('slick-header-column-active');\n\t invalidateAllRows();\n\t updateCanvasWidth(true);\n\t render();\n\t trigger(self.onColumnsResized, { grid: self });\n\t });\n\t }\n\t });\n\t }\n\t\n\t function getVBoxDelta($el) {\n\t var p = ['borderTopWidth', 'borderBottomWidth', 'paddingTop', 'paddingBottom'];\n\t var delta = 0;\n\t _jquery2.default.each(p, function (n, val) {\n\t delta += parseFloat($el.css(val)) || 0;\n\t });\n\t return delta;\n\t }\n\t\n\t function measureCellPaddingAndBorder() {\n\t var el;\n\t var h = ['borderLeftWidth', 'borderRightWidth', 'paddingLeft', 'paddingRight'];\n\t var v = ['borderTopWidth', 'borderBottomWidth', 'paddingTop', 'paddingBottom'];\n\t\n\t // jquery prior to version 1.8 handles .width setter/getter as a direct css write/read\n\t // jquery 1.8 changed .width to read the true inner element width if box-sizing is set to border-box, and introduced a setter for .outerWidth\n\t // so for equivalent functionality, prior to 1.8 use .width, and after use .outerWidth\n\t var verArray = _jquery2.default.fn.jquery.split('.');\n\t jQueryNewWidthBehaviour = verArray[0] == 1 && verArray[1] >= 8 || verArray[0] >= 2;\n\t\n\t el = (0, _jquery2.default)(\"
-
\").appendTo($headers);\n\t headerColumnWidthDiff = headerColumnHeightDiff = 0;\n\t if (el.css('box-sizing') != 'border-box' && el.css('-moz-box-sizing') != 'border-box' && el.css('-webkit-box-sizing') != 'border-box') {\n\t _jquery2.default.each(h, function (n, val) {\n\t headerColumnWidthDiff += parseFloat(el.css(val)) || 0;\n\t });\n\t _jquery2.default.each(v, function (n, val) {\n\t headerColumnHeightDiff += parseFloat(el.css(val)) || 0;\n\t });\n\t }\n\t el.remove();\n\t\n\t var r = (0, _jquery2.default)(\"\").appendTo($canvas);\n\t el = (0, _jquery2.default)(\"
-
\").appendTo(r);\n\t cellWidthDiff = cellHeightDiff = 0;\n\t if (el.css('box-sizing') != 'border-box' && el.css('-moz-box-sizing') != 'border-box' && el.css('-webkit-box-sizing') != 'border-box') {\n\t _jquery2.default.each(h, function (n, val) {\n\t cellWidthDiff += parseFloat(el.css(val)) || 0;\n\t });\n\t _jquery2.default.each(v, function (n, val) {\n\t cellHeightDiff += parseFloat(el.css(val)) || 0;\n\t });\n\t }\n\t r.remove();\n\t\n\t absoluteColumnMinWidth = Math.max(headerColumnWidthDiff, cellWidthDiff);\n\t }\n\t\n\t function createCssRules() {\n\t $style = (0, _jquery2.default)(\"\").appendTo((0, _jquery2.default)('head'));\n\t var rowHeight = options.rowHeight - cellHeightDiff;\n\t var rules = ['.' + uid + ' .slick-header-column { left: 0; }', '.' + uid + ' .slick-top-panel { height:' + options.topPanelHeight + 'px; }', '.' + uid + ' .slick-headerrow-columns { height:' + options.headerRowHeight + 'px; }', '.' + uid + ' .slick-footerrow-columns { height:' + options.footerRowHeight + 'px; }', '.' + uid + ' .slick-cell { height:' + rowHeight + 'px; }', '.' + uid + ' .slick-row { height:' + options.rowHeight + 'px; }'];\n\t\n\t for (var i = 0; i < columns.length; i++) {\n\t rules.push('.' + uid + ' .l' + i + ' { }');\n\t rules.push('.' + uid + ' .r' + i + ' { }');\n\t }\n\t\n\t if ($style[0].styleSheet) {\n\t // IE\n\t $style[0].styleSheet.cssText = rules.join(' ');\n\t } else {\n\t $style[0].appendChild(document.createTextNode(rules.join(' ')));\n\t }\n\t }\n\t\n\t function getColumnCssRules(idx) {\n\t if (!stylesheet) {\n\t var sheets = document.styleSheets;\n\t for (var i = 0; i < sheets.length; i++) {\n\t if ((sheets[i].ownerNode || sheets[i].owningElement) == $style[0]) {\n\t stylesheet = sheets[i];\n\t break;\n\t }\n\t }\n\t\n\t if (!stylesheet) {\n\t throw new Error('Cannot find stylesheet.');\n\t }\n\t\n\t // find and cache column CSS rules\n\t columnCssRulesL = [];\n\t columnCssRulesR = [];\n\t var cssRules = stylesheet.cssRules || stylesheet.rules;\n\t var matches, columnIdx;\n\t for (var i = 0; i < cssRules.length; i++) {\n\t var selector = cssRules[i].selectorText;\n\t if (matches = /\\.l\\d+/.exec(selector)) {\n\t columnIdx = parseInt(matches[0].substr(2, matches[0].length - 2), 10);\n\t columnCssRulesL[columnIdx] = cssRules[i];\n\t } else if (matches = /\\.r\\d+/.exec(selector)) {\n\t columnIdx = parseInt(matches[0].substr(2, matches[0].length - 2), 10);\n\t columnCssRulesR[columnIdx] = cssRules[i];\n\t }\n\t }\n\t }\n\t\n\t return {\n\t 'left': columnCssRulesL[idx],\n\t 'right': columnCssRulesR[idx]\n\t };\n\t }\n\t\n\t function removeCssRules() {\n\t $style.remove();\n\t stylesheet = null;\n\t }\n\t\n\t function destroy() {\n\t getEditorLock().cancelCurrentEdit();\n\t\n\t trigger(self.onBeforeDestroy, { grid: self });\n\t\n\t var i = plugins.length;\n\t while (i--) {\n\t unregisterPlugin(plugins[i]);\n\t }\n\t\n\t unbindAncestorScrollEvents();\n\t $container.unbind('.slickgrid');\n\t removeCssRules();\n\t\n\t $container.empty().removeClass(uid);\n\t }\n\t\n\t // ////////////////////////////////////////////////////////////////////////////////////////////\n\t // General\n\t\n\t function trigger(evt, args, e) {\n\t e = e || new _slick2.default.EventData();\n\t args = args || {};\n\t args.grid = self;\n\t return evt.notify(args, e, self);\n\t }\n\t\n\t function getEditorLock() {\n\t return options.editorLock;\n\t }\n\t\n\t function getEditController() {\n\t return editController;\n\t }\n\t\n\t function getColumnIndex(id) {\n\t return columnsById[id];\n\t }\n\t\n\t function autosizeColumns() {\n\t var i,\n\t c,\n\t widths = [],\n\t shrinkLeeway = 0,\n\t total = 0,\n\t prevTotal,\n\t availWidth = viewportHasVScroll ? viewportW - scrollbarDimensions.width : viewportW;\n\t\n\t for (i = 0; i < columns.length; i++) {\n\t c = columns[i];\n\t widths.push(c.width);\n\t total += c.width;\n\t if (c.resizable) {\n\t shrinkLeeway += c.width - Math.max(c.minWidth, absoluteColumnMinWidth);\n\t }\n\t }\n\t\n\t // shrink\n\t prevTotal = total;\n\t while (total > availWidth && shrinkLeeway) {\n\t var shrinkProportion = (total - availWidth) / shrinkLeeway;\n\t for (i = 0; i < columns.length && total > availWidth; i++) {\n\t c = columns[i];\n\t var width = widths[i];\n\t if (!c.resizable || width <= c.minWidth || width <= absoluteColumnMinWidth) {\n\t continue;\n\t }\n\t var absMinWidth = Math.max(c.minWidth, absoluteColumnMinWidth);\n\t var shrinkSize = Math.floor(shrinkProportion * (width - absMinWidth)) || 1;\n\t shrinkSize = Math.min(shrinkSize, width - absMinWidth);\n\t total -= shrinkSize;\n\t shrinkLeeway -= shrinkSize;\n\t widths[i] -= shrinkSize;\n\t }\n\t if (prevTotal <= total) {\n\t // avoid infinite loop\n\t break;\n\t }\n\t prevTotal = total;\n\t }\n\t\n\t // grow\n\t prevTotal = total;\n\t while (total < availWidth) {\n\t var growProportion = availWidth / total;\n\t for (i = 0; i < columns.length && total < availWidth; i++) {\n\t c = columns[i];\n\t var currentWidth = widths[i];\n\t var growSize;\n\t\n\t if (!c.resizable || c.maxWidth <= currentWidth) {\n\t growSize = 0;\n\t } else {\n\t growSize = Math.min(Math.floor(growProportion * currentWidth) - currentWidth, c.maxWidth - currentWidth || 1000000) || 1;\n\t }\n\t total += growSize;\n\t widths[i] += total <= availWidth ? growSize : 0;\n\t }\n\t if (prevTotal >= total) {\n\t // avoid infinite loop\n\t break;\n\t }\n\t prevTotal = total;\n\t }\n\t\n\t var reRender = false;\n\t for (i = 0; i < columns.length; i++) {\n\t if (columns[i].rerenderOnResize && columns[i].width != widths[i]) {\n\t reRender = true;\n\t }\n\t columns[i].width = widths[i];\n\t }\n\t\n\t applyColumnHeaderWidths();\n\t updateCanvasWidth(true);\n\t if (reRender) {\n\t invalidateAllRows();\n\t render();\n\t }\n\t }\n\t\n\t function applyColumnHeaderWidths() {\n\t if (!initialized) {\n\t return;\n\t }\n\t var h;\n\t for (var i = 0, headers = $headers.children('[id]'), ii = headers.length; i < ii; i++) {\n\t h = (0, _jquery2.default)(headers[i]);\n\t if (jQueryNewWidthBehaviour) {\n\t if (h.outerWidth() !== columns[i].width) {\n\t h.outerWidth(columns[i].width);\n\t }\n\t } else {\n\t if (h.width() !== columns[i].width - headerColumnWidthDiff) {\n\t h.width(columns[i].width - headerColumnWidthDiff);\n\t }\n\t }\n\t }\n\t\n\t updateColumnCaches();\n\t }\n\t\n\t function applyColumnWidths() {\n\t var x = 0,\n\t w,\n\t rule;\n\t for (var i = 0; i < columns.length; i++) {\n\t w = columns[i].width;\n\t\n\t rule = getColumnCssRules(i);\n\t rule.left.style.left = x + 'px';\n\t rule.right.style.right = canvasWidth - x - w + 'px';\n\t\n\t x += columns[i].width;\n\t }\n\t }\n\t\n\t function setSortColumn(columnId, ascending) {\n\t setSortColumns([{ columnId: columnId, sortAsc: ascending }]);\n\t }\n\t\n\t function setSortColumns(cols) {\n\t sortColumns = cols;\n\t\n\t var headerColumnEls = $headers.children();\n\t headerColumnEls.removeClass('slick-header-column-sorted').find('.slick-sort-indicator').removeClass('slick-sort-indicator-asc slick-sort-indicator-desc');\n\t\n\t _jquery2.default.each(sortColumns, function (i, col) {\n\t if (col.sortAsc == null) {\n\t col.sortAsc = true;\n\t }\n\t var columnIndex = getColumnIndex(col.columnId);\n\t if (columnIndex != null) {\n\t headerColumnEls.eq(columnIndex).addClass('slick-header-column-sorted').find('.slick-sort-indicator').addClass(col.sortAsc ? 'slick-sort-indicator-asc' : 'slick-sort-indicator-desc');\n\t }\n\t });\n\t }\n\t\n\t function getSortColumns() {\n\t return sortColumns;\n\t }\n\t\n\t function handleSelectedRangesChanged(e, ranges) {\n\t selectedRows = [];\n\t var hash = {};\n\t for (var i = 0; i < ranges.length; i++) {\n\t for (var j = ranges[i].fromRow; j <= ranges[i].toRow; j++) {\n\t if (!hash[j]) {\n\t // prevent duplicates\n\t selectedRows.push(j);\n\t hash[j] = {};\n\t }\n\t for (var k = ranges[i].fromCell; k <= ranges[i].toCell; k++) {\n\t if (canCellBeSelected(j, k)) {\n\t hash[j][columns[k].id] = options.selectedCellCssClass;\n\t }\n\t }\n\t }\n\t }\n\t\n\t setCellCssStyles(options.selectedCellCssClass, hash);\n\t\n\t trigger(self.onSelectedRowsChanged, { rows: getSelectedRows(), grid: self }, e);\n\t }\n\t\n\t function getColumns() {\n\t return columns;\n\t }\n\t\n\t function updateColumnCaches() {\n\t // Pre-calculate cell boundaries.\n\t columnPosLeft = [];\n\t columnPosRight = [];\n\t var x = 0;\n\t for (var i = 0, ii = columns.length; i < ii; i++) {\n\t columnPosLeft[i] = x;\n\t columnPosRight[i] = x + columns[i].width;\n\t x += columns[i].width;\n\t }\n\t }\n\t\n\t function setColumns(columnDefinitions) {\n\t columns = columnDefinitions;\n\t\n\t columnsById = {};\n\t for (var i = 0; i < columns.length; i++) {\n\t var m = columns[i] = _jquery2.default.extend({}, columnDefaults, columns[i]);\n\t columnsById[m.id] = i;\n\t if (m.minWidth && m.width < m.minWidth) {\n\t m.width = m.minWidth;\n\t }\n\t if (m.maxWidth && m.width > m.maxWidth) {\n\t m.width = m.maxWidth;\n\t }\n\t }\n\t\n\t updateColumnCaches();\n\t\n\t if (initialized) {\n\t invalidateAllRows();\n\t createColumnHeaders();\n\t removeCssRules();\n\t createCssRules();\n\t resizeCanvas();\n\t applyColumnWidths();\n\t handleScroll();\n\t }\n\t }\n\t\n\t function getOptions() {\n\t return options;\n\t }\n\t\n\t function setOptions(args) {\n\t if (!getEditorLock().commitCurrentEdit()) {\n\t return;\n\t }\n\t\n\t makeActiveCellNormal();\n\t\n\t if (options.enableAddRow !== args.enableAddRow) {\n\t invalidateRow(getDataLength());\n\t }\n\t\n\t options = _jquery2.default.extend(options, args);\n\t validateAndEnforceOptions();\n\t\n\t $viewport.css('overflow-y', options.autoHeight ? 'hidden' : 'auto');\n\t render();\n\t }\n\t\n\t function validateAndEnforceOptions() {\n\t if (options.autoHeight) {\n\t options.leaveSpaceForNewRows = false;\n\t }\n\t }\n\t\n\t function setData(newData, scrollToTop) {\n\t data = newData;\n\t invalidateAllRows();\n\t updateRowCount();\n\t if (scrollToTop) {\n\t scrollTo(0);\n\t }\n\t }\n\t\n\t function getData() {\n\t return data;\n\t }\n\t\n\t function getDataLength() {\n\t if (data.getLength) {\n\t return data.getLength();\n\t } else {\n\t return data.length;\n\t }\n\t }\n\t\n\t function getDataLengthIncludingAddNew() {\n\t return getDataLength() + (options.enableAddRow ? 1 : 0);\n\t }\n\t\n\t function getDataItem(i) {\n\t if (data.getItem) {\n\t return data.getItem(i);\n\t } else {\n\t return data[i];\n\t }\n\t }\n\t\n\t function getTopPanel() {\n\t return $topPanel[0];\n\t }\n\t\n\t function setTopPanelVisibility(visible) {\n\t if (options.showTopPanel != visible) {\n\t options.showTopPanel = visible;\n\t if (visible) {\n\t $topPanelScroller.slideDown('fast', resizeCanvas);\n\t } else {\n\t $topPanelScroller.slideUp('fast', resizeCanvas);\n\t }\n\t }\n\t }\n\t\n\t function setHeaderRowVisibility(visible) {\n\t if (options.showHeaderRow != visible) {\n\t options.showHeaderRow = visible;\n\t if (visible) {\n\t $headerRowScroller.slideDown('fast', resizeCanvas);\n\t } else {\n\t $headerRowScroller.slideUp('fast', resizeCanvas);\n\t }\n\t }\n\t }\n\t\n\t function setFooterRowVisibility(visible) {\n\t if (options.showFooterRow != visible) {\n\t options.showFooterRow = visible;\n\t if (visible) {\n\t $footerRowScroller.slideDown('fast', resizeCanvas);\n\t } else {\n\t $footerRowScroller.slideUp('fast', resizeCanvas);\n\t }\n\t }\n\t }\n\t\n\t function getContainerNode() {\n\t return $container.get(0);\n\t }\n\t\n\t // ////////////////////////////////////////////////////////////////////////////////////////////\n\t // Rendering / Scrolling\n\t\n\t function getRowTop(row) {\n\t return options.rowHeight * row - offset;\n\t }\n\t\n\t function getRowFromPosition(y) {\n\t return Math.floor((y + offset) / options.rowHeight);\n\t }\n\t\n\t function scrollTo(y) {\n\t y = Math.max(y, 0);\n\t y = Math.min(y, th - viewportH + (viewportHasHScroll ? scrollbarDimensions.height : 0));\n\t\n\t var oldOffset = offset;\n\t\n\t page = Math.min(n - 1, Math.floor(y / ph));\n\t offset = Math.round(page * cj);\n\t var newScrollTop = y - offset;\n\t\n\t if (offset != oldOffset) {\n\t var range = getVisibleRange(newScrollTop);\n\t cleanupRows(range);\n\t updateRowPositions();\n\t }\n\t\n\t if (prevScrollTop != newScrollTop) {\n\t vScrollDir = prevScrollTop + oldOffset < newScrollTop + offset ? 1 : -1;\n\t $viewport[0].scrollTop = lastRenderedScrollTop = scrollTop = prevScrollTop = newScrollTop;\n\t\n\t trigger(self.onViewportChanged, { grid: self });\n\t }\n\t }\n\t\n\t function defaultFormatter(row, cell, value, columnDef, dataContext) {\n\t if (value == null) {\n\t return '';\n\t } else {\n\t return (value + '').replace(/&/g, '&').replace(//g, '>');\n\t }\n\t }\n\t\n\t function getFormatter(row, column) {\n\t var rowMetadata = data.getItemMetadata && data.getItemMetadata(row);\n\t\n\t // look up by id, then index\n\t var columnOverrides = rowMetadata && rowMetadata.columns && (rowMetadata.columns[column.id] || rowMetadata.columns[getColumnIndex(column.id)]);\n\t\n\t return columnOverrides && columnOverrides.formatter || rowMetadata && rowMetadata.formatter || column.formatter || options.formatterFactory && options.formatterFactory.getFormatter(column) || options.defaultFormatter;\n\t }\n\t\n\t function getEditor(row, cell) {\n\t var column = columns[cell];\n\t var rowMetadata = data.getItemMetadata && data.getItemMetadata(row);\n\t var columnMetadata = rowMetadata && rowMetadata.columns;\n\t\n\t if (columnMetadata && columnMetadata[column.id] && columnMetadata[column.id].editor !== undefined) {\n\t return columnMetadata[column.id].editor;\n\t }\n\t if (columnMetadata && columnMetadata[cell] && columnMetadata[cell].editor !== undefined) {\n\t return columnMetadata[cell].editor;\n\t }\n\t\n\t return column.editor || options.editorFactory && options.editorFactory.getEditor(column);\n\t }\n\t\n\t function getDataItemValueForColumn(item, columnDef) {\n\t if (options.dataItemColumnValueExtractor) {\n\t return options.dataItemColumnValueExtractor(item, columnDef);\n\t }\n\t return item[columnDef.field];\n\t }\n\t\n\t function appendRowHtml(stringArray, row, range, dataLength) {\n\t var d = getDataItem(row);\n\t var dataLoading = row < dataLength && !d;\n\t var rowCss = 'slick-row' + (dataLoading ? ' loading' : '') + (row === activeRow ? ' active' : '') + (row % 2 == 1 ? ' odd' : ' even');\n\t\n\t if (!d) {\n\t rowCss += ' ' + options.addNewRowCssClass;\n\t }\n\t\n\t var metadata = data.getItemMetadata && data.getItemMetadata(row);\n\t\n\t if (metadata && metadata.cssClasses) {\n\t rowCss += ' ' + metadata.cssClasses;\n\t }\n\t\n\t stringArray.push(\"
\");\n\t\n\t var colspan, m;\n\t for (var i = 0, ii = columns.length; i < ii; i++) {\n\t m = columns[i];\n\t colspan = 1;\n\t if (metadata && metadata.columns) {\n\t var columnData = metadata.columns[m.id] || metadata.columns[i];\n\t colspan = columnData && columnData.colspan || 1;\n\t if (colspan === '*') {\n\t colspan = ii - i;\n\t }\n\t }\n\t\n\t // Do not render cells outside of the viewport.\n\t if (columnPosRight[Math.min(ii - 1, i + colspan - 1)] > range.leftPx) {\n\t if (columnPosLeft[i] > range.rightPx) {\n\t // All columns to the right are outside the range.\n\t break;\n\t }\n\t\n\t appendCellHtml(stringArray, row, i, colspan, d);\n\t }\n\t\n\t if (colspan > 1) {\n\t i += colspan - 1;\n\t }\n\t }\n\t\n\t stringArray.push('
');\n\t }\n\t\n\t function appendCellHtml(stringArray, row, cell, colspan, item) {\n\t // stringArray: stringBuilder containing the HTML parts\n\t // row, cell: row and column index\n\t // colspan: HTML colspan\n\t // item: grid data for row\n\t\n\t var m = columns[cell];\n\t var cellCss = 'slick-cell l' + cell + ' r' + Math.min(columns.length - 1, cell + colspan - 1) + (m.cssClass ? ' ' + m.cssClass : '');\n\t if (row === activeRow && cell === activeCell) {\n\t cellCss += ' active';\n\t }\n\t\n\t // TODO: merge them together in the setter\n\t for (var key in cellCssClasses) {\n\t if (cellCssClasses[key][row] && cellCssClasses[key][row][m.id]) {\n\t cellCss += ' ' + cellCssClasses[key][row][m.id];\n\t }\n\t }\n\t\n\t stringArray.push(\"
\");\n\t\n\t // if there is a corresponding row (if not, this is the Add New row or this data hasn't been loaded yet)\n\t if (item) {\n\t var value = getDataItemValueForColumn(item, m);\n\t stringArray.push(getFormatter(row, m)(row, cell, value, m, item));\n\t }\n\t\n\t stringArray.push('
');\n\t\n\t rowsCache[row].cellRenderQueue.push(cell);\n\t rowsCache[row].cellColSpans[cell] = colspan;\n\t }\n\t\n\t function cleanupRows(rangeToKeep) {\n\t for (var i in rowsCache) {\n\t if ((i = parseInt(i, 10)) !== activeRow && (i < rangeToKeep.top || i > rangeToKeep.bottom)) {\n\t removeRowFromCache(i);\n\t }\n\t }\n\t if (options.enableAsyncPostRenderCleanup) {\n\t startPostProcessingCleanup();\n\t }\n\t }\n\t\n\t function invalidate() {\n\t updateRowCount();\n\t invalidateAllRows();\n\t render();\n\t }\n\t\n\t function invalidateAllRows() {\n\t if (currentEditor) {\n\t makeActiveCellNormal();\n\t }\n\t for (var row in rowsCache) {\n\t removeRowFromCache(row);\n\t }\n\t if (options.enableAsyncPostRenderCleanup) {\n\t startPostProcessingCleanup();\n\t }\n\t }\n\t\n\t function queuePostProcessedRowForCleanup(cacheEntry, postProcessedRow, rowIdx) {\n\t postProcessgroupId++;\n\t\n\t // store and detach node for later async cleanup\n\t for (var columnIdx in postProcessedRow) {\n\t if (postProcessedRow.hasOwnProperty(columnIdx)) {\n\t postProcessedCleanupQueue.push({\n\t actionType: 'C',\n\t groupId: postProcessgroupId,\n\t node: cacheEntry.cellNodesByColumnIdx[columnIdx | 0],\n\t columnIdx: columnIdx | 0,\n\t rowIdx: rowIdx\n\t });\n\t }\n\t }\n\t postProcessedCleanupQueue.push({\n\t actionType: 'R',\n\t groupId: postProcessgroupId,\n\t node: cacheEntry.rowNode\n\t });\n\t (0, _jquery2.default)(cacheEntry.rowNode).detach();\n\t }\n\t\n\t function queuePostProcessedCellForCleanup(cellnode, columnIdx, rowIdx) {\n\t postProcessedCleanupQueue.push({\n\t actionType: 'C',\n\t groupId: postProcessgroupId,\n\t node: cellnode,\n\t columnIdx: columnIdx,\n\t rowIdx: rowIdx\n\t });\n\t (0, _jquery2.default)(cellnode).detach();\n\t }\n\t\n\t function removeRowFromCache(row) {\n\t var cacheEntry = rowsCache[row];\n\t if (!cacheEntry) {\n\t return;\n\t }\n\t\n\t if (rowNodeFromLastMouseWheelEvent === cacheEntry.rowNode) {\n\t cacheEntry.rowNode.style.display = 'none';\n\t zombieRowNodeFromLastMouseWheelEvent = rowNodeFromLastMouseWheelEvent;\n\t zombieRowCacheFromLastMouseWheelEvent = cacheEntry;\n\t zombieRowPostProcessedFromLastMouseWheelEvent = postProcessedRows[row];\n\t // ignore post processing cleanup in this case - it will be dealt with later\n\t } else {\n\t if (options.enableAsyncPostRenderCleanup && postProcessedRows[row]) {\n\t queuePostProcessedRowForCleanup(cacheEntry, postProcessedRows[row], row);\n\t } else {\n\t $canvas[0].removeChild(cacheEntry.rowNode);\n\t }\n\t }\n\t\n\t delete rowsCache[row];\n\t delete postProcessedRows[row];\n\t renderedRows--;\n\t counter_rows_removed++;\n\t }\n\t\n\t function invalidateRows(rows) {\n\t var i, rl;\n\t if (!rows || !rows.length) {\n\t return;\n\t }\n\t vScrollDir = 0;\n\t for (i = 0, rl = rows.length; i < rl; i++) {\n\t if (currentEditor && activeRow === rows[i]) {\n\t makeActiveCellNormal();\n\t }\n\t if (rowsCache[rows[i]]) {\n\t removeRowFromCache(rows[i]);\n\t }\n\t }\n\t if (options.enableAsyncPostRenderCleanup) {\n\t startPostProcessingCleanup();\n\t }\n\t }\n\t\n\t function invalidateRow(row) {\n\t invalidateRows([row]);\n\t }\n\t\n\t function updateCell(row, cell) {\n\t var cellNode = getCellNode(row, cell);\n\t if (!cellNode) {\n\t return;\n\t }\n\t\n\t var m = columns[cell],\n\t d = getDataItem(row);\n\t if (currentEditor && activeRow === row && activeCell === cell) {\n\t currentEditor.loadValue(d);\n\t } else {\n\t cellNode.innerHTML = d ? getFormatter(row, m)(row, cell, getDataItemValueForColumn(d, m), m, d) : '';\n\t invalidatePostProcessingResults(row);\n\t }\n\t }\n\t\n\t function updateRow(row) {\n\t var cacheEntry = rowsCache[row];\n\t if (!cacheEntry) {\n\t return;\n\t }\n\t\n\t ensureCellNodesInRowsCache(row);\n\t\n\t var d = getDataItem(row);\n\t\n\t for (var columnIdx in cacheEntry.cellNodesByColumnIdx) {\n\t if (!cacheEntry.cellNodesByColumnIdx.hasOwnProperty(columnIdx)) {\n\t continue;\n\t }\n\t\n\t columnIdx = columnIdx | 0;\n\t var m = columns[columnIdx],\n\t node = cacheEntry.cellNodesByColumnIdx[columnIdx];\n\t\n\t if (row === activeRow && columnIdx === activeCell && currentEditor) {\n\t currentEditor.loadValue(d);\n\t } else if (d) {\n\t node.innerHTML = getFormatter(row, m)(row, columnIdx, getDataItemValueForColumn(d, m), m, d);\n\t } else {\n\t node.innerHTML = '';\n\t }\n\t }\n\t\n\t invalidatePostProcessingResults(row);\n\t }\n\t\n\t function getViewportHeight() {\n\t return parseFloat(_jquery2.default.css($container[0], 'height', true)) - parseFloat(_jquery2.default.css($container[0], 'paddingTop', true)) - parseFloat(_jquery2.default.css($container[0], 'paddingBottom', true)) - parseFloat(_jquery2.default.css($headerScroller[0], 'height')) - getVBoxDelta($headerScroller) - (options.showTopPanel ? options.topPanelHeight + getVBoxDelta($topPanelScroller) : 0) - (options.showHeaderRow ? options.headerRowHeight + getVBoxDelta($headerRowScroller) : 0) - (options.createFooterRow && options.showFooterRow ? options.footerRowHeight + getVBoxDelta($footerRowScroller) : 0);\n\t }\n\t\n\t function resizeCanvas() {\n\t if (!initialized) {\n\t return;\n\t }\n\t if (options.autoHeight) {\n\t viewportH = options.rowHeight * getDataLengthIncludingAddNew();\n\t } else {\n\t viewportH = getViewportHeight();\n\t }\n\t\n\t numVisibleRows = Math.ceil(viewportH / options.rowHeight);\n\t viewportW = parseFloat(_jquery2.default.css($container[0], 'width', true));\n\t if (!options.autoHeight) {\n\t $viewport.height(viewportH);\n\t }\n\t\n\t if (options.forceFitColumns) {\n\t autosizeColumns();\n\t }\n\t\n\t updateRowCount();\n\t handleScroll();\n\t // Since the width has changed, force the render() to reevaluate virtually rendered cells.\n\t lastRenderedScrollLeft = -1;\n\t render();\n\t }\n\t\n\t function updateRowCount() {\n\t if (!initialized) {\n\t return;\n\t }\n\t\n\t var dataLengthIncludingAddNew = getDataLengthIncludingAddNew();\n\t var numberOfRows = dataLengthIncludingAddNew + (options.leaveSpaceForNewRows ? numVisibleRows - 1 : 0);\n\t\n\t var oldViewportHasVScroll = viewportHasVScroll;\n\t // with autoHeight, we do not need to accommodate the vertical scroll bar\n\t viewportHasVScroll = !options.autoHeight && numberOfRows * options.rowHeight > viewportH;\n\t viewportHasHScroll = canvasWidth > viewportW - scrollbarDimensions.width;\n\t\n\t makeActiveCellNormal();\n\t\n\t // remove the rows that are now outside of the data range\n\t // this helps avoid redundant calls to .removeRow() when the size of the data decreased by thousands of rows\n\t var l = dataLengthIncludingAddNew - 1;\n\t for (var i in rowsCache) {\n\t if (i > l) {\n\t removeRowFromCache(i);\n\t }\n\t }\n\t if (options.enableAsyncPostRenderCleanup) {\n\t startPostProcessingCleanup();\n\t }\n\t\n\t if (activeCellNode && activeRow > l) {\n\t resetActiveCell();\n\t }\n\t\n\t var oldH = h;\n\t th = Math.max(options.rowHeight * numberOfRows, viewportH - scrollbarDimensions.height);\n\t if (th < maxSupportedCssHeight) {\n\t // just one page\n\t h = ph = th;\n\t n = 1;\n\t cj = 0;\n\t } else {\n\t // break into pages\n\t h = maxSupportedCssHeight;\n\t ph = h / 100;\n\t n = Math.floor(th / ph);\n\t cj = (th - h) / (n - 1);\n\t }\n\t\n\t if (h !== oldH) {\n\t $canvas.css('height', h);\n\t scrollTop = $viewport[0].scrollTop;\n\t }\n\t\n\t var oldScrollTopInRange = scrollTop + offset <= th - viewportH;\n\t\n\t if (th == 0 || scrollTop == 0) {\n\t page = offset = 0;\n\t } else if (oldScrollTopInRange) {\n\t // maintain virtual position\n\t scrollTo(scrollTop + offset);\n\t } else {\n\t // scroll to bottom\n\t scrollTo(th - viewportH);\n\t }\n\t\n\t if (h != oldH && options.autoHeight) {\n\t resizeCanvas();\n\t }\n\t\n\t if (options.forceFitColumns && oldViewportHasVScroll != viewportHasVScroll) {\n\t autosizeColumns();\n\t }\n\t updateCanvasWidth(false);\n\t }\n\t\n\t function getVisibleRange(viewportTop, viewportLeft) {\n\t if (viewportTop == null) {\n\t viewportTop = scrollTop;\n\t }\n\t if (viewportLeft == null) {\n\t viewportLeft = scrollLeft;\n\t }\n\t\n\t return {\n\t top: getRowFromPosition(viewportTop),\n\t bottom: getRowFromPosition(viewportTop + viewportH) + 1,\n\t leftPx: viewportLeft,\n\t rightPx: viewportLeft + viewportW\n\t };\n\t }\n\t\n\t function getRenderedRange(viewportTop, viewportLeft) {\n\t var range = getVisibleRange(viewportTop, viewportLeft);\n\t var buffer = Math.round(viewportH / options.rowHeight);\n\t var minBuffer = 3;\n\t\n\t if (vScrollDir == -1) {\n\t range.top -= buffer;\n\t range.bottom += minBuffer;\n\t } else if (vScrollDir == 1) {\n\t range.top -= minBuffer;\n\t range.bottom += buffer;\n\t } else {\n\t range.top -= minBuffer;\n\t range.bottom += minBuffer;\n\t }\n\t\n\t range.top = Math.max(0, range.top);\n\t range.bottom = Math.min(getDataLengthIncludingAddNew() - 1, range.bottom);\n\t\n\t range.leftPx -= viewportW;\n\t range.rightPx += viewportW;\n\t\n\t range.leftPx = Math.max(0, range.leftPx);\n\t range.rightPx = Math.min(canvasWidth, range.rightPx);\n\t\n\t return range;\n\t }\n\t\n\t function ensureCellNodesInRowsCache(row) {\n\t var cacheEntry = rowsCache[row];\n\t if (cacheEntry) {\n\t if (cacheEntry.cellRenderQueue.length) {\n\t var lastChild = cacheEntry.rowNode.lastChild;\n\t while (cacheEntry.cellRenderQueue.length) {\n\t var columnIdx = cacheEntry.cellRenderQueue.pop();\n\t cacheEntry.cellNodesByColumnIdx[columnIdx] = lastChild;\n\t lastChild = lastChild.previousSibling;\n\t }\n\t }\n\t }\n\t }\n\t\n\t function cleanUpCells(range, row) {\n\t var totalCellsRemoved = 0;\n\t var cacheEntry = rowsCache[row];\n\t\n\t // Remove cells outside the range.\n\t var cellsToRemove = [];\n\t for (var i in cacheEntry.cellNodesByColumnIdx) {\n\t // I really hate it when people mess with Array.prototype.\n\t if (!cacheEntry.cellNodesByColumnIdx.hasOwnProperty(i)) {\n\t continue;\n\t }\n\t\n\t // This is a string, so it needs to be cast back to a number.\n\t i = i | 0;\n\t\n\t var colspan = cacheEntry.cellColSpans[i];\n\t if (columnPosLeft[i] > range.rightPx || columnPosRight[Math.min(columns.length - 1, i + colspan - 1)] < range.leftPx) {\n\t if (!(row == activeRow && i == activeCell)) {\n\t cellsToRemove.push(i);\n\t }\n\t }\n\t }\n\t\n\t var cellToRemove, node;\n\t postProcessgroupId++;\n\t while ((cellToRemove = cellsToRemove.pop()) != null) {\n\t node = cacheEntry.cellNodesByColumnIdx[cellToRemove];\n\t if (options.enableAsyncPostRenderCleanup && postProcessedRows[row] && postProcessedRows[row][cellToRemove]) {\n\t queuePostProcessedCellForCleanup(node, cellToRemove, row);\n\t } else {\n\t cacheEntry.rowNode.removeChild(node);\n\t }\n\t\n\t delete cacheEntry.cellColSpans[cellToRemove];\n\t delete cacheEntry.cellNodesByColumnIdx[cellToRemove];\n\t if (postProcessedRows[row]) {\n\t delete postProcessedRows[row][cellToRemove];\n\t }\n\t totalCellsRemoved++;\n\t }\n\t }\n\t\n\t function cleanUpAndRenderCells(range) {\n\t var cacheEntry;\n\t var stringArray = [];\n\t var processedRows = [];\n\t var cellsAdded;\n\t var totalCellsAdded = 0;\n\t var colspan;\n\t\n\t for (var row = range.top, btm = range.bottom; row <= btm; row++) {\n\t cacheEntry = rowsCache[row];\n\t if (!cacheEntry) {\n\t continue;\n\t }\n\t\n\t // cellRenderQueue populated in renderRows() needs to be cleared first\n\t ensureCellNodesInRowsCache(row);\n\t\n\t cleanUpCells(range, row);\n\t\n\t // Render missing cells.\n\t cellsAdded = 0;\n\t\n\t var metadata = data.getItemMetadata && data.getItemMetadata(row);\n\t metadata = metadata && metadata.columns;\n\t\n\t var d = getDataItem(row);\n\t\n\t // TODO: shorten this loop (index? heuristics? binary search?)\n\t for (var i = 0, ii = columns.length; i < ii; i++) {\n\t // Cells to the right are outside the range.\n\t if (columnPosLeft[i] > range.rightPx) {\n\t break;\n\t }\n\t\n\t // Already rendered.\n\t if ((colspan = cacheEntry.cellColSpans[i]) != null) {\n\t i += colspan > 1 ? colspan - 1 : 0;\n\t continue;\n\t }\n\t\n\t colspan = 1;\n\t if (metadata) {\n\t var columnData = metadata[columns[i].id] || metadata[i];\n\t colspan = columnData && columnData.colspan || 1;\n\t if (colspan === '*') {\n\t colspan = ii - i;\n\t }\n\t }\n\t\n\t if (columnPosRight[Math.min(ii - 1, i + colspan - 1)] > range.leftPx) {\n\t appendCellHtml(stringArray, row, i, colspan, d);\n\t cellsAdded++;\n\t }\n\t\n\t i += colspan > 1 ? colspan - 1 : 0;\n\t }\n\t\n\t if (cellsAdded) {\n\t totalCellsAdded += cellsAdded;\n\t processedRows.push(row);\n\t }\n\t }\n\t\n\t if (!stringArray.length) {\n\t return;\n\t }\n\t\n\t var x = document.createElement('div');\n\t x.innerHTML = stringArray.join('');\n\t\n\t var processedRow;\n\t var node;\n\t while ((processedRow = processedRows.pop()) != null) {\n\t cacheEntry = rowsCache[processedRow];\n\t var columnIdx;\n\t while ((columnIdx = cacheEntry.cellRenderQueue.pop()) != null) {\n\t node = x.lastChild;\n\t cacheEntry.rowNode.appendChild(node);\n\t cacheEntry.cellNodesByColumnIdx[columnIdx] = node;\n\t }\n\t }\n\t }\n\t\n\t function renderRows(range) {\n\t var parentNode = $canvas[0],\n\t stringArray = [],\n\t rows = [],\n\t needToReselectCell = false,\n\t dataLength = getDataLength();\n\t\n\t for (var i = range.top, ii = range.bottom; i <= ii; i++) {\n\t if (rowsCache[i]) {\n\t continue;\n\t }\n\t renderedRows++;\n\t rows.push(i);\n\t\n\t // Create an entry right away so that appendRowHtml() can\n\t // start populatating it.\n\t rowsCache[i] = {\n\t 'rowNode': null,\n\t\n\t // ColSpans of rendered cells (by column idx).\n\t // Can also be used for checking whether a cell has been rendered.\n\t 'cellColSpans': [],\n\t\n\t // Cell nodes (by column idx). Lazy-populated by ensureCellNodesInRowsCache().\n\t 'cellNodesByColumnIdx': [],\n\t\n\t // Column indices of cell nodes that have been rendered, but not yet indexed in\n\t // cellNodesByColumnIdx. These are in the same order as cell nodes added at the\n\t // end of the row.\n\t 'cellRenderQueue': []\n\t };\n\t\n\t appendRowHtml(stringArray, i, range, dataLength);\n\t if (activeCellNode && activeRow === i) {\n\t needToReselectCell = true;\n\t }\n\t counter_rows_rendered++;\n\t }\n\t\n\t if (!rows.length) {\n\t return;\n\t }\n\t\n\t var x = document.createElement('div');\n\t x.innerHTML = stringArray.join('');\n\t\n\t for (var i = 0, ii = rows.length; i < ii; i++) {\n\t rowsCache[rows[i]].rowNode = parentNode.appendChild(x.firstChild);\n\t }\n\t\n\t if (needToReselectCell) {\n\t activeCellNode = getCellNode(activeRow, activeCell);\n\t }\n\t }\n\t\n\t function startPostProcessing() {\n\t if (!options.enableAsyncPostRender) {\n\t return;\n\t }\n\t clearTimeout(h_postrender);\n\t h_postrender = setTimeout(asyncPostProcessRows, options.asyncPostRenderDelay);\n\t }\n\t\n\t function startPostProcessingCleanup() {\n\t if (!options.enableAsyncPostRenderCleanup) {\n\t return;\n\t }\n\t clearTimeout(h_postrenderCleanup);\n\t h_postrenderCleanup = setTimeout(asyncPostProcessCleanupRows, options.asyncPostRenderCleanupDelay);\n\t }\n\t\n\t function invalidatePostProcessingResults(row) {\n\t // change status of columns to be re-rendered\n\t for (var columnIdx in postProcessedRows[row]) {\n\t if (postProcessedRows[row].hasOwnProperty(columnIdx)) {\n\t postProcessedRows[row][columnIdx] = 'C';\n\t }\n\t }\n\t postProcessFromRow = Math.min(postProcessFromRow, row);\n\t postProcessToRow = Math.max(postProcessToRow, row);\n\t startPostProcessing();\n\t }\n\t\n\t function updateRowPositions() {\n\t for (var row in rowsCache) {\n\t rowsCache[row].rowNode.style.top = getRowTop(row) + 'px';\n\t }\n\t }\n\t\n\t function render() {\n\t if (!initialized) {\n\t return;\n\t }\n\t var visible = getVisibleRange();\n\t var rendered = getRenderedRange();\n\t\n\t // remove rows no longer in the viewport\n\t cleanupRows(rendered);\n\t\n\t // add new rows & missing cells in existing rows\n\t if (lastRenderedScrollLeft != scrollLeft) {\n\t cleanUpAndRenderCells(rendered);\n\t }\n\t\n\t // render missing rows\n\t renderRows(rendered);\n\t\n\t postProcessFromRow = visible.top;\n\t postProcessToRow = Math.min(getDataLengthIncludingAddNew() - 1, visible.bottom);\n\t startPostProcessing();\n\t\n\t lastRenderedScrollTop = scrollTop;\n\t lastRenderedScrollLeft = scrollLeft;\n\t h_render = null;\n\t }\n\t\n\t function handleHeaderRowScroll() {\n\t var scrollLeft = $headerRowScroller[0].scrollLeft;\n\t if (scrollLeft != $viewport[0].scrollLeft) {\n\t $viewport[0].scrollLeft = scrollLeft;\n\t }\n\t }\n\t\n\t function handleFooterRowScroll() {\n\t var scrollLeft = $footerRowScroller[0].scrollLeft;\n\t if (scrollLeft != $viewport[0].scrollLeft) {\n\t $viewport[0].scrollLeft = scrollLeft;\n\t }\n\t }\n\t\n\t function handleScroll() {\n\t scrollTop = $viewport[0].scrollTop;\n\t scrollLeft = $viewport[0].scrollLeft;\n\t var vScrollDist = Math.abs(scrollTop - prevScrollTop);\n\t var hScrollDist = Math.abs(scrollLeft - prevScrollLeft);\n\t\n\t if (hScrollDist) {\n\t prevScrollLeft = scrollLeft;\n\t $headerScroller[0].scrollLeft = scrollLeft;\n\t $topPanelScroller[0].scrollLeft = scrollLeft;\n\t $headerRowScroller[0].scrollLeft = scrollLeft;\n\t if (options.createFooterRow) {\n\t $footerRowScroller[0].scrollLeft = scrollLeft;\n\t }\n\t }\n\t\n\t if (vScrollDist) {\n\t vScrollDir = prevScrollTop < scrollTop ? 1 : -1;\n\t prevScrollTop = scrollTop;\n\t\n\t // switch virtual pages if needed\n\t if (vScrollDist < viewportH) {\n\t scrollTo(scrollTop + offset);\n\t } else {\n\t var oldOffset = offset;\n\t if (h == viewportH) {\n\t page = 0;\n\t } else {\n\t page = Math.min(n - 1, Math.floor(scrollTop * ((th - viewportH) / (h - viewportH)) * (1 / ph)));\n\t }\n\t offset = Math.round(page * cj);\n\t if (oldOffset != offset) {\n\t invalidateAllRows();\n\t }\n\t }\n\t }\n\t\n\t if (hScrollDist || vScrollDist) {\n\t if (h_render) {\n\t clearTimeout(h_render);\n\t }\n\t\n\t if (Math.abs(lastRenderedScrollTop - scrollTop) > 20 || Math.abs(lastRenderedScrollLeft - scrollLeft) > 20) {\n\t if (options.forceSyncScrolling || Math.abs(lastRenderedScrollTop - scrollTop) < viewportH && Math.abs(lastRenderedScrollLeft - scrollLeft) < viewportW) {\n\t render();\n\t } else {\n\t h_render = setTimeout(render, 50);\n\t }\n\t\n\t trigger(self.onViewportChanged, { grid: self });\n\t }\n\t }\n\t\n\t trigger(self.onScroll, { scrollLeft: scrollLeft, scrollTop: scrollTop, grid: self });\n\t }\n\t\n\t function asyncPostProcessRows() {\n\t var dataLength = getDataLength();\n\t while (postProcessFromRow <= postProcessToRow) {\n\t var row = vScrollDir >= 0 ? postProcessFromRow++ : postProcessToRow--;\n\t var cacheEntry = rowsCache[row];\n\t if (!cacheEntry || row >= dataLength) {\n\t continue;\n\t }\n\t\n\t if (!postProcessedRows[row]) {\n\t postProcessedRows[row] = {};\n\t }\n\t\n\t ensureCellNodesInRowsCache(row);\n\t for (var columnIdx in cacheEntry.cellNodesByColumnIdx) {\n\t if (!cacheEntry.cellNodesByColumnIdx.hasOwnProperty(columnIdx)) {\n\t continue;\n\t }\n\t\n\t columnIdx = columnIdx | 0;\n\t\n\t var m = columns[columnIdx];\n\t var processedStatus = postProcessedRows[row][columnIdx]; // C=cleanup and re-render, R=rendered\n\t if (m.asyncPostRender && processedStatus !== 'R') {\n\t var node = cacheEntry.cellNodesByColumnIdx[columnIdx];\n\t if (node) {\n\t m.asyncPostRender(node, row, getDataItem(row), m, processedStatus === 'C');\n\t }\n\t postProcessedRows[row][columnIdx] = 'R';\n\t }\n\t }\n\t\n\t h_postrender = setTimeout(asyncPostProcessRows, options.asyncPostRenderDelay);\n\t return;\n\t }\n\t }\n\t\n\t function asyncPostProcessCleanupRows() {\n\t if (postProcessedCleanupQueue.length > 0) {\n\t var groupId = postProcessedCleanupQueue[0].groupId;\n\t\n\t // loop through all queue members with this groupID\n\t while (postProcessedCleanupQueue.length > 0 && postProcessedCleanupQueue[0].groupId == groupId) {\n\t var entry = postProcessedCleanupQueue.shift();\n\t if (entry.actionType == 'R') {\n\t (0, _jquery2.default)(entry.node).remove();\n\t }\n\t if (entry.actionType == 'C') {\n\t var column = columns[entry.columnIdx];\n\t if (column.asyncPostRenderCleanup && entry.node) {\n\t // cleanup must also remove element\n\t column.asyncPostRenderCleanup(entry.node, entry.rowIdx, column);\n\t }\n\t }\n\t }\n\t\n\t // call this function again after the specified delay\n\t h_postrenderCleanup = setTimeout(asyncPostProcessCleanupRows, options.asyncPostRenderCleanupDelay);\n\t }\n\t }\n\t\n\t function updateCellCssStylesOnRenderedRows(addedHash, removedHash) {\n\t var node, columnId, addedRowHash, removedRowHash;\n\t for (var row in rowsCache) {\n\t removedRowHash = removedHash && removedHash[row];\n\t addedRowHash = addedHash && addedHash[row];\n\t\n\t if (removedRowHash) {\n\t for (columnId in removedRowHash) {\n\t if (!addedRowHash || removedRowHash[columnId] != addedRowHash[columnId]) {\n\t node = getCellNode(row, getColumnIndex(columnId));\n\t if (node) {\n\t (0, _jquery2.default)(node).removeClass(removedRowHash[columnId]);\n\t }\n\t }\n\t }\n\t }\n\t\n\t if (addedRowHash) {\n\t for (columnId in addedRowHash) {\n\t if (!removedRowHash || removedRowHash[columnId] != addedRowHash[columnId]) {\n\t node = getCellNode(row, getColumnIndex(columnId));\n\t if (node) {\n\t (0, _jquery2.default)(node).addClass(addedRowHash[columnId]);\n\t }\n\t }\n\t }\n\t }\n\t }\n\t }\n\t\n\t function addCellCssStyles(key, hash) {\n\t if (cellCssClasses[key]) {\n\t throw \"addCellCssStyles: cell CSS hash with key '\" + key + \"' already exists.\";\n\t }\n\t\n\t cellCssClasses[key] = hash;\n\t updateCellCssStylesOnRenderedRows(hash, null);\n\t\n\t trigger(self.onCellCssStylesChanged, { 'key': key, 'hash': hash, 'grid': self });\n\t }\n\t\n\t function removeCellCssStyles(key) {\n\t if (!cellCssClasses[key]) {\n\t return;\n\t }\n\t\n\t updateCellCssStylesOnRenderedRows(null, cellCssClasses[key]);\n\t delete cellCssClasses[key];\n\t\n\t trigger(self.onCellCssStylesChanged, { 'key': key, 'hash': null, 'grid': self });\n\t }\n\t\n\t function setCellCssStyles(key, hash) {\n\t var prevHash = cellCssClasses[key];\n\t\n\t cellCssClasses[key] = hash;\n\t updateCellCssStylesOnRenderedRows(hash, prevHash);\n\t\n\t trigger(self.onCellCssStylesChanged, { 'key': key, 'hash': hash, 'grid': self });\n\t }\n\t\n\t function getCellCssStyles(key) {\n\t return cellCssClasses[key];\n\t }\n\t\n\t function flashCell(row, cell, speed) {\n\t speed = speed || 100;\n\t if (rowsCache[row]) {\n\t var toggleCellClass = function toggleCellClass(times) {\n\t if (!times) {\n\t return;\n\t }\n\t setTimeout(function () {\n\t $cell.queue(function () {\n\t $cell.toggleClass(options.cellFlashingCssClass).dequeue();\n\t toggleCellClass(times - 1);\n\t });\n\t }, speed);\n\t };\n\t\n\t var $cell = (0, _jquery2.default)(getCellNode(row, cell));\n\t\n\t toggleCellClass(4);\n\t }\n\t }\n\t\n\t // ////////////////////////////////////////////////////////////////////////////////////////////\n\t // Interactivity\n\t\n\t function handleMouseWheel(e) {\n\t var rowNode = (0, _jquery2.default)(e.target).closest('.slick-row')[0];\n\t if (rowNode != rowNodeFromLastMouseWheelEvent) {\n\t if (zombieRowNodeFromLastMouseWheelEvent && zombieRowNodeFromLastMouseWheelEvent != rowNode) {\n\t if (options.enableAsyncPostRenderCleanup && zombieRowPostProcessedFromLastMouseWheelEvent) {\n\t queuePostProcessedRowForCleanup(zombieRowCacheFromLastMouseWheelEvent, zombieRowPostProcessedFromLastMouseWheelEvent);\n\t } else {\n\t $canvas[0].removeChild(zombieRowNodeFromLastMouseWheelEvent);\n\t }\n\t zombieRowNodeFromLastMouseWheelEvent = null;\n\t zombieRowCacheFromLastMouseWheelEvent = null;\n\t zombieRowPostProcessedFromLastMouseWheelEvent = null;\n\t\n\t if (options.enableAsyncPostRenderCleanup) {\n\t startPostProcessingCleanup();\n\t }\n\t }\n\t rowNodeFromLastMouseWheelEvent = rowNode;\n\t }\n\t }\n\t\n\t function handleDragStart(interactEvent) {\n\t var event = _jquery2.default.Event(interactEvent.originalEvent.type, interactEvent.originalEvent);\n\t var cell = getCellFromEvent(event);\n\t if (!cell || !cellExists(cell.row, cell.cell)) {\n\t return false;\n\t }\n\t\n\t var retval = trigger(self.onDragStart, interactEvent, event);\n\t if (event.isImmediatePropagationStopped()) {\n\t return retval;\n\t }\n\t\n\t return false;\n\t }\n\t\n\t function handleDrag(interactEvent) {\n\t var event = _jquery2.default.Event(interactEvent.originalEvent.type, interactEvent.originalEvent);\n\t return trigger(self.onDrag, interactEvent, event);\n\t }\n\t\n\t function handleDragEnd(interactEvent) {\n\t trigger(self.onDragEnd, interactEvent, _jquery2.default.Event('mousedown'));\n\t }\n\t\n\t function handleKeyDown(e) {\n\t trigger(self.onKeyDown, { row: activeRow, cell: activeCell, grid: self }, e);\n\t var handled = e.isImmediatePropagationStopped();\n\t var keyCode = _slick2.default.keyCode;\n\t\n\t if (!handled) {\n\t if (!e.shiftKey && !e.altKey && !e.ctrlKey) {\n\t // editor may specify an array of keys to bubble\n\t if (options.editable && currentEditor && currentEditor.keyCaptureList) {\n\t if (currentEditor.keyCaptureList.indexOf(e.which) > -1) {\n\t return;\n\t }\n\t }\n\t if (e.which == keyCode.ESCAPE) {\n\t if (!getEditorLock().isActive()) {\n\t return; // no editing mode to cancel, allow bubbling and default processing (exit without cancelling the event)\n\t }\n\t cancelEditAndSetFocus();\n\t } else if (e.which == keyCode.PAGE_DOWN) {\n\t navigatePageDown();\n\t handled = true;\n\t } else if (e.which == keyCode.PAGE_UP) {\n\t navigatePageUp();\n\t handled = true;\n\t } else if (e.which == keyCode.LEFT) {\n\t handled = navigateLeft();\n\t } else if (e.which == keyCode.RIGHT) {\n\t handled = navigateRight();\n\t } else if (e.which == keyCode.UP) {\n\t handled = navigateUp();\n\t } else if (e.which == keyCode.DOWN) {\n\t handled = navigateDown();\n\t } else if (e.which == keyCode.TAB) {\n\t handled = navigateNext();\n\t } else if (e.which == keyCode.ENTER) {\n\t if (options.editable) {\n\t if (currentEditor) {\n\t // adding new row\n\t if (activeRow === getDataLength()) {\n\t navigateDown();\n\t } else {\n\t commitEditAndSetFocus();\n\t }\n\t } else {\n\t if (getEditorLock().commitCurrentEdit()) {\n\t makeActiveCellEditable();\n\t }\n\t }\n\t }\n\t handled = true;\n\t }\n\t } else if (e.which == keyCode.TAB && e.shiftKey && !e.ctrlKey && !e.altKey) {\n\t handled = navigatePrev();\n\t }\n\t }\n\t\n\t if (handled) {\n\t // the event has been handled so don't let parent element (bubbling/propagation) or browser (default) handle it\n\t e.stopPropagation();\n\t e.preventDefault();\n\t try {\n\t e.originalEvent.keyCode = 0; // prevent default behaviour for special keys in IE browsers (F3, F5, etc.)\n\t }\n\t // ignore exceptions - setting the original event's keycode throws access denied exception for \"Ctrl\"\n\t // (hitting control key only, nothing else), \"Shift\" (maybe others)\n\t catch (error) {}\n\t }\n\t }\n\t\n\t function handleClick(e) {\n\t if (!currentEditor) {\n\t // if this click resulted in some cell child node getting focus,\n\t // don't steal it back - keyboard events will still bubble up\n\t // IE9+ seems to default DIVs to tabIndex=0 instead of -1, so check for cell clicks directly.\n\t if (e.target != document.activeElement || (0, _jquery2.default)(e.target).hasClass('slick-cell')) {\n\t setFocus();\n\t }\n\t }\n\t\n\t var cell = getCellFromEvent(e);\n\t if (!cell || currentEditor !== null && activeRow == cell.row && activeCell == cell.cell) {\n\t return;\n\t }\n\t\n\t trigger(self.onClick, { row: cell.row, cell: cell.cell, grid: self }, e);\n\t if (e.isImmediatePropagationStopped()) {\n\t return;\n\t }\n\t\n\t if ((activeCell != cell.cell || activeRow != cell.row) && canCellBeActive(cell.row, cell.cell)) {\n\t if (!getEditorLock().isActive() || getEditorLock().commitCurrentEdit()) {\n\t scrollRowIntoView(cell.row, false);\n\t setActiveCellInternal(getCellNode(cell.row, cell.cell));\n\t }\n\t }\n\t }\n\t\n\t function handleContextMenu(e) {\n\t var $cell = (0, _jquery2.default)(e.target).closest('.slick-cell', $canvas);\n\t if ($cell.length === 0) {\n\t return;\n\t }\n\t\n\t // are we editing this cell?\n\t if (activeCellNode === $cell[0] && currentEditor !== null) {\n\t return;\n\t }\n\t\n\t trigger(self.onContextMenu, { grid: self }, e);\n\t }\n\t\n\t function handleDblClick(e) {\n\t var cell = getCellFromEvent(e);\n\t if (!cell || currentEditor !== null && activeRow == cell.row && activeCell == cell.cell) {\n\t return;\n\t }\n\t\n\t trigger(self.onDblClick, { row: cell.row, cell: cell.cell, grid: self }, e);\n\t if (e.isImmediatePropagationStopped()) {\n\t return;\n\t }\n\t\n\t if (options.editable) {\n\t gotoCell(cell.row, cell.cell, true);\n\t }\n\t }\n\t\n\t function handleHeaderMouseEnter(e) {\n\t trigger(self.onHeaderMouseEnter, {\n\t 'column': (0, _jquery2.default)(this).data('column'),\n\t 'grid': self\n\t }, e);\n\t }\n\t\n\t function handleHeaderMouseLeave(e) {\n\t trigger(self.onHeaderMouseLeave, {\n\t 'column': (0, _jquery2.default)(this).data('column'),\n\t 'grid': self\n\t }, e);\n\t }\n\t\n\t function handleHeaderContextMenu(e) {\n\t var $header = (0, _jquery2.default)(e.target).closest('.slick-header-column', '.slick-header-columns');\n\t var column = $header && $header.data('column');\n\t trigger(self.onHeaderContextMenu, { column: column, grid: self }, e);\n\t }\n\t\n\t function handleHeaderClick(e) {\n\t var $header = (0, _jquery2.default)(e.target).closest('.slick-header-column', '.slick-header-columns');\n\t var column = $header && $header.data('column');\n\t if (column) {\n\t trigger(self.onHeaderClick, { column: column, grid: self }, e);\n\t }\n\t }\n\t\n\t function handleMouseEnter(e) {\n\t trigger(self.onMouseEnter, { grid: self }, e);\n\t }\n\t\n\t function handleMouseLeave(e) {\n\t trigger(self.onMouseLeave, { grid: self }, e);\n\t }\n\t\n\t function cellExists(row, cell) {\n\t return !(row < 0 || row >= getDataLength() || cell < 0 || cell >= columns.length);\n\t }\n\t\n\t function getCellFromPoint(x, y) {\n\t var row = getRowFromPosition(y);\n\t var cell = 0;\n\t\n\t var w = 0;\n\t for (var i = 0; i < columns.length && w < x; i++) {\n\t w += columns[i].width;\n\t cell++;\n\t }\n\t\n\t if (cell < 0) {\n\t cell = 0;\n\t }\n\t\n\t return { row: row, cell: cell - 1 };\n\t }\n\t\n\t function getCellFromNode(cellNode) {\n\t // read column number from .l CSS class\n\t var cls = /l\\d+/.exec(cellNode.className);\n\t if (!cls) {\n\t throw 'getCellFromNode: cannot get cell - ' + cellNode.className;\n\t }\n\t return parseInt(cls[0].substr(1, cls[0].length - 1), 10);\n\t }\n\t\n\t function getRowFromNode(rowNode) {\n\t for (var row in rowsCache) {\n\t if (rowsCache[row].rowNode === rowNode) {\n\t return row | 0;\n\t }\n\t }\n\t\n\t return null;\n\t }\n\t\n\t function getCellFromEvent(e) {\n\t var $cell = (0, _jquery2.default)(e.target).closest('.slick-cell', $canvas);\n\t if (!$cell.length) {\n\t return null;\n\t }\n\t\n\t var row = getRowFromNode($cell[0].parentNode);\n\t var cell = getCellFromNode($cell[0]);\n\t\n\t if (row == null || cell == null) {\n\t return null;\n\t } else {\n\t return {\n\t 'row': row,\n\t 'cell': cell\n\t };\n\t }\n\t }\n\t\n\t function getCellNodeBox(row, cell) {\n\t if (!cellExists(row, cell)) {\n\t return null;\n\t }\n\t\n\t var y1 = getRowTop(row);\n\t var y2 = y1 + options.rowHeight - 1;\n\t var x1 = 0;\n\t for (var i = 0; i < cell; i++) {\n\t x1 += columns[i].width;\n\t }\n\t var x2 = x1 + columns[cell].width;\n\t\n\t return {\n\t top: y1,\n\t left: x1,\n\t bottom: y2,\n\t right: x2\n\t };\n\t }\n\t\n\t // ////////////////////////////////////////////////////////////////////////////////////////////\n\t // Cell switching\n\t\n\t function resetActiveCell() {\n\t setActiveCellInternal(null, false);\n\t }\n\t\n\t function setFocus() {\n\t if (tabbingDirection == -1) {\n\t $focusSink[0].focus();\n\t } else {\n\t $focusSink2[0].focus();\n\t }\n\t }\n\t\n\t function scrollCellIntoView(row, cell, doPaging) {\n\t scrollRowIntoView(row, doPaging);\n\t\n\t var colspan = getColspan(row, cell);\n\t var left = columnPosLeft[cell],\n\t right = columnPosRight[cell + (colspan > 1 ? colspan - 1 : 0)],\n\t scrollRight = scrollLeft + viewportW;\n\t\n\t if (left < scrollLeft) {\n\t $viewport.scrollLeft(left);\n\t handleScroll();\n\t render();\n\t } else if (right > scrollRight) {\n\t $viewport.scrollLeft(Math.min(left, right - $viewport[0].clientWidth));\n\t handleScroll();\n\t render();\n\t }\n\t }\n\t\n\t function setActiveCellInternal(newCell, opt_editMode) {\n\t if (activeCellNode !== null) {\n\t makeActiveCellNormal();\n\t (0, _jquery2.default)(activeCellNode).removeClass('active');\n\t if (rowsCache[activeRow]) {\n\t (0, _jquery2.default)(rowsCache[activeRow].rowNode).removeClass('active');\n\t }\n\t }\n\t\n\t var activeCellChanged = activeCellNode !== newCell;\n\t activeCellNode = newCell;\n\t\n\t if (activeCellNode != null) {\n\t activeRow = getRowFromNode(activeCellNode.parentNode);\n\t activeCell = activePosX = getCellFromNode(activeCellNode);\n\t\n\t if (opt_editMode == null) {\n\t opt_editMode = activeRow == getDataLength() || options.autoEdit;\n\t }\n\t\n\t (0, _jquery2.default)(activeCellNode).addClass('active');\n\t (0, _jquery2.default)(rowsCache[activeRow].rowNode).addClass('active');\n\t\n\t if (options.editable && opt_editMode && isCellPotentiallyEditable(activeRow, activeCell)) {\n\t clearTimeout(h_editorLoader);\n\t\n\t if (options.asyncEditorLoading) {\n\t h_editorLoader = setTimeout(function () {\n\t makeActiveCellEditable();\n\t }, options.asyncEditorLoadDelay);\n\t } else {\n\t makeActiveCellEditable();\n\t }\n\t }\n\t } else {\n\t activeRow = activeCell = null;\n\t }\n\t\n\t if (activeCellChanged) {\n\t trigger(self.onActiveCellChanged, getActiveCell());\n\t }\n\t }\n\t\n\t function clearTextSelection() {\n\t if (document.selection && document.selection.empty) {\n\t try {\n\t // IE fails here if selected element is not in dom\n\t document.selection.empty();\n\t } catch (e) {}\n\t } else if (window.getSelection) {\n\t var sel = window.getSelection();\n\t if (sel && sel.removeAllRanges) {\n\t sel.removeAllRanges();\n\t }\n\t }\n\t }\n\t\n\t function isCellPotentiallyEditable(row, cell) {\n\t var dataLength = getDataLength();\n\t // is the data for this row loaded?\n\t if (row < dataLength && !getDataItem(row)) {\n\t return false;\n\t }\n\t\n\t // are we in the Add New row? can we create new from this cell?\n\t if (columns[cell].cannotTriggerInsert && row >= dataLength) {\n\t return false;\n\t }\n\t\n\t // does this cell have an editor?\n\t if (!getEditor(row, cell)) {\n\t return false;\n\t }\n\t\n\t return true;\n\t }\n\t\n\t function makeActiveCellNormal() {\n\t if (!currentEditor) {\n\t return;\n\t }\n\t trigger(self.onBeforeCellEditorDestroy, { editor: currentEditor, grid: self });\n\t currentEditor.destroy();\n\t currentEditor = null;\n\t\n\t if (activeCellNode) {\n\t var d = getDataItem(activeRow);\n\t (0, _jquery2.default)(activeCellNode).removeClass('editable invalid');\n\t if (d) {\n\t var column = columns[activeCell];\n\t var formatter = getFormatter(activeRow, column);\n\t activeCellNode.innerHTML = formatter(activeRow, activeCell, getDataItemValueForColumn(d, column), column, d, self);\n\t invalidatePostProcessingResults(activeRow);\n\t }\n\t }\n\t\n\t // if there previously was text selected on a page (such as selected text in the edit cell just removed),\n\t // IE can't set focus to anything else correctly\n\t if (navigator.userAgent.toLowerCase().match(/msie/)) {\n\t clearTextSelection();\n\t }\n\t\n\t getEditorLock().deactivate(editController);\n\t }\n\t\n\t function makeActiveCellEditable(editor) {\n\t if (!activeCellNode) {\n\t return;\n\t }\n\t if (!options.editable) {\n\t throw 'Grid : makeActiveCellEditable : should never get called when options.editable is false';\n\t }\n\t\n\t // cancel pending async call if there is one\n\t clearTimeout(h_editorLoader);\n\t\n\t if (!isCellPotentiallyEditable(activeRow, activeCell)) {\n\t return;\n\t }\n\t\n\t var columnDef = columns[activeCell];\n\t var item = getDataItem(activeRow);\n\t\n\t if (trigger(self.onBeforeEditCell, {\n\t row: activeRow,\n\t cell: activeCell,\n\t item: item,\n\t column: columnDef,\n\t grid: self\n\t }) === false) {\n\t setFocus();\n\t return;\n\t }\n\t\n\t getEditorLock().activate(editController);\n\t (0, _jquery2.default)(activeCellNode).addClass('editable');\n\t\n\t var useEditor = editor || getEditor(activeRow, activeCell);\n\t\n\t // don't clear the cell if a custom editor is passed through\n\t if (!editor && !useEditor.suppressClearOnEdit) {\n\t activeCellNode.innerHTML = '';\n\t }\n\t\n\t currentEditor = new useEditor({\n\t grid: self,\n\t gridPosition: absBox($container[0]),\n\t position: absBox(activeCellNode),\n\t container: activeCellNode,\n\t column: columnDef,\n\t item: item || {},\n\t commitChanges: commitEditAndSetFocus,\n\t cancelChanges: cancelEditAndSetFocus\n\t });\n\t\n\t if (item) {\n\t currentEditor.loadValue(item);\n\t }\n\t\n\t serializedEditorValue = currentEditor.serializeValue();\n\t\n\t if (currentEditor.position) {\n\t handleActiveCellPositionChange();\n\t }\n\t }\n\t\n\t function commitEditAndSetFocus() {\n\t // if the commit fails, it would do so due to a validation error\n\t // if so, do not steal the focus from the editor\n\t if (getEditorLock().commitCurrentEdit()) {\n\t setFocus();\n\t if (options.autoEdit) {\n\t navigateDown();\n\t }\n\t }\n\t }\n\t\n\t function cancelEditAndSetFocus() {\n\t if (getEditorLock().cancelCurrentEdit()) {\n\t setFocus();\n\t }\n\t }\n\t\n\t function absBox(elem) {\n\t var box = {\n\t top: elem.offsetTop,\n\t left: elem.offsetLeft,\n\t bottom: 0,\n\t right: 0,\n\t width: (0, _jquery2.default)(elem).outerWidth(),\n\t height: (0, _jquery2.default)(elem).outerHeight(),\n\t visible: true\n\t };\n\t box.bottom = box.top + box.height;\n\t box.right = box.left + box.width;\n\t\n\t // walk up the tree\n\t var offsetParent = elem.offsetParent;\n\t while ((elem = elem.parentNode) != document.body) {\n\t if (elem == null) break;\n\t\n\t if (box.visible && elem.scrollHeight != elem.offsetHeight && (0, _jquery2.default)(elem).css('overflowY') != 'visible') {\n\t box.visible = box.bottom > elem.scrollTop && box.top < elem.scrollTop + elem.clientHeight;\n\t }\n\t\n\t if (box.visible && elem.scrollWidth != elem.offsetWidth && (0, _jquery2.default)(elem).css('overflowX') != 'visible') {\n\t box.visible = box.right > elem.scrollLeft && box.left < elem.scrollLeft + elem.clientWidth;\n\t }\n\t\n\t box.left -= elem.scrollLeft;\n\t box.top -= elem.scrollTop;\n\t\n\t if (elem === offsetParent) {\n\t box.left += elem.offsetLeft;\n\t box.top += elem.offsetTop;\n\t offsetParent = elem.offsetParent;\n\t }\n\t\n\t box.bottom = box.top + box.height;\n\t box.right = box.left + box.width;\n\t }\n\t\n\t return box;\n\t }\n\t\n\t function getActiveCellPosition() {\n\t return absBox(activeCellNode);\n\t }\n\t\n\t function getGridPosition() {\n\t return absBox($container[0]);\n\t }\n\t\n\t function handleActiveCellPositionChange() {\n\t if (!activeCellNode) {\n\t return;\n\t }\n\t\n\t trigger(self.onActiveCellPositionChanged, { grid: self });\n\t\n\t if (currentEditor) {\n\t var cellBox = getActiveCellPosition();\n\t if (currentEditor.show && currentEditor.hide) {\n\t if (!cellBox.visible) {\n\t currentEditor.hide();\n\t } else {\n\t currentEditor.show();\n\t }\n\t }\n\t\n\t if (currentEditor.position) {\n\t currentEditor.position(cellBox);\n\t }\n\t }\n\t }\n\t\n\t function getCellEditor() {\n\t return currentEditor;\n\t }\n\t\n\t function getActiveCell() {\n\t if (!activeCellNode) {\n\t return null;\n\t } else {\n\t return { row: activeRow, cell: activeCell, grid: self };\n\t }\n\t }\n\t\n\t function getActiveCellNode() {\n\t return activeCellNode;\n\t }\n\t\n\t function scrollRowIntoView(row, doPaging) {\n\t var rowAtTop = row * options.rowHeight;\n\t var rowAtBottom = (row + 1) * options.rowHeight - viewportH + (viewportHasHScroll ? scrollbarDimensions.height : 0);\n\t\n\t // need to page down?\n\t if ((row + 1) * options.rowHeight > scrollTop + viewportH + offset) {\n\t scrollTo(doPaging ? rowAtTop : rowAtBottom);\n\t render();\n\t }\n\t // or page up?\n\t else if (row * options.rowHeight < scrollTop + offset) {\n\t scrollTo(doPaging ? rowAtBottom : rowAtTop);\n\t render();\n\t }\n\t }\n\t\n\t function scrollRowToTop(row) {\n\t scrollTo(row * options.rowHeight);\n\t render();\n\t }\n\t\n\t function scrollPage(dir) {\n\t var deltaRows = dir * numVisibleRows;\n\t scrollTo((getRowFromPosition(scrollTop) + deltaRows) * options.rowHeight);\n\t render();\n\t\n\t if (options.enableCellNavigation && activeRow != null) {\n\t var row = activeRow + deltaRows;\n\t var dataLengthIncludingAddNew = getDataLengthIncludingAddNew();\n\t if (row >= dataLengthIncludingAddNew) {\n\t row = dataLengthIncludingAddNew - 1;\n\t }\n\t if (row < 0) {\n\t row = 0;\n\t }\n\t\n\t var cell = 0,\n\t prevCell = null;\n\t var prevActivePosX = activePosX;\n\t while (cell <= activePosX) {\n\t if (canCellBeActive(row, cell)) {\n\t prevCell = cell;\n\t }\n\t cell += getColspan(row, cell);\n\t }\n\t\n\t if (prevCell !== null) {\n\t setActiveCellInternal(getCellNode(row, prevCell));\n\t activePosX = prevActivePosX;\n\t } else {\n\t resetActiveCell();\n\t }\n\t }\n\t }\n\t\n\t function navigatePageDown() {\n\t scrollPage(1);\n\t }\n\t\n\t function navigatePageUp() {\n\t scrollPage(-1);\n\t }\n\t\n\t function getColspan(row, cell) {\n\t var metadata = data.getItemMetadata && data.getItemMetadata(row);\n\t if (!metadata || !metadata.columns) {\n\t return 1;\n\t }\n\t\n\t var columnData = metadata.columns[columns[cell].id] || metadata.columns[cell];\n\t var colspan = columnData && columnData.colspan;\n\t if (colspan === '*') {\n\t colspan = columns.length - cell;\n\t } else {\n\t colspan = colspan || 1;\n\t }\n\t\n\t return colspan;\n\t }\n\t\n\t function findFirstFocusableCell(row) {\n\t var cell = 0;\n\t while (cell < columns.length) {\n\t if (canCellBeActive(row, cell)) {\n\t return cell;\n\t }\n\t cell += getColspan(row, cell);\n\t }\n\t return null;\n\t }\n\t\n\t function findLastFocusableCell(row) {\n\t var cell = 0;\n\t var lastFocusableCell = null;\n\t while (cell < columns.length) {\n\t if (canCellBeActive(row, cell)) {\n\t lastFocusableCell = cell;\n\t }\n\t cell += getColspan(row, cell);\n\t }\n\t return lastFocusableCell;\n\t }\n\t\n\t function gotoRight(row, cell, posX) {\n\t if (cell >= columns.length) {\n\t return null;\n\t }\n\t\n\t do {\n\t cell += getColspan(row, cell);\n\t } while (cell < columns.length && !canCellBeActive(row, cell));\n\t\n\t if (cell < columns.length) {\n\t return {\n\t 'row': row,\n\t 'cell': cell,\n\t 'posX': cell\n\t };\n\t }\n\t return null;\n\t }\n\t\n\t function gotoLeft(row, cell, posX) {\n\t if (cell <= 0) {\n\t return null;\n\t }\n\t\n\t var firstFocusableCell = findFirstFocusableCell(row);\n\t if (firstFocusableCell === null || firstFocusableCell >= cell) {\n\t return null;\n\t }\n\t\n\t var prev = {\n\t 'row': row,\n\t 'cell': firstFocusableCell,\n\t 'posX': firstFocusableCell\n\t };\n\t var pos;\n\t while (true) {\n\t pos = gotoRight(prev.row, prev.cell, prev.posX);\n\t if (!pos) {\n\t return null;\n\t }\n\t if (pos.cell >= cell) {\n\t return prev;\n\t }\n\t prev = pos;\n\t }\n\t }\n\t\n\t function gotoDown(row, cell, posX) {\n\t var prevCell;\n\t var dataLengthIncludingAddNew = getDataLengthIncludingAddNew();\n\t while (true) {\n\t if (++row >= dataLengthIncludingAddNew) {\n\t return null;\n\t }\n\t\n\t prevCell = cell = 0;\n\t while (cell <= posX) {\n\t prevCell = cell;\n\t cell += getColspan(row, cell);\n\t }\n\t\n\t if (canCellBeActive(row, prevCell)) {\n\t return {\n\t 'row': row,\n\t 'cell': prevCell,\n\t 'posX': posX\n\t };\n\t }\n\t }\n\t }\n\t\n\t function gotoUp(row, cell, posX) {\n\t var prevCell;\n\t while (true) {\n\t if (--row < 0) {\n\t return null;\n\t }\n\t\n\t prevCell = cell = 0;\n\t while (cell <= posX) {\n\t prevCell = cell;\n\t cell += getColspan(row, cell);\n\t }\n\t\n\t if (canCellBeActive(row, prevCell)) {\n\t return {\n\t 'row': row,\n\t 'cell': prevCell,\n\t 'posX': posX\n\t };\n\t }\n\t }\n\t }\n\t\n\t function gotoNext(row, cell, posX) {\n\t if (row == null && cell == null) {\n\t row = cell = posX = 0;\n\t if (canCellBeActive(row, cell)) {\n\t return {\n\t 'row': row,\n\t 'cell': cell,\n\t 'posX': cell\n\t };\n\t }\n\t }\n\t\n\t var pos = gotoRight(row, cell, posX);\n\t if (pos) {\n\t return pos;\n\t }\n\t\n\t var firstFocusableCell = null;\n\t var dataLengthIncludingAddNew = getDataLengthIncludingAddNew();\n\t while (++row < dataLengthIncludingAddNew) {\n\t firstFocusableCell = findFirstFocusableCell(row);\n\t if (firstFocusableCell !== null) {\n\t return {\n\t 'row': row,\n\t 'cell': firstFocusableCell,\n\t 'posX': firstFocusableCell\n\t };\n\t }\n\t }\n\t return null;\n\t }\n\t\n\t function gotoPrev(row, cell, posX) {\n\t if (row == null && cell == null) {\n\t row = getDataLengthIncludingAddNew() - 1;\n\t cell = posX = columns.length - 1;\n\t if (canCellBeActive(row, cell)) {\n\t return {\n\t 'row': row,\n\t 'cell': cell,\n\t 'posX': cell\n\t };\n\t }\n\t }\n\t\n\t var pos;\n\t var lastSelectableCell;\n\t while (!pos) {\n\t pos = gotoLeft(row, cell, posX);\n\t if (pos) {\n\t break;\n\t }\n\t if (--row < 0) {\n\t return null;\n\t }\n\t\n\t cell = 0;\n\t lastSelectableCell = findLastFocusableCell(row);\n\t if (lastSelectableCell !== null) {\n\t pos = {\n\t 'row': row,\n\t 'cell': lastSelectableCell,\n\t 'posX': lastSelectableCell\n\t };\n\t }\n\t }\n\t return pos;\n\t }\n\t\n\t function navigateRight() {\n\t return navigate('right');\n\t }\n\t\n\t function navigateLeft() {\n\t return navigate('left');\n\t }\n\t\n\t function navigateDown() {\n\t return navigate('down');\n\t }\n\t\n\t function navigateUp() {\n\t return navigate('up');\n\t }\n\t\n\t function navigateNext() {\n\t return navigate('next');\n\t }\n\t\n\t function navigatePrev() {\n\t return navigate('prev');\n\t }\n\t\n\t /**\n\t * @param {string} dir Navigation direction.\n\t * @return {boolean} Whether navigation resulted in a change of active cell.\n\t */\n\t function navigate(dir) {\n\t if (!options.enableCellNavigation) {\n\t return false;\n\t }\n\t\n\t if (!activeCellNode && dir != 'prev' && dir != 'next') {\n\t return false;\n\t }\n\t\n\t if (!getEditorLock().commitCurrentEdit()) {\n\t return true;\n\t }\n\t setFocus();\n\t\n\t var tabbingDirections = {\n\t 'up': -1,\n\t 'down': 1,\n\t 'left': -1,\n\t 'right': 1,\n\t 'prev': -1,\n\t 'next': 1\n\t };\n\t tabbingDirection = tabbingDirections[dir];\n\t\n\t var stepFunctions = {\n\t 'up': gotoUp,\n\t 'down': gotoDown,\n\t 'left': gotoLeft,\n\t 'right': gotoRight,\n\t 'prev': gotoPrev,\n\t 'next': gotoNext\n\t };\n\t var stepFn = stepFunctions[dir];\n\t var pos = stepFn(activeRow, activeCell, activePosX);\n\t if (pos) {\n\t var isAddNewRow = pos.row == getDataLength();\n\t scrollCellIntoView(pos.row, pos.cell, !isAddNewRow);\n\t setActiveCellInternal(getCellNode(pos.row, pos.cell));\n\t activePosX = pos.posX;\n\t return true;\n\t } else {\n\t setActiveCellInternal(getCellNode(activeRow, activeCell));\n\t return false;\n\t }\n\t }\n\t\n\t function getCellNode(row, cell) {\n\t if (rowsCache[row]) {\n\t ensureCellNodesInRowsCache(row);\n\t return rowsCache[row].cellNodesByColumnIdx[cell];\n\t }\n\t return null;\n\t }\n\t\n\t function setActiveCell(row, cell) {\n\t if (!initialized) {\n\t return;\n\t }\n\t if (row > getDataLength() || row < 0 || cell >= columns.length || cell < 0) {\n\t return;\n\t }\n\t\n\t if (!options.enableCellNavigation) {\n\t return;\n\t }\n\t\n\t scrollCellIntoView(row, cell, false);\n\t setActiveCellInternal(getCellNode(row, cell), false);\n\t }\n\t\n\t function canCellBeActive(row, cell) {\n\t if (!options.enableCellNavigation || row >= getDataLengthIncludingAddNew() || row < 0 || cell >= columns.length || cell < 0) {\n\t return false;\n\t }\n\t\n\t var rowMetadata = data.getItemMetadata && data.getItemMetadata(row);\n\t if (rowMetadata && typeof rowMetadata.focusable === 'boolean') {\n\t return rowMetadata.focusable;\n\t }\n\t\n\t var columnMetadata = rowMetadata && rowMetadata.columns;\n\t if (columnMetadata && columnMetadata[columns[cell].id] && typeof columnMetadata[columns[cell].id].focusable === 'boolean') {\n\t return columnMetadata[columns[cell].id].focusable;\n\t }\n\t if (columnMetadata && columnMetadata[cell] && typeof columnMetadata[cell].focusable === 'boolean') {\n\t return columnMetadata[cell].focusable;\n\t }\n\t\n\t return columns[cell].focusable;\n\t }\n\t\n\t function canCellBeSelected(row, cell) {\n\t if (row >= getDataLength() || row < 0 || cell >= columns.length || cell < 0) {\n\t return false;\n\t }\n\t\n\t var rowMetadata = data.getItemMetadata && data.getItemMetadata(row);\n\t if (rowMetadata && typeof rowMetadata.selectable === 'boolean') {\n\t return rowMetadata.selectable;\n\t }\n\t\n\t var columnMetadata = rowMetadata && rowMetadata.columns && (rowMetadata.columns[columns[cell].id] || rowMetadata.columns[cell]);\n\t if (columnMetadata && typeof columnMetadata.selectable === 'boolean') {\n\t return columnMetadata.selectable;\n\t }\n\t\n\t return columns[cell].selectable;\n\t }\n\t\n\t function gotoCell(row, cell, forceEdit) {\n\t if (!initialized) {\n\t return;\n\t }\n\t if (!canCellBeActive(row, cell)) {\n\t return;\n\t }\n\t\n\t if (!getEditorLock().commitCurrentEdit()) {\n\t return;\n\t }\n\t\n\t scrollCellIntoView(row, cell, false);\n\t\n\t var newCell = getCellNode(row, cell);\n\t\n\t // if selecting the 'add new' row, start editing right away\n\t setActiveCellInternal(newCell, forceEdit || row === getDataLength() || options.autoEdit);\n\t\n\t // if no editor was created, set the focus back on the grid\n\t if (!currentEditor) {\n\t setFocus();\n\t }\n\t }\n\t\n\t // ////////////////////////////////////////////////////////////////////////////////////////////\n\t // IEditor implementation for the editor lock\n\t\n\t function commitCurrentEdit() {\n\t var item = getDataItem(activeRow);\n\t var column = columns[activeCell];\n\t\n\t if (currentEditor) {\n\t if (currentEditor.isValueChanged()) {\n\t var validationResults = currentEditor.validate();\n\t\n\t if (validationResults.valid) {\n\t if (activeRow < getDataLength()) {\n\t var editCommand = {\n\t row: activeRow,\n\t cell: activeCell,\n\t editor: currentEditor,\n\t serializedValue: currentEditor.serializeValue(),\n\t prevSerializedValue: serializedEditorValue,\n\t execute: function execute() {\n\t this.editor.applyValue(item, this.serializedValue);\n\t updateRow(this.row);\n\t trigger(self.onCellChange, {\n\t row: activeRow,\n\t cell: activeCell,\n\t item: item,\n\t grid: self\n\t });\n\t },\n\t undo: function undo() {\n\t this.editor.applyValue(item, this.prevSerializedValue);\n\t updateRow(this.row);\n\t trigger(self.onCellChange, {\n\t row: activeRow,\n\t cell: activeCell,\n\t item: item,\n\t grid: self\n\t });\n\t }\n\t };\n\t\n\t if (options.editCommandHandler) {\n\t makeActiveCellNormal();\n\t options.editCommandHandler(item, column, editCommand);\n\t } else {\n\t editCommand.execute();\n\t makeActiveCellNormal();\n\t }\n\t } else {\n\t var newItem = {};\n\t currentEditor.applyValue(newItem, currentEditor.serializeValue());\n\t makeActiveCellNormal();\n\t trigger(self.onAddNewRow, { item: newItem, column: column, grid: self });\n\t }\n\t\n\t // check whether the lock has been re-acquired by event handlers\n\t return !getEditorLock().isActive();\n\t } else {\n\t // Re-add the CSS class to trigger transitions, if any.\n\t (0, _jquery2.default)(activeCellNode).removeClass('invalid');\n\t (0, _jquery2.default)(activeCellNode).width(); // force layout\n\t (0, _jquery2.default)(activeCellNode).addClass('invalid');\n\t\n\t trigger(self.onValidationError, {\n\t editor: currentEditor,\n\t cellNode: activeCellNode,\n\t validationResults: validationResults,\n\t row: activeRow,\n\t cell: activeCell,\n\t column: column,\n\t grid: self\n\t });\n\t\n\t currentEditor.focus();\n\t return false;\n\t }\n\t }\n\t\n\t makeActiveCellNormal();\n\t }\n\t return true;\n\t }\n\t\n\t function cancelCurrentEdit() {\n\t makeActiveCellNormal();\n\t return true;\n\t }\n\t\n\t function rowsToRanges(rows) {\n\t var ranges = [];\n\t var lastCell = columns.length - 1;\n\t for (var i = 0; i < rows.length; i++) {\n\t ranges.push(new _slick2.default.Range(rows[i], 0, rows[i], lastCell));\n\t }\n\t return ranges;\n\t }\n\t\n\t function getSelectedRows() {\n\t if (!selectionModel) {\n\t throw 'Selection model is not set';\n\t }\n\t return selectedRows;\n\t }\n\t\n\t function setSelectedRows(rows) {\n\t if (!selectionModel) {\n\t throw 'Selection model is not set';\n\t }\n\t selectionModel.setSelectedRanges(rowsToRanges(rows));\n\t }\n\t\n\t // ////////////////////////////////////////////////////////////////////////////////////////////\n\t // Debug\n\t\n\t this.debug = function () {\n\t var s = '';\n\t\n\t s += '\\n' + 'counter_rows_rendered: ' + counter_rows_rendered;\n\t s += '\\n' + 'counter_rows_removed: ' + counter_rows_removed;\n\t s += '\\n' + 'renderedRows: ' + renderedRows;\n\t s += '\\n' + 'numVisibleRows: ' + numVisibleRows;\n\t s += '\\n' + 'maxSupportedCssHeight: ' + maxSupportedCssHeight;\n\t s += '\\n' + 'n(umber of pages): ' + n;\n\t s += '\\n' + '(current) page: ' + page;\n\t s += '\\n' + 'page height (ph): ' + ph;\n\t s += '\\n' + 'vScrollDir: ' + vScrollDir;\n\t\n\t alert(s);\n\t };\n\t\n\t // a debug helper to be able to access private members\n\t this.eval = function (expr) {\n\t return eval(expr);\n\t };\n\t\n\t // ////////////////////////////////////////////////////////////////////////////////////////////\n\t // Public API\n\t\n\t _jquery2.default.extend(this, {\n\t 'slickGridVersion': '2.2.4',\n\t\n\t // Events\n\t 'onScroll': new _slick2.default.Event(),\n\t 'onSort': new _slick2.default.Event(),\n\t 'onHeaderMouseEnter': new _slick2.default.Event(),\n\t 'onHeaderMouseLeave': new _slick2.default.Event(),\n\t 'onHeaderContextMenu': new _slick2.default.Event(),\n\t 'onHeaderClick': new _slick2.default.Event(),\n\t 'onHeaderCellRendered': new _slick2.default.Event(),\n\t 'onBeforeHeaderCellDestroy': new _slick2.default.Event(),\n\t 'onHeaderRowCellRendered': new _slick2.default.Event(),\n\t 'onFooterRowCellRendered': new _slick2.default.Event(),\n\t 'onBeforeHeaderRowCellDestroy': new _slick2.default.Event(),\n\t 'onBeforeFooterRowCellDestroy': new _slick2.default.Event(),\n\t 'onMouseEnter': new _slick2.default.Event(),\n\t 'onMouseLeave': new _slick2.default.Event(),\n\t 'onClick': new _slick2.default.Event(),\n\t 'onDblClick': new _slick2.default.Event(),\n\t 'onContextMenu': new _slick2.default.Event(),\n\t 'onKeyDown': new _slick2.default.Event(),\n\t 'onAddNewRow': new _slick2.default.Event(),\n\t 'onValidationError': new _slick2.default.Event(),\n\t 'onViewportChanged': new _slick2.default.Event(),\n\t 'onColumnsReordered': new _slick2.default.Event(),\n\t 'onColumnsResized': new _slick2.default.Event(),\n\t 'onCellChange': new _slick2.default.Event(),\n\t 'onBeforeEditCell': new _slick2.default.Event(),\n\t 'onBeforeCellEditorDestroy': new _slick2.default.Event(),\n\t 'onBeforeDestroy': new _slick2.default.Event(),\n\t 'onActiveCellChanged': new _slick2.default.Event(),\n\t 'onActiveCellPositionChanged': new _slick2.default.Event(),\n\t 'onDragInit': new _slick2.default.Event(),\n\t 'onDragStart': new _slick2.default.Event(),\n\t 'onDrag': new _slick2.default.Event(),\n\t 'onDragEnd': new _slick2.default.Event(),\n\t 'onSelectedRowsChanged': new _slick2.default.Event(),\n\t 'onCellCssStylesChanged': new _slick2.default.Event(),\n\t\n\t // Methods\n\t 'registerPlugin': registerPlugin,\n\t 'unregisterPlugin': unregisterPlugin,\n\t 'getColumns': getColumns,\n\t 'setColumns': setColumns,\n\t 'getColumnIndex': getColumnIndex,\n\t 'updateColumnHeader': updateColumnHeader,\n\t 'setSortColumn': setSortColumn,\n\t 'setSortColumns': setSortColumns,\n\t 'getSortColumns': getSortColumns,\n\t 'autosizeColumns': autosizeColumns,\n\t 'getOptions': getOptions,\n\t 'setOptions': setOptions,\n\t 'getData': getData,\n\t 'getDataLength': getDataLength,\n\t 'getDataItem': getDataItem,\n\t 'setData': setData,\n\t 'getSelectionModel': getSelectionModel,\n\t 'setSelectionModel': setSelectionModel,\n\t 'getSelectedRows': getSelectedRows,\n\t 'setSelectedRows': setSelectedRows,\n\t 'getContainerNode': getContainerNode,\n\t\n\t 'render': render,\n\t 'invalidate': invalidate,\n\t 'invalidateRow': invalidateRow,\n\t 'invalidateRows': invalidateRows,\n\t 'invalidateAllRows': invalidateAllRows,\n\t 'updateCell': updateCell,\n\t 'updateRow': updateRow,\n\t 'getViewport': getVisibleRange,\n\t 'getRenderedRange': getRenderedRange,\n\t 'resizeCanvas': resizeCanvas,\n\t 'updateRowCount': updateRowCount,\n\t 'scrollRowIntoView': scrollRowIntoView,\n\t 'scrollRowToTop': scrollRowToTop,\n\t 'scrollCellIntoView': scrollCellIntoView,\n\t 'getCanvasNode': getCanvasNode,\n\t 'focus': setFocus,\n\t\n\t 'getCellFromPoint': getCellFromPoint,\n\t 'getCellFromEvent': getCellFromEvent,\n\t 'getActiveCell': getActiveCell,\n\t 'setActiveCell': setActiveCell,\n\t 'getActiveCellNode': getActiveCellNode,\n\t 'getActiveCellPosition': getActiveCellPosition,\n\t 'resetActiveCell': resetActiveCell,\n\t 'editActiveCell': makeActiveCellEditable,\n\t 'getCellEditor': getCellEditor,\n\t 'getCellNode': getCellNode,\n\t 'getCellNodeBox': getCellNodeBox,\n\t 'canCellBeSelected': canCellBeSelected,\n\t 'canCellBeActive': canCellBeActive,\n\t 'navigatePrev': navigatePrev,\n\t 'navigateNext': navigateNext,\n\t 'navigateUp': navigateUp,\n\t 'navigateDown': navigateDown,\n\t 'navigateLeft': navigateLeft,\n\t 'navigateRight': navigateRight,\n\t 'navigatePageUp': navigatePageUp,\n\t 'navigatePageDown': navigatePageDown,\n\t 'gotoCell': gotoCell,\n\t 'getTopPanel': getTopPanel,\n\t 'setTopPanelVisibility': setTopPanelVisibility,\n\t 'setHeaderRowVisibility': setHeaderRowVisibility,\n\t 'getHeaderRow': getHeaderRow,\n\t 'getHeaderRowColumn': getHeaderRowColumn,\n\t 'setFooterRowVisibility': setFooterRowVisibility,\n\t 'getFooterRow': getFooterRow,\n\t 'getFooterRowColumn': getFooterRowColumn,\n\t 'getGridPosition': getGridPosition,\n\t 'flashCell': flashCell,\n\t 'addCellCssStyles': addCellCssStyles,\n\t 'setCellCssStyles': setCellCssStyles,\n\t 'removeCellCssStyles': removeCellCssStyles,\n\t 'getCellCssStyles': getCellCssStyles,\n\t\n\t 'init': finishInitialization,\n\t 'destroy': destroy,\n\t\n\t // IEditor implementation\n\t 'getEditorLock': getEditorLock,\n\t 'getEditController': getEditController\n\t });\n\t\n\t init();\n\t}\n\n/***/ }),\n/* 31 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _jquery = __webpack_require__(2);\n\t\n\tvar _jquery2 = _interopRequireDefault(_jquery);\n\t\n\tvar _slick = __webpack_require__(1);\n\t\n\tvar _slick2 = _interopRequireDefault(_slick);\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\t\n\texports.default = GroupItemMetadataProvider;\n\t\n\t/***\n\t * Provides item metadata for group (Slick.Group) and totals (Slick.Totals) rows produced by the DataView.\n\t * This metadata overrides the default behavior and formatting of those rows so that they appear and function\n\t * correctly when processed by the grid.\n\t *\n\t * This class also acts as a grid plugin providing event handlers to expand & collapse groups.\n\t * If \"grid.registerPlugin(...)\" is not called, expand & collapse will not work.\n\t *\n\t * @class GroupItemMetadataProvider\n\t * @module Data\n\t * @namespace Slick.Data\n\t * @constructor\n\t * @param options\n\t */\n\t\n\tfunction GroupItemMetadataProvider(options) {\n\t var _grid = void 0;\n\t var _defaults = {\n\t groupCssClass: \"slick-group\",\n\t groupTitleCssClass: \"slick-group-title\",\n\t totalsCssClass: \"slick-group-totals\",\n\t groupFocusable: true,\n\t totalsFocusable: false,\n\t toggleCssClass: \"slick-group-toggle\",\n\t toggleExpandedCssClass: \"expanded\",\n\t toggleCollapsedCssClass: \"collapsed\",\n\t enableExpandCollapse: true,\n\t groupFormatter: defaultGroupCellFormatter,\n\t totalsFormatter: defaultTotalsCellFormatter\n\t };\n\t\n\t options = _jquery2.default.extend(true, {}, _defaults, options);\n\t\n\t function defaultGroupCellFormatter(row, cell, value, columnDef, item) {\n\t if (!options.enableExpandCollapse) {\n\t return item.title;\n\t }\n\t\n\t var indentation = item.level * 15 + \"px\";\n\t\n\t return \"\" + \"\" + \"\" + item.title + \"\";\n\t }\n\t\n\t function defaultTotalsCellFormatter(row, cell, value, columnDef, item) {\n\t return columnDef.groupTotalsFormatter && columnDef.groupTotalsFormatter(item, columnDef) || \"\";\n\t }\n\t\n\t function init(grid) {\n\t _grid = grid;\n\t _grid.onClick.subscribe(handleGridClick);\n\t _grid.onKeyDown.subscribe(handleGridKeyDown);\n\t }\n\t\n\t function destroy() {\n\t if (_grid) {\n\t _grid.onClick.unsubscribe(handleGridClick);\n\t _grid.onKeyDown.unsubscribe(handleGridKeyDown);\n\t }\n\t }\n\t\n\t function handleGridClick(e, args) {\n\t var item = this.getDataItem(args.row);\n\t if (item && item instanceof _slick2.default.Group && (0, _jquery2.default)(e.target).hasClass(options.toggleCssClass)) {\n\t var range = _grid.getRenderedRange();\n\t this.getData().setRefreshHints({\n\t ignoreDiffsBefore: range.top,\n\t ignoreDiffsAfter: range.bottom + 1\n\t });\n\t\n\t if (item.collapsed) {\n\t this.getData().expandGroup(item.groupingKey);\n\t } else {\n\t this.getData().collapseGroup(item.groupingKey);\n\t }\n\t\n\t e.stopImmediatePropagation();\n\t e.preventDefault();\n\t }\n\t }\n\t\n\t // TODO: add -/+ handling\n\t function handleGridKeyDown(e) {\n\t if (options.enableExpandCollapse && e.which == _slick2.default.keyCode.SPACE) {\n\t var activeCell = this.getActiveCell();\n\t if (activeCell) {\n\t var item = this.getDataItem(activeCell.row);\n\t if (item && item instanceof _slick2.default.Group) {\n\t var range = _grid.getRenderedRange();\n\t this.getData().setRefreshHints({\n\t ignoreDiffsBefore: range.top,\n\t ignoreDiffsAfter: range.bottom + 1\n\t });\n\t\n\t if (item.collapsed) {\n\t this.getData().expandGroup(item.groupingKey);\n\t } else {\n\t this.getData().collapseGroup(item.groupingKey);\n\t }\n\t\n\t e.stopImmediatePropagation();\n\t e.preventDefault();\n\t }\n\t }\n\t }\n\t }\n\t\n\t function getGroupRowMetadata(item) {\n\t return {\n\t selectable: false,\n\t focusable: options.groupFocusable,\n\t cssClasses: options.groupCssClass,\n\t columns: {\n\t 0: {\n\t colspan: \"*\",\n\t formatter: options.groupFormatter,\n\t editor: null\n\t }\n\t }\n\t };\n\t }\n\t\n\t function getTotalsRowMetadata(item) {\n\t return {\n\t selectable: false,\n\t focusable: options.totalsFocusable,\n\t cssClasses: options.totalsCssClass,\n\t formatter: options.totalsFormatter,\n\t editor: null\n\t };\n\t }\n\t\n\t return {\n\t init: init,\n\t destroy: destroy,\n\t getGroupRowMetadata: getGroupRowMetadata,\n\t getTotalsRowMetadata: getTotalsRowMetadata\n\t };\n\t}\n\n/***/ }),\n/* 32 */\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"flatpickr\");\n\n/***/ })\n/******/ ])));\n\n\n// WEBPACK FOOTER //\n// slick.es6.min.js"," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\texports: {},\n \t\t\tid: moduleId,\n \t\t\tloaded: false\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.loaded = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"/\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(0);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap 954b9e24953f6fac1bb7","/** *\n * Contains core SlickGrid classes.\n * @module Core\n * @namespace Slick\n */\nconst Slick = {\n Event: Event,\n EventData: EventData,\n EventHandler: EventHandler,\n Range: Range,\n NonDataRow: NonDataItem,\n Group: Group,\n GroupTotals: GroupTotals,\n EditorLock: EditorLock,\n /** *\n * A global singleton editor lock.\n * @class GlobalEditorLock\n * @static\n * @constructor\n */\n GlobalEditorLock: new EditorLock(),\n TreeColumns: TreeColumns,\n\n keyCode: {\n BACKSPACE: 8,\n DELETE: 46,\n DOWN: 40,\n END: 35,\n ENTER: 13,\n ESCAPE: 27,\n HOME: 36,\n INSERT: 45,\n LEFT: 37,\n PAGE_DOWN: 34,\n PAGE_UP: 33,\n RIGHT: 39,\n TAB: 9,\n UP: 38,\n SPACE: 32\n }\n};\n\nexport default Slick;\n\n/***\n * An event object for passing data to event handlers and letting them control propagation.\n *
This is pretty much identical to how W3C and jQuery implement events.
\n * @class EventData\n * @constructor\n */\nfunction EventData() {\n var isPropagationStopped = false;\n var isImmediatePropagationStopped = false;\n\n /***\n * Stops event from propagating up the DOM tree.\n * @method stopPropagation\n */\n this.stopPropagation = function() {\n isPropagationStopped = true;\n };\n\n /***\n * Returns whether stopPropagation was called on this event object.\n * @method isPropagationStopped\n * @return {Boolean}\n */\n this.isPropagationStopped = function() {\n return isPropagationStopped;\n };\n\n /***\n * Prevents the rest of the handlers from being executed.\n * @method stopImmediatePropagation\n */\n this.stopImmediatePropagation = function() {\n isImmediatePropagationStopped = true;\n };\n\n /***\n * Returns whether stopImmediatePropagation was called on this event object.\\\n * @method isImmediatePropagationStopped\n * @return {Boolean}\n */\n this.isImmediatePropagationStopped = function() {\n return isImmediatePropagationStopped;\n }\n}\n\n/***\n * A simple publisher-subscriber implementation.\n * @class Event\n * @constructor\n */\nfunction Event() {\n var handlers = [];\n\n /***\n * Adds an event handler to be called when the event is fired.\n *
Event handler will receive two arguments - an EventData and the data\n * object the event was fired with.
\n * @method subscribe\n * @param fn {Function} Event handler.\n */\n this.subscribe = function(fn) {\n handlers.push(fn);\n };\n\n /***\n * Removes an event handler added with subscribe(fn).\n * @method unsubscribe\n * @param fn {Function} Event handler to be removed.\n */\n this.unsubscribe = function(fn) {\n for (var i = handlers.length - 1; i >= 0; i--) {\n if (handlers[i] === fn) {\n handlers.splice(i, 1);\n }\n }\n };\n\n /***\n * Fires an event notifying all subscribers.\n * @method notify\n * @param args {Object} Additional data object to be passed to all handlers.\n * @param e {EventData}\n * Optional.\n * An EventData object to be passed to all handlers.\n * For DOM events, an existing W3C/jQuery event object can be passed in.\n * @param scope {Object}\n * Optional.\n * The scope (\"this\") within which the handler will be executed.\n * If not specified, the scope will be set to the Event instance.\n */\n this.notify = function(args, e, scope) {\n e = e || new EventData();\n scope = scope || this;\n\n var returnValue;\n for (var i = 0; i < handlers.length && !(e.isPropagationStopped() || e.isImmediatePropagationStopped()); i++) {\n returnValue = handlers[i].call(scope, e, args);\n }\n\n return returnValue;\n };\n}\n\nfunction EventHandler() {\n var handlers = [];\n\n this.subscribe = function(event, handler) {\n handlers.push({\n event: event,\n handler: handler\n });\n event.subscribe(handler);\n\n return this; // allow chaining\n };\n\n this.unsubscribe = function(event, handler) {\n var i = handlers.length;\n while (i--) {\n if (handlers[i].event === event && handlers[i].handler === handler) {\n handlers.splice(i, 1);\n event.unsubscribe(handler);\n return;\n }\n }\n\n return this; // allow chaining\n };\n\n this.unsubscribeAll = function() {\n var i = handlers.length;\n while (i--) {\n handlers[i].event.unsubscribe(handlers[i].handler);\n }\n handlers = [];\n\n return this; // allow chaining\n }\n}\n\n/***\n * A structure containing a range of cells.\n * @class Range\n * @constructor\n * @param fromRow {Integer} Starting row.\n * @param fromCell {Integer} Starting cell.\n * @param toRow {Integer} Optional. Ending row. Defaults to fromRow.\n * @param toCell {Integer} Optional. Ending cell. Defaults to fromCell.\n */\nfunction Range(fromRow, fromCell, toRow, toCell) {\n if (toRow === undefined && toCell === undefined) {\n toRow = fromRow;\n toCell = fromCell;\n }\n\n /***\n * @property fromRow\n * @type {Integer}\n */\n this.fromRow = Math.min(fromRow, toRow);\n\n /***\n * @property fromCell\n * @type {Integer}\n */\n this.fromCell = Math.min(fromCell, toCell);\n\n /***\n * @property toRow\n * @type {Integer}\n */\n this.toRow = Math.max(fromRow, toRow);\n\n /***\n * @property toCell\n * @type {Integer}\n */\n this.toCell = Math.max(fromCell, toCell);\n\n /***\n * Returns whether a range represents a single row.\n * @method isSingleRow\n * @return {Boolean}\n */\n this.isSingleRow = function() {\n return this.fromRow == this.toRow;\n };\n\n /***\n * Returns whether a range represents a single cell.\n * @method isSingleCell\n * @return {Boolean}\n */\n this.isSingleCell = function() {\n return this.fromRow == this.toRow && this.fromCell == this.toCell;\n };\n\n /***\n * Returns whether a range contains a given cell.\n * @method contains\n * @param row {Integer}\n * @param cell {Integer}\n * @return {Boolean}\n */\n this.contains = function(row, cell) {\n return row >= this.fromRow && row <= this.toRow && cell >= this.fromCell && cell <= this.toCell;\n };\n\n /***\n * Returns a readable representation of a range.\n * @method toString\n * @return {String}\n */\n this.toString = function() {\n if (this.isSingleCell()) {\n return \"(\" + this.fromRow + \":\" + this.fromCell + \")\";\n } else {\n return \"(\" + this.fromRow + \":\" + this.fromCell + \" - \" + this.toRow + \":\" + this.toCell + \")\";\n }\n }\n}\n\n\n/***\n * A base class that all special / non-data rows (like Group and GroupTotals) derive from.\n * @class NonDataItem\n * @constructor\n */\nfunction NonDataItem() {\n this.__nonDataRow = true;\n}\n\n\n/***\n * Information about a group of rows.\n * @class Group\n * @extends Slick.NonDataItem\n * @constructor\n */\nfunction Group() {\n this.__group = true;\n\n /**\n * Grouping level, starting with 0.\n * @property level\n * @type {Number}\n */\n this.level = 0;\n\n /***\n * Number of rows in the group.\n * @property count\n * @type {Integer}\n */\n this.count = 0;\n\n /***\n * Grouping value.\n * @property value\n * @type {Object}\n */\n this.value = null;\n\n /***\n * Formatted display value of the group.\n * @property title\n * @type {String}\n */\n this.title = null;\n\n /***\n * Whether a group is collapsed.\n * @property collapsed\n * @type {Boolean}\n */\n this.collapsed = false;\n\n /***\n * GroupTotals, if any.\n * @property totals\n * @type {GroupTotals}\n */\n this.totals = null;\n\n /**\n * Rows that are part of the group.\n * @property rows\n * @type {Array}\n */\n this.rows = [];\n\n /**\n * Sub-groups that are part of the group.\n * @property groups\n * @type {Array}\n */\n this.groups = null;\n\n /**\n * A unique key used to identify the group. This key can be used in calls to DataView\n * collapseGroup() or expandGroup().\n * @property groupingKey\n * @type {Object}\n */\n this.groupingKey = null;\n}\n\nGroup.prototype = new NonDataItem();\n\n/***\n * Compares two Group instances.\n * @method equals\n * @return {Boolean}\n * @param group {Group} Group instance to compare to.\n */\nGroup.prototype.equals = function(group) {\n return this.value === group.value && this.count === group.count && this.collapsed === group.collapsed && this.title === group.title;\n};\n\n/***\n * Information about group totals.\n * An instance of GroupTotals will be created for each totals row and passed to the aggregators\n * so that they can store arbitrary data in it. That data can later be accessed by group totals\n * formatters during the display.\n * @class GroupTotals\n * @extends Slick.NonDataItem\n * @constructor\n */\nfunction GroupTotals() {\n this.__groupTotals = true;\n\n /***\n * Parent Group.\n * @param group\n * @type {Group}\n */\n this.group = null;\n\n /***\n * Whether the totals have been fully initialized / calculated.\n * Will be set to false for lazy-calculated group totals.\n * @param initialized\n * @type {Boolean}\n */\n this.initialized = false;\n}\n\nGroupTotals.prototype = new NonDataItem();\n\n/***\n * A locking helper to track the active edit controller and ensure that only a single controller\n * can be active at a time. This prevents a whole class of state and validation synchronization\n * issues. An edit controller (such as SlickGrid) can query if an active edit is in progress\n * and attempt a commit or cancel before proceeding.\n * @class EditorLock\n * @constructor\n */\nfunction EditorLock() {\n var activeEditController = null;\n\n /***\n * Returns true if a specified edit controller is active (has the edit lock).\n * If the parameter is not specified, returns true if any edit controller is active.\n * @method isActive\n * @param editController {EditController}\n * @return {Boolean}\n */\n this.isActive = function(editController) {\n return (editController ? activeEditController === editController : activeEditController !== null);\n };\n\n /***\n * Sets the specified edit controller as the active edit controller (acquire edit lock).\n * If another edit controller is already active, and exception will be thrown.\n * @method activate\n * @param editController {EditController} edit controller acquiring the lock\n */\n this.activate = function(editController) {\n if (editController === activeEditController) { // already activated?\n return;\n }\n if (activeEditController !== null) {\n throw \"SlickGrid.EditorLock.activate: an editController is still active, can't activate another editController\";\n }\n if (!editController.commitCurrentEdit) {\n throw \"SlickGrid.EditorLock.activate: editController must implement .commitCurrentEdit()\";\n }\n if (!editController.cancelCurrentEdit) {\n throw \"SlickGrid.EditorLock.activate: editController must implement .cancelCurrentEdit()\";\n }\n activeEditController = editController;\n };\n\n /***\n * Unsets the specified edit controller as the active edit controller (release edit lock).\n * If the specified edit controller is not the active one, an exception will be thrown.\n * @method deactivate\n * @param editController {EditController} edit controller releasing the lock\n */\n this.deactivate = function(editController) {\n if (activeEditController !== editController) {\n throw \"SlickGrid.EditorLock.deactivate: specified editController is not the currently active one\";\n }\n activeEditController = null;\n };\n\n /***\n * Attempts to commit the current edit by calling \"commitCurrentEdit\" method on the active edit\n * controller and returns whether the commit attempt was successful (commit may fail due to validation\n * errors, etc.). Edit controller's \"commitCurrentEdit\" must return true if the commit has succeeded\n * and false otherwise. If no edit controller is active, returns true.\n * @method commitCurrentEdit\n * @return {Boolean}\n */\n this.commitCurrentEdit = function() {\n return (activeEditController ? activeEditController.commitCurrentEdit() : true);\n };\n\n /***\n * Attempts to cancel the current edit by calling \"cancelCurrentEdit\" method on the active edit\n * controller and returns whether the edit was successfully cancelled. If no edit controller is\n * active, returns true.\n * @method cancelCurrentEdit\n * @return {Boolean}\n */\n this.cancelCurrentEdit = function cancelCurrentEdit() {\n return (activeEditController ? activeEditController.cancelCurrentEdit() : true);\n };\n}\n\n/**\n *\n * @param {Array} treeColumns Array com levels of columns\n * @returns {{hasDepth: 'hasDepth', getTreeColumns: 'getTreeColumns', extractColumns: 'extractColumns', getDepth: 'getDepth', getColumnsInDepth: 'getColumnsInDepth', getColumnsInGroup: 'getColumnsInGroup', visibleColumns: 'visibleColumns', filter: 'filter', reOrder: reOrder}}\n * @constructor\n */\nfunction TreeColumns(treeColumns) {\n\n var columnsById = {};\n\n function init() {\n mapToId(treeColumns);\n }\n\n function mapToId(columns) {\n columns.forEach(function(column) {\n columnsById[column.id] = column;\n\n if (column.columns) mapToId(column.columns);\n });\n }\n\n function filter(node, condition) {\n\n return node.filter(function(column) {\n\n var valid = condition.call(column);\n\n if (valid && column.columns) column.columns = filter(column.columns, condition);\n\n return valid && (!column.columns || column.columns.length);\n });\n\n }\n\n function sort(columns, grid) {\n columns.sort(function(a, b) {\n var indexA = getOrDefault(grid.getColumnIndex(a.id)),\n indexB = getOrDefault(grid.getColumnIndex(b.id));\n\n return indexA - indexB;\n })\n .forEach(function(column) {\n if (column.columns) sort(column.columns, grid);\n });\n }\n\n function getOrDefault(value) {\n return typeof value === 'undefined' ? -1 : value;\n }\n\n function getDepth(node) {\n if (node.length) for (var i in node)\n return getDepth(node[i]);\n else if (node.columns) return 1 + getDepth(node.columns);\n else return 1;\n }\n\n function getColumnsInDepth(node, depth, current) {\n var columns = [];\n current = current || 0;\n\n if (depth == current) {\n\n if (node.length) node.forEach(function(n) {\n if (n.columns) n.extractColumns = function() {\n return extractColumns(n);\n };\n });\n\n return node;\n } else for (var i in node)\n if (node[i].columns) {\n columns = columns.concat(getColumnsInDepth(node[i].columns, depth, current + 1));\n }\n\n return columns;\n }\n\n function extractColumns(node) {\n var result = [];\n\n if (node.hasOwnProperty('length')) {\n\n for (var i = 0; i < node.length; i++)\n result = result.concat(extractColumns(node[i]));\n\n } else {\n\n if (node.hasOwnProperty('columns'))\n\n result = result.concat(extractColumns(node.columns));\n\n else return node;\n\n }\n\n return result;\n }\n\n function cloneTreeColumns() {\n return $.extend(true, [], treeColumns);\n }\n\n init();\n\n this.hasDepth = function() {\n\n for (var i in treeColumns)\n if (treeColumns[i].hasOwnProperty('columns')) return true;\n\n return false;\n };\n\n this.getTreeColumns = function() {\n return treeColumns;\n };\n\n this.extractColumns = function() {\n return this.hasDepth() ? extractColumns(treeColumns) : treeColumns;\n };\n\n this.getDepth = function() {\n return getDepth(treeColumns);\n };\n\n this.getColumnsInDepth = function(depth) {\n return getColumnsInDepth(treeColumns, depth);\n };\n\n this.getColumnsInGroup = function(groups) {\n return extractColumns(groups);\n };\n\n this.visibleColumns = function() {\n return filter(cloneTreeColumns(), function() {\n return this.visible;\n });\n };\n\n this.filter = function(condition) {\n return filter(cloneTreeColumns(), condition);\n };\n\n this.reOrder = function(grid) {\n return sort(treeColumns, grid);\n };\n\n this.getById = function(id) {\n return columnsById[id];\n };\n\n this.getInIds = function(ids) {\n return ids.map(function(id) {\n return columnsById[id];\n });\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ../src/slick.core.js","module.exports = require(\"jquery\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"jquery\"\n// module id = 2\n// module chunks = 0","import $ from 'jquery';\nimport Slick from '../../src/slick.core';\n\nexport default CellRangeDecorator;\n\n/** *\n * Displays an overlay on top of a given cell range.\n *\n * TODO:\n * Currently, it blocks mouse events to DOM nodes behind it.\n * Use FF and WebKit-specific 'pointer-events' CSS style, or some kind of event forwarding.\n * Could also construct the borders separately using 4 individual DIVs.\n *\n * @param {Grid} grid\n * @param {Object} options\n */\nfunction CellRangeDecorator(grid, options){\n let _elem;\n const _defaults = {\n selectionCssClass: 'slick-range-decorator',\n selectionCss: {\n zIndex: '9999',\n border: '2px dashed red'\n }\n };\n\n options = Object.assign({}, _defaults, options);\n\n function show(range){\n if (!_elem){\n _elem = $('
', {css: options.selectionCss})\n .addClass(options.selectionCssClass)\n .css('position', 'absolute')\n .appendTo(grid.getCanvasNode());\n }\n\n const from = grid.getCellNodeBox(range.fromRow, range.fromCell);\n const to = grid.getCellNodeBox(range.toRow, range.toCell);\n\n _elem.css({\n top: from.top - 1,\n left: from.left - 1,\n height: to.bottom - from.top - 2,\n width: to.right - from.left - 2\n });\n\n return _elem;\n }\n\n function hide(){\n if (_elem){\n _elem.remove();\n _elem = null;\n }\n }\n\n Object.assign(this, {\n show,\n hide\n });\n}\n\n\n\n// WEBPACK FOOTER //\n// ../plugins/slick.cellrangedecorator/slick.cellrangedecorator.js","import $ from 'jquery';\nimport Slick from '../../src/slick.core';\nimport CellRangeDecorator from '../slick.cellrangedecorator/slick.cellrangedecorator';\n\nexport default CellRangeSelector;\n\nfunction CellRangeSelector(options){\n let _grid;\n let _canvas;\n let _dragging;\n let _decorator;\n let _range = {};\n\n const _self = this;\n const _handler = new Slick.EventHandler();\n const _defaults = {\n selectionCss: {\n // 'border': '2px dashed blue'\n }\n };\n\n function init(grid){\n options = Object.assign({}, _defaults, options);\n _decorator = new CellRangeDecorator(grid, options);\n _grid = grid;\n _canvas = _grid.getCanvasNode();\n _handler\n .subscribe(_grid.onDragInit, handleDragInit)\n .subscribe(_grid.onDragStart, handleDragStart)\n .subscribe(_grid.onDrag, handleDrag)\n .subscribe(_grid.onDragEnd, handleDragEnd);\n }\n\n function destroy(){\n _handler.unsubscribeAll();\n }\n\n function handleDragInit(e, dd){\n // prevent the grid from cancelling drag'n'drop by default\n e.stopImmediatePropagation();\n }\n\n function handleDragStart(jqueryEvent, interactEvent){\n const cell = _grid.getCellFromEvent(interactEvent.originalEvent);\n if (_self.onBeforeCellRangeSelected.notify(cell) !== false){\n if (_grid.canCellBeSelected(cell.row, cell.cell)){\n _dragging = true;\n // jqueryEvent.stopImmediatePropagation();\n }\n }\n if (!_dragging){\n return;\n }\n\n _grid.focus();\n\n const start = _grid.getCellFromPoint(\n interactEvent.x0 - $(_canvas).offset().left,\n interactEvent.y0 - $(_canvas).offset().top\n );\n\n _range = {\n start,\n end: {}\n };\n\n return _decorator.show(new Slick.Range(start.row, start.cell));\n }\n\n function handleDrag(e, interactEvent){\n if (!_dragging){\n return;\n }\n // e.stopImmediatePropagation();\n\n const end = _grid.getCellFromPoint(\n interactEvent.pageX - $(_canvas).offset().left,\n interactEvent.pageY - $(_canvas).offset().top);\n\n if (!_grid.canCellBeSelected(end.row, end.cell)){\n return;\n }\n\n _range.end = end;\n _decorator.show(new Slick.Range(_range.start.row, _range.start.cell, end.row, end.cell));\n }\n\n function handleDragEnd(e){\n if (!_dragging){\n return;\n }\n\n _dragging = false;\n // e.stopImmediatePropagation();\n\n _decorator.hide();\n _self.onCellRangeSelected.notify({\n range: new Slick.Range(\n _range.start.row,\n _range.start.cell,\n _range.end.row,\n _range.end.cell\n )\n });\n _range = {};\n }\n\n Object.assign(this, {\n init,\n destroy,\n\n onBeforeCellRangeSelected: new Slick.Event(),\n onCellRangeSelected: new Slick.Event()\n });\n}\n\n\n\n// WEBPACK FOOTER //\n// ../plugins/slick.cellrangeselector/slick.cellrangeselector.js","/**\n * interact.js v1.2.6\n *\n * Copyright (c) 2012-2015 Taye Adeyemi \n * Open source under the MIT License.\n * https://raw.github.com/taye/interact.js/master/LICENSE\n *\n * This file has been monkey patched to pass the originalEvent on to drag events\n */\n(function(realWindow){\n 'use strict';\n\n // return early if there's no window to work with (eg. Node.js)\n if (!realWindow){ return; }\n\n var // get wrapped window if using Shadow DOM polyfill\n window = (function(){\n // create a TextNode\n var el = realWindow.document.createTextNode('');\n\n // check if it's wrapped by a polyfill\n if (el.ownerDocument !== realWindow.document\n && typeof realWindow.wrap === 'function'\n && realWindow.wrap(el) === el){\n // return wrapped window\n return realWindow.wrap(realWindow);\n }\n\n // no Shadow DOM polyfil or native implementation\n return realWindow;\n }()),\n\n document = window.document,\n DocumentFragment = window.DocumentFragment || blank,\n SVGElement = window.SVGElement || blank,\n SVGSVGElement = window.SVGSVGElement || blank,\n SVGElementInstance = window.SVGElementInstance || blank,\n HTMLElement = window.HTMLElement || window.Element,\n\n PointerEvent = (window.PointerEvent || window.MSPointerEvent),\n pEventTypes,\n\n hypot = Math.hypot || function(x, y){ return Math.sqrt(x * x + y * y); },\n\n tmpXY = {}, // reduce object creation in getXY()\n\n documents = [], // all documents being listened to\n\n interactables = [], // all set interactables\n interactions = [], // all interactions\n\n dynamicDrop = false,\n\n // {\n // type: {\n // selectors: ['selector', ...],\n // contexts : [document, ...],\n // listeners: [[listener, useCapture], ...]\n // }\n // }\n delegatedEvents = {},\n\n defaultOptions = {\n base: {\n accept: null,\n actionChecker: null,\n styleCursor: true,\n preventDefault: 'auto',\n origin: { x: 0, y: 0 },\n deltaSource: 'page',\n allowFrom: null,\n ignoreFrom: null,\n _context: document,\n dropChecker: null\n },\n\n drag: {\n enabled: false,\n manualStart: true,\n max: Infinity,\n maxPerElement: 1,\n\n snap: null,\n restrict: null,\n inertia: null,\n autoScroll: null,\n\n axis: 'xy'\n },\n\n drop: {\n enabled: false,\n accept: null,\n overlap: 'pointer'\n },\n\n resize: {\n enabled: false,\n manualStart: false,\n max: Infinity,\n maxPerElement: 1,\n\n snap: null,\n restrict: null,\n inertia: null,\n autoScroll: null,\n\n square: false,\n preserveAspectRatio: false,\n axis: 'xy',\n\n // use default margin\n margin: NaN,\n\n // object with props left, right, top, bottom which are\n // true/false values to resize when the pointer is over that edge,\n // CSS selectors to match the handles for each direction\n // or the Elements for each handle\n edges: null,\n\n // a value of 'none' will limit the resize rect to a minimum of 0x0\n // 'negate' will alow the rect to have negative width/height\n // 'reposition' will keep the width/height positive by swapping\n // the top and bottom edges and/or swapping the left and right edges\n invert: 'none'\n },\n\n gesture: {\n manualStart: false,\n enabled: false,\n max: Infinity,\n maxPerElement: 1,\n\n restrict: null\n },\n\n perAction: {\n manualStart: false,\n max: Infinity,\n maxPerElement: 1,\n\n snap: {\n enabled: false,\n endOnly: false,\n range: Infinity,\n targets: null,\n offsets: null,\n\n relativePoints: null\n },\n\n restrict: {\n enabled: false,\n endOnly: false\n },\n\n autoScroll: {\n enabled: false,\n container: null, // the item that is scrolled (Window or HTMLElement)\n margin: 60,\n speed: 300 // the scroll speed in pixels per second\n },\n\n inertia: {\n enabled: false,\n resistance: 10, // the lambda in exponential decay\n minSpeed: 100, // target speed must be above this for inertia to start\n endSpeed: 10, // the speed at which inertia is slow enough to stop\n allowResume: true, // allow resuming an action in inertia phase\n zeroResumeDelta: true, // if an action is resumed after launch, set dx/dy to 0\n smoothEndDuration: 300 // animate to snap/restrict endOnly if there's no inertia\n }\n },\n\n _holdDuration: 600\n },\n\n // Things related to autoScroll\n autoScroll = {\n interaction: null,\n i: null, // the handle returned by window.setInterval\n x: 0, y: 0, // Direction each pulse is to scroll in\n\n // scroll the window by the values in scroll.x/y\n scroll: function(){\n var options = autoScroll.interaction.target.options[autoScroll.interaction.prepared.name].autoScroll,\n container = options.container || getWindow(autoScroll.interaction.element),\n now = new Date().getTime(),\n // change in time in seconds\n dtx = (now - autoScroll.prevTimeX) / 1000,\n dty = (now - autoScroll.prevTimeY) / 1000,\n vx, vy, sx, sy;\n\n // displacement\n if (options.velocity){\n vx = options.velocity.x;\n vy = options.velocity.y;\n }\n else {\n vx = vy = options.speed;\n }\n\n sx = vx * dtx;\n sy = vy * dty;\n\n if (sx >= 1 || sy >= 1){\n if (isWindow(container)){\n container.scrollBy(autoScroll.x * sx, autoScroll.y * sy);\n }\n else if (container){\n container.scrollLeft += autoScroll.x * sx;\n container.scrollTop += autoScroll.y * sy;\n }\n\n if (sx >= 1) autoScroll.prevTimeX = now;\n if (sy >= 1) autoScroll.prevTimeY = now;\n }\n\n if (autoScroll.isScrolling){\n cancelFrame(autoScroll.i);\n autoScroll.i = reqFrame(autoScroll.scroll);\n }\n },\n\n isScrolling: false,\n prevTimeX: 0,\n prevTimeY: 0,\n\n start: function(interaction){\n autoScroll.isScrolling = true;\n cancelFrame(autoScroll.i);\n\n autoScroll.interaction = interaction;\n autoScroll.prevTimeX = new Date().getTime();\n autoScroll.prevTimeY = new Date().getTime();\n autoScroll.i = reqFrame(autoScroll.scroll);\n },\n\n stop: function(){\n autoScroll.isScrolling = false;\n cancelFrame(autoScroll.i);\n }\n },\n\n // Does the browser support touch input?\n supportsTouch = (('ontouchstart' in window) || window.DocumentTouch && document instanceof window.DocumentTouch),\n\n // Does the browser support PointerEvents\n supportsPointerEvent = PointerEvent && !/Chrome/.test(navigator.userAgent),\n\n // Less Precision with touch input\n margin = supportsTouch || supportsPointerEvent ? 20 : 10,\n\n pointerMoveTolerance = 1,\n\n // for ignoring browser's simulated mouse events\n prevTouchTime = 0,\n\n // Allow this many interactions to happen simultaneously\n maxInteractions = Infinity,\n\n // Check if is IE9 or older\n actionCursors = (document.all && !window.atob) ? {\n drag: 'move',\n resizex: 'e-resize',\n resizey: 's-resize',\n resizexy: 'se-resize',\n\n resizetop: 'n-resize',\n resizeleft: 'w-resize',\n resizebottom: 's-resize',\n resizeright: 'e-resize',\n resizetopleft: 'se-resize',\n resizebottomright: 'se-resize',\n resizetopright: 'ne-resize',\n resizebottomleft: 'ne-resize',\n\n gesture: ''\n } : {\n drag: 'move',\n resizex: 'ew-resize',\n resizey: 'ns-resize',\n resizexy: 'nwse-resize',\n\n resizetop: 'ns-resize',\n resizeleft: 'ew-resize',\n resizebottom: 'ns-resize',\n resizeright: 'ew-resize',\n resizetopleft: 'nwse-resize',\n resizebottomright: 'nwse-resize',\n resizetopright: 'nesw-resize',\n resizebottomleft: 'nesw-resize',\n\n gesture: ''\n },\n\n actionIsEnabled = {\n drag: true,\n resize: true,\n gesture: true\n },\n\n // because Webkit and Opera still use 'mousewheel' event type\n wheelEvent = 'onmousewheel' in document ? 'mousewheel' : 'wheel',\n\n eventTypes = [\n 'dragstart',\n 'dragmove',\n 'draginertiastart',\n 'dragend',\n 'dragenter',\n 'dragleave',\n 'dropactivate',\n 'dropdeactivate',\n 'dropmove',\n 'drop',\n 'resizestart',\n 'resizemove',\n 'resizeinertiastart',\n 'resizeend',\n 'gesturestart',\n 'gesturemove',\n 'gestureinertiastart',\n 'gestureend',\n\n 'down',\n 'move',\n 'up',\n 'cancel',\n 'tap',\n 'doubletap',\n 'hold'\n ],\n\n globalEvents = {},\n\n // Opera Mobile must be handled differently\n isOperaMobile = navigator.appName == 'Opera' &&\n supportsTouch &&\n navigator.userAgent.match('Presto'),\n\n // scrolling doesn't change the result of getClientRects on iOS 7\n isIOS7 = (/iP(hone|od|ad)/.test(navigator.platform)\n && /OS 7[^\\d]/.test(navigator.appVersion)),\n\n // prefix matchesSelector\n prefixedMatchesSelector = 'matches' in Element.prototype ?\n 'matches' : 'webkitMatchesSelector' in Element.prototype ?\n 'webkitMatchesSelector' : 'mozMatchesSelector' in Element.prototype ?\n 'mozMatchesSelector' : 'oMatchesSelector' in Element.prototype ?\n 'oMatchesSelector' : 'msMatchesSelector',\n\n // will be polyfill function if browser is IE8\n ie8MatchesSelector,\n\n // native requestAnimationFrame or polyfill\n reqFrame = realWindow.requestAnimationFrame,\n cancelFrame = realWindow.cancelAnimationFrame,\n\n // Events wrapper\n events = (function(){\n var useAttachEvent = ('attachEvent' in window) && !('addEventListener' in window),\n addEvent = useAttachEvent ? 'attachEvent' : 'addEventListener',\n removeEvent = useAttachEvent ? 'detachEvent' : 'removeEventListener',\n on = useAttachEvent ? 'on' : '',\n\n elements = [],\n targets = [],\n attachedListeners = [];\n\n function add(element, type, listener, useCapture){\n var elementIndex = indexOf(elements, element),\n target = targets[elementIndex];\n\n if (!target){\n target = {\n events: {},\n typeCount: 0\n };\n\n elementIndex = elements.push(element) - 1;\n targets.push(target);\n\n attachedListeners.push((useAttachEvent ? {\n supplied: [],\n wrapped: [],\n useCount: []\n } : null));\n }\n\n if (!target.events[type]){\n target.events[type] = [];\n target.typeCount++;\n }\n\n if (!contains(target.events[type], listener)){\n var ret;\n\n if (useAttachEvent){\n var listeners = attachedListeners[elementIndex],\n listenerIndex = indexOf(listeners.supplied, listener);\n\n var wrapped = listeners.wrapped[listenerIndex] || function(event){\n if (!event.immediatePropagationStopped){\n event.target = event.srcElement;\n event.currentTarget = element;\n\n event.preventDefault = event.preventDefault || preventDef;\n event.stopPropagation = event.stopPropagation || stopProp;\n event.stopImmediatePropagation = event.stopImmediatePropagation || stopImmProp;\n\n if (/mouse|click/.test(event.type)){\n event.pageX = event.clientX + getWindow(element).document.documentElement.scrollLeft;\n event.pageY = event.clientY + getWindow(element).document.documentElement.scrollTop;\n }\n\n listener(event);\n }\n };\n\n ret = element[addEvent](on + type, wrapped, Boolean(useCapture));\n\n if (listenerIndex === -1){\n listeners.supplied.push(listener);\n listeners.wrapped.push(wrapped);\n listeners.useCount.push(1);\n }\n else {\n listeners.useCount[listenerIndex]++;\n }\n }\n else {\n ret = element[addEvent](type, listener, useCapture || false);\n }\n target.events[type].push(listener);\n\n return ret;\n }\n }\n\n function remove(element, type, listener, useCapture){\n var i,\n elementIndex = indexOf(elements, element),\n target = targets[elementIndex],\n listeners,\n listenerIndex,\n wrapped = listener;\n\n if (!target || !target.events){\n return;\n }\n\n if (useAttachEvent){\n listeners = attachedListeners[elementIndex];\n listenerIndex = indexOf(listeners.supplied, listener);\n wrapped = listeners.wrapped[listenerIndex];\n }\n\n if (type === 'all'){\n for (type in target.events){\n if (target.events.hasOwnProperty(type)){\n remove(element, type, 'all');\n }\n }\n return;\n }\n\n if (target.events[type]){\n var len = target.events[type].length;\n\n if (listener === 'all'){\n for (i = 0; i < len; i++){\n remove(element, type, target.events[type][i], Boolean(useCapture));\n }\n return;\n } else {\n for (i = 0; i < len; i++){\n if (target.events[type][i] === listener){\n element[removeEvent](on + type, wrapped, useCapture || false);\n target.events[type].splice(i, 1);\n\n if (useAttachEvent && listeners){\n listeners.useCount[listenerIndex]--;\n if (listeners.useCount[listenerIndex] === 0){\n listeners.supplied.splice(listenerIndex, 1);\n listeners.wrapped.splice(listenerIndex, 1);\n listeners.useCount.splice(listenerIndex, 1);\n }\n }\n\n break;\n }\n }\n }\n\n if (target.events[type] && target.events[type].length === 0){\n target.events[type] = null;\n target.typeCount--;\n }\n }\n\n if (!target.typeCount){\n targets.splice(elementIndex, 1);\n elements.splice(elementIndex, 1);\n attachedListeners.splice(elementIndex, 1);\n }\n }\n\n function preventDef(){\n this.returnValue = false;\n }\n\n function stopProp(){\n this.cancelBubble = true;\n }\n\n function stopImmProp(){\n this.cancelBubble = true;\n this.immediatePropagationStopped = true;\n }\n\n return {\n add: add,\n remove: remove,\n useAttachEvent: useAttachEvent,\n\n _elements: elements,\n _targets: targets,\n _attachedListeners: attachedListeners\n };\n }());\n\n function blank(){}\n\n function isElement(o){\n if (!o || (typeof o !== 'object')){ return false; }\n\n var _window = getWindow(o) || window;\n\n return (/object|function/.test(typeof _window.Element)\n ? o instanceof _window.Element // DOM2\n : o.nodeType === 1 && typeof o.nodeName === 'string');\n }\n function isWindow(thing){ return thing === window || !!(thing && thing.Window) && (thing instanceof thing.Window); }\n function isDocFrag(thing){ return !!thing && thing instanceof DocumentFragment; }\n function isArray(thing){\n return isObject(thing)\n && (typeof thing.length !== undefined)\n && isFunction(thing.splice);\n }\n function isObject(thing){ return !!thing && (typeof thing === 'object'); }\n function isFunction(thing){ return typeof thing === 'function'; }\n function isNumber(thing){ return typeof thing === 'number'; }\n function isBool(thing){ return typeof thing === 'boolean'; }\n function isString(thing){ return typeof thing === 'string'; }\n\n function trySelector(value){\n if (!isString(value)){ return false; }\n\n // an exception will be raised if it is invalid\n document.querySelector(value);\n return true;\n }\n\n function extend(dest, source){\n for (var prop in source){\n dest[prop] = source[prop];\n }\n return dest;\n }\n\n var prefixedPropREs = {\n webkit: /(Movement[XY]|Radius[XY]|RotationAngle|Force)$/\n };\n\n function pointerExtend(dest, source){\n for (var prop in source){\n var deprecated = false;\n\n // skip deprecated prefixed properties\n for (var vendor in prefixedPropREs){\n if (prop.indexOf(vendor) === 0 && prefixedPropREs[vendor].test(prop)){\n deprecated = true;\n break;\n }\n }\n\n if (!deprecated){\n dest[prop] = source[prop];\n }\n }\n return dest;\n }\n\n function copyCoords(dest, src){\n dest.page = dest.page || {};\n dest.page.x = src.page.x;\n dest.page.y = src.page.y;\n\n dest.client = dest.client || {};\n dest.client.x = src.client.x;\n dest.client.y = src.client.y;\n\n dest.timeStamp = src.timeStamp;\n }\n\n function setEventXY(targetObj, pointers, interaction){\n var pointer = (pointers.length > 1\n ? pointerAverage(pointers)\n : pointers[0]);\n\n getPageXY(pointer, tmpXY, interaction);\n targetObj.page.x = tmpXY.x;\n targetObj.page.y = tmpXY.y;\n\n getClientXY(pointer, tmpXY, interaction);\n targetObj.client.x = tmpXY.x;\n targetObj.client.y = tmpXY.y;\n\n targetObj.timeStamp = new Date().getTime();\n }\n\n function setEventDeltas(targetObj, prev, cur){\n targetObj.page.x = cur.page.x - prev.page.x;\n targetObj.page.y = cur.page.y - prev.page.y;\n targetObj.client.x = cur.client.x - prev.client.x;\n targetObj.client.y = cur.client.y - prev.client.y;\n targetObj.timeStamp = new Date().getTime() - prev.timeStamp;\n\n // set pointer velocity\n var dt = Math.max(targetObj.timeStamp / 1000, 0.001);\n targetObj.page.speed = hypot(targetObj.page.x, targetObj.page.y) / dt;\n targetObj.page.vx = targetObj.page.x / dt;\n targetObj.page.vy = targetObj.page.y / dt;\n\n targetObj.client.speed = hypot(targetObj.client.x, targetObj.page.y) / dt;\n targetObj.client.vx = targetObj.client.x / dt;\n targetObj.client.vy = targetObj.client.y / dt;\n }\n\n function isNativePointer(pointer){\n return (pointer instanceof window.Event\n || (supportsTouch && window.Touch && pointer instanceof window.Touch));\n }\n\n // Get specified X/Y coords for mouse or event.touches[0]\n function getXY(type, pointer, xy){\n xy = xy || {};\n type = type || 'page';\n\n xy.x = pointer[type + 'X'];\n xy.y = pointer[type + 'Y'];\n\n return xy;\n }\n\n function getPageXY(pointer, page){\n page = page || {};\n\n // Opera Mobile handles the viewport and scrolling oddly\n if (isOperaMobile && isNativePointer(pointer)){\n getXY('screen', pointer, page);\n\n page.x += window.scrollX;\n page.y += window.scrollY;\n }\n else {\n getXY('page', pointer, page);\n }\n\n return page;\n }\n\n function getClientXY(pointer, client){\n client = client || {};\n\n if (isOperaMobile && isNativePointer(pointer)){\n // Opera Mobile handles the viewport and scrolling oddly\n getXY('screen', pointer, client);\n }\n else {\n getXY('client', pointer, client);\n }\n\n return client;\n }\n\n function getScrollXY(win){\n win = win || window;\n return {\n x: win.scrollX || win.document.documentElement.scrollLeft,\n y: win.scrollY || win.document.documentElement.scrollTop\n };\n }\n\n function getPointerId(pointer){\n return isNumber(pointer.pointerId) ? pointer.pointerId : pointer.identifier;\n }\n\n function getActualElement(element){\n return (element instanceof SVGElementInstance\n ? element.correspondingUseElement\n : element);\n }\n\n function getWindow(node){\n if (isWindow(node)){\n return node;\n }\n\n var rootNode = (node.ownerDocument || node);\n\n return rootNode.defaultView || rootNode.parentWindow || window;\n }\n\n function getElementClientRect(element){\n var clientRect = (element instanceof SVGElement\n ? element.getBoundingClientRect()\n : element.getClientRects()[0]);\n\n return clientRect && {\n left: clientRect.left,\n right: clientRect.right,\n top: clientRect.top,\n bottom: clientRect.bottom,\n width: clientRect.width || clientRect.right - clientRect.left,\n height: clientRect.height || clientRect.bottom - clientRect.top\n };\n }\n\n function getElementRect(element){\n var clientRect = getElementClientRect(element);\n\n if (!isIOS7 && clientRect){\n var scroll = getScrollXY(getWindow(element));\n\n clientRect.left += scroll.x;\n clientRect.right += scroll.x;\n clientRect.top += scroll.y;\n clientRect.bottom += scroll.y;\n }\n\n return clientRect;\n }\n\n function getTouchPair(event){\n var touches = [];\n\n // array of touches is supplied\n if (isArray(event)){\n touches[0] = event[0];\n touches[1] = event[1];\n }\n // an event\n else {\n if (event.type === 'touchend'){\n if (event.touches.length === 1){\n touches[0] = event.touches[0];\n touches[1] = event.changedTouches[0];\n }\n else if (event.touches.length === 0){\n touches[0] = event.changedTouches[0];\n touches[1] = event.changedTouches[1];\n }\n }\n else {\n touches[0] = event.touches[0];\n touches[1] = event.touches[1];\n }\n }\n\n return touches;\n }\n\n function pointerAverage(pointers){\n var average = {\n pageX: 0,\n pageY: 0,\n clientX: 0,\n clientY: 0,\n screenX: 0,\n screenY: 0\n };\n var prop;\n\n for (var i = 0; i < pointers.length; i++){\n for (prop in average){\n average[prop] += pointers[i][prop];\n }\n }\n for (prop in average){\n average[prop] /= pointers.length;\n }\n\n return average;\n }\n\n function touchBBox(event){\n if (!event.length && !(event.touches && event.touches.length > 1)){\n return;\n }\n\n var touches = getTouchPair(event),\n minX = Math.min(touches[0].pageX, touches[1].pageX),\n minY = Math.min(touches[0].pageY, touches[1].pageY),\n maxX = Math.max(touches[0].pageX, touches[1].pageX),\n maxY = Math.max(touches[0].pageY, touches[1].pageY);\n\n return {\n x: minX,\n y: minY,\n left: minX,\n top: minY,\n width: maxX - minX,\n height: maxY - minY\n };\n }\n\n function touchDistance(event, deltaSource){\n deltaSource = deltaSource || defaultOptions.deltaSource;\n\n var sourceX = deltaSource + 'X',\n sourceY = deltaSource + 'Y',\n touches = getTouchPair(event);\n\n var dx = touches[0][sourceX] - touches[1][sourceX],\n dy = touches[0][sourceY] - touches[1][sourceY];\n\n return hypot(dx, dy);\n }\n\n function touchAngle(event, prevAngle, deltaSource){\n deltaSource = deltaSource || defaultOptions.deltaSource;\n\n var sourceX = deltaSource + 'X',\n sourceY = deltaSource + 'Y',\n touches = getTouchPair(event),\n dx = touches[0][sourceX] - touches[1][sourceX],\n dy = touches[0][sourceY] - touches[1][sourceY],\n angle = 180 * Math.atan(dy / dx) / Math.PI;\n\n if (isNumber(prevAngle)){\n var dr = angle - prevAngle,\n drClamped = dr % 360;\n\n if (drClamped > 315){\n angle -= 360 + (angle / 360) | 0 * 360;\n }\n else if (drClamped > 135){\n angle -= 180 + (angle / 360) | 0 * 360;\n }\n else if (drClamped < -315){\n angle += 360 + (angle / 360) | 0 * 360;\n }\n else if (drClamped < -135){\n angle += 180 + (angle / 360) | 0 * 360;\n }\n }\n\n return angle;\n }\n\n function getOriginXY(interactable, element){\n var origin = interactable\n ? interactable.options.origin\n : defaultOptions.origin;\n\n if (origin === 'parent'){\n origin = parentElement(element);\n }\n else if (origin === 'self'){\n origin = interactable.getRect(element);\n }\n else if (trySelector(origin)){\n origin = closest(element, origin) || { x: 0, y: 0 };\n }\n\n if (isFunction(origin)){\n origin = origin(interactable && element);\n }\n\n if (isElement(origin)){\n origin = getElementRect(origin);\n }\n\n origin.x = ('x' in origin) ? origin.x : origin.left;\n origin.y = ('y' in origin) ? origin.y : origin.top;\n\n return origin;\n }\n\n // http://stackoverflow.com/a/5634528/2280888\n function _getQBezierValue(t, p1, p2, p3){\n var iT = 1 - t;\n return iT * iT * p1 + 2 * iT * t * p2 + t * t * p3;\n }\n\n function getQuadraticCurvePoint(startX, startY, cpX, cpY, endX, endY, position){\n return {\n x: _getQBezierValue(position, startX, cpX, endX),\n y: _getQBezierValue(position, startY, cpY, endY)\n };\n }\n\n // http://gizma.com/easing/\n function easeOutQuad(t, b, c, d){\n t /= d;\n return -c * t * (t - 2) + b;\n }\n\n function nodeContains(parent, child){\n while (child){\n if (child === parent){\n return true;\n }\n\n child = child.parentNode;\n }\n\n return false;\n }\n\n function closest(child, selector){\n var parent = parentElement(child);\n\n while (isElement(parent)){\n if (matchesSelector(parent, selector)){ return parent; }\n\n parent = parentElement(parent);\n }\n\n return null;\n }\n\n function parentElement(node){\n var parent = node.parentNode;\n\n if (isDocFrag(parent)){\n // skip past #shado-root fragments\n while ((parent = parent.host) && isDocFrag(parent)){}\n\n return parent;\n }\n\n return parent;\n }\n\n function inContext(interactable, element){\n return interactable._context === element.ownerDocument\n || nodeContains(interactable._context, element);\n }\n\n function testIgnore(interactable, interactableElement, element){\n var ignoreFrom = interactable.options.ignoreFrom;\n\n if (!ignoreFrom || !isElement(element)){ return false; }\n\n if (isString(ignoreFrom)){\n return matchesUpTo(element, ignoreFrom, interactableElement);\n }\n else if (isElement(ignoreFrom)){\n return nodeContains(ignoreFrom, element);\n }\n\n return false;\n }\n\n function testAllow(interactable, interactableElement, element){\n var allowFrom = interactable.options.allowFrom;\n\n if (!allowFrom){ return true; }\n\n if (!isElement(element)){ return false; }\n\n if (isString(allowFrom)){\n return matchesUpTo(element, allowFrom, interactableElement);\n }\n else if (isElement(allowFrom)){\n return nodeContains(allowFrom, element);\n }\n\n return false;\n }\n\n function checkAxis(axis, interactable){\n if (!interactable){ return false; }\n\n var thisAxis = interactable.options.drag.axis;\n\n return (axis === 'xy' || thisAxis === 'xy' || thisAxis === axis);\n }\n\n function checkSnap(interactable, action){\n var options = interactable.options;\n\n if (/^resize/.test(action)){\n action = 'resize';\n }\n\n return options[action].snap && options[action].snap.enabled;\n }\n\n function checkRestrict(interactable, action){\n var options = interactable.options;\n\n if (/^resize/.test(action)){\n action = 'resize';\n }\n\n return options[action].restrict && options[action].restrict.enabled;\n }\n\n function checkAutoScroll(interactable, action){\n var options = interactable.options;\n\n if (/^resize/.test(action)){\n action = 'resize';\n }\n\n return options[action].autoScroll && options[action].autoScroll.enabled;\n }\n\n function withinInteractionLimit(interactable, element, action){\n var options = interactable.options,\n maxActions = options[action.name].max,\n maxPerElement = options[action.name].maxPerElement,\n activeInteractions = 0,\n targetCount = 0,\n targetElementCount = 0;\n\n for (var i = 0, len = interactions.length; i < len; i++){\n var interaction = interactions[i],\n otherAction = interaction.prepared.name,\n active = interaction.interacting();\n\n if (!active){ continue; }\n\n activeInteractions++;\n\n if (activeInteractions >= maxInteractions){\n return false;\n }\n\n if (interaction.target !== interactable){ continue; }\n\n targetCount += (otherAction === action.name) | 0;\n\n if (targetCount >= maxActions){\n return false;\n }\n\n if (interaction.element === element){\n targetElementCount++;\n\n if (otherAction !== action.name || targetElementCount >= maxPerElement){\n return false;\n }\n }\n }\n\n return maxInteractions > 0;\n }\n\n // Test for the element that's \"above\" all other qualifiers\n function indexOfDeepestElement(elements){\n var dropzone,\n deepestZone = elements[0],\n index = deepestZone ? 0 : -1,\n parent,\n deepestZoneParents = [],\n dropzoneParents = [],\n child,\n i,\n n;\n\n for (i = 1; i < elements.length; i++){\n dropzone = elements[i];\n\n // an element might belong to multiple selector dropzones\n if (!dropzone || dropzone === deepestZone){\n continue;\n }\n\n if (!deepestZone){\n deepestZone = dropzone;\n index = i;\n continue;\n }\n\n // check if the deepest or current are document.documentElement or document.rootElement\n // - if the current dropzone is, do nothing and continue\n if (dropzone.parentNode === dropzone.ownerDocument){\n continue;\n }\n // - if deepest is, update with the current dropzone and continue to next\n else if (deepestZone.parentNode === dropzone.ownerDocument){\n deepestZone = dropzone;\n index = i;\n continue;\n }\n\n if (!deepestZoneParents.length){\n parent = deepestZone;\n while (parent.parentNode && parent.parentNode !== parent.ownerDocument){\n deepestZoneParents.unshift(parent);\n parent = parent.parentNode;\n }\n }\n\n // if this element is an svg element and the current deepest is\n // an HTMLElement\n if (deepestZone instanceof HTMLElement\n && dropzone instanceof SVGElement\n && !(dropzone instanceof SVGSVGElement)){\n if (dropzone === deepestZone.parentNode){\n continue;\n }\n\n parent = dropzone.ownerSVGElement;\n }\n else {\n parent = dropzone;\n }\n\n dropzoneParents = [];\n\n while (parent.parentNode !== parent.ownerDocument){\n dropzoneParents.unshift(parent);\n parent = parent.parentNode;\n }\n\n n = 0;\n\n // get (position of last common ancestor) + 1\n while (dropzoneParents[n] && dropzoneParents[n] === deepestZoneParents[n]){\n n++;\n }\n\n var parents = [\n dropzoneParents[n - 1],\n dropzoneParents[n],\n deepestZoneParents[n]\n ];\n\n child = parents[0].lastChild;\n\n while (child){\n if (child === parents[1]){\n deepestZone = dropzone;\n index = i;\n deepestZoneParents = [];\n\n break;\n }\n else if (child === parents[2]){\n break;\n }\n\n child = child.previousSibling;\n }\n }\n\n return index;\n }\n\n function Interaction(){\n this.target = null; // current interactable being interacted with\n this.element = null; // the target element of the interactable\n this.dropTarget = null; // the dropzone a drag target might be dropped into\n this.dropElement = null; // the element at the time of checking\n this.prevDropTarget = null; // the dropzone that was recently dragged away from\n this.prevDropElement = null; // the element at the time of checking\n\n this.prepared = { // action that's ready to be fired on next move event\n name: null,\n axis: null,\n edges: null\n };\n\n this.matches = []; // all selectors that are matched by target element\n this.matchElements = []; // corresponding elements\n\n this.inertiaStatus = {\n active: false,\n smoothEnd: false,\n ending: false,\n\n startEvent: null,\n upCoords: {},\n\n xe: 0, ye: 0,\n sx: 0, sy: 0,\n\n t0: 0,\n vx0: 0, vys: 0,\n duration: 0,\n\n resumeDx: 0,\n resumeDy: 0,\n\n lambda_v0: 0,\n one_ve_v0: 0,\n i: null\n };\n\n if (isFunction(Function.prototype.bind)){\n this.boundInertiaFrame = this.inertiaFrame.bind(this);\n this.boundSmoothEndFrame = this.smoothEndFrame.bind(this);\n }\n else {\n var that = this;\n\n this.boundInertiaFrame = function(){ return that.inertiaFrame(); };\n this.boundSmoothEndFrame = function(){ return that.smoothEndFrame(); };\n }\n\n this.activeDrops = {\n dropzones: [], // the dropzones that are mentioned below\n elements: [], // elements of dropzones that accept the target draggable\n rects: [] // the rects of the elements mentioned above\n };\n\n // keep track of added pointers\n this.pointers = [];\n this.pointerIds = [];\n this.downTargets = [];\n this.downTimes = [];\n this.holdTimers = [];\n\n // Previous native pointer move event coordinates\n this.prevCoords = {\n page: { x: 0, y: 0 },\n client: { x: 0, y: 0 },\n timeStamp: 0\n };\n // current native pointer move event coordinates\n this.curCoords = {\n page: { x: 0, y: 0 },\n client: { x: 0, y: 0 },\n timeStamp: 0\n };\n\n // Starting InteractEvent pointer coordinates\n this.startCoords = {\n page: { x: 0, y: 0 },\n client: { x: 0, y: 0 },\n timeStamp: 0\n };\n\n // Change in coordinates and time of the pointer\n this.pointerDelta = {\n page: { x: 0, y: 0, vx: 0, vy: 0, speed: 0 },\n client: { x: 0, y: 0, vx: 0, vy: 0, speed: 0 },\n timeStamp: 0\n };\n\n this.downEvent = null; // pointerdown/mousedown/touchstart event\n this.downPointer = {};\n\n this._eventTarget = null;\n this._curEventTarget = null;\n\n this.prevEvent = null; // previous action event\n this.tapTime = 0; // time of the most recent tap event\n this.prevTap = null;\n\n this.startOffset = { left: 0, right: 0, top: 0, bottom: 0 };\n this.restrictOffset = { left: 0, right: 0, top: 0, bottom: 0 };\n this.snapOffsets = [];\n\n this.gesture = {\n start: { x: 0, y: 0 },\n\n startDistance: 0, // distance between two touches of touchStart\n prevDistance: 0,\n distance: 0,\n\n scale: 1, // gesture.distance / gesture.startDistance\n\n startAngle: 0, // angle of line joining two touches\n prevAngle: 0 // angle of the previous gesture event\n };\n\n this.snapStatus = {\n x: 0, y: 0,\n dx: 0, dy: 0,\n realX: 0, realY: 0,\n snappedX: 0, snappedY: 0,\n targets: [],\n locked: false,\n changed: false\n };\n\n this.restrictStatus = {\n dx: 0, dy: 0,\n restrictedX: 0, restrictedY: 0,\n snap: null,\n restricted: false,\n changed: false\n };\n\n this.restrictStatus.snap = this.snapStatus;\n\n this.pointerIsDown = false;\n this.pointerWasMoved = false;\n this.gesturing = false;\n this.dragging = false;\n this.resizing = false;\n this.resizeAxes = 'xy';\n\n this.mouse = false;\n\n interactions.push(this);\n }\n\n Interaction.prototype = {\n getPageXY: function(pointer, xy){ return getPageXY(pointer, xy, this); },\n getClientXY: function(pointer, xy){ return getClientXY(pointer, xy, this); },\n setEventXY: function(target, ptr){ return setEventXY(target, ptr, this); },\n\n pointerOver: function(pointer, event, eventTarget){\n if (this.prepared.name || !this.mouse){ return; }\n\n var curMatches = [],\n curMatchElements = [],\n prevTargetElement = this.element;\n\n this.addPointer(pointer);\n\n if (this.target\n && (testIgnore(this.target, this.element, eventTarget)\n || !testAllow(this.target, this.element, eventTarget))){\n // if the eventTarget should be ignored or shouldn't be allowed\n // clear the previous target\n this.target = null;\n this.element = null;\n this.matches = [];\n this.matchElements = [];\n }\n\n var elementInteractable = interactables.get(eventTarget),\n elementAction = (elementInteractable\n && !testIgnore(elementInteractable, eventTarget, eventTarget)\n && testAllow(elementInteractable, eventTarget, eventTarget)\n && validateAction(\n elementInteractable.getAction(pointer, event, this, eventTarget),\n elementInteractable));\n\n if (elementAction && !withinInteractionLimit(elementInteractable, eventTarget, elementAction)){\n elementAction = null;\n }\n\n function pushCurMatches(interactable, selector){\n if (interactable\n && inContext(interactable, eventTarget)\n && !testIgnore(interactable, eventTarget, eventTarget)\n && testAllow(interactable, eventTarget, eventTarget)\n && matchesSelector(eventTarget, selector)){\n curMatches.push(interactable);\n curMatchElements.push(eventTarget);\n }\n }\n\n if (elementAction){\n this.target = elementInteractable;\n this.element = eventTarget;\n this.matches = [];\n this.matchElements = [];\n }\n else {\n interactables.forEachSelector(pushCurMatches);\n\n if (this.validateSelector(pointer, event, curMatches, curMatchElements)){\n this.matches = curMatches;\n this.matchElements = curMatchElements;\n\n this.pointerHover(pointer, event, this.matches, this.matchElements);\n events.add(eventTarget, supportsPointerEvent ?\n pEventTypes.move :\n 'mousemove',\n listeners.pointerHover);\n }\n else if (this.target){\n if (nodeContains(prevTargetElement, eventTarget)){\n this.pointerHover(pointer, event, this.matches, this.matchElements);\n events.add(this.element, supportsPointerEvent ?\n pEventTypes.move :\n 'mousemove',\n listeners.pointerHover);\n }\n else {\n this.target = null;\n this.element = null;\n this.matches = [];\n this.matchElements = [];\n }\n }\n }\n },\n\n // Check what action would be performed on pointerMove target if a mouse\n // button were pressed and change the cursor accordingly\n pointerHover: function(pointer, event, eventTarget, curEventTarget, matches, matchElements){\n var target = this.target;\n\n if (!this.prepared.name && this.mouse){\n var action;\n\n // update pointer coords for defaultActionChecker to use\n this.setEventXY(this.curCoords, [pointer]);\n\n if (matches){\n action = this.validateSelector(pointer, event, matches, matchElements);\n }\n else if (target){\n action = validateAction(target.getAction(this.pointers[0], event, this, this.element), this.target);\n }\n\n if (target && target.options.styleCursor){\n if (action){\n target._doc.documentElement.style.cursor = getActionCursor(action);\n }\n else {\n target._doc.documentElement.style.cursor = '';\n }\n }\n }\n else if (this.prepared.name){\n this.checkAndPreventDefault(event, target, this.element);\n }\n },\n\n pointerOut: function(pointer, event, eventTarget){\n if (this.prepared.name){ return; }\n\n // Remove temporary event listeners for selector Interactables\n if (!interactables.get(eventTarget)){\n events.remove(eventTarget,\n supportsPointerEvent ? pEventTypes.move : 'mousemove',\n listeners.pointerHover);\n }\n\n if (this.target && this.target.options.styleCursor && !this.interacting()){\n this.target._doc.documentElement.style.cursor = '';\n }\n },\n\n selectorDown: function(pointer, event, eventTarget, curEventTarget){\n var that = this,\n // copy event to be used in timeout for IE8\n eventCopy = events.useAttachEvent ? extend({}, event) : event,\n element = eventTarget,\n pointerIndex = this.addPointer(pointer),\n action;\n\n this.holdTimers[pointerIndex] = setTimeout(function(){\n that.pointerHold(events.useAttachEvent ? eventCopy : pointer, eventCopy, eventTarget, curEventTarget);\n }, defaultOptions._holdDuration);\n\n this.pointerIsDown = true;\n\n // Check if the down event hits the current inertia target\n if (this.inertiaStatus.active && this.target.selector){\n // climb up the DOM tree from the event target\n while (isElement(element)){\n // if this element is the current inertia target element\n if (element === this.element\n // and the prospective action is the same as the ongoing one\n && validateAction(this.target.getAction(pointer, event, this, this.element), this.target).name === this.prepared.name){\n // stop inertia so that the next move will be a normal one\n cancelFrame(this.inertiaStatus.i);\n this.inertiaStatus.active = false;\n\n this.collectEventTargets(pointer, event, eventTarget, 'down');\n return;\n }\n element = parentElement(element);\n }\n }\n\n // do nothing if interacting\n if (this.interacting()){\n this.collectEventTargets(pointer, event, eventTarget, 'down');\n return;\n }\n\n function pushMatches(interactable, selector, context){\n var elements = ie8MatchesSelector\n ? context.querySelectorAll(selector)\n : undefined;\n\n if (inContext(interactable, element)\n && !testIgnore(interactable, element, eventTarget)\n && testAllow(interactable, element, eventTarget)\n && matchesSelector(element, selector, elements)){\n that.matches.push(interactable);\n that.matchElements.push(element);\n }\n }\n\n // update pointer coords for defaultActionChecker to use\n this.setEventXY(this.curCoords, [pointer]);\n this.downEvent = event;\n\n while (isElement(element) && !action){\n this.matches = [];\n this.matchElements = [];\n\n interactables.forEachSelector(pushMatches);\n\n action = this.validateSelector(pointer, event, this.matches, this.matchElements);\n element = parentElement(element);\n }\n\n if (action){\n this.prepared.name = action.name;\n this.prepared.axis = action.axis;\n this.prepared.edges = action.edges;\n\n this.collectEventTargets(pointer, event, eventTarget, 'down');\n\n return this.pointerDown(pointer, event, eventTarget, curEventTarget, action);\n }\n else {\n // do these now since pointerDown isn't being called from here\n this.downTimes[pointerIndex] = new Date().getTime();\n this.downTargets[pointerIndex] = eventTarget;\n pointerExtend(this.downPointer, pointer);\n\n copyCoords(this.prevCoords, this.curCoords);\n this.pointerWasMoved = false;\n }\n\n this.collectEventTargets(pointer, event, eventTarget, 'down');\n },\n\n // Determine action to be performed on next pointerMove and add appropriate\n // style and event Listeners\n pointerDown: function(pointer, event, eventTarget, curEventTarget, forceAction){\n if (!forceAction && !this.inertiaStatus.active && this.pointerWasMoved && this.prepared.name){\n this.checkAndPreventDefault(event, this.target, this.element);\n\n return;\n }\n\n this.pointerIsDown = true;\n this.downEvent = event;\n\n var pointerIndex = this.addPointer(pointer),\n action;\n\n // If it is the second touch of a multi-touch gesture, keep the\n // target the same and get a new action if a target was set by the\n // first touch\n if (this.pointerIds.length > 1 && this.target._element === this.element){\n var newAction = validateAction(forceAction || this.target.getAction(pointer, event, this, this.element), this.target);\n\n if (withinInteractionLimit(this.target, this.element, newAction)){\n action = newAction;\n }\n\n this.prepared.name = null;\n }\n // Otherwise, set the target if there is no action prepared\n else if (!this.prepared.name){\n var interactable = interactables.get(curEventTarget);\n\n if (interactable\n && !testIgnore(interactable, curEventTarget, eventTarget)\n && testAllow(interactable, curEventTarget, eventTarget)\n && (action = validateAction(forceAction || interactable.getAction(pointer, event, this, curEventTarget), interactable, eventTarget))\n && withinInteractionLimit(interactable, curEventTarget, action)){\n this.target = interactable;\n this.element = curEventTarget;\n }\n }\n\n var target = this.target,\n options = target && target.options;\n\n if (target && (forceAction || !this.prepared.name)){\n action = action || validateAction(forceAction || target.getAction(pointer, event, this, curEventTarget), target, this.element);\n\n this.setEventXY(this.startCoords, this.pointers);\n\n if (!action){ return; }\n\n if (options.styleCursor){\n target._doc.documentElement.style.cursor = getActionCursor(action);\n }\n\n this.resizeAxes = action.name === 'resize' ? action.axis : null;\n\n if (action === 'gesture' && this.pointerIds.length < 2){\n action = null;\n }\n\n this.prepared.name = action.name;\n this.prepared.axis = action.axis;\n this.prepared.edges = action.edges;\n\n this.snapStatus.snappedX = this.snapStatus.snappedY =\n this.restrictStatus.restrictedX = this.restrictStatus.restrictedY = NaN;\n\n this.downTimes[pointerIndex] = new Date().getTime();\n this.downTargets[pointerIndex] = eventTarget;\n pointerExtend(this.downPointer, pointer);\n\n copyCoords(this.prevCoords, this.startCoords);\n this.pointerWasMoved = false;\n\n this.checkAndPreventDefault(event, target, this.element);\n }\n // if inertia is active try to resume action\n else if (this.inertiaStatus.active\n && curEventTarget === this.element\n && validateAction(target.getAction(pointer, event, this, this.element), target).name === this.prepared.name){\n cancelFrame(this.inertiaStatus.i);\n this.inertiaStatus.active = false;\n\n this.checkAndPreventDefault(event, target, this.element);\n }\n },\n\n setModifications: function(coords, preEnd){\n var target = this.target,\n shouldMove = true,\n shouldSnap = checkSnap(target, this.prepared.name) && (!target.options[this.prepared.name].snap.endOnly || preEnd),\n shouldRestrict = checkRestrict(target, this.prepared.name) && (!target.options[this.prepared.name].restrict.endOnly || preEnd);\n\n if (shouldSnap){ this.setSnapping(coords); } else { this.snapStatus.locked = false; }\n if (shouldRestrict){ this.setRestriction(coords); } else { this.restrictStatus.restricted = false; }\n\n if (shouldSnap && this.snapStatus.locked && !this.snapStatus.changed){\n shouldMove = shouldRestrict && this.restrictStatus.restricted && this.restrictStatus.changed;\n }\n else if (shouldRestrict && this.restrictStatus.restricted && !this.restrictStatus.changed){\n shouldMove = false;\n }\n\n return shouldMove;\n },\n\n setStartOffsets: function(action, interactable, element){\n var rect = interactable.getRect(element),\n origin = getOriginXY(interactable, element),\n snap = interactable.options[this.prepared.name].snap,\n restrict = interactable.options[this.prepared.name].restrict,\n width, height;\n\n if (rect){\n this.startOffset.left = this.startCoords.page.x - rect.left;\n this.startOffset.top = this.startCoords.page.y - rect.top;\n\n this.startOffset.right = rect.right - this.startCoords.page.x;\n this.startOffset.bottom = rect.bottom - this.startCoords.page.y;\n\n if ('width' in rect){ width = rect.width; }\n else { width = rect.right - rect.left; }\n if ('height' in rect){ height = rect.height; }\n else { height = rect.bottom - rect.top; }\n }\n else {\n this.startOffset.left = this.startOffset.top = this.startOffset.right = this.startOffset.bottom = 0;\n }\n\n this.snapOffsets.splice(0);\n\n var snapOffset = snap && snap.offset === 'startCoords'\n ? {\n x: this.startCoords.page.x - origin.x,\n y: this.startCoords.page.y - origin.y\n }\n : snap && snap.offset || { x: 0, y: 0 };\n\n if (rect && snap && snap.relativePoints && snap.relativePoints.length){\n for (var i = 0; i < snap.relativePoints.length; i++){\n this.snapOffsets.push({\n x: this.startOffset.left - (width * snap.relativePoints[i].x) + snapOffset.x,\n y: this.startOffset.top - (height * snap.relativePoints[i].y) + snapOffset.y\n });\n }\n }\n else {\n this.snapOffsets.push(snapOffset);\n }\n\n if (rect && restrict.elementRect){\n this.restrictOffset.left = this.startOffset.left - (width * restrict.elementRect.left);\n this.restrictOffset.top = this.startOffset.top - (height * restrict.elementRect.top);\n\n this.restrictOffset.right = this.startOffset.right - (width * (1 - restrict.elementRect.right));\n this.restrictOffset.bottom = this.startOffset.bottom - (height * (1 - restrict.elementRect.bottom));\n }\n else {\n this.restrictOffset.left = this.restrictOffset.top = this.restrictOffset.right = this.restrictOffset.bottom = 0;\n }\n },\n\n /* \\\n * Interaction.start\n [ method ]\n *\n * Start an action with the given Interactable and Element as tartgets. The\n * action must be enabled for the target Interactable and an appropriate number\n * of pointers must be held down – 1 for drag/resize, 2 for gesture.\n *\n * Use it with `interactable.able({ manualStart: false })` to always\n * [start actions manually](https://github.com/taye/interact.js/issues/114)\n *\n - action (object) The action to be performed - drag, resize, etc.\n - interactable (Interactable) The Interactable to target\n - element (Element) The DOM Element to target\n = (object) interact\n **\n | interact(target)\n | .draggable({\n | // disable the default drag start by down->move\n | manualStart: true\n | })\n | // start dragging after the user holds the pointer down\n | .on('hold', function (event) {\n | var interaction = event.interaction;\n |\n | if (!interaction.interacting()) {\n | interaction.start({ name: 'drag' },\n | event.interactable,\n | event.currentTarget);\n | }\n | });\n \\*/\n start: function(action, interactable, element){\n if (this.interacting()\n || !this.pointerIsDown\n || this.pointerIds.length < (action.name === 'gesture' ? 2 : 1)){\n return;\n }\n\n // if this interaction had been removed after stopping\n // add it back\n if (indexOf(interactions, this) === -1){\n interactions.push(this);\n }\n\n // set the startCoords if there was no prepared action\n if (!this.prepared.name){\n this.setEventXY(this.startCoords);\n }\n\n this.prepared.name = action.name;\n this.prepared.axis = action.axis;\n this.prepared.edges = action.edges;\n this.target = interactable;\n this.element = element;\n\n this.setStartOffsets(action.name, interactable, element);\n this.setModifications(this.startCoords.page);\n\n this.prevEvent = this[this.prepared.name + 'Start'](this.downEvent);\n },\n\n pointerMove: function(pointer, event, eventTarget, curEventTarget, preEnd){\n if (this.inertiaStatus.active){\n var pageUp = this.inertiaStatus.upCoords.page;\n var clientUp = this.inertiaStatus.upCoords.client;\n\n var inertiaPosition = {\n pageX: pageUp.x + this.inertiaStatus.sx,\n pageY: pageUp.y + this.inertiaStatus.sy,\n clientX: clientUp.x + this.inertiaStatus.sx,\n clientY: clientUp.y + this.inertiaStatus.sy\n };\n\n this.setEventXY(this.curCoords, [inertiaPosition]);\n }\n else {\n this.recordPointer(pointer);\n this.setEventXY(this.curCoords, this.pointers);\n }\n\n var duplicateMove = (this.curCoords.page.x === this.prevCoords.page.x\n && this.curCoords.page.y === this.prevCoords.page.y\n && this.curCoords.client.x === this.prevCoords.client.x\n && this.curCoords.client.y === this.prevCoords.client.y);\n\n var dx, dy,\n pointerIndex = this.mouse ? 0 : indexOf(this.pointerIds, getPointerId(pointer));\n\n // register movement greater than pointerMoveTolerance\n if (this.pointerIsDown && !this.pointerWasMoved){\n dx = this.curCoords.client.x - this.startCoords.client.x;\n dy = this.curCoords.client.y - this.startCoords.client.y;\n\n this.pointerWasMoved = hypot(dx, dy) > pointerMoveTolerance;\n }\n\n if (!duplicateMove && (!this.pointerIsDown || this.pointerWasMoved)){\n if (this.pointerIsDown){\n clearTimeout(this.holdTimers[pointerIndex]);\n }\n\n this.collectEventTargets(pointer, event, eventTarget, 'move');\n }\n\n if (!this.pointerIsDown){ return; }\n\n if (duplicateMove && this.pointerWasMoved && !preEnd){\n this.checkAndPreventDefault(event, this.target, this.element);\n return;\n }\n\n // set pointer coordinate, time changes and speeds\n setEventDeltas(this.pointerDelta, this.prevCoords, this.curCoords);\n\n if (!this.prepared.name){ return; }\n\n if (this.pointerWasMoved\n // ignore movement while inertia is active\n && (!this.inertiaStatus.active || (pointer instanceof InteractEvent && /inertiastart/.test(pointer.type)))){\n // if just starting an action, calculate the pointer speed now\n if (!this.interacting()){\n setEventDeltas(this.pointerDelta, this.prevCoords, this.curCoords);\n\n // check if a drag is in the correct axis\n if (this.prepared.name === 'drag'){\n var absX = Math.abs(dx),\n absY = Math.abs(dy),\n targetAxis = this.target.options.drag.axis,\n axis = (absX > absY ? 'x' : absX < absY ? 'y' : 'xy');\n\n // if the movement isn't in the axis of the interactable\n if (axis !== 'xy' && targetAxis !== 'xy' && targetAxis !== axis){\n // cancel the prepared action\n this.prepared.name = null;\n\n // then try to get a drag from another ineractable\n\n var element = eventTarget;\n\n // check element interactables\n while (isElement(element)){\n var elementInteractable = interactables.get(element);\n\n if (elementInteractable\n && elementInteractable !== this.target\n && !elementInteractable.options.drag.manualStart\n && elementInteractable.getAction(this.downPointer, this.downEvent, this, element).name === 'drag'\n && checkAxis(axis, elementInteractable)){\n this.prepared.name = 'drag';\n this.target = elementInteractable;\n this.element = element;\n break;\n }\n\n element = parentElement(element);\n }\n\n // if there's no drag from element interactables,\n // check the selector interactables\n if (!this.prepared.name){\n var thisInteraction = this;\n\n var getDraggable = function(interactable, selector, context){\n var elements = ie8MatchesSelector\n ? context.querySelectorAll(selector)\n : undefined;\n\n if (interactable === thisInteraction.target){ return; }\n\n if (inContext(interactable, eventTarget)\n && !interactable.options.drag.manualStart\n && !testIgnore(interactable, element, eventTarget)\n && testAllow(interactable, element, eventTarget)\n && matchesSelector(element, selector, elements)\n && interactable.getAction(thisInteraction.downPointer, thisInteraction.downEvent, thisInteraction, element).name === 'drag'\n && checkAxis(axis, interactable)\n && withinInteractionLimit(interactable, element, 'drag')){\n return interactable;\n }\n };\n\n element = eventTarget;\n\n while (isElement(element)){\n var selectorInteractable = interactables.forEachSelector(getDraggable);\n\n if (selectorInteractable){\n this.prepared.name = 'drag';\n this.target = selectorInteractable;\n this.element = element;\n break;\n }\n\n element = parentElement(element);\n }\n }\n }\n }\n }\n\n var starting = !!this.prepared.name && !this.interacting();\n\n if (starting\n && (this.target.options[this.prepared.name].manualStart\n || !withinInteractionLimit(this.target, this.element, this.prepared))){\n this.stop(event);\n return;\n }\n\n if (this.prepared.name && this.target){\n if (starting){\n this.start(this.prepared, this.target, this.element);\n }\n\n var shouldMove = this.setModifications(this.curCoords.page, preEnd);\n\n // move if snapping or restriction doesn't prevent it\n if (shouldMove || starting){\n this.prevEvent = this[this.prepared.name + 'Move'](event);\n }\n\n this.checkAndPreventDefault(event, this.target, this.element);\n }\n }\n\n copyCoords(this.prevCoords, this.curCoords);\n\n if (this.dragging || this.resizing){\n this.autoScrollMove(pointer);\n }\n },\n\n dragStart: function(event){\n var dragEvent = new InteractEvent(this, event, 'drag', 'start', this.element);\n\n dragEvent.originalEvent = event;\n this.dragging = true;\n this.target.fire(dragEvent);\n\n // reset active dropzones\n this.activeDrops.dropzones = [];\n this.activeDrops.elements = [];\n this.activeDrops.rects = [];\n\n if (!this.dynamicDrop){\n this.setActiveDrops(this.element);\n }\n\n var dropEvents = this.getDropEvents(event, dragEvent);\n\n if (dropEvents.activate){\n this.fireActiveDrops(dropEvents.activate);\n }\n\n return dragEvent;\n },\n\n dragMove: function(event){\n var target = this.target,\n dragEvent = new InteractEvent(this, event, 'drag', 'move', this.element),\n draggableElement = this.element,\n drop = this.getDrop(dragEvent, event, draggableElement);\n\n dragEvent.originalEvent = event;\n\n this.dropTarget = drop.dropzone;\n this.dropElement = drop.element;\n\n var dropEvents = this.getDropEvents(event, dragEvent);\n\n target.fire(dragEvent);\n\n if (dropEvents.leave){ this.prevDropTarget.fire(dropEvents.leave); }\n if (dropEvents.enter){ this.dropTarget.fire(dropEvents.enter); }\n if (dropEvents.move){ this.dropTarget.fire(dropEvents.move); }\n\n this.prevDropTarget = this.dropTarget;\n this.prevDropElement = this.dropElement;\n\n return dragEvent;\n },\n\n resizeStart: function(event){\n var resizeEvent = new InteractEvent(this, event, 'resize', 'start', this.element);\n\n if (this.prepared.edges){\n var startRect = this.target.getRect(this.element);\n\n /*\n * When using the `resizable.square` or `resizable.preserveAspectRatio` options, resizing from one edge\n * will affect another. E.g. with `resizable.square`, resizing to make the right edge larger will make\n * the bottom edge larger by the same amount. We call these 'linked' edges. Any linked edges will depend\n * on the active edges and the edge being interacted with.\n */\n if (this.target.options.resize.square || this.target.options.resize.preserveAspectRatio){\n var linkedEdges = extend({}, this.prepared.edges);\n\n linkedEdges.top = linkedEdges.top || (linkedEdges.left && !linkedEdges.bottom);\n linkedEdges.left = linkedEdges.left || (linkedEdges.top && !linkedEdges.right);\n linkedEdges.bottom = linkedEdges.bottom || (linkedEdges.right && !linkedEdges.top);\n linkedEdges.right = linkedEdges.right || (linkedEdges.bottom && !linkedEdges.left);\n\n this.prepared._linkedEdges = linkedEdges;\n }\n else {\n this.prepared._linkedEdges = null;\n }\n\n // if using `resizable.preserveAspectRatio` option, record aspect ratio at the start of the resize\n if (this.target.options.resize.preserveAspectRatio){\n this.resizeStartAspectRatio = startRect.width / startRect.height;\n }\n\n this.resizeRects = {\n start: startRect,\n current: extend({}, startRect),\n restricted: extend({}, startRect),\n previous: extend({}, startRect),\n delta: {\n left: 0, right: 0, width: 0,\n top: 0, bottom: 0, height: 0\n }\n };\n\n resizeEvent.rect = this.resizeRects.restricted;\n resizeEvent.deltaRect = this.resizeRects.delta;\n }\n\n this.target.fire(resizeEvent);\n\n this.resizing = true;\n\n return resizeEvent;\n },\n\n resizeMove: function(event){\n var resizeEvent = new InteractEvent(this, event, 'resize', 'move', this.element);\n\n var edges = this.prepared.edges,\n invert = this.target.options.resize.invert,\n invertible = invert === 'reposition' || invert === 'negate';\n\n if (edges){\n var dx = resizeEvent.dx,\n dy = resizeEvent.dy,\n\n start = this.resizeRects.start,\n current = this.resizeRects.current,\n restricted = this.resizeRects.restricted,\n delta = this.resizeRects.delta,\n previous = extend(this.resizeRects.previous, restricted),\n\n originalEdges = edges;\n\n // `resize.preserveAspectRatio` takes precedence over `resize.square`\n if (this.target.options.resize.preserveAspectRatio){\n var resizeStartAspectRatio = this.resizeStartAspectRatio;\n\n edges = this.prepared._linkedEdges;\n\n if ((originalEdges.left && originalEdges.bottom)\n || (originalEdges.right && originalEdges.top)){\n dy = -dx / resizeStartAspectRatio;\n }\n else if (originalEdges.left || originalEdges.right){ dy = dx / resizeStartAspectRatio; }\n else if (originalEdges.top || originalEdges.bottom){ dx = dy * resizeStartAspectRatio; }\n }\n else if (this.target.options.resize.square){\n edges = this.prepared._linkedEdges;\n\n if ((originalEdges.left && originalEdges.bottom)\n || (originalEdges.right && originalEdges.top)){\n dy = -dx;\n }\n else if (originalEdges.left || originalEdges.right){ dy = dx; }\n else if (originalEdges.top || originalEdges.bottom){ dx = dy; }\n }\n\n // update the 'current' rect without modifications\n if (edges.top){ current.top += dy; }\n if (edges.bottom){ current.bottom += dy; }\n if (edges.left){ current.left += dx; }\n if (edges.right){ current.right += dx; }\n\n if (invertible){\n // if invertible, copy the current rect\n extend(restricted, current);\n\n if (invert === 'reposition'){\n // swap edge values if necessary to keep width/height positive\n var swap;\n\n if (restricted.top > restricted.bottom){\n swap = restricted.top;\n\n restricted.top = restricted.bottom;\n restricted.bottom = swap;\n }\n if (restricted.left > restricted.right){\n swap = restricted.left;\n\n restricted.left = restricted.right;\n restricted.right = swap;\n }\n }\n }\n else {\n // if not invertible, restrict to minimum of 0x0 rect\n restricted.top = Math.min(current.top, start.bottom);\n restricted.bottom = Math.max(current.bottom, start.top);\n restricted.left = Math.min(current.left, start.right);\n restricted.right = Math.max(current.right, start.left);\n }\n\n restricted.width = restricted.right - restricted.left;\n restricted.height = restricted.bottom - restricted.top;\n\n for (var edge in restricted){\n delta[edge] = restricted[edge] - previous[edge];\n }\n\n resizeEvent.edges = this.prepared.edges;\n resizeEvent.rect = restricted;\n resizeEvent.deltaRect = delta;\n }\n\n this.target.fire(resizeEvent);\n\n return resizeEvent;\n },\n\n gestureStart: function(event){\n var gestureEvent = new InteractEvent(this, event, 'gesture', 'start', this.element);\n\n gestureEvent.ds = 0;\n\n this.gesture.startDistance = this.gesture.prevDistance = gestureEvent.distance;\n this.gesture.startAngle = this.gesture.prevAngle = gestureEvent.angle;\n this.gesture.scale = 1;\n\n this.gesturing = true;\n\n this.target.fire(gestureEvent);\n\n return gestureEvent;\n },\n\n gestureMove: function(event){\n if (!this.pointerIds.length){\n return this.prevEvent;\n }\n\n var gestureEvent;\n\n gestureEvent = new InteractEvent(this, event, 'gesture', 'move', this.element);\n gestureEvent.ds = gestureEvent.scale - this.gesture.scale;\n\n this.target.fire(gestureEvent);\n\n this.gesture.prevAngle = gestureEvent.angle;\n this.gesture.prevDistance = gestureEvent.distance;\n\n if (gestureEvent.scale !== Infinity &&\n gestureEvent.scale !== null &&\n gestureEvent.scale !== undefined &&\n !isNaN(gestureEvent.scale)){\n this.gesture.scale = gestureEvent.scale;\n }\n\n return gestureEvent;\n },\n\n pointerHold: function(pointer, event, eventTarget){\n this.collectEventTargets(pointer, event, eventTarget, 'hold');\n },\n\n pointerUp: function(pointer, event, eventTarget, curEventTarget){\n var pointerIndex = this.mouse ? 0 : indexOf(this.pointerIds, getPointerId(pointer));\n\n clearTimeout(this.holdTimers[pointerIndex]);\n\n this.collectEventTargets(pointer, event, eventTarget, 'up');\n this.collectEventTargets(pointer, event, eventTarget, 'tap');\n\n this.pointerEnd(pointer, event, eventTarget, curEventTarget);\n\n this.removePointer(pointer);\n },\n\n pointerCancel: function(pointer, event, eventTarget, curEventTarget){\n var pointerIndex = this.mouse ? 0 : indexOf(this.pointerIds, getPointerId(pointer));\n\n clearTimeout(this.holdTimers[pointerIndex]);\n\n this.collectEventTargets(pointer, event, eventTarget, 'cancel');\n this.pointerEnd(pointer, event, eventTarget, curEventTarget);\n\n this.removePointer(pointer);\n },\n\n // http://www.quirksmode.org/dom/events/click.html\n // >Events leading to dblclick\n //\n // IE8 doesn't fire down event before dblclick.\n // This workaround tries to fire a tap and doubletap after dblclick\n ie8Dblclick: function(pointer, event, eventTarget){\n if (this.prevTap\n && event.clientX === this.prevTap.clientX\n && event.clientY === this.prevTap.clientY\n && eventTarget === this.prevTap.target){\n this.downTargets[0] = eventTarget;\n this.downTimes[0] = new Date().getTime();\n this.collectEventTargets(pointer, event, eventTarget, 'tap');\n }\n },\n\n // End interact move events and stop auto-scroll unless inertia is enabled\n pointerEnd: function(pointer, event, eventTarget, curEventTarget){\n var endEvent,\n target = this.target,\n options = target && target.options,\n inertiaOptions = options && this.prepared.name && options[this.prepared.name].inertia,\n inertiaStatus = this.inertiaStatus;\n\n if (this.interacting()){\n if (inertiaStatus.active && !inertiaStatus.ending){ return; }\n\n var pointerSpeed,\n now = new Date().getTime(),\n inertiaPossible = false,\n inertia = false,\n smoothEnd = false,\n endSnap = checkSnap(target, this.prepared.name) && options[this.prepared.name].snap.endOnly,\n endRestrict = checkRestrict(target, this.prepared.name) && options[this.prepared.name].restrict.endOnly,\n dx = 0,\n dy = 0,\n startEvent;\n\n if (this.dragging){\n if (options.drag.axis === 'x'){ pointerSpeed = Math.abs(this.pointerDelta.client.vx); }\n else if (options.drag.axis === 'y'){ pointerSpeed = Math.abs(this.pointerDelta.client.vy); }\n else /* options.drag.axis === 'xy'*/{ pointerSpeed = this.pointerDelta.client.speed; }\n }\n else {\n pointerSpeed = this.pointerDelta.client.speed;\n }\n\n // check if inertia should be started\n inertiaPossible = (inertiaOptions && inertiaOptions.enabled\n && this.prepared.name !== 'gesture'\n && event !== inertiaStatus.startEvent);\n\n inertia = (inertiaPossible\n && (now - this.curCoords.timeStamp) < 50\n && pointerSpeed > inertiaOptions.minSpeed\n && pointerSpeed > inertiaOptions.endSpeed);\n\n if (inertiaPossible && !inertia && (endSnap || endRestrict)){\n var snapRestrict = {};\n\n snapRestrict.snap = snapRestrict.restrict = snapRestrict;\n\n if (endSnap){\n this.setSnapping(this.curCoords.page, snapRestrict);\n if (snapRestrict.locked){\n dx += snapRestrict.dx;\n dy += snapRestrict.dy;\n }\n }\n\n if (endRestrict){\n this.setRestriction(this.curCoords.page, snapRestrict);\n if (snapRestrict.restricted){\n dx += snapRestrict.dx;\n dy += snapRestrict.dy;\n }\n }\n\n if (dx || dy){\n smoothEnd = true;\n }\n }\n\n if (inertia || smoothEnd){\n copyCoords(inertiaStatus.upCoords, this.curCoords);\n\n this.pointers[0] = inertiaStatus.startEvent = startEvent =\n new InteractEvent(this, event, this.prepared.name, 'inertiastart', this.element);\n\n inertiaStatus.t0 = now;\n\n target.fire(inertiaStatus.startEvent);\n\n if (inertia){\n inertiaStatus.vx0 = this.pointerDelta.client.vx;\n inertiaStatus.vy0 = this.pointerDelta.client.vy;\n inertiaStatus.v0 = pointerSpeed;\n\n this.calcInertia(inertiaStatus);\n\n var page = extend({}, this.curCoords.page),\n origin = getOriginXY(target, this.element),\n statusObject;\n\n page.x = page.x + inertiaStatus.xe - origin.x;\n page.y = page.y + inertiaStatus.ye - origin.y;\n\n statusObject = {\n useStatusXY: true,\n x: page.x,\n y: page.y,\n dx: 0,\n dy: 0,\n snap: null\n };\n\n statusObject.snap = statusObject;\n\n dx = dy = 0;\n\n if (endSnap){\n var snap = this.setSnapping(this.curCoords.page, statusObject);\n\n if (snap.locked){\n dx += snap.dx;\n dy += snap.dy;\n }\n }\n\n if (endRestrict){\n var restrict = this.setRestriction(this.curCoords.page, statusObject);\n\n if (restrict.restricted){\n dx += restrict.dx;\n dy += restrict.dy;\n }\n }\n\n inertiaStatus.modifiedXe += dx;\n inertiaStatus.modifiedYe += dy;\n\n inertiaStatus.i = reqFrame(this.boundInertiaFrame);\n }\n else {\n inertiaStatus.smoothEnd = true;\n inertiaStatus.xe = dx;\n inertiaStatus.ye = dy;\n\n inertiaStatus.sx = inertiaStatus.sy = 0;\n\n inertiaStatus.i = reqFrame(this.boundSmoothEndFrame);\n }\n\n inertiaStatus.active = true;\n return;\n }\n\n if (endSnap || endRestrict){\n // fire a move event at the snapped coordinates\n this.pointerMove(pointer, event, eventTarget, curEventTarget, true);\n }\n }\n\n if (this.dragging){\n endEvent = new InteractEvent(this, event, 'drag', 'end', this.element);\n\n var draggableElement = this.element,\n drop = this.getDrop(endEvent, event, draggableElement);\n\n this.dropTarget = drop.dropzone;\n this.dropElement = drop.element;\n\n var dropEvents = this.getDropEvents(event, endEvent);\n\n if (dropEvents.leave){ this.prevDropTarget.fire(dropEvents.leave); }\n if (dropEvents.enter){ this.dropTarget.fire(dropEvents.enter); }\n if (dropEvents.drop){ this.dropTarget.fire(dropEvents.drop); }\n if (dropEvents.deactivate){\n this.fireActiveDrops(dropEvents.deactivate);\n }\n\n target.fire(endEvent);\n }\n else if (this.resizing){\n endEvent = new InteractEvent(this, event, 'resize', 'end', this.element);\n target.fire(endEvent);\n }\n else if (this.gesturing){\n endEvent = new InteractEvent(this, event, 'gesture', 'end', this.element);\n target.fire(endEvent);\n }\n\n this.stop(event);\n },\n\n collectDrops: function(element){\n var drops = [],\n elements = [],\n i;\n\n element = element || this.element;\n\n // collect all dropzones and their elements which qualify for a drop\n for (i = 0; i < interactables.length; i++){\n if (!interactables[i].options.drop.enabled){ continue; }\n\n var current = interactables[i],\n accept = current.options.drop.accept;\n\n // test the draggable element against the dropzone's accept setting\n if ((isElement(accept) && accept !== element)\n || (isString(accept)\n && !matchesSelector(element, accept))){\n continue;\n }\n\n // query for new elements if necessary\n var dropElements = current.selector ? current._context.querySelectorAll(current.selector) : [current._element];\n\n for (var j = 0, len = dropElements.length; j < len; j++){\n var currentElement = dropElements[j];\n\n if (currentElement === element){\n continue;\n }\n\n drops.push(current);\n elements.push(currentElement);\n }\n }\n\n return {\n dropzones: drops,\n elements: elements\n };\n },\n\n fireActiveDrops: function(event){\n var i,\n current,\n currentElement,\n prevElement;\n\n // loop through all active dropzones and trigger event\n for (i = 0; i < this.activeDrops.dropzones.length; i++){\n current = this.activeDrops.dropzones[i];\n currentElement = this.activeDrops.elements[i];\n\n // prevent trigger of duplicate events on same element\n if (currentElement !== prevElement){\n // set current element as event target\n event.target = currentElement;\n current.fire(event);\n }\n prevElement = currentElement;\n }\n },\n\n // Collect a new set of possible drops and save them in activeDrops.\n // setActiveDrops should always be called when a drag has just started or a\n // drag event happens while dynamicDrop is true\n setActiveDrops: function(dragElement){\n // get dropzones and their elements that could receive the draggable\n var possibleDrops = this.collectDrops(dragElement, true);\n\n this.activeDrops.dropzones = possibleDrops.dropzones;\n this.activeDrops.elements = possibleDrops.elements;\n this.activeDrops.rects = [];\n\n for (var i = 0; i < this.activeDrops.dropzones.length; i++){\n this.activeDrops.rects[i] = this.activeDrops.dropzones[i].getRect(this.activeDrops.elements[i]);\n }\n },\n\n getDrop: function(dragEvent, event, dragElement){\n var validDrops = [];\n\n if (dynamicDrop){\n this.setActiveDrops(dragElement);\n }\n\n // collect all dropzones and their elements which qualify for a drop\n for (var j = 0; j < this.activeDrops.dropzones.length; j++){\n var current = this.activeDrops.dropzones[j],\n currentElement = this.activeDrops.elements[j],\n rect = this.activeDrops.rects[j];\n\n validDrops.push(current.dropCheck(dragEvent, event, this.target, dragElement, currentElement, rect)\n ? currentElement\n : null);\n }\n\n // get the most appropriate dropzone based on DOM depth and order\n var dropIndex = indexOfDeepestElement(validDrops),\n dropzone = this.activeDrops.dropzones[dropIndex] || null,\n element = this.activeDrops.elements[dropIndex] || null;\n\n return {\n dropzone: dropzone,\n element: element\n };\n },\n\n getDropEvents: function(pointerEvent, dragEvent){\n var dropEvents = {\n enter: null,\n leave: null,\n activate: null,\n deactivate: null,\n move: null,\n drop: null\n };\n\n if (this.dropElement !== this.prevDropElement){\n // if there was a prevDropTarget, create a dragleave event\n if (this.prevDropTarget){\n dropEvents.leave = {\n target: this.prevDropElement,\n dropzone: this.prevDropTarget,\n relatedTarget: dragEvent.target,\n draggable: dragEvent.interactable,\n dragEvent: dragEvent,\n interaction: this,\n timeStamp: dragEvent.timeStamp,\n type: 'dragleave'\n };\n\n dragEvent.dragLeave = this.prevDropElement;\n dragEvent.prevDropzone = this.prevDropTarget;\n }\n // if the dropTarget is not null, create a dragenter event\n if (this.dropTarget){\n dropEvents.enter = {\n target: this.dropElement,\n dropzone: this.dropTarget,\n relatedTarget: dragEvent.target,\n draggable: dragEvent.interactable,\n dragEvent: dragEvent,\n interaction: this,\n timeStamp: dragEvent.timeStamp,\n type: 'dragenter'\n };\n\n dragEvent.dragEnter = this.dropElement;\n dragEvent.dropzone = this.dropTarget;\n }\n }\n\n if (dragEvent.type === 'dragend' && this.dropTarget){\n dropEvents.drop = {\n target: this.dropElement,\n dropzone: this.dropTarget,\n relatedTarget: dragEvent.target,\n draggable: dragEvent.interactable,\n dragEvent: dragEvent,\n interaction: this,\n timeStamp: dragEvent.timeStamp,\n type: 'drop'\n };\n\n dragEvent.dropzone = this.dropTarget;\n }\n if (dragEvent.type === 'dragstart'){\n dropEvents.activate = {\n target: null,\n dropzone: null,\n relatedTarget: dragEvent.target,\n draggable: dragEvent.interactable,\n dragEvent: dragEvent,\n interaction: this,\n timeStamp: dragEvent.timeStamp,\n type: 'dropactivate'\n };\n }\n if (dragEvent.type === 'dragend'){\n dropEvents.deactivate = {\n target: null,\n dropzone: null,\n relatedTarget: dragEvent.target,\n draggable: dragEvent.interactable,\n dragEvent: dragEvent,\n interaction: this,\n timeStamp: dragEvent.timeStamp,\n type: 'dropdeactivate'\n };\n }\n if (dragEvent.type === 'dragmove' && this.dropTarget){\n dropEvents.move = {\n target: this.dropElement,\n dropzone: this.dropTarget,\n relatedTarget: dragEvent.target,\n draggable: dragEvent.interactable,\n dragEvent: dragEvent,\n interaction: this,\n dragmove: dragEvent,\n timeStamp: dragEvent.timeStamp,\n type: 'dropmove'\n };\n dragEvent.dropzone = this.dropTarget;\n }\n\n return dropEvents;\n },\n\n currentAction: function(){\n return (this.dragging && 'drag') || (this.resizing && 'resize') || (this.gesturing && 'gesture') || null;\n },\n\n interacting: function(){\n return this.dragging || this.resizing || this.gesturing;\n },\n\n clearTargets: function(){\n this.target = this.element = null;\n\n this.dropTarget = this.dropElement = this.prevDropTarget = this.prevDropElement = null;\n },\n\n stop: function(event){\n if (this.interacting()){\n autoScroll.stop();\n this.matches = [];\n this.matchElements = [];\n\n var target = this.target;\n\n if (target.options.styleCursor){\n target._doc.documentElement.style.cursor = '';\n }\n\n // prevent Default only if were previously interacting\n if (event && isFunction(event.preventDefault)){\n this.checkAndPreventDefault(event, target, this.element);\n }\n\n if (this.dragging){\n this.activeDrops.dropzones = this.activeDrops.elements = this.activeDrops.rects = null;\n }\n }\n\n this.clearTargets();\n\n this.pointerIsDown = this.snapStatus.locked = this.dragging = this.resizing = this.gesturing = false;\n this.prepared.name = this.prevEvent = null;\n this.inertiaStatus.resumeDx = this.inertiaStatus.resumeDy = 0;\n\n // remove pointers if their ID isn't in this.pointerIds\n for (var i = 0; i < this.pointers.length; i++){\n if (indexOf(this.pointerIds, getPointerId(this.pointers[i])) === -1){\n this.pointers.splice(i, 1);\n }\n }\n },\n\n inertiaFrame: function(){\n var inertiaStatus = this.inertiaStatus,\n options = this.target.options[this.prepared.name].inertia,\n lambda = options.resistance,\n t = new Date().getTime() / 1000 - inertiaStatus.t0;\n\n if (t < inertiaStatus.te){\n var progress = 1 - (Math.exp(-lambda * t) - inertiaStatus.lambda_v0) / inertiaStatus.one_ve_v0;\n\n if (inertiaStatus.modifiedXe === inertiaStatus.xe && inertiaStatus.modifiedYe === inertiaStatus.ye){\n inertiaStatus.sx = inertiaStatus.xe * progress;\n inertiaStatus.sy = inertiaStatus.ye * progress;\n }\n else {\n var quadPoint = getQuadraticCurvePoint(\n 0, 0,\n inertiaStatus.xe, inertiaStatus.ye,\n inertiaStatus.modifiedXe, inertiaStatus.modifiedYe,\n progress);\n\n inertiaStatus.sx = quadPoint.x;\n inertiaStatus.sy = quadPoint.y;\n }\n\n this.pointerMove(inertiaStatus.startEvent, inertiaStatus.startEvent);\n\n inertiaStatus.i = reqFrame(this.boundInertiaFrame);\n }\n else {\n inertiaStatus.ending = true;\n\n inertiaStatus.sx = inertiaStatus.modifiedXe;\n inertiaStatus.sy = inertiaStatus.modifiedYe;\n\n this.pointerMove(inertiaStatus.startEvent, inertiaStatus.startEvent);\n this.pointerEnd(inertiaStatus.startEvent, inertiaStatus.startEvent);\n\n inertiaStatus.active = inertiaStatus.ending = false;\n }\n },\n\n smoothEndFrame: function(){\n var inertiaStatus = this.inertiaStatus,\n t = new Date().getTime() - inertiaStatus.t0,\n duration = this.target.options[this.prepared.name].inertia.smoothEndDuration;\n\n if (t < duration){\n inertiaStatus.sx = easeOutQuad(t, 0, inertiaStatus.xe, duration);\n inertiaStatus.sy = easeOutQuad(t, 0, inertiaStatus.ye, duration);\n\n this.pointerMove(inertiaStatus.startEvent, inertiaStatus.startEvent);\n\n inertiaStatus.i = reqFrame(this.boundSmoothEndFrame);\n }\n else {\n inertiaStatus.ending = true;\n\n inertiaStatus.sx = inertiaStatus.xe;\n inertiaStatus.sy = inertiaStatus.ye;\n\n this.pointerMove(inertiaStatus.startEvent, inertiaStatus.startEvent);\n this.pointerEnd(inertiaStatus.startEvent, inertiaStatus.startEvent);\n\n inertiaStatus.smoothEnd =\n inertiaStatus.active = inertiaStatus.ending = false;\n }\n },\n\n addPointer: function(pointer){\n var id = getPointerId(pointer),\n index = this.mouse ? 0 : indexOf(this.pointerIds, id);\n\n if (index === -1){\n index = this.pointerIds.length;\n }\n\n this.pointerIds[index] = id;\n this.pointers[index] = pointer;\n\n return index;\n },\n\n removePointer: function(pointer){\n var id = getPointerId(pointer),\n index = this.mouse ? 0 : indexOf(this.pointerIds, id);\n\n if (index === -1){ return; }\n\n this.pointers.splice(index, 1);\n this.pointerIds.splice(index, 1);\n this.downTargets.splice(index, 1);\n this.downTimes.splice(index, 1);\n this.holdTimers.splice(index, 1);\n },\n\n recordPointer: function(pointer){\n var index = this.mouse ? 0 : indexOf(this.pointerIds, getPointerId(pointer));\n\n if (index === -1){ return; }\n\n this.pointers[index] = pointer;\n },\n\n collectEventTargets: function(pointer, event, eventTarget, eventType){\n var pointerIndex = this.mouse ? 0 : indexOf(this.pointerIds, getPointerId(pointer));\n\n // do not fire a tap event if the pointer was moved before being lifted\n if (eventType === 'tap' && (this.pointerWasMoved\n // or if the pointerup target is different to the pointerdown target\n || !(this.downTargets[pointerIndex] && this.downTargets[pointerIndex] === eventTarget))){\n return;\n }\n\n var targets = [],\n elements = [],\n element = eventTarget;\n\n function collectSelectors(interactable, selector, context){\n var els = ie8MatchesSelector\n ? context.querySelectorAll(selector)\n : undefined;\n\n if (interactable._iEvents[eventType]\n && isElement(element)\n && inContext(interactable, element)\n && !testIgnore(interactable, element, eventTarget)\n && testAllow(interactable, element, eventTarget)\n && matchesSelector(element, selector, els)){\n targets.push(interactable);\n elements.push(element);\n }\n }\n\n while (element){\n if (interact.isSet(element) && interact(element)._iEvents[eventType]){\n targets.push(interact(element));\n elements.push(element);\n }\n\n interactables.forEachSelector(collectSelectors);\n\n element = parentElement(element);\n }\n\n // create the tap event even if there are no listeners so that\n // doubletap can still be created and fired\n if (targets.length || eventType === 'tap'){\n this.firePointers(pointer, event, eventTarget, targets, elements, eventType);\n }\n },\n\n firePointers: function(pointer, event, eventTarget, targets, elements, eventType){\n var pointerIndex = this.mouse ? 0 : indexOf(this.pointerIds, getPointerId(pointer)),\n pointerEvent = {},\n i,\n // for tap events\n interval, createNewDoubleTap;\n\n // if it's a doubletap then the event properties would have been\n // copied from the tap event and provided as the pointer argument\n if (eventType === 'doubletap'){\n pointerEvent = pointer;\n }\n else {\n pointerExtend(pointerEvent, event);\n if (event !== pointer){\n pointerExtend(pointerEvent, pointer);\n }\n\n pointerEvent.preventDefault = preventOriginalDefault;\n pointerEvent.stopPropagation = InteractEvent.prototype.stopPropagation;\n pointerEvent.stopImmediatePropagation = InteractEvent.prototype.stopImmediatePropagation;\n pointerEvent.interaction = this;\n\n pointerEvent.timeStamp = new Date().getTime();\n pointerEvent.originalEvent = event;\n pointerEvent.originalPointer = pointer;\n pointerEvent.type = eventType;\n pointerEvent.pointerId = getPointerId(pointer);\n pointerEvent.pointerType = this.mouse ? 'mouse' : !supportsPointerEvent ? 'touch'\n : isString(pointer.pointerType)\n ? pointer.pointerType\n : [,, 'touch', 'pen', 'mouse'][pointer.pointerType];\n }\n\n if (eventType === 'tap'){\n pointerEvent.dt = pointerEvent.timeStamp - this.downTimes[pointerIndex];\n\n interval = pointerEvent.timeStamp - this.tapTime;\n createNewDoubleTap = !!(this.prevTap && this.prevTap.type !== 'doubletap'\n && this.prevTap.target === pointerEvent.target\n && interval < 500);\n\n pointerEvent.double = createNewDoubleTap;\n\n this.tapTime = pointerEvent.timeStamp;\n }\n\n for (i = 0; i < targets.length; i++){\n pointerEvent.currentTarget = elements[i];\n pointerEvent.interactable = targets[i];\n targets[i].fire(pointerEvent);\n\n if (pointerEvent.immediatePropagationStopped\n || (pointerEvent.propagationStopped && elements[i + 1] !== pointerEvent.currentTarget)){\n break;\n }\n }\n\n if (createNewDoubleTap){\n var doubleTap = {};\n\n extend(doubleTap, pointerEvent);\n\n doubleTap.dt = interval;\n doubleTap.type = 'doubletap';\n\n this.collectEventTargets(doubleTap, event, eventTarget, 'doubletap');\n\n this.prevTap = doubleTap;\n }\n else if (eventType === 'tap'){\n this.prevTap = pointerEvent;\n }\n },\n\n validateSelector: function(pointer, event, matches, matchElements){\n for (var i = 0, len = matches.length; i < len; i++){\n var match = matches[i],\n matchElement = matchElements[i],\n action = validateAction(match.getAction(pointer, event, this, matchElement), match);\n\n if (action && withinInteractionLimit(match, matchElement, action)){\n this.target = match;\n this.element = matchElement;\n\n return action;\n }\n }\n },\n\n setSnapping: function(pageCoords, status){\n var snap = this.target.options[this.prepared.name].snap,\n targets = [],\n target,\n page,\n i;\n\n status = status || this.snapStatus;\n\n if (status.useStatusXY){\n page = { x: status.x, y: status.y };\n }\n else {\n var origin = getOriginXY(this.target, this.element);\n\n page = extend({}, pageCoords);\n\n page.x -= origin.x;\n page.y -= origin.y;\n }\n\n status.realX = page.x;\n status.realY = page.y;\n\n page.x = page.x - this.inertiaStatus.resumeDx;\n page.y = page.y - this.inertiaStatus.resumeDy;\n\n var len = snap.targets ? snap.targets.length : 0;\n\n for (var relIndex = 0; relIndex < this.snapOffsets.length; relIndex++){\n var relative = {\n x: page.x - this.snapOffsets[relIndex].x,\n y: page.y - this.snapOffsets[relIndex].y\n };\n\n for (i = 0; i < len; i++){\n if (isFunction(snap.targets[i])){\n target = snap.targets[i](relative.x, relative.y, this);\n }\n else {\n target = snap.targets[i];\n }\n\n if (!target){ continue; }\n\n targets.push({\n x: isNumber(target.x) ? (target.x + this.snapOffsets[relIndex].x) : relative.x,\n y: isNumber(target.y) ? (target.y + this.snapOffsets[relIndex].y) : relative.y,\n\n range: isNumber(target.range) ? target.range : snap.range\n });\n }\n }\n\n var closest = {\n target: null,\n inRange: false,\n distance: 0,\n range: 0,\n dx: 0,\n dy: 0\n };\n\n for (i = 0, len = targets.length; i < len; i++){\n target = targets[i];\n\n var range = target.range,\n dx = target.x - page.x,\n dy = target.y - page.y,\n distance = hypot(dx, dy),\n inRange = distance <= range;\n\n // Infinite targets count as being out of range\n // compared to non infinite ones that are in range\n if (range === Infinity && closest.inRange && closest.range !== Infinity){\n inRange = false;\n }\n\n if (!closest.target || (inRange\n // is the closest target in range?\n ? (closest.inRange && range !== Infinity\n // the pointer is relatively deeper in this target\n ? distance / range < closest.distance / closest.range\n // this target has Infinite range and the closest doesn't\n : (range === Infinity && closest.range !== Infinity)\n // OR this target is closer that the previous closest\n || distance < closest.distance)\n // The other is not in range and the pointer is closer to this target\n : (!closest.inRange && distance < closest.distance))){\n if (range === Infinity){\n inRange = true;\n }\n\n closest.target = target;\n closest.distance = distance;\n closest.range = range;\n closest.inRange = inRange;\n closest.dx = dx;\n closest.dy = dy;\n\n status.range = range;\n }\n }\n\n var snapChanged;\n\n if (closest.target){\n snapChanged = (status.snappedX !== closest.target.x || status.snappedY !== closest.target.y);\n\n status.snappedX = closest.target.x;\n status.snappedY = closest.target.y;\n }\n else {\n snapChanged = true;\n\n status.snappedX = NaN;\n status.snappedY = NaN;\n }\n\n status.dx = closest.dx;\n status.dy = closest.dy;\n\n status.changed = (snapChanged || (closest.inRange && !status.locked));\n status.locked = closest.inRange;\n\n return status;\n },\n\n setRestriction: function(pageCoords, status){\n var target = this.target,\n restrict = target && target.options[this.prepared.name].restrict,\n restriction = restrict && restrict.restriction,\n page;\n\n if (!restriction){\n return status;\n }\n\n status = status || this.restrictStatus;\n\n page = status.useStatusXY\n ? page = { x: status.x, y: status.y }\n : page = extend({}, pageCoords);\n\n if (status.snap && status.snap.locked){\n page.x += status.snap.dx || 0;\n page.y += status.snap.dy || 0;\n }\n\n page.x -= this.inertiaStatus.resumeDx;\n page.y -= this.inertiaStatus.resumeDy;\n\n status.dx = 0;\n status.dy = 0;\n status.restricted = false;\n\n var rect, restrictedX, restrictedY;\n\n if (isString(restriction)){\n if (restriction === 'parent'){\n restriction = parentElement(this.element);\n }\n else if (restriction === 'self'){\n restriction = target.getRect(this.element);\n }\n else {\n restriction = closest(this.element, restriction);\n }\n\n if (!restriction){ return status; }\n }\n\n if (isFunction(restriction)){\n restriction = restriction(page.x, page.y, this.element);\n }\n\n if (isElement(restriction)){\n restriction = getElementRect(restriction);\n }\n\n rect = restriction;\n\n if (!restriction){\n restrictedX = page.x;\n restrictedY = page.y;\n }\n // object is assumed to have\n // x, y, width, height or\n // left, top, right, bottom\n else if ('x' in restriction && 'y' in restriction){\n restrictedX = Math.max(Math.min(rect.x + rect.width - this.restrictOffset.right, page.x), rect.x + this.restrictOffset.left);\n restrictedY = Math.max(Math.min(rect.y + rect.height - this.restrictOffset.bottom, page.y), rect.y + this.restrictOffset.top);\n }\n else {\n restrictedX = Math.max(Math.min(rect.right - this.restrictOffset.right, page.x), rect.left + this.restrictOffset.left);\n restrictedY = Math.max(Math.min(rect.bottom - this.restrictOffset.bottom, page.y), rect.top + this.restrictOffset.top);\n }\n\n status.dx = restrictedX - page.x;\n status.dy = restrictedY - page.y;\n\n status.changed = status.restrictedX !== restrictedX || status.restrictedY !== restrictedY;\n status.restricted = !!(status.dx || status.dy);\n\n status.restrictedX = restrictedX;\n status.restrictedY = restrictedY;\n\n return status;\n },\n\n checkAndPreventDefault: function(event, interactable, element){\n if (!(interactable = interactable || this.target)){ return; }\n\n var options = interactable.options,\n prevent = options.preventDefault;\n\n if (prevent === 'auto' && element && !/^(input|select|textarea)$/i.test(event.target.nodeName)){\n // do not preventDefault on pointerdown if the prepared action is a drag\n // and dragging can only start from a certain direction - this allows\n // a touch to pan the viewport if a drag isn't in the right direction\n if (/down|start/i.test(event.type)\n && this.prepared.name === 'drag' && options.drag.axis !== 'xy'){\n return;\n }\n\n // with manualStart, only preventDefault while interacting\n if (options[this.prepared.name] && options[this.prepared.name].manualStart\n && !this.interacting()){\n return;\n }\n\n event.preventDefault();\n return;\n }\n\n if (prevent === 'always'){\n event.preventDefault();\n return;\n }\n },\n\n calcInertia: function(status){\n var inertiaOptions = this.target.options[this.prepared.name].inertia,\n lambda = inertiaOptions.resistance,\n inertiaDur = -Math.log(inertiaOptions.endSpeed / status.v0) / lambda;\n\n status.x0 = this.prevEvent.pageX;\n status.y0 = this.prevEvent.pageY;\n status.t0 = status.startEvent.timeStamp / 1000;\n status.sx = status.sy = 0;\n\n status.modifiedXe = status.xe = (status.vx0 - inertiaDur) / lambda;\n status.modifiedYe = status.ye = (status.vy0 - inertiaDur) / lambda;\n status.te = inertiaDur;\n\n status.lambda_v0 = lambda / status.v0;\n status.one_ve_v0 = 1 - inertiaOptions.endSpeed / status.v0;\n },\n\n autoScrollMove: function(pointer){\n if (!(this.interacting()\n && checkAutoScroll(this.target, this.prepared.name))){\n return;\n }\n\n if (this.inertiaStatus.active){\n autoScroll.x = autoScroll.y = 0;\n return;\n }\n\n var top,\n right,\n bottom,\n left,\n options = this.target.options[this.prepared.name].autoScroll,\n container = options.container || getWindow(this.element);\n\n if (isWindow(container)){\n left = pointer.clientX < autoScroll.margin;\n top = pointer.clientY < autoScroll.margin;\n right = pointer.clientX > container.innerWidth - autoScroll.margin;\n bottom = pointer.clientY > container.innerHeight - autoScroll.margin;\n }\n else {\n var rect = getElementClientRect(container);\n\n left = pointer.clientX < rect.left + autoScroll.margin;\n top = pointer.clientY < rect.top + autoScroll.margin;\n right = pointer.clientX > rect.right - autoScroll.margin;\n bottom = pointer.clientY > rect.bottom - autoScroll.margin;\n }\n\n autoScroll.x = (right ? 1 : left ? -1 : 0);\n autoScroll.y = (bottom ? 1 : top ? -1 : 0);\n\n if (!autoScroll.isScrolling){\n // set the autoScroll properties to those of the target\n autoScroll.margin = options.margin;\n autoScroll.speed = options.speed;\n\n autoScroll.start(this);\n }\n },\n\n _updateEventTargets: function(target, currentTarget){\n this._eventTarget = target;\n this._curEventTarget = currentTarget;\n }\n\n };\n\n function getInteractionFromPointer(pointer, eventType, eventTarget){\n var i = 0, len = interactions.length,\n mouseEvent = (/mouse/i.test(pointer.pointerType || eventType)\n // MSPointerEvent.MSPOINTER_TYPE_MOUSE\n || pointer.pointerType === 4),\n interaction;\n\n var id = getPointerId(pointer);\n\n // try to resume inertia with a new pointer\n if (/down|start/i.test(eventType)){\n for (i = 0; i < len; i++){\n interaction = interactions[i];\n\n var element = eventTarget;\n\n if (interaction.inertiaStatus.active && interaction.target.options[interaction.prepared.name].inertia.allowResume\n && (interaction.mouse === mouseEvent)){\n while (element){\n // if the element is the interaction element\n if (element === interaction.element){\n return interaction;\n }\n element = parentElement(element);\n }\n }\n }\n }\n\n // if it's a mouse interaction\n if (mouseEvent || !supportsTouch || supportsPointerEvent){\n // find a mouse interaction that's not in inertia phase\n for (i = 0; i < len; i++){\n if (interactions[i].mouse && !interactions[i].inertiaStatus.active){\n return interactions[i];\n }\n }\n\n // find any interaction specifically for mouse.\n // if the eventType is a mousedown, and inertia is active\n // ignore the interaction\n for (i = 0; i < len; i++){\n if (interactions[i].mouse && !(/down/.test(eventType) && interactions[i].inertiaStatus.active)){\n return interaction;\n }\n }\n\n // create a new interaction for mouse\n interaction = new Interaction();\n interaction.mouse = true;\n\n return interaction;\n }\n\n // get interaction that has this pointer\n for (i = 0; i < len; i++){\n if (contains(interactions[i].pointerIds, id)){\n return interactions[i];\n }\n }\n\n // at this stage, a pointerUp should not return an interaction\n if (/up|end|out/i.test(eventType)){\n return null;\n }\n\n // get first idle interaction\n for (i = 0; i < len; i++){\n interaction = interactions[i];\n\n if ((!interaction.prepared.name || (interaction.target.options.gesture.enabled))\n && !interaction.interacting()\n && !(!mouseEvent && interaction.mouse)){\n return interaction;\n }\n }\n\n return new Interaction();\n }\n\n function doOnInteractions(method){\n return (function(event){\n var interaction,\n eventTarget = getActualElement(event.path\n ? event.path[0]\n : event.target),\n curEventTarget = getActualElement(event.currentTarget),\n i;\n\n if (supportsTouch && /touch/.test(event.type)){\n prevTouchTime = new Date().getTime();\n\n for (i = 0; i < event.changedTouches.length; i++){\n var pointer = event.changedTouches[i];\n\n interaction = getInteractionFromPointer(pointer, event.type, eventTarget);\n\n if (!interaction){ continue; }\n\n interaction._updateEventTargets(eventTarget, curEventTarget);\n\n interaction[method](pointer, event, eventTarget, curEventTarget);\n }\n }\n else {\n if (!supportsPointerEvent && /mouse/.test(event.type)){\n // ignore mouse events while touch interactions are active\n for (i = 0; i < interactions.length; i++){\n if (!interactions[i].mouse && interactions[i].pointerIsDown){\n return;\n }\n }\n\n // try to ignore mouse events that are simulated by the browser\n // after a touch event\n if (new Date().getTime() - prevTouchTime < 500){\n return;\n }\n }\n\n interaction = getInteractionFromPointer(event, event.type, eventTarget);\n\n if (!interaction){ return; }\n\n interaction._updateEventTargets(eventTarget, curEventTarget);\n\n interaction[method](event, event, eventTarget, curEventTarget);\n }\n });\n }\n\n function InteractEvent(interaction, event, action, phase, element, related){\n var client,\n page,\n target = interaction.target,\n snapStatus = interaction.snapStatus,\n restrictStatus = interaction.restrictStatus,\n pointers = interaction.pointers,\n deltaSource = (target && target.options || defaultOptions).deltaSource,\n sourceX = deltaSource + 'X',\n sourceY = deltaSource + 'Y',\n options = target ? target.options : defaultOptions,\n origin = getOriginXY(target, element),\n starting = phase === 'start',\n ending = phase === 'end',\n coords = starting ? interaction.startCoords : interaction.curCoords;\n\n element = element || interaction.element;\n\n page = extend({}, coords.page);\n client = extend({}, coords.client);\n\n page.x -= origin.x;\n page.y -= origin.y;\n\n client.x -= origin.x;\n client.y -= origin.y;\n\n var relativePoints = options[action].snap && options[action].snap.relativePoints;\n\n if (checkSnap(target, action) && !(starting && relativePoints && relativePoints.length)){\n this.snap = {\n range: snapStatus.range,\n locked: snapStatus.locked,\n x: snapStatus.snappedX,\n y: snapStatus.snappedY,\n realX: snapStatus.realX,\n realY: snapStatus.realY,\n dx: snapStatus.dx,\n dy: snapStatus.dy\n };\n\n if (snapStatus.locked){\n page.x += snapStatus.dx;\n page.y += snapStatus.dy;\n client.x += snapStatus.dx;\n client.y += snapStatus.dy;\n }\n }\n\n if (checkRestrict(target, action) && !(starting && options[action].restrict.elementRect) && restrictStatus.restricted){\n page.x += restrictStatus.dx;\n page.y += restrictStatus.dy;\n client.x += restrictStatus.dx;\n client.y += restrictStatus.dy;\n\n this.restrict = {\n dx: restrictStatus.dx,\n dy: restrictStatus.dy\n };\n }\n\n this.pageX = page.x;\n this.pageY = page.y;\n this.clientX = client.x;\n this.clientY = client.y;\n\n this.x0 = interaction.startCoords.page.x - origin.x;\n this.y0 = interaction.startCoords.page.y - origin.y;\n this.clientX0 = interaction.startCoords.client.x - origin.x;\n this.clientY0 = interaction.startCoords.client.y - origin.y;\n this.ctrlKey = event.ctrlKey;\n this.altKey = event.altKey;\n this.shiftKey = event.shiftKey;\n this.metaKey = event.metaKey;\n this.button = event.button;\n this.buttons = event.buttons;\n this.target = element;\n this.t0 = interaction.downTimes[0];\n this.type = action + (phase || '');\n\n this.interaction = interaction;\n this.interactable = target;\n\n var inertiaStatus = interaction.inertiaStatus;\n\n if (inertiaStatus.active){\n this.detail = 'inertia';\n }\n\n if (related){\n this.relatedTarget = related;\n }\n\n // end event dx, dy is difference between start and end points\n if (ending){\n if (deltaSource === 'client'){\n this.dx = client.x - interaction.startCoords.client.x;\n this.dy = client.y - interaction.startCoords.client.y;\n }\n else {\n this.dx = page.x - interaction.startCoords.page.x;\n this.dy = page.y - interaction.startCoords.page.y;\n }\n }\n else if (starting){\n this.dx = 0;\n this.dy = 0;\n }\n // copy properties from previousmove if starting inertia\n else if (phase === 'inertiastart'){\n this.dx = interaction.prevEvent.dx;\n this.dy = interaction.prevEvent.dy;\n }\n else {\n if (deltaSource === 'client'){\n this.dx = client.x - interaction.prevEvent.clientX;\n this.dy = client.y - interaction.prevEvent.clientY;\n }\n else {\n this.dx = page.x - interaction.prevEvent.pageX;\n this.dy = page.y - interaction.prevEvent.pageY;\n }\n }\n if (interaction.prevEvent && interaction.prevEvent.detail === 'inertia'\n && !inertiaStatus.active\n && options[action].inertia && options[action].inertia.zeroResumeDelta){\n inertiaStatus.resumeDx += this.dx;\n inertiaStatus.resumeDy += this.dy;\n\n this.dx = this.dy = 0;\n }\n\n if (action === 'resize' && interaction.resizeAxes){\n if (options.resize.square){\n if (interaction.resizeAxes === 'y'){\n this.dx = this.dy;\n }\n else {\n this.dy = this.dx;\n }\n this.axes = 'xy';\n }\n else {\n this.axes = interaction.resizeAxes;\n\n if (interaction.resizeAxes === 'x'){\n this.dy = 0;\n }\n else if (interaction.resizeAxes === 'y'){\n this.dx = 0;\n }\n }\n }\n else if (action === 'gesture'){\n this.touches = [pointers[0], pointers[1]];\n\n if (starting){\n this.distance = touchDistance(pointers, deltaSource);\n this.box = touchBBox(pointers);\n this.scale = 1;\n this.ds = 0;\n this.angle = touchAngle(pointers, undefined, deltaSource);\n this.da = 0;\n }\n else if (ending || event instanceof InteractEvent){\n this.distance = interaction.prevEvent.distance;\n this.box = interaction.prevEvent.box;\n this.scale = interaction.prevEvent.scale;\n this.ds = this.scale - 1;\n this.angle = interaction.prevEvent.angle;\n this.da = this.angle - interaction.gesture.startAngle;\n }\n else {\n this.distance = touchDistance(pointers, deltaSource);\n this.box = touchBBox(pointers);\n this.scale = this.distance / interaction.gesture.startDistance;\n this.angle = touchAngle(pointers, interaction.gesture.prevAngle, deltaSource);\n\n this.ds = this.scale - interaction.gesture.prevScale;\n this.da = this.angle - interaction.gesture.prevAngle;\n }\n }\n\n if (starting){\n this.timeStamp = interaction.downTimes[0];\n this.dt = 0;\n this.duration = 0;\n this.speed = 0;\n this.velocityX = 0;\n this.velocityY = 0;\n }\n else if (phase === 'inertiastart'){\n this.timeStamp = interaction.prevEvent.timeStamp;\n this.dt = interaction.prevEvent.dt;\n this.duration = interaction.prevEvent.duration;\n this.speed = interaction.prevEvent.speed;\n this.velocityX = interaction.prevEvent.velocityX;\n this.velocityY = interaction.prevEvent.velocityY;\n }\n else {\n this.timeStamp = new Date().getTime();\n this.dt = this.timeStamp - interaction.prevEvent.timeStamp;\n this.duration = this.timeStamp - interaction.downTimes[0];\n\n if (event instanceof InteractEvent){\n var dx = this[sourceX] - interaction.prevEvent[sourceX],\n dy = this[sourceY] - interaction.prevEvent[sourceY],\n dt = this.dt / 1000;\n\n this.speed = hypot(dx, dy) / dt;\n this.velocityX = dx / dt;\n this.velocityY = dy / dt;\n }\n // if normal move or end event, use previous user event coords\n else {\n // speed and velocity in pixels per second\n this.speed = interaction.pointerDelta[deltaSource].speed;\n this.velocityX = interaction.pointerDelta[deltaSource].vx;\n this.velocityY = interaction.pointerDelta[deltaSource].vy;\n }\n }\n\n if ((ending || phase === 'inertiastart')\n && interaction.prevEvent.speed > 600 && this.timeStamp - interaction.prevEvent.timeStamp < 150){\n var angle = 180 * Math.atan2(interaction.prevEvent.velocityY, interaction.prevEvent.velocityX) / Math.PI,\n overlap = 22.5;\n\n if (angle < 0){\n angle += 360;\n }\n\n var left = 135 - overlap <= angle && angle < 225 + overlap,\n up = 225 - overlap <= angle && angle < 315 + overlap,\n\n right = !left && (315 - overlap <= angle || angle < 45 + overlap),\n down = !up && 45 - overlap <= angle && angle < 135 + overlap;\n\n this.swipe = {\n up: up,\n down: down,\n left: left,\n right: right,\n angle: angle,\n speed: interaction.prevEvent.speed,\n velocity: {\n x: interaction.prevEvent.velocityX,\n y: interaction.prevEvent.velocityY\n }\n };\n }\n }\n\n InteractEvent.prototype = {\n preventDefault: blank,\n stopImmediatePropagation: function(){\n this.immediatePropagationStopped = this.propagationStopped = true;\n },\n stopPropagation: function(){\n this.propagationStopped = true;\n }\n };\n\n function preventOriginalDefault(){\n this.originalEvent.preventDefault();\n }\n\n function getActionCursor(action){\n var cursor = '';\n\n if (action.name === 'drag'){\n cursor = actionCursors.drag;\n }\n if (action.name === 'resize'){\n if (action.axis){\n cursor = actionCursors[action.name + action.axis];\n }\n else if (action.edges){\n var cursorKey = 'resize',\n edgeNames = ['top', 'bottom', 'left', 'right'];\n\n for (var i = 0; i < 4; i++){\n if (action.edges[edgeNames[i]]){\n cursorKey += edgeNames[i];\n }\n }\n\n cursor = actionCursors[cursorKey];\n }\n }\n\n return cursor;\n }\n\n function checkResizeEdge(name, value, page, element, interactableElement, rect, margin){\n // false, '', undefined, null\n if (!value){ return false; }\n\n // true value, use pointer coords and element rect\n if (value === true){\n // if dimensions are negative, \"switch\" edges\n var width = isNumber(rect.width) ? rect.width : rect.right - rect.left,\n height = isNumber(rect.height) ? rect.height : rect.bottom - rect.top;\n\n if (width < 0){\n if (name === 'left'){ name = 'right'; }\n else if (name === 'right'){ name = 'left'; }\n }\n if (height < 0){\n if (name === 'top'){ name = 'bottom'; }\n else if (name === 'bottom'){ name = 'top'; }\n }\n\n if (name === 'left'){ return page.x < ((width >= 0 ? rect.left : rect.right) + margin); }\n if (name === 'top'){ return page.y < ((height >= 0 ? rect.top : rect.bottom) + margin); }\n\n if (name === 'right'){ return page.x > ((width >= 0 ? rect.right : rect.left) - margin); }\n if (name === 'bottom'){ return page.y > ((height >= 0 ? rect.bottom : rect.top) - margin); }\n }\n\n // the remaining checks require an element\n if (!isElement(element)){ return false; }\n\n return isElement(value)\n // the value is an element to use as a resize handle\n ? value === element\n // otherwise check if element matches value as selector\n : matchesUpTo(element, value, interactableElement);\n }\n\n function defaultActionChecker(pointer, interaction, element){\n var rect = this.getRect(element),\n shouldResize = false,\n action = null,\n resizeAxes = null,\n resizeEdges,\n page = extend({}, interaction.curCoords.page),\n options = this.options;\n\n if (!rect){ return null; }\n\n if (actionIsEnabled.resize && options.resize.enabled){\n var resizeOptions = options.resize;\n\n resizeEdges = {\n left: false, right: false, top: false, bottom: false\n };\n\n // if using resize.edges\n if (isObject(resizeOptions.edges)){\n for (var edge in resizeEdges){\n resizeEdges[edge] = checkResizeEdge(edge,\n resizeOptions.edges[edge],\n page,\n interaction._eventTarget,\n element,\n rect,\n resizeOptions.margin || margin);\n }\n\n resizeEdges.left = resizeEdges.left && !resizeEdges.right;\n resizeEdges.top = resizeEdges.top && !resizeEdges.bottom;\n\n shouldResize = resizeEdges.left || resizeEdges.right || resizeEdges.top || resizeEdges.bottom;\n }\n else {\n var right = options.resize.axis !== 'y' && page.x > (rect.right - margin),\n bottom = options.resize.axis !== 'x' && page.y > (rect.bottom - margin);\n\n shouldResize = right || bottom;\n resizeAxes = (right ? 'x' : '') + (bottom ? 'y' : '');\n }\n }\n\n action = shouldResize\n ? 'resize'\n : actionIsEnabled.drag && options.drag.enabled\n ? 'drag'\n : null;\n\n if (actionIsEnabled.gesture\n && interaction.pointerIds.length >= 2\n && !(interaction.dragging || interaction.resizing)){\n action = 'gesture';\n }\n\n if (action){\n return {\n name: action,\n axis: resizeAxes,\n edges: resizeEdges\n };\n }\n\n return null;\n }\n\n // Check if action is enabled globally and the current target supports it\n // If so, return the validated action. Otherwise, return null\n function validateAction(action, interactable){\n if (!isObject(action)){ return null; }\n\n var actionName = action.name,\n options = interactable.options;\n\n if (((actionName === 'resize' && options.resize.enabled)\n || (actionName === 'drag' && options.drag.enabled)\n || (actionName === 'gesture' && options.gesture.enabled))\n && actionIsEnabled[actionName]){\n if (actionName === 'resize' || actionName === 'resizeyx'){\n actionName = 'resizexy';\n }\n\n return action;\n }\n return null;\n }\n\n var listeners = {},\n interactionListeners = [\n 'dragStart', 'dragMove', 'resizeStart', 'resizeMove', 'gestureStart', 'gestureMove',\n 'pointerOver', 'pointerOut', 'pointerHover', 'selectorDown',\n 'pointerDown', 'pointerMove', 'pointerUp', 'pointerCancel', 'pointerEnd',\n 'addPointer', 'removePointer', 'recordPointer', 'autoScrollMove'\n ];\n\n for (var i = 0, len = interactionListeners.length; i < len; i++){\n var name = interactionListeners[i];\n\n listeners[name] = doOnInteractions(name);\n }\n\n // bound to the interactable context when a DOM event\n // listener is added to a selector interactable\n function delegateListener(event, useCapture){\n var fakeEvent = {},\n delegated = delegatedEvents[event.type],\n eventTarget = getActualElement(event.path\n ? event.path[0]\n : event.target),\n element = eventTarget;\n\n useCapture = useCapture ? true : false;\n\n // duplicate the event so that currentTarget can be changed\n for (var prop in event){\n fakeEvent[prop] = event[prop];\n }\n\n fakeEvent.originalEvent = event;\n fakeEvent.preventDefault = preventOriginalDefault;\n\n // climb up document tree looking for selector matches\n while (isElement(element)){\n for (var i = 0; i < delegated.selectors.length; i++){\n var selector = delegated.selectors[i],\n context = delegated.contexts[i];\n\n if (matchesSelector(element, selector)\n && nodeContains(context, eventTarget)\n && nodeContains(context, element)){\n var listeners = delegated.listeners[i];\n\n fakeEvent.currentTarget = element;\n\n for (var j = 0; j < listeners.length; j++){\n if (listeners[j][1] === useCapture){\n listeners[j][0](fakeEvent);\n }\n }\n }\n }\n\n element = parentElement(element);\n }\n }\n\n function delegateUseCapture(event){\n return delegateListener.call(this, event, true);\n }\n\n interactables.indexOfElement = function indexOfElement(element, context){\n context = context || document;\n\n for (var i = 0; i < this.length; i++){\n var interactable = this[i];\n\n if ((interactable.selector === element\n && (interactable._context === context))\n || (!interactable.selector && interactable._element === element)){\n return i;\n }\n }\n return -1;\n };\n\n interactables.get = function interactableGet(element, options){\n return this[this.indexOfElement(element, options && options.context)];\n };\n\n interactables.forEachSelector = function(callback){\n for (var i = 0; i < this.length; i++){\n var interactable = this[i];\n\n if (!interactable.selector){\n continue;\n }\n\n var ret = callback(interactable, interactable.selector, interactable._context, i, this);\n\n if (ret !== undefined){\n return ret;\n }\n }\n };\n\n /* \\\n * interact\n [ method ]\n *\n * The methods of this variable can be used to set elements as\n * interactables and also to change various default settings.\n *\n * Calling it as a function and passing an element or a valid CSS selector\n * string returns an Interactable object which has various methods to\n * configure it.\n *\n - element (Element | string) The HTML or SVG Element to interact with or CSS selector\n = (object) An @Interactable\n *\n > Usage\n | interact(document.getElementById('draggable')).draggable(true);\n |\n | var rectables = interact('rect');\n | rectables\n | .gesturable(true)\n | .on('gesturemove', function (event) {\n | // something cool...\n | })\n | .autoScroll(true);\n \\*/\n function interact(element, options){\n return interactables.get(element, options) || new Interactable(element, options);\n }\n\n /* \\\n * Interactable\n [ property ]\n **\n * Object type returned by @interact\n \\*/\n function Interactable(element, options){\n this._element = element;\n this._iEvents = this._iEvents || {};\n\n var _window;\n\n if (trySelector(element)){\n this.selector = element;\n\n var context = options && options.context;\n\n _window = context ? getWindow(context) : window;\n\n if (context && (_window.Node\n ? context instanceof _window.Node\n : (isElement(context) || context === _window.document))){\n this._context = context;\n }\n }\n else {\n _window = getWindow(element);\n\n if (isElement(element, _window)){\n if (supportsPointerEvent){\n events.add(this._element, pEventTypes.down, listeners.pointerDown);\n events.add(this._element, pEventTypes.move, listeners.pointerHover);\n }\n else {\n events.add(this._element, 'mousedown', listeners.pointerDown);\n events.add(this._element, 'mousemove', listeners.pointerHover);\n events.add(this._element, 'touchstart', listeners.pointerDown);\n events.add(this._element, 'touchmove', listeners.pointerHover);\n }\n }\n }\n\n this._doc = _window.document;\n\n if (!contains(documents, this._doc)){\n listenToDocument(this._doc);\n }\n\n interactables.push(this);\n\n this.set(options);\n }\n\n Interactable.prototype = {\n setOnEvents: function(action, phases){\n if (action === 'drop'){\n if (isFunction(phases.ondrop)){ this.ondrop = phases.ondrop; }\n if (isFunction(phases.ondropactivate)){ this.ondropactivate = phases.ondropactivate; }\n if (isFunction(phases.ondropdeactivate)){ this.ondropdeactivate = phases.ondropdeactivate; }\n if (isFunction(phases.ondragenter)){ this.ondragenter = phases.ondragenter; }\n if (isFunction(phases.ondragleave)){ this.ondragleave = phases.ondragleave; }\n if (isFunction(phases.ondropmove)){ this.ondropmove = phases.ondropmove; }\n }\n else {\n action = 'on' + action;\n\n if (isFunction(phases.onstart)){ this[action + 'start' ] = phases.onstart; }\n if (isFunction(phases.onmove)){ this[action + 'move' ] = phases.onmove; }\n if (isFunction(phases.onend)){ this[action + 'end' ] = phases.onend; }\n if (isFunction(phases.oninertiastart)){ this[action + 'inertiastart' ] = phases.oninertiastart; }\n }\n\n return this;\n },\n\n /* \\\n * Interactable.draggable\n [ method ]\n *\n * Gets or sets whether drag actions can be performed on the\n * Interactable\n *\n = (boolean) Indicates if this can be the target of drag events\n | var isDraggable = interact('ul li').draggable();\n * or\n - options (boolean | object) #optional true/false or An object with event listeners to be fired on drag events (object makes the Interactable draggable)\n = (object) This Interactable\n | interact(element).draggable({\n | onstart: function (event) {},\n | onmove : function (event) {},\n | onend : function (event) {},\n |\n | // the axis in which the first movement must be\n | // for the drag sequence to start\n | // 'xy' by default - any direction\n | axis: 'x' || 'y' || 'xy',\n |\n | // max number of drags that can happen concurrently\n | // with elements of this Interactable. Infinity by default\n | max: Infinity,\n |\n | // max number of drags that can target the same element+Interactable\n | // 1 by default\n | maxPerElement: 2\n | });\n \\*/\n draggable: function(options){\n if (isObject(options)){\n this.options.drag.enabled = options.enabled === false ? false : true;\n this.setPerAction('drag', options);\n this.setOnEvents('drag', options);\n\n if (/^x$|^y$|^xy$/.test(options.axis)){\n this.options.drag.axis = options.axis;\n }\n else if (options.axis === null){\n delete this.options.drag.axis;\n }\n\n return this;\n }\n\n if (isBool(options)){\n this.options.drag.enabled = options;\n\n return this;\n }\n\n return this.options.drag;\n },\n\n setPerAction: function(action, options){\n // for all the default per-action options\n for (var option in options){\n // if this option exists for this action\n if (option in defaultOptions[action]){\n // if the option in the options arg is an object value\n if (isObject(options[option])){\n // duplicate the object\n this.options[action][option] = extend(this.options[action][option] || {}, options[option]);\n\n if (isObject(defaultOptions.perAction[option]) && 'enabled' in defaultOptions.perAction[option]){\n this.options[action][option].enabled = options[option].enabled === false ? false : true;\n }\n }\n else if (isBool(options[option]) && isObject(defaultOptions.perAction[option])){\n this.options[action][option].enabled = options[option];\n }\n else if (options[option] !== undefined){\n // or if it's not undefined, do a plain assignment\n this.options[action][option] = options[option];\n }\n }\n }\n },\n\n /* \\\n * Interactable.dropzone\n [ method ]\n *\n * Returns or sets whether elements can be dropped onto this\n * Interactable to trigger drop events\n *\n * Dropzones can receive the following events:\n * - `dropactivate` and `dropdeactivate` when an acceptable drag starts and ends\n * - `dragenter` and `dragleave` when a draggable enters and leaves the dropzone\n * - `dragmove` when a draggable that has entered the dropzone is moved\n * - `drop` when a draggable is dropped into this dropzone\n *\n * Use the `accept` option to allow only elements that match the given CSS selector or element.\n *\n * Use the `overlap` option to set how drops are checked for. The allowed values are:\n * - `'pointer'`, the pointer must be over the dropzone (default)\n * - `'center'`, the draggable element's center must be over the dropzone\n * - a number from 0-1 which is the `(intersection area) / (draggable area)`.\n * e.g. `0.5` for drop to happen when half of the area of the\n * draggable is over the dropzone\n *\n - options (boolean | object | null) #optional The new value to be set.\n | interact('.drop').dropzone({\n | accept: '.can-drop' || document.getElementById('single-drop'),\n | overlap: 'pointer' || 'center' || zeroToOne\n | }\n = (boolean | object) The current setting or this Interactable\n \\*/\n dropzone: function(options){\n if (isObject(options)){\n this.options.drop.enabled = options.enabled === false ? false : true;\n this.setOnEvents('drop', options);\n\n if (/^(pointer|center)$/.test(options.overlap)){\n this.options.drop.overlap = options.overlap;\n }\n else if (isNumber(options.overlap)){\n this.options.drop.overlap = Math.max(Math.min(1, options.overlap), 0);\n }\n if ('accept' in options){\n this.options.drop.accept = options.accept;\n }\n if ('checker' in options){\n this.options.drop.checker = options.checker;\n }\n\n return this;\n }\n\n if (isBool(options)){\n this.options.drop.enabled = options;\n\n return this;\n }\n\n return this.options.drop;\n },\n\n dropCheck: function(dragEvent, event, draggable, draggableElement, dropElement, rect){\n var dropped = false;\n\n // if the dropzone has no rect (eg. display: none)\n // call the custom dropChecker or just return false\n if (!(rect = rect || this.getRect(dropElement))){\n return (this.options.drop.checker\n ? this.options.drop.checker(dragEvent, event, dropped, this, dropElement, draggable, draggableElement)\n : false);\n }\n\n var dropOverlap = this.options.drop.overlap;\n\n if (dropOverlap === 'pointer'){\n var page = getPageXY(dragEvent),\n origin = getOriginXY(draggable, draggableElement),\n horizontal,\n vertical;\n\n page.x += origin.x;\n page.y += origin.y;\n\n horizontal = (page.x > rect.left) && (page.x < rect.right);\n vertical = (page.y > rect.top) && (page.y < rect.bottom);\n\n dropped = horizontal && vertical;\n }\n\n var dragRect = draggable.getRect(draggableElement);\n\n if (dropOverlap === 'center'){\n var cx = dragRect.left + dragRect.width / 2,\n cy = dragRect.top + dragRect.height / 2;\n\n dropped = cx >= rect.left && cx <= rect.right && cy >= rect.top && cy <= rect.bottom;\n }\n\n if (isNumber(dropOverlap)){\n var overlapArea = (Math.max(0, Math.min(rect.right, dragRect.right) - Math.max(rect.left, dragRect.left))\n * Math.max(0, Math.min(rect.bottom, dragRect.bottom) - Math.max(rect.top, dragRect.top))),\n overlapRatio = overlapArea / (dragRect.width * dragRect.height);\n\n dropped = overlapRatio >= dropOverlap;\n }\n\n if (this.options.drop.checker){\n dropped = this.options.drop.checker(dragEvent, event, dropped, this, dropElement, draggable, draggableElement);\n }\n\n return dropped;\n },\n\n /* \\\n * Interactable.dropChecker\n [ method ]\n *\n * DEPRECATED. Use interactable.dropzone({ checker: function... }) instead.\n *\n * Gets or sets the function used to check if a dragged element is\n * over this Interactable.\n *\n - checker (function) #optional The function that will be called when checking for a drop\n = (Function | Interactable) The checker function or this Interactable\n *\n * The checker function takes the following arguments:\n *\n - dragEvent (InteractEvent) The related dragmove or dragend event\n - event (TouchEvent | PointerEvent | MouseEvent) The user move/up/end Event related to the dragEvent\n - dropped (boolean) The value from the default drop checker\n - dropzone (Interactable) The dropzone interactable\n - dropElement (Element) The dropzone element\n - draggable (Interactable) The Interactable being dragged\n - draggableElement (Element) The actual element that's being dragged\n *\n > Usage:\n | interact(target)\n | .dropChecker(function(dragEvent, // related dragmove or dragend event\n | event, // TouchEvent/PointerEvent/MouseEvent\n | dropped, // bool result of the default checker\n | dropzone, // dropzone Interactable\n | dropElement, // dropzone elemnt\n | draggable, // draggable Interactable\n | draggableElement) {// draggable element\n |\n | return dropped && event.target.hasAttribute('allow-drop');\n | }\n \\*/\n dropChecker: function(checker){\n if (isFunction(checker)){\n this.options.drop.checker = checker;\n\n return this;\n }\n if (checker === null){\n delete this.options.getRect;\n\n return this;\n }\n\n return this.options.drop.checker;\n },\n\n /* \\\n * Interactable.accept\n [ method ]\n *\n * Deprecated. add an `accept` property to the options object passed to\n * @Interactable.dropzone instead.\n *\n * Gets or sets the Element or CSS selector match that this\n * Interactable accepts if it is a dropzone.\n *\n - newValue (Element | string | null) #optional\n * If it is an Element, then only that element can be dropped into this dropzone.\n * If it is a string, the element being dragged must match it as a selector.\n * If it is null, the accept options is cleared - it accepts any element.\n *\n = (string | Element | null | Interactable) The current accept option if given `undefined` or this Interactable\n \\*/\n accept: function(newValue){\n if (isElement(newValue)){\n this.options.drop.accept = newValue;\n\n return this;\n }\n\n // test if it is a valid CSS selector\n if (trySelector(newValue)){\n this.options.drop.accept = newValue;\n\n return this;\n }\n\n if (newValue === null){\n delete this.options.drop.accept;\n\n return this;\n }\n\n return this.options.drop.accept;\n },\n\n /* \\\n * Interactable.resizable\n [ method ]\n *\n * Gets or sets whether resize actions can be performed on the\n * Interactable\n *\n = (boolean) Indicates if this can be the target of resize elements\n | var isResizeable = interact('input[type=text]').resizable();\n * or\n - options (boolean | object) #optional true/false or An object with event listeners to be fired on resize events (object makes the Interactable resizable)\n = (object) This Interactable\n | interact(element).resizable({\n | onstart: function (event) {},\n | onmove : function (event) {},\n | onend : function (event) {},\n |\n | edges: {\n | top : true, // Use pointer coords to check for resize.\n | left : false, // Disable resizing from left edge.\n | bottom: '.resize-s',// Resize if pointer target matches selector\n | right : handleEl // Resize if pointer target is the given Element\n | },\n |\n | // Width and height can be adjusted independently. When `true`, width and\n | // height are adjusted at a 1:1 ratio.\n | square: false,\n |\n | // Width and height can be adjusted independently. When `true`, width and\n | // height maintain the aspect ratio they had when resizing started.\n | preserveAspectRatio: false,\n |\n | // a value of 'none' will limit the resize rect to a minimum of 0x0\n | // 'negate' will allow the rect to have negative width/height\n | // 'reposition' will keep the width/height positive by swapping\n | // the top and bottom edges and/or swapping the left and right edges\n | invert: 'none' || 'negate' || 'reposition'\n |\n | // limit multiple resizes.\n | // See the explanation in the @Interactable.draggable example\n | max: Infinity,\n | maxPerElement: 1,\n | });\n \\*/\n resizable: function(options){\n if (isObject(options)){\n this.options.resize.enabled = options.enabled === false ? false : true;\n this.setPerAction('resize', options);\n this.setOnEvents('resize', options);\n\n if (/^x$|^y$|^xy$/.test(options.axis)){\n this.options.resize.axis = options.axis;\n }\n else if (options.axis === null){\n this.options.resize.axis = defaultOptions.resize.axis;\n }\n\n if (isBool(options.preserveAspectRatio)){\n this.options.resize.preserveAspectRatio = options.preserveAspectRatio;\n }\n else if (isBool(options.square)){\n this.options.resize.square = options.square;\n }\n\n return this;\n }\n if (isBool(options)){\n this.options.resize.enabled = options;\n\n return this;\n }\n return this.options.resize;\n },\n\n /* \\\n * Interactable.squareResize\n [ method ]\n *\n * Deprecated. Add a `square: true || false` property to @Interactable.resizable instead\n *\n * Gets or sets whether resizing is forced 1:1 aspect\n *\n = (boolean) Current setting\n *\n * or\n *\n - newValue (boolean) #optional\n = (object) this Interactable\n \\*/\n squareResize: function(newValue){\n if (isBool(newValue)){\n this.options.resize.square = newValue;\n\n return this;\n }\n\n if (newValue === null){\n delete this.options.resize.square;\n\n return this;\n }\n\n return this.options.resize.square;\n },\n\n /* \\\n * Interactable.gesturable\n [ method ]\n *\n * Gets or sets whether multitouch gestures can be performed on the\n * Interactable's element\n *\n = (boolean) Indicates if this can be the target of gesture events\n | var isGestureable = interact(element).gesturable();\n * or\n - options (boolean | object) #optional true/false or An object with event listeners to be fired on gesture events (makes the Interactable gesturable)\n = (object) this Interactable\n | interact(element).gesturable({\n | onstart: function (event) {},\n | onmove : function (event) {},\n | onend : function (event) {},\n |\n | // limit multiple gestures.\n | // See the explanation in @Interactable.draggable example\n | max: Infinity,\n | maxPerElement: 1,\n | });\n \\*/\n gesturable: function(options){\n if (isObject(options)){\n this.options.gesture.enabled = options.enabled === false ? false : true;\n this.setPerAction('gesture', options);\n this.setOnEvents('gesture', options);\n\n return this;\n }\n\n if (isBool(options)){\n this.options.gesture.enabled = options;\n\n return this;\n }\n\n return this.options.gesture;\n },\n\n /* \\\n * Interactable.autoScroll\n [ method ]\n **\n * Deprecated. Add an `autoscroll` property to the options object\n * passed to @Interactable.draggable or @Interactable.resizable instead.\n *\n * Returns or sets whether dragging and resizing near the edges of the\n * window/container trigger autoScroll for this Interactable\n *\n = (object) Object with autoScroll properties\n *\n * or\n *\n - options (object | boolean) #optional\n * options can be:\n * - an object with margin, distance and interval properties,\n * - true or false to enable or disable autoScroll or\n = (Interactable) this Interactable\n \\*/\n autoScroll: function(options){\n if (isObject(options)){\n options = extend({ actions: ['drag', 'resize']}, options);\n }\n else if (isBool(options)){\n options = { actions: ['drag', 'resize'], enabled: options };\n }\n\n return this.setOptions('autoScroll', options);\n },\n\n /* \\\n * Interactable.snap\n [ method ]\n **\n * Deprecated. Add a `snap` property to the options object passed\n * to @Interactable.draggable or @Interactable.resizable instead.\n *\n * Returns or sets if and how action coordinates are snapped. By\n * default, snapping is relative to the pointer coordinates. You can\n * change this by setting the\n * [`elementOrigin`](https://github.com/taye/interact.js/pull/72).\n **\n = (boolean | object) `false` if snap is disabled; object with snap properties if snap is enabled\n **\n * or\n **\n - options (object | boolean | null) #optional\n = (Interactable) this Interactable\n > Usage\n | interact(document.querySelector('#thing')).snap({\n | targets: [\n | // snap to this specific point\n | {\n | x: 100,\n | y: 100,\n | range: 25\n | },\n | // give this function the x and y page coords and snap to the object returned\n | function (x, y) {\n | return {\n | x: x,\n | y: (75 + 50 * Math.sin(x * 0.04)),\n | range: 40\n | };\n | },\n | // create a function that snaps to a grid\n | interact.createSnapGrid({\n | x: 50,\n | y: 50,\n | range: 10, // optional\n | offset: { x: 5, y: 10 } // optional\n | })\n | ],\n | // do not snap during normal movement.\n | // Instead, trigger only one snapped move event\n | // immediately before the end event.\n | endOnly: true,\n |\n | relativePoints: [\n | { x: 0, y: 0 }, // snap relative to the top left of the element\n | { x: 1, y: 1 }, // and also to the bottom right\n | ],\n |\n | // offset the snap target coordinates\n | // can be an object with x/y or 'startCoords'\n | offset: { x: 50, y: 50 }\n | }\n | });\n \\*/\n snap: function(options){\n var ret = this.setOptions('snap', options);\n\n if (ret === this){ return this; }\n\n return ret.drag;\n },\n\n setOptions: function(option, options){\n var actions = options && isArray(options.actions)\n ? options.actions\n : ['drag'];\n\n var i;\n\n if (isObject(options) || isBool(options)){\n for (i = 0; i < actions.length; i++){\n var action = /resize/.test(actions[i]) ? 'resize' : actions[i];\n\n if (!isObject(this.options[action])){ continue; }\n\n var thisOption = this.options[action][option];\n\n if (isObject(options)){\n extend(thisOption, options);\n thisOption.enabled = options.enabled === false ? false : true;\n\n if (option === 'snap'){\n if (thisOption.mode === 'grid'){\n thisOption.targets = [\n interact.createSnapGrid(extend({\n offset: thisOption.gridOffset || { x: 0, y: 0 }\n }, thisOption.grid || {}))\n ];\n }\n else if (thisOption.mode === 'anchor'){\n thisOption.targets = thisOption.anchors;\n }\n else if (thisOption.mode === 'path'){\n thisOption.targets = thisOption.paths;\n }\n\n if ('elementOrigin' in options){\n thisOption.relativePoints = [options.elementOrigin];\n }\n }\n }\n else if (isBool(options)){\n thisOption.enabled = options;\n }\n }\n\n return this;\n }\n\n var ret = {},\n allActions = ['drag', 'resize', 'gesture'];\n\n for (i = 0; i < allActions.length; i++){\n if (option in defaultOptions[allActions[i]]){\n ret[allActions[i]] = this.options[allActions[i]][option];\n }\n }\n\n return ret;\n },\n\n /* \\\n * Interactable.inertia\n [ method ]\n **\n * Deprecated. Add an `inertia` property to the options object passed\n * to @Interactable.draggable or @Interactable.resizable instead.\n *\n * Returns or sets if and how events continue to run after the pointer is released\n **\n = (boolean | object) `false` if inertia is disabled; `object` with inertia properties if inertia is enabled\n **\n * or\n **\n - options (object | boolean | null) #optional\n = (Interactable) this Interactable\n > Usage\n | // enable and use default settings\n | interact(element).inertia(true);\n |\n | // enable and use custom settings\n | interact(element).inertia({\n | // value greater than 0\n | // high values slow the object down more quickly\n | resistance : 16,\n |\n | // the minimum launch speed (pixels per second) that results in inertia start\n | minSpeed : 200,\n |\n | // inertia will stop when the object slows down to this speed\n | endSpeed : 20,\n |\n | // boolean; should actions be resumed when the pointer goes down during inertia\n | allowResume : true,\n |\n | // boolean; should the jump when resuming from inertia be ignored in event.dx/dy\n | zeroResumeDelta: false,\n |\n | // if snap/restrict are set to be endOnly and inertia is enabled, releasing\n | // the pointer without triggering inertia will animate from the release\n | // point to the snaped/restricted point in the given amount of time (ms)\n | smoothEndDuration: 300,\n |\n | // an array of action types that can have inertia (no gesture)\n | actions : ['drag', 'resize']\n | });\n |\n | // reset custom settings and use all defaults\n | interact(element).inertia(null);\n \\*/\n inertia: function(options){\n var ret = this.setOptions('inertia', options);\n\n if (ret === this){ return this; }\n\n return ret.drag;\n },\n\n getAction: function(pointer, event, interaction, element){\n var action = this.defaultActionChecker(pointer, interaction, element);\n\n if (this.options.actionChecker){\n return this.options.actionChecker(pointer, event, action, this, element, interaction);\n }\n\n return action;\n },\n\n defaultActionChecker: defaultActionChecker,\n\n /* \\\n * Interactable.actionChecker\n [ method ]\n *\n * Gets or sets the function used to check action to be performed on\n * pointerDown\n *\n - checker (function | null) #optional A function which takes a pointer event, defaultAction string, interactable, element and interaction as parameters and returns an object with name property 'drag' 'resize' or 'gesture' and optionally an `edges` object with boolean 'top', 'left', 'bottom' and right props.\n = (Function | Interactable) The checker function or this Interactable\n *\n | interact('.resize-drag')\n | .resizable(true)\n | .draggable(true)\n | .actionChecker(function (pointer, event, action, interactable, element, interaction) {\n |\n | if (interact.matchesSelector(event.target, '.drag-handle') {\n | // force drag with handle target\n | action.name = drag;\n | }\n | else {\n | // resize from the top and right edges\n | action.name = 'resize';\n | action.edges = { top: true, right: true };\n | }\n |\n | return action;\n | });\n \\*/\n actionChecker: function(checker){\n if (isFunction(checker)){\n this.options.actionChecker = checker;\n\n return this;\n }\n\n if (checker === null){\n delete this.options.actionChecker;\n\n return this;\n }\n\n return this.options.actionChecker;\n },\n\n /* \\\n * Interactable.getRect\n [ method ]\n *\n * The default function to get an Interactables bounding rect. Can be\n * overridden using @Interactable.rectChecker.\n *\n - element (Element) #optional The element to measure.\n = (object) The object's bounding rectangle.\n o {\n o top : 0,\n o left : 0,\n o bottom: 0,\n o right : 0,\n o width : 0,\n o height: 0\n o }\n \\*/\n getRect: function rectCheck(element){\n element = element || this._element;\n\n if (this.selector && !(isElement(element))){\n element = this._context.querySelector(this.selector);\n }\n\n return getElementRect(element);\n },\n\n /* \\\n * Interactable.rectChecker\n [ method ]\n *\n * Returns or sets the function used to calculate the interactable's\n * element's rectangle\n *\n - checker (function) #optional A function which returns this Interactable's bounding rectangle. See @Interactable.getRect\n = (function | object) The checker function or this Interactable\n \\*/\n rectChecker: function(checker){\n if (isFunction(checker)){\n this.getRect = checker;\n\n return this;\n }\n\n if (checker === null){\n delete this.options.getRect;\n\n return this;\n }\n\n return this.getRect;\n },\n\n /* \\\n * Interactable.styleCursor\n [ method ]\n *\n * Returns or sets whether the action that would be performed when the\n * mouse on the element are checked on `mousemove` so that the cursor\n * may be styled appropriately\n *\n - newValue (boolean) #optional\n = (boolean | Interactable) The current setting or this Interactable\n \\*/\n styleCursor: function(newValue){\n if (isBool(newValue)){\n this.options.styleCursor = newValue;\n\n return this;\n }\n\n if (newValue === null){\n delete this.options.styleCursor;\n\n return this;\n }\n\n return this.options.styleCursor;\n },\n\n /* \\\n * Interactable.preventDefault\n [ method ]\n *\n * Returns or sets whether to prevent the browser's default behaviour\n * in response to pointer events. Can be set to:\n * - `'always'` to always prevent\n * - `'never'` to never prevent\n * - `'auto'` to let interact.js try to determine what would be best\n *\n - newValue (string) #optional `true`, `false` or `'auto'`\n = (string | Interactable) The current setting or this Interactable\n \\*/\n preventDefault: function(newValue){\n if (/^(always|never|auto)$/.test(newValue)){\n this.options.preventDefault = newValue;\n return this;\n }\n\n if (isBool(newValue)){\n this.options.preventDefault = newValue ? 'always' : 'never';\n return this;\n }\n\n return this.options.preventDefault;\n },\n\n /* \\\n * Interactable.origin\n [ method ]\n *\n * Gets or sets the origin of the Interactable's element. The x and y\n * of the origin will be subtracted from action event coordinates.\n *\n - origin (object | string) #optional An object eg. { x: 0, y: 0 } or string 'parent', 'self' or any CSS selector\n * OR\n - origin (Element) #optional An HTML or SVG Element whose rect will be used\n **\n = (object) The current origin or this Interactable\n \\*/\n origin: function(newValue){\n if (trySelector(newValue)){\n this.options.origin = newValue;\n return this;\n }\n else if (isObject(newValue)){\n this.options.origin = newValue;\n return this;\n }\n\n return this.options.origin;\n },\n\n /* \\\n * Interactable.deltaSource\n [ method ]\n *\n * Returns or sets the mouse coordinate types used to calculate the\n * movement of the pointer.\n *\n - newValue (string) #optional Use 'client' if you will be scrolling while interacting; Use 'page' if you want autoScroll to work\n = (string | object) The current deltaSource or this Interactable\n \\*/\n deltaSource: function(newValue){\n if (newValue === 'page' || newValue === 'client'){\n this.options.deltaSource = newValue;\n\n return this;\n }\n\n return this.options.deltaSource;\n },\n\n /* \\\n * Interactable.restrict\n [ method ]\n **\n * Deprecated. Add a `restrict` property to the options object passed to\n * @Interactable.draggable, @Interactable.resizable or @Interactable.gesturable instead.\n *\n * Returns or sets the rectangles within which actions on this\n * interactable (after snap calculations) are restricted. By default,\n * restricting is relative to the pointer coordinates. You can change\n * this by setting the\n * [`elementRect`](https://github.com/taye/interact.js/pull/72).\n **\n - options (object) #optional an object with keys drag, resize, and/or gesture whose values are rects, Elements, CSS selectors, or 'parent' or 'self'\n = (object) The current restrictions object or this Interactable\n **\n | interact(element).restrict({\n | // the rect will be `interact.getElementRect(element.parentNode)`\n | drag: element.parentNode,\n |\n | // x and y are relative to the the interactable's origin\n | resize: { x: 100, y: 100, width: 200, height: 200 }\n | })\n |\n | interact('.draggable').restrict({\n | // the rect will be the selected element's parent\n | drag: 'parent',\n |\n | // do not restrict during normal movement.\n | // Instead, trigger only one restricted move event\n | // immediately before the end event.\n | endOnly: true,\n |\n | // https://github.com/taye/interact.js/pull/72#issue-41813493\n | elementRect: { top: 0, left: 0, bottom: 1, right: 1 }\n | });\n \\*/\n restrict: function(options){\n if (!isObject(options)){\n return this.setOptions('restrict', options);\n }\n\n var actions = ['drag', 'resize', 'gesture'],\n ret;\n\n for (var i = 0; i < actions.length; i++){\n var action = actions[i];\n\n if (action in options){\n var perAction = extend({\n actions: [action],\n restriction: options[action]\n }, options);\n\n ret = this.setOptions('restrict', perAction);\n }\n }\n\n return ret;\n },\n\n /* \\\n * Interactable.context\n [ method ]\n *\n * Gets the selector context Node of the Interactable. The default is `window.document`.\n *\n = (Node) The context Node of this Interactable\n **\n \\*/\n context: function(){\n return this._context;\n },\n\n _context: document,\n\n /* \\\n * Interactable.ignoreFrom\n [ method ]\n *\n * If the target of the `mousedown`, `pointerdown` or `touchstart`\n * event or any of it's parents match the given CSS selector or\n * Element, no drag/resize/gesture is started.\n *\n - newValue (string | Element | null) #optional a CSS selector string, an Element or `null` to not ignore any elements\n = (string | Element | object) The current ignoreFrom value or this Interactable\n **\n | interact(element, { ignoreFrom: document.getElementById('no-action') });\n | // or\n | interact(element).ignoreFrom('input, textarea, a');\n \\*/\n ignoreFrom: function(newValue){\n if (trySelector(newValue)){ // CSS selector to match event.target\n this.options.ignoreFrom = newValue;\n return this;\n }\n\n if (isElement(newValue)){ // specific element\n this.options.ignoreFrom = newValue;\n return this;\n }\n\n return this.options.ignoreFrom;\n },\n\n /* \\\n * Interactable.allowFrom\n [ method ]\n *\n * A drag/resize/gesture is started only If the target of the\n * `mousedown`, `pointerdown` or `touchstart` event or any of it's\n * parents match the given CSS selector or Element.\n *\n - newValue (string | Element | null) #optional a CSS selector string, an Element or `null` to allow from any element\n = (string | Element | object) The current allowFrom value or this Interactable\n **\n | interact(element, { allowFrom: document.getElementById('drag-handle') });\n | // or\n | interact(element).allowFrom('.handle');\n \\*/\n allowFrom: function(newValue){\n if (trySelector(newValue)){ // CSS selector to match event.target\n this.options.allowFrom = newValue;\n return this;\n }\n\n if (isElement(newValue)){ // specific element\n this.options.allowFrom = newValue;\n return this;\n }\n\n return this.options.allowFrom;\n },\n\n /* \\\n * Interactable.element\n [ method ]\n *\n * If this is not a selector Interactable, it returns the element this\n * interactable represents\n *\n = (Element) HTML / SVG Element\n \\*/\n element: function(){\n return this._element;\n },\n\n /* \\\n * Interactable.fire\n [ method ]\n *\n * Calls listeners for the given InteractEvent type bound globally\n * and directly to this Interactable\n *\n - iEvent (InteractEvent) The InteractEvent object to be fired on this Interactable\n = (Interactable) this Interactable\n \\*/\n fire: function(iEvent){\n if (!(iEvent && iEvent.type) || !contains(eventTypes, iEvent.type)){\n return this;\n }\n\n var listeners,\n i,\n len,\n onEvent = 'on' + iEvent.type,\n funcName = '';\n\n // Interactable#on() listeners\n if (iEvent.type in this._iEvents){\n listeners = this._iEvents[iEvent.type];\n\n for (i = 0, len = listeners.length; i < len && !iEvent.immediatePropagationStopped; i++){\n funcName = listeners[i].name;\n listeners[i](iEvent);\n }\n }\n\n // interactable.onevent listener\n if (isFunction(this[onEvent])){\n funcName = this[onEvent].name;\n this[onEvent](iEvent);\n }\n\n // interact.on() listeners\n if (iEvent.type in globalEvents && (listeners = globalEvents[iEvent.type])){\n for (i = 0, len = listeners.length; i < len && !iEvent.immediatePropagationStopped; i++){\n funcName = listeners[i].name;\n listeners[i](iEvent);\n }\n }\n\n return this;\n },\n\n /* \\\n * Interactable.on\n [ method ]\n *\n * Binds a listener for an InteractEvent or DOM event.\n *\n - eventType (string | array | object) The types of events to listen for\n - listener (function) The function to be called on the given event(s)\n - useCapture (boolean) #optional useCapture flag for addEventListener\n = (object) This Interactable\n \\*/\n on: function(eventType, listener, useCapture){\n var i;\n\n if (isString(eventType) && eventType.search(' ') !== -1){\n eventType = eventType.trim().split(/ +/);\n }\n\n if (isArray(eventType)){\n for (i = 0; i < eventType.length; i++){\n this.on(eventType[i], listener, useCapture);\n }\n\n return this;\n }\n\n if (isObject(eventType)){\n for (var prop in eventType){\n this.on(prop, eventType[prop], listener);\n }\n\n return this;\n }\n\n if (eventType === 'wheel'){\n eventType = wheelEvent;\n }\n\n // convert to boolean\n useCapture = useCapture ? true : false;\n\n if (contains(eventTypes, eventType)){\n // if this type of event was never bound to this Interactable\n if (!(eventType in this._iEvents)){\n this._iEvents[eventType] = [listener];\n }\n else {\n this._iEvents[eventType].push(listener);\n }\n }\n // delegated event for selector\n else if (this.selector){\n if (!delegatedEvents[eventType]){\n delegatedEvents[eventType] = {\n selectors: [],\n contexts: [],\n listeners: []\n };\n\n // add delegate listener functions\n for (i = 0; i < documents.length; i++){\n events.add(documents[i], eventType, delegateListener);\n events.add(documents[i], eventType, delegateUseCapture, true);\n }\n }\n\n var delegated = delegatedEvents[eventType],\n index;\n\n for (index = delegated.selectors.length - 1; index >= 0; index--){\n if (delegated.selectors[index] === this.selector\n && delegated.contexts[index] === this._context){\n break;\n }\n }\n\n if (index === -1){\n index = delegated.selectors.length;\n\n delegated.selectors.push(this.selector);\n delegated.contexts.push(this._context);\n delegated.listeners.push([]);\n }\n\n // keep listener and useCapture flag\n delegated.listeners[index].push([listener, useCapture]);\n }\n else {\n events.add(this._element, eventType, listener, useCapture);\n }\n\n return this;\n },\n\n /* \\\n * Interactable.off\n [ method ]\n *\n * Removes an InteractEvent or DOM event listener\n *\n - eventType (string | array | object) The types of events that were listened for\n - listener (function) The listener function to be removed\n - useCapture (boolean) #optional useCapture flag for removeEventListener\n = (object) This Interactable\n \\*/\n off: function(eventType, listener, useCapture){\n var i;\n\n if (isString(eventType) && eventType.search(' ') !== -1){\n eventType = eventType.trim().split(/ +/);\n }\n\n if (isArray(eventType)){\n for (i = 0; i < eventType.length; i++){\n this.off(eventType[i], listener, useCapture);\n }\n\n return this;\n }\n\n if (isObject(eventType)){\n for (var prop in eventType){\n this.off(prop, eventType[prop], listener);\n }\n\n return this;\n }\n\n var eventList,\n index = -1;\n\n // convert to boolean\n useCapture = useCapture ? true : false;\n\n if (eventType === 'wheel'){\n eventType = wheelEvent;\n }\n\n // if it is an action event type\n if (contains(eventTypes, eventType)){\n eventList = this._iEvents[eventType];\n\n if (eventList && (index = indexOf(eventList, listener)) !== -1){\n this._iEvents[eventType].splice(index, 1);\n }\n }\n // delegated event\n else if (this.selector){\n var delegated = delegatedEvents[eventType],\n matchFound = false;\n\n if (!delegated){ return this; }\n\n // count from last index of delegated to 0\n for (index = delegated.selectors.length - 1; index >= 0; index--){\n // look for matching selector and context Node\n if (delegated.selectors[index] === this.selector\n && delegated.contexts[index] === this._context){\n var listeners = delegated.listeners[index];\n\n // each item of the listeners array is an array: [function, useCaptureFlag]\n for (i = listeners.length - 1; i >= 0; i--){\n var fn = listeners[i][0],\n useCap = listeners[i][1];\n\n // check if the listener functions and useCapture flags match\n if (fn === listener && useCap === useCapture){\n // remove the listener from the array of listeners\n listeners.splice(i, 1);\n\n // if all listeners for this interactable have been removed\n // remove the interactable from the delegated arrays\n if (!listeners.length){\n delegated.selectors.splice(index, 1);\n delegated.contexts.splice(index, 1);\n delegated.listeners.splice(index, 1);\n\n // remove delegate function from context\n events.remove(this._context, eventType, delegateListener);\n events.remove(this._context, eventType, delegateUseCapture, true);\n\n // remove the arrays if they are empty\n if (!delegated.selectors.length){\n delegatedEvents[eventType] = null;\n }\n }\n\n // only remove one listener\n matchFound = true;\n break;\n }\n }\n\n if (matchFound){ break; }\n }\n }\n }\n // remove listener from this Interatable's element\n else {\n events.remove(this._element, eventType, listener, useCapture);\n }\n\n return this;\n },\n\n /* \\\n * Interactable.set\n [ method ]\n *\n * Reset the options of this Interactable\n - options (object) The new settings to apply\n = (object) This Interactable\n \\*/\n set: function(options){\n if (!isObject(options)){\n options = {};\n }\n\n this.options = extend({}, defaultOptions.base);\n\n var i,\n actions = ['drag', 'drop', 'resize', 'gesture'],\n methods = ['draggable', 'dropzone', 'resizable', 'gesturable'],\n perActions = extend(extend({}, defaultOptions.perAction), options[action] || {});\n\n for (i = 0; i < actions.length; i++){\n var action = actions[i];\n\n this.options[action] = extend({}, defaultOptions[action]);\n\n this.setPerAction(action, perActions);\n\n this[methods[i]](options[action]);\n }\n\n var settings = [\n 'accept', 'actionChecker', 'allowFrom', 'deltaSource',\n 'dropChecker', 'ignoreFrom', 'origin', 'preventDefault',\n 'rectChecker', 'styleCursor'\n ];\n\n for (i = 0, len = settings.length; i < len; i++){\n var setting = settings[i];\n\n this.options[setting] = defaultOptions.base[setting];\n\n if (setting in options){\n this[setting](options[setting]);\n }\n }\n\n return this;\n },\n\n /* \\\n * Interactable.unset\n [ method ]\n *\n * Remove this interactable from the list of interactables and remove\n * it's drag, drop, resize and gesture capabilities\n *\n = (object) @interact\n \\*/\n unset: function(){\n events.remove(this._element, 'all');\n\n if (!isString(this.selector)){\n events.remove(this, 'all');\n if (this.options.styleCursor){\n this._element.style.cursor = '';\n }\n }\n else {\n // remove delegated events\n for (var type in delegatedEvents){\n var delegated = delegatedEvents[type];\n\n for (var i = 0; i < delegated.selectors.length; i++){\n if (delegated.selectors[i] === this.selector\n && delegated.contexts[i] === this._context){\n delegated.selectors.splice(i, 1);\n delegated.contexts.splice(i, 1);\n delegated.listeners.splice(i, 1);\n\n // remove the arrays if they are empty\n if (!delegated.selectors.length){\n delegatedEvents[type] = null;\n }\n }\n\n events.remove(this._context, type, delegateListener);\n events.remove(this._context, type, delegateUseCapture, true);\n\n break;\n }\n }\n }\n\n this.dropzone(false);\n\n interactables.splice(indexOf(interactables, this), 1);\n\n return interact;\n }\n };\n\n function warnOnce(method, message){\n var warned = false;\n\n return function(){\n if (!warned){\n window.console.warn(message);\n warned = true;\n }\n\n return method.apply(this, arguments);\n };\n }\n\n Interactable.prototype.snap = warnOnce(Interactable.prototype.snap,\n 'Interactable#snap is deprecated. See the new documentation for snapping at http://interactjs.io/docs/snapping');\n Interactable.prototype.restrict = warnOnce(Interactable.prototype.restrict,\n 'Interactable#restrict is deprecated. See the new documentation for resticting at http://interactjs.io/docs/restriction');\n Interactable.prototype.inertia = warnOnce(Interactable.prototype.inertia,\n 'Interactable#inertia is deprecated. See the new documentation for inertia at http://interactjs.io/docs/inertia');\n Interactable.prototype.autoScroll = warnOnce(Interactable.prototype.autoScroll,\n 'Interactable#autoScroll is deprecated. See the new documentation for autoScroll at http://interactjs.io/docs/#autoscroll');\n Interactable.prototype.squareResize = warnOnce(Interactable.prototype.squareResize,\n 'Interactable#squareResize is deprecated. See http://interactjs.io/docs/#resize-square');\n\n Interactable.prototype.accept = warnOnce(Interactable.prototype.accept,\n 'Interactable#accept is deprecated. use Interactable#dropzone({ accept: target }) instead');\n Interactable.prototype.dropChecker = warnOnce(Interactable.prototype.dropChecker,\n 'Interactable#dropChecker is deprecated. use Interactable#dropzone({ dropChecker: checkerFunction }) instead');\n Interactable.prototype.context = warnOnce(Interactable.prototype.context,\n 'Interactable#context as a method is deprecated. It will soon be a DOM Node instead');\n\n /* \\\n * interact.isSet\n [ method ]\n *\n * Check if an element has been set\n - element (Element) The Element being searched for\n = (boolean) Indicates if the element or CSS selector was previously passed to interact\n \\*/\n interact.isSet = function(element, options){\n return interactables.indexOfElement(element, options && options.context) !== -1;\n };\n\n /* \\\n * interact.on\n [ method ]\n *\n * Adds a global listener for an InteractEvent or adds a DOM event to\n * `document`\n *\n - type (string | array | object) The types of events to listen for\n - listener (function) The function to be called on the given event(s)\n - useCapture (boolean) #optional useCapture flag for addEventListener\n = (object) interact\n \\*/\n interact.on = function(type, listener, useCapture){\n if (isString(type) && type.search(' ') !== -1){\n type = type.trim().split(/ +/);\n }\n\n if (isArray(type)){\n for (var i = 0; i < type.length; i++){\n interact.on(type[i], listener, useCapture);\n }\n\n return interact;\n }\n\n if (isObject(type)){\n for (var prop in type){\n interact.on(prop, type[prop], listener);\n }\n\n return interact;\n }\n\n // if it is an InteractEvent type, add listener to globalEvents\n if (contains(eventTypes, type)){\n // if this type of event was never bound\n if (!globalEvents[type]){\n globalEvents[type] = [listener];\n }\n else {\n globalEvents[type].push(listener);\n }\n }\n // If non InteractEvent type, addEventListener to document\n else {\n events.add(document, type, listener, useCapture);\n }\n\n return interact;\n };\n\n /* \\\n * interact.off\n [ method ]\n *\n * Removes a global InteractEvent listener or DOM event from `document`\n *\n - type (string | array | object) The types of events that were listened for\n - listener (function) The listener function to be removed\n - useCapture (boolean) #optional useCapture flag for removeEventListener\n = (object) interact\n \\*/\n interact.off = function(type, listener, useCapture){\n if (isString(type) && type.search(' ') !== -1){\n type = type.trim().split(/ +/);\n }\n\n if (isArray(type)){\n for (var i = 0; i < type.length; i++){\n interact.off(type[i], listener, useCapture);\n }\n\n return interact;\n }\n\n if (isObject(type)){\n for (var prop in type){\n interact.off(prop, type[prop], listener);\n }\n\n return interact;\n }\n\n if (!contains(eventTypes, type)){\n events.remove(document, type, listener, useCapture);\n }\n else {\n var index;\n\n if (type in globalEvents\n && (index = indexOf(globalEvents[type], listener)) !== -1){\n globalEvents[type].splice(index, 1);\n }\n }\n\n return interact;\n };\n\n /* \\\n * interact.enableDragging\n [ method ]\n *\n * Deprecated.\n *\n * Returns or sets whether dragging is enabled for any Interactables\n *\n - newValue (boolean) #optional `true` to allow the action; `false` to disable action for all Interactables\n = (boolean | object) The current setting or interact\n \\*/\n interact.enableDragging = warnOnce(function(newValue){\n if (newValue !== null && newValue !== undefined){\n actionIsEnabled.drag = newValue;\n\n return interact;\n }\n return actionIsEnabled.drag;\n }, 'interact.enableDragging is deprecated and will soon be removed.');\n\n /* \\\n * interact.enableResizing\n [ method ]\n *\n * Deprecated.\n *\n * Returns or sets whether resizing is enabled for any Interactables\n *\n - newValue (boolean) #optional `true` to allow the action; `false` to disable action for all Interactables\n = (boolean | object) The current setting or interact\n \\*/\n interact.enableResizing = warnOnce(function(newValue){\n if (newValue !== null && newValue !== undefined){\n actionIsEnabled.resize = newValue;\n\n return interact;\n }\n return actionIsEnabled.resize;\n }, 'interact.enableResizing is deprecated and will soon be removed.');\n\n /* \\\n * interact.enableGesturing\n [ method ]\n *\n * Deprecated.\n *\n * Returns or sets whether gesturing is enabled for any Interactables\n *\n - newValue (boolean) #optional `true` to allow the action; `false` to disable action for all Interactables\n = (boolean | object) The current setting or interact\n \\*/\n interact.enableGesturing = warnOnce(function(newValue){\n if (newValue !== null && newValue !== undefined){\n actionIsEnabled.gesture = newValue;\n\n return interact;\n }\n return actionIsEnabled.gesture;\n }, 'interact.enableGesturing is deprecated and will soon be removed.');\n\n interact.eventTypes = eventTypes;\n\n /* \\\n * interact.debug\n [ method ]\n *\n * Returns debugging data\n = (object) An object with properties that outline the current state and expose internal functions and variables\n \\*/\n interact.debug = function(){\n var interaction = interactions[0] || new Interaction();\n\n return {\n interactions: interactions,\n target: interaction.target,\n dragging: interaction.dragging,\n resizing: interaction.resizing,\n gesturing: interaction.gesturing,\n prepared: interaction.prepared,\n matches: interaction.matches,\n matchElements: interaction.matchElements,\n\n prevCoords: interaction.prevCoords,\n startCoords: interaction.startCoords,\n\n pointerIds: interaction.pointerIds,\n pointers: interaction.pointers,\n addPointer: listeners.addPointer,\n removePointer: listeners.removePointer,\n recordPointer: listeners.recordPointer,\n\n snap: interaction.snapStatus,\n restrict: interaction.restrictStatus,\n inertia: interaction.inertiaStatus,\n\n downTime: interaction.downTimes[0],\n downEvent: interaction.downEvent,\n downPointer: interaction.downPointer,\n prevEvent: interaction.prevEvent,\n\n Interactable: Interactable,\n interactables: interactables,\n pointerIsDown: interaction.pointerIsDown,\n defaultOptions: defaultOptions,\n defaultActionChecker: defaultActionChecker,\n\n actionCursors: actionCursors,\n dragMove: listeners.dragMove,\n resizeMove: listeners.resizeMove,\n gestureMove: listeners.gestureMove,\n pointerUp: listeners.pointerUp,\n pointerDown: listeners.pointerDown,\n pointerMove: listeners.pointerMove,\n pointerHover: listeners.pointerHover,\n\n eventTypes: eventTypes,\n\n events: events,\n globalEvents: globalEvents,\n delegatedEvents: delegatedEvents,\n\n prefixedPropREs: prefixedPropREs\n };\n };\n\n // expose the functions used to calculate multi-touch properties\n interact.getPointerAverage = pointerAverage;\n interact.getTouchBBox = touchBBox;\n interact.getTouchDistance = touchDistance;\n interact.getTouchAngle = touchAngle;\n\n interact.getElementRect = getElementRect;\n interact.getElementClientRect = getElementClientRect;\n interact.matchesSelector = matchesSelector;\n interact.closest = closest;\n\n /* \\\n * interact.margin\n [ method ]\n *\n * Deprecated. Use `interact(target).resizable({ margin: number });` instead.\n * Returns or sets the margin for autocheck resizing used in\n * @Interactable.getAction. That is the distance from the bottom and right\n * edges of an element clicking in which will start resizing\n *\n - newValue (number) #optional\n = (number | interact) The current margin value or interact\n \\*/\n interact.margin = warnOnce(function(newvalue){\n if (isNumber(newvalue)){\n margin = newvalue;\n\n return interact;\n }\n return margin;\n },\n 'interact.margin is deprecated. Use interact(target).resizable({ margin: number }); instead.');\n\n /* \\\n * interact.supportsTouch\n [ method ]\n *\n = (boolean) Whether or not the browser supports touch input\n \\*/\n interact.supportsTouch = function(){\n return supportsTouch;\n };\n\n /* \\\n * interact.supportsPointerEvent\n [ method ]\n *\n = (boolean) Whether or not the browser supports PointerEvents\n \\*/\n interact.supportsPointerEvent = function(){\n return supportsPointerEvent;\n };\n\n /* \\\n * interact.stop\n [ method ]\n *\n * Cancels all interactions (end events are not fired)\n *\n - event (Event) An event on which to call preventDefault()\n = (object) interact\n \\*/\n interact.stop = function(event){\n for (var i = interactions.length - 1; i >= 0; i--){\n interactions[i].stop(event);\n }\n\n return interact;\n };\n\n /* \\\n * interact.dynamicDrop\n [ method ]\n *\n * Returns or sets whether the dimensions of dropzone elements are\n * calculated on every dragmove or only on dragstart for the default\n * dropChecker\n *\n - newValue (boolean) #optional True to check on each move. False to check only before start\n = (boolean | interact) The current setting or interact\n \\*/\n interact.dynamicDrop = function(newValue){\n if (isBool(newValue)){\n // if (dragging && dynamicDrop !== newValue && !newValue) {\n // calcRects(dropzones);\n // }\n\n dynamicDrop = newValue;\n\n return interact;\n }\n return dynamicDrop;\n };\n\n /* \\\n * interact.pointerMoveTolerance\n [ method ]\n * Returns or sets the distance the pointer must be moved before an action\n * sequence occurs. This also affects tolerance for tap events.\n *\n - newValue (number) #optional The movement from the start position must be greater than this value\n = (number | Interactable) The current setting or interact\n \\*/\n interact.pointerMoveTolerance = function(newValue){\n if (isNumber(newValue)){\n pointerMoveTolerance = newValue;\n\n return this;\n }\n\n return pointerMoveTolerance;\n };\n\n /* \\\n * interact.maxInteractions\n [ method ]\n **\n * Returns or sets the maximum number of concurrent interactions allowed.\n * By default only 1 interaction is allowed at a time (for backwards\n * compatibility). To allow multiple interactions on the same Interactables\n * and elements, you need to enable it in the draggable, resizable and\n * gesturable `'max'` and `'maxPerElement'` options.\n **\n - newValue (number) #optional Any number. newValue <= 0 means no interactions.\n \\*/\n interact.maxInteractions = function(newValue){\n if (isNumber(newValue)){\n maxInteractions = newValue;\n\n return this;\n }\n\n return maxInteractions;\n };\n\n interact.createSnapGrid = function(grid){\n return function(x, y){\n var offsetX = 0,\n offsetY = 0;\n\n if (isObject(grid.offset)){\n offsetX = grid.offset.x;\n offsetY = grid.offset.y;\n }\n\n var gridx = Math.round((x - offsetX) / grid.x),\n gridy = Math.round((y - offsetY) / grid.y),\n\n newX = gridx * grid.x + offsetX,\n newY = gridy * grid.y + offsetY;\n\n return {\n x: newX,\n y: newY,\n range: grid.range\n };\n };\n };\n\n function endAllInteractions(event){\n for (var i = 0; i < interactions.length; i++){\n interactions[i].pointerEnd(event, event);\n }\n }\n\n function listenToDocument(doc){\n if (contains(documents, doc)){ return; }\n\n var win = doc.defaultView || doc.parentWindow;\n\n // add delegate event listener\n for (var eventType in delegatedEvents){\n events.add(doc, eventType, delegateListener);\n events.add(doc, eventType, delegateUseCapture, true);\n }\n\n if (supportsPointerEvent){\n if (PointerEvent === win.MSPointerEvent){\n pEventTypes = {\n up: 'MSPointerUp', down: 'MSPointerDown', over: 'mouseover',\n out: 'mouseout', move: 'MSPointerMove', cancel: 'MSPointerCancel' };\n }\n else {\n pEventTypes = {\n up: 'pointerup', down: 'pointerdown', over: 'pointerover',\n out: 'pointerout', move: 'pointermove', cancel: 'pointercancel' };\n }\n\n events.add(doc, pEventTypes.down, listeners.selectorDown);\n events.add(doc, pEventTypes.move, listeners.pointerMove);\n events.add(doc, pEventTypes.over, listeners.pointerOver);\n events.add(doc, pEventTypes.out, listeners.pointerOut);\n events.add(doc, pEventTypes.up, listeners.pointerUp);\n events.add(doc, pEventTypes.cancel, listeners.pointerCancel);\n\n // autoscroll\n events.add(doc, pEventTypes.move, listeners.autoScrollMove);\n }\n else {\n events.add(doc, 'mousedown', listeners.selectorDown);\n events.add(doc, 'mousemove', listeners.pointerMove);\n events.add(doc, 'mouseup', listeners.pointerUp);\n events.add(doc, 'mouseover', listeners.pointerOver);\n events.add(doc, 'mouseout', listeners.pointerOut);\n\n events.add(doc, 'touchstart', listeners.selectorDown);\n events.add(doc, 'touchmove', listeners.pointerMove);\n events.add(doc, 'touchend', listeners.pointerUp);\n events.add(doc, 'touchcancel', listeners.pointerCancel);\n\n // autoscroll\n events.add(doc, 'mousemove', listeners.autoScrollMove);\n events.add(doc, 'touchmove', listeners.autoScrollMove);\n }\n\n events.add(win, 'blur', endAllInteractions);\n\n try {\n if (win.frameElement){\n var parentDoc = win.frameElement.ownerDocument,\n parentWindow = parentDoc.defaultView;\n\n events.add(parentDoc, 'mouseup', listeners.pointerEnd);\n events.add(parentDoc, 'touchend', listeners.pointerEnd);\n events.add(parentDoc, 'touchcancel', listeners.pointerEnd);\n events.add(parentDoc, 'pointerup', listeners.pointerEnd);\n events.add(parentDoc, 'MSPointerUp', listeners.pointerEnd);\n events.add(parentWindow, 'blur', endAllInteractions);\n }\n }\n catch (error){\n interact.windowParentError = error;\n }\n\n // prevent native HTML5 drag on interact.js target elements\n events.add(doc, 'dragstart', function(event){\n for (var i = 0; i < interactions.length; i++){\n var interaction = interactions[i];\n\n if (interaction.element\n && (interaction.element === event.target\n || nodeContains(interaction.element, event.target))){\n interaction.checkAndPreventDefault(event, interaction.target, interaction.element);\n return;\n }\n }\n });\n\n if (events.useAttachEvent){\n // For IE's lack of Event#preventDefault\n events.add(doc, 'selectstart', function(event){\n var interaction = interactions[0];\n\n if (interaction.currentAction()){\n interaction.checkAndPreventDefault(event);\n }\n });\n\n // For IE's bad dblclick event sequence\n events.add(doc, 'dblclick', doOnInteractions('ie8Dblclick'));\n }\n\n documents.push(doc);\n }\n\n listenToDocument(document);\n\n function indexOf(array, target){\n for (var i = 0, len = array.length; i < len; i++){\n if (array[i] === target){\n return i;\n }\n }\n\n return -1;\n }\n\n function contains(array, target){\n return indexOf(array, target) !== -1;\n }\n\n function matchesSelector(element, selector, nodeList){\n if (ie8MatchesSelector){\n return ie8MatchesSelector(element, selector, nodeList);\n }\n\n // remove /deep/ from selectors if shadowDOM polyfill is used\n if (window !== realWindow){\n selector = selector.replace(/\\/deep\\//g, ' ');\n }\n\n return element[prefixedMatchesSelector](selector);\n }\n\n function matchesUpTo(element, selector, limit){\n while (isElement(element)){\n if (matchesSelector(element, selector)){\n return true;\n }\n\n element = parentElement(element);\n\n if (element === limit){\n return matchesSelector(element, selector);\n }\n }\n\n return false;\n }\n\n // For IE8's lack of an Element#matchesSelector\n // taken from http://tanalin.com/en/blog/2012/12/matches-selector-ie8/ and modified\n if (!(prefixedMatchesSelector in Element.prototype) || !isFunction(Element.prototype[prefixedMatchesSelector])){\n ie8MatchesSelector = function(element, selector, elems){\n elems = elems || element.parentNode.querySelectorAll(selector);\n\n for (var i = 0, len = elems.length; i < len; i++){\n if (elems[i] === element){\n return true;\n }\n }\n\n return false;\n };\n }\n\n // requestAnimationFrame polyfill\n (function(){\n var lastTime = 0,\n vendors = ['ms', 'moz', 'webkit', 'o'];\n\n for (var x = 0; x < vendors.length && !realWindow.requestAnimationFrame; ++x){\n reqFrame = realWindow[vendors[x] + 'RequestAnimationFrame'];\n cancelFrame = realWindow[vendors[x] + 'CancelAnimationFrame'] || realWindow[vendors[x] + 'CancelRequestAnimationFrame'];\n }\n\n if (!reqFrame){\n reqFrame = function(callback){\n var currTime = new Date().getTime(),\n timeToCall = Math.max(0, 16 - (currTime - lastTime)),\n id = setTimeout(function(){ callback(currTime + timeToCall); },\n timeToCall);\n lastTime = currTime + timeToCall;\n return id;\n };\n }\n\n if (!cancelFrame){\n cancelFrame = function(id){\n clearTimeout(id);\n };\n }\n }());\n\n /* global exports: true, module, define */\n\n // http://documentcloud.github.io/underscore/docs/underscore.html#section-11\n if (typeof exports !== 'undefined'){\n if (typeof module !== 'undefined' && module.exports){\n exports = module.exports = interact;\n }\n exports.interact = interact;\n }\n // AMD\n else if (typeof define === 'function' && define.amd){\n define('interact', function(){\n return interact;\n });\n }\n else {\n realWindow.interact = interact;\n }\n}(typeof window === 'undefined' ? undefined : window));\n\n\n\n// WEBPACK FOOTER //\n// ../src/interact.js","export AutoTooltips from './slick.autotooltips';\nexport CellCopyManager from './slick.cellcopymanager';\nexport CellRangeDecorator from './slick.cellrangedecorator';\nexport CellRangeSelector from './slick.cellrangeselector';\nexport CellSelectionModel from './slick.cellselectionmodel';\nexport CheckboxSelectColumn from './slick.checkboxselectcolumn';\nexport HeaderButtons from './slick.headerbuttons';\nexport HeaderMenu from './slick.headermenu';\nexport RowMoveManager from './slick.rowmovemanager';\nexport RowSelectionModel from './slick.rowselectionmodel';\n\n\n\n// WEBPACK FOOTER //\n// ../plugins/index.js","import AutoTooltips from './slick.autotooltips';\nexport default AutoTooltips;\n\n\n\n// WEBPACK FOOTER //\n// ../plugins/slick.autotooltips/index.js","import $ from 'jquery';\n\nexport default AutoTooltips;\n\n /**\n * AutoTooltips plugin to show/hide tooltips when columns are too narrow to fit content.\n * @constructor\n * @param {boolean} [options.enableForCells=true] - Enable tooltip for grid cells\n * @param {boolean} [options.enableForHeaderCells=false] - Enable tooltip for header cells\n * @param {number} [options.maxToolTipLength=null] - The maximum length for a tooltip\n */\nfunction AutoTooltips(options){\n let _grid;\n const _self = this;\n const _defaults = {\n enableForCells: true,\n enableForHeaderCells: false,\n maxToolTipLength: null\n };\n\n /**\n * Initialize plugin.\n */\n function init(grid){\n options = Object.assign({}, _defaults, options);\n _grid = grid;\n if (options.enableForCells) _grid.onMouseEnter.subscribe(handleMouseEnter);\n if (options.enableForHeaderCells) _grid.onHeaderMouseEnter.subscribe(handleHeaderMouseEnter);\n }\n\n /**\n * Destroy plugin.\n */\n function destroy(){\n if (options.enableForCells) _grid.onMouseEnter.unsubscribe(handleMouseEnter);\n if (options.enableForHeaderCells) _grid.onHeaderMouseEnter.unsubscribe(handleHeaderMouseEnter);\n }\n\n /**\n * Handle mouse entering grid cell to add/remove tooltip.\n * @param {jQuery.Event} e - The event\n */\n function handleMouseEnter(e){\n const cell = _grid.getCellFromEvent(e);\n if (cell){\n let $node = $(_grid.getCellNode(cell.row, cell.cell));\n let text;\n if ($node.innerWidth() < $node[0].scrollWidth){\n text = $.trim($node.text());\n if (options.maxToolTipLength && text.length > options.maxToolTipLength){\n text = text.substr(0, options.maxToolTipLength - 3) + '...';\n }\n } else {\n text = '';\n }\n $node.attr('title', text);\n }\n }\n\n /**\n * Handle mouse entering header cell to add/remove tooltip.\n * @param {jQuery.Event} e - The event\n * @param {object} args.column - The column definition\n */\n function handleHeaderMouseEnter(e, args){\n const column = args.column,\n $node = $(e.target).closest('.slick-header-column');\n if (column && !column.toolTip){\n $node.attr('title', ($node.innerWidth() < $node[0].scrollWidth) ? column.name : '');\n }\n }\n\n // Public API\n Object.assign(this, {\n init,\n destroy\n });\n}\n\n\n\n// WEBPACK FOOTER //\n// ../plugins/slick.autotooltips/slick.autotooltips.js","import CellCopyManager from './slick.cellcopymanager';\nexport default CellCopyManager;\n\n\n\n// WEBPACK FOOTER //\n// ../plugins/slick.cellcopymanager/index.js","import Slick from '../../src/slick.core';\nconst { keyCode } = Slick;\n\nexport default CellCopyManager;\n\nfunction CellCopyManager(){\n var _grid;\n var _self = this;\n var _copiedRanges;\n\n function init(grid){\n _grid = grid;\n _grid.onKeyDown.subscribe(handleKeyDown);\n }\n\n function destroy(){\n _grid.onKeyDown.unsubscribe(handleKeyDown);\n }\n\n function handleKeyDown(e, args){\n var ranges;\n if (!_grid.getEditorLock().isActive()){\n if (e.which == keyCode.ESCAPE){\n if (_copiedRanges){\n e.preventDefault();\n clearCopySelection();\n _self.onCopyCancelled.notify({ranges: _copiedRanges});\n _copiedRanges = null;\n }\n }\n\n if (e.which == 67 && (e.ctrlKey || e.metaKey)){\n ranges = _grid.getSelectionModel().getSelectedRanges();\n if (ranges.length != 0){\n e.preventDefault();\n _copiedRanges = ranges;\n markCopySelection(ranges);\n _self.onCopyCells.notify({ranges: ranges});\n }\n }\n\n if (e.which == 86 && (e.ctrlKey || e.metaKey)){\n if (_copiedRanges){\n e.preventDefault();\n clearCopySelection();\n ranges = _grid.getSelectionModel().getSelectedRanges();\n _self.onPasteCells.notify({from: _copiedRanges, to: ranges});\n _copiedRanges = null;\n }\n }\n }\n }\n\n function markCopySelection(ranges){\n var columns = _grid.getColumns();\n var hash = {};\n for (var i = 0; i < ranges.length; i++){\n for (var j = ranges[i].fromRow; j <= ranges[i].toRow; j++){\n hash[j] = {};\n for (var k = ranges[i].fromCell; k <= ranges[i].toCell; k++){\n hash[j][columns[k].id] = 'copied';\n }\n }\n }\n _grid.setCellCssStyles('copy-manager', hash);\n }\n\n function clearCopySelection(){\n _grid.removeCellCssStyles('copy-manager');\n }\n\n Object.assign(this, {\n init,\n destroy,\n clearCopySelection,\n\n onCopyCells: new Slick.Event(),\n onCopyCancelled: new Slick.Event(),\n onPasteCells: new Slick.Event()\n });\n}\n\n\n\n// WEBPACK FOOTER //\n// ../plugins/slick.cellcopymanager/slick.cellcopymanager.js","import CellRangeDecorator from './slick.cellrangedecorator';\nexport default CellRangeDecorator;\n\n\n\n// WEBPACK FOOTER //\n// ../plugins/slick.cellrangedecorator/index.js","import CellRangeDecorator from './slick.cellrangeselector';\nexport default CellRangeDecorator;\n\n\n\n// WEBPACK FOOTER //\n// ../plugins/slick.cellrangeselector/index.js","import CellSelectionModel from './slick.cellselectionmodel';\nexport default CellSelectionModel;\n\n\n\n// WEBPACK FOOTER //\n// ../plugins/slick.cellselectionmodel/index.js","import Slick from '../../src/slick.core';\nimport CellRangeSelector from '../slick.cellrangeselector/slick.cellrangeselector';\n\nexport default CellSelectionModel;\n\nfunction CellSelectionModel(options = {\n selectActiveCell: true\n}){\n let _grid;\n let _canvas;\n let _ranges = [];\n const _self = this;\n const _selector = new CellRangeSelector({\n selectionCss: {\n border: '2px solid black'\n }\n });\n let _options;\n const _defaults = {\n selectActiveCell: true\n };\n\n function init(grid){\n _options = Object.assign({}, options);\n _grid = grid;\n _canvas = _grid.getCanvasNode();\n _grid.onActiveCellChanged.subscribe(handleActiveCellChange);\n _grid.onKeyDown.subscribe(handleKeyDown);\n grid.registerPlugin(_selector);\n _selector.onCellRangeSelected.subscribe(handleCellRangeSelected);\n _selector.onBeforeCellRangeSelected.subscribe(handleBeforeCellRangeSelected);\n }\n\n function destroy(){\n _grid.onActiveCellChanged.unsubscribe(handleActiveCellChange);\n _grid.onKeyDown.unsubscribe(handleKeyDown);\n _selector.onCellRangeSelected.unsubscribe(handleCellRangeSelected);\n _selector.onBeforeCellRangeSelected.unsubscribe(handleBeforeCellRangeSelected);\n _grid.unregisterPlugin(_selector);\n }\n\n function removeInvalidRanges(ranges){\n const result = [];\n\n for (let i = 0; i < ranges.length; i++){\n const r = ranges[i];\n if (_grid.canCellBeSelected(r.fromRow, r.fromCell) && _grid.canCellBeSelected(r.toRow, r.toCell)){\n result.push(r);\n }\n }\n\n return result;\n }\n\n function setSelectedRanges(ranges){\n // simle check for: empty selection didn't change, prevent firing onSelectedRangesChanged\n if ((!_ranges || _ranges.length === 0) && (!ranges || ranges.length === 0)){\n return;\n }\n\n _ranges = removeInvalidRanges(ranges);\n _self.onSelectedRangesChanged.notify(_ranges);\n }\n\n function getSelectedRanges(){\n return _ranges;\n }\n\n function handleBeforeCellRangeSelected(e, args){\n if (_grid.getEditorLock().isActive()){\n e.stopPropagation();\n return false;\n }\n }\n\n function handleCellRangeSelected(e, args){\n setSelectedRanges([args.range]);\n }\n\n function handleActiveCellChange(e, args){\n if (_options.selectActiveCell && args.row != null && args.cell != null){\n setSelectedRanges([new Slick.Range(args.row, args.cell)]);\n }\n }\n\n function handleKeyDown(e){\n /** *\n * Кey codes\n * 37 left\n * 38 up\n * 39 right\n * 40 down\n */\n let ranges, last;\n const active = _grid.getActiveCell();\n\n if (active && e.shiftKey && !e.ctrlKey && !e.altKey &&\n (e.which == 37 || e.which == 39 || e.which == 38 || e.which == 40)){\n ranges = getSelectedRanges();\n if (!ranges.length)\n ranges.push(new Slick.Range(active.row, active.cell));\n\n // keyboard can work with last range only\n last = ranges.pop();\n\n // can't handle selection out of active cell\n if (!last.contains(active.row, active.cell))\n last = new Slick.Range(active.row, active.cell);\n\n let dRow = last.toRow - last.fromRow,\n dCell = last.toCell - last.fromCell,\n // walking direction\n dirRow = active.row == last.fromRow ? 1 : -1,\n dirCell = active.cell == last.fromCell ? 1 : -1;\n\n if (e.which == 37){\n dCell -= dirCell;\n } else if (e.which == 39){\n dCell += dirCell;\n } else if (e.which == 38){\n dRow -= dirRow;\n } else if (e.which == 40){\n dRow += dirRow;\n }\n\n // define new selection range\n const new_last = new Slick.Range(active.row, active.cell, active.row + dirRow * dRow, active.cell + dirCell * dCell);\n if (removeInvalidRanges([new_last]).length){\n ranges.push(new_last);\n const viewRow = dirRow > 0 ? new_last.toRow : new_last.fromRow;\n const viewCell = dirCell > 0 ? new_last.toCell : new_last.fromCell;\n _grid.scrollRowIntoView(viewRow);\n _grid.scrollCellIntoView(viewRow, viewCell);\n }\n else\n ranges.push(last);\n\n setSelectedRanges(ranges);\n\n e.preventDefault();\n e.stopPropagation();\n }\n }\n\n Object.assign(this, {\n getSelectedRanges,\n setSelectedRanges,\n\n init,\n destroy,\n\n onSelectedRangesChanged: new Slick.Event()\n });\n}\n\n\n\n// WEBPACK FOOTER //\n// ../plugins/slick.cellselectionmodel/slick.cellselectionmodel.js","import CheckboxSelectColumn from './slick.checkboxselectcolumn';\nexport default CheckboxSelectColumn;\n\n\n\n// WEBPACK FOOTER //\n// ../plugins/slick.checkboxselectcolumn/index.js","import $ from 'jquery';\nimport Slick from '../../src/slick.core';\n\nexport default CheckboxSelectColumn;\n\nfunction CheckboxSelectColumn(options){\n let _grid;\n const _self = this;\n const _handler = new Slick.EventHandler();\n let _selectedRowsLookup = {};\n const _defaults = {\n columnId: '_checkbox_selector',\n cssClass: null,\n toolTip: 'Select/Deselect All',\n width: 30\n };\n\n const _options = $.extend(true, {}, _defaults, options);\n\n function init(grid){\n _grid = grid;\n _handler\n .subscribe(_grid.onSelectedRowsChanged, handleSelectedRowsChanged)\n .subscribe(_grid.onClick, handleClick)\n .subscribe(_grid.onHeaderClick, handleHeaderClick)\n .subscribe(_grid.onKeyDown, handleKeyDown);\n }\n\n function destroy(){\n _handler.unsubscribeAll();\n }\n\n function handleSelectedRowsChanged(e, args){\n let selectedRows = _grid.getSelectedRows();\n let lookup = {}, row, i;\n for (i = 0; i < selectedRows.length; i++){\n row = selectedRows[i];\n lookup[row] = true;\n if (lookup[row] !== _selectedRowsLookup[row]){\n _grid.invalidateRow(row);\n delete _selectedRowsLookup[row];\n }\n }\n for (i in _selectedRowsLookup){\n _grid.invalidateRow(i);\n }\n _selectedRowsLookup = lookup;\n _grid.render();\n\n if (selectedRows.length && selectedRows.length == _grid.getDataLength()){\n _grid.updateColumnHeader(_options.columnId, \"\", _options.toolTip);\n } else {\n _grid.updateColumnHeader(_options.columnId, \"\", _options.toolTip);\n }\n }\n\n function handleKeyDown(e, args){\n if (e.which == 32){\n if (_grid.getColumns()[args.cell].id === _options.columnId){\n // if editing, try to commit\n if (!_grid.getEditorLock().isActive() || _grid.getEditorLock().commitCurrentEdit()){\n toggleRowSelection(args.row);\n }\n e.preventDefault();\n e.stopImmediatePropagation();\n }\n }\n }\n\n function handleClick(e, args){\n // clicking on a row select checkbox\n if (_grid.getColumns()[args.cell].id === _options.columnId && $(e.target).is(':checkbox')){\n // if editing, try to commit\n if (_grid.getEditorLock().isActive() && !_grid.getEditorLock().commitCurrentEdit()){\n e.preventDefault();\n e.stopImmediatePropagation();\n return;\n }\n\n toggleRowSelection(args.row);\n e.stopPropagation();\n e.stopImmediatePropagation();\n }\n }\n\n function toggleRowSelection(row){\n if (_selectedRowsLookup[row]){\n _grid.setSelectedRows($.grep(_grid.getSelectedRows(), function(n){\n return n != row;\n }));\n } else {\n _grid.setSelectedRows(_grid.getSelectedRows().concat(row));\n }\n }\n\n function handleHeaderClick(e, args){\n if (args.column.id == _options.columnId && $(e.target).is(':checkbox')){\n // if editing, try to commit\n if (_grid.getEditorLock().isActive() && !_grid.getEditorLock().commitCurrentEdit()){\n e.preventDefault();\n e.stopImmediatePropagation();\n return;\n }\n\n if ($(e.target).is(':checked')){\n const rows = [];\n for (let i = 0; i < _grid.getDataLength(); i++){\n rows.push(i);\n }\n _grid.setSelectedRows(rows);\n } else {\n _grid.setSelectedRows([]);\n }\n e.stopPropagation();\n e.stopImmediatePropagation();\n }\n }\n\n function getColumnDefinition(){\n return {\n id: _options.columnId,\n name: \"\",\n toolTip: _options.toolTip,\n field: 'sel',\n width: _options.width,\n resizable: false,\n sortable: false,\n cssClass: _options.cssClass,\n formatter: checkboxSelectionFormatter\n };\n }\n\n function checkboxSelectionFormatter(row, cell, value, columnDef, dataContext){\n if (dataContext){\n return _selectedRowsLookup[row]\n ? \"\"\n : \"\";\n }\n return null;\n }\n\n Object.assign(this, {\n init,\n destroy,\n\n getColumnDefinition\n });\n}\n\n\n\n// WEBPACK FOOTER //\n// ../plugins/slick.checkboxselectcolumn/slick.checkboxselectcolumn.js","import HeaderButtons from './slick.headerbuttons';\nexport default HeaderButtons;\n\n\n\n// WEBPACK FOOTER //\n// ../plugins/slick.headerbuttons/index.js","import $ from 'jquery';\nimport Slick from '../../src/slick.core';\n\nexport default HeaderButtons;\n/** *\n * A plugin to add custom buttons to column headers.\n *\n * USAGE:\n *\n * Add the plugin .js & .css files and register it with the grid.\n *\n * To specify a custom button in a column header, extend the column definition like so:\n *\n * var columns = [\n * {\n * id: 'myColumn',\n * name: 'My column',\n *\n * // This is the relevant part\n * header: {\n * buttons: [\n * {\n * // button options\n * },\n * {\n * // button options\n * }\n * ]\n * }\n * }\n * ];\n *\n * Available button options:\n * cssClass: CSS class to add to the button.\n * image: Relative button image path.\n * tooltip: Button tooltip.\n * showOnHover: Only show the button on hover.\n * handler: Button click handler.\n * command: A command identifier to be passed to the onCommand event handlers.\n *\n * The plugin exposes the following events:\n * onCommand: Fired on button click for buttons with 'command' specified.\n * Event args:\n * grid: Reference to the grid.\n * column: Column definition.\n * command: Button command identified.\n * button: Button options. Note that you can change the button options in your\n * event handler, and the column header will be automatically updated to\n * reflect them. This is useful if you want to implement something like a\n * toggle button.\n *\n *\n * @param options {Object} Options:\n * buttonCssClass: a CSS class to use for buttons (default 'slick-header-button')\n * @class Slick.Plugins.HeaderButtons\n * @constructor\n */\nfunction HeaderButtons(options){\n var _grid;\n var _self = this;\n var _handler = new Slick.EventHandler();\n var _defaults = {\n buttonCssClass: 'slick-header-button'\n };\n\n function init(grid){\n options = Object.assign({}, _defaults, options);\n _grid = grid;\n _handler\n .subscribe(_grid.onHeaderCellRendered, handleHeaderCellRendered)\n .subscribe(_grid.onBeforeHeaderCellDestroy, handleBeforeHeaderCellDestroy);\n\n // Force the grid to re-render the header now that the events are hooked up.\n _grid.setColumns(_grid.getColumns());\n }\n\n function destroy(){\n _handler.unsubscribeAll();\n }\n\n function handleHeaderCellRendered(e, args){\n var column = args.column;\n\n if (column.header && column.header.buttons){\n // Append buttons in reverse order since they are floated to the right.\n var i = column.header.buttons.length;\n while (i--){\n var button = column.header.buttons[i];\n var btn = $('')\n .addClass(options.buttonCssClass)\n .data('column', column)\n .data('button', button);\n\n if (button.showOnHover){\n btn.addClass('slick-header-button-hidden');\n }\n\n if (button.image){\n btn.css('backgroundImage', 'url(' + button.image + ')');\n }\n\n if (button.cssClass){\n btn.addClass(button.cssClass);\n }\n\n if (button.tooltip){\n btn.attr('title', button.tooltip);\n }\n\n if (button.command){\n btn.data('command', button.command);\n }\n\n if (button.handler){\n btn.bind('click', button.handler);\n }\n\n btn\n .bind('click', handleButtonClick)\n .appendTo(args.node);\n args.node.classList.add('has-buttons');\n }\n }\n }\n\n function handleBeforeHeaderCellDestroy(e, args){\n var column = args.column;\n\n if (column.header && column.header.buttons){\n // Removing buttons via jQuery will also clean up any event handlers and data.\n // NOTE: If you attach event handlers directly or using a different framework,\n // you must also clean them up here to avoid memory leaks.\n $(args.node).find(`.${options.buttonCssClass}`).remove();\n }\n }\n\n function handleButtonClick(e){\n var command = $(this).data('command');\n var columnDef = $(this).data('column');\n var button = $(this).data('button');\n\n if (command != null){\n _self.onCommand.notify({\n 'grid': _grid,\n 'column': columnDef,\n 'command': command,\n 'button': button\n }, e, _self);\n\n // Update the header in case the user updated the button definition in the handler.\n _grid.updateColumnHeader(columnDef.id);\n }\n\n // Stop propagation so that it doesn't register as a header click event.\n e.preventDefault();\n e.stopPropagation();\n }\n\n Object.assign(this, {\n init,\n destroy,\n\n 'onCommand': new Slick.Event()\n });\n}\n\n\n\n// WEBPACK FOOTER //\n// ../plugins/slick.headerbuttons/slick.headerbuttons.js","import HeaderMenu from './slick.headermenu';\nexport default HeaderMenu;\n\n\n\n// WEBPACK FOOTER //\n// ../plugins/slick.headermenu/index.js","import $ from 'jquery';\nimport Slick from '../../src/slick.core';\n\n// import './slick.headermenu.css';\n\nexport default HeaderMenu;\n\n/** *\n * A plugin to add drop-down menus to column headers.\n *\n * USAGE:\n *\n * Add the plugin .js & .css files and register it with the grid.\n *\n * To specify a menu in a column header, extend the column definition like so:\n *\n * const columns = [\n * {\n * id: 'myColumn',\n * name: 'My column',\n *\n * // This is the relevant part\n * header: {\n * menu: {\n * items: [\n * {\n * // menu item options\n * },\n * {\n * // menu item options\n * }\n * ]\n * }\n * }\n * }\n * ];\n *\n *\n * Available menu options:\n * tooltip: Menu button tooltip.\n *\n *\n * Available menu item options:\n * title: Menu item text.\n * disabled: Whether the item is disabled.\n * tooltip: Item tooltip.\n * command: A command identifier to be passed to the onCommand event handlers.\n * iconCssClass: A CSS class to be added to the menu item icon.\n * iconImage: A url to the icon image.\n *\n *\n * The plugin exposes the following events:\n * onBeforeMenuShow: Fired before the menu is shown. You can customize the menu or dismiss it by returning false.\n * Event args:\n * grid: Reference to the grid.\n * column: Column definition.\n * menu: Menu options. Note that you can change the menu items here.\n *\n * onCommand: Fired on menu item click for buttons with 'command' specified.\n * Event args:\n * grid: Reference to the grid.\n * column: Column definition.\n * command: Button command identified.\n * button: Button options. Note that you can change the button options in your\n * event handler, and the column header will be automatically updated to\n * reflect them. This is useful if you want to implement something like a\n * toggle button.\n *\n *\n * @param options {Object} Options:\n * buttonCssClass: an extra CSS class to add to the menu button\n * buttonImage: a url to the menu button image (default '../images/down.gif')\n * @class Slick.Plugins.HeaderButtons\n * @constructor\n */\nfunction HeaderMenu(options){\n let _grid;\n const _self = this;\n const _handler = new Slick.EventHandler();\n const _defaults = {\n buttonCssClass: null,\n buttonImage: null\n };\n\n let $menu;\n let $activeHeaderColumn;\n\n function init(grid){\n options = Object.assign({}, _defaults, options);\n _grid = grid;\n _handler\n .subscribe(_grid.onHeaderCellRendered, handleHeaderCellRendered)\n .subscribe(_grid.onBeforeHeaderCellDestroy, handleBeforeHeaderCellDestroy);\n\n // Force the grid to re-render the header now that the events are hooked up.\n _grid.setColumns(_grid.getColumns());\n\n // Hide the menu on outside click.\n $(document.body).bind('mousedown', handleBodyMouseDown);\n }\n\n function destroy(){\n _handler.unsubscribeAll();\n $(document.body).unbind('mousedown', handleBodyMouseDown);\n }\n\n function handleBodyMouseDown(e){\n if ($menu && $menu[0] != e.target && !$.contains($menu[0], e.target)){\n hideMenu();\n }\n }\n\n function hideMenu(){\n if ($menu){\n $menu.remove();\n $menu = null;\n $activeHeaderColumn\n .removeClass('slick-header-column-active');\n }\n }\n\n function handleHeaderCellRendered(e, args){\n const column = args.column;\n const menu = column.header && column.header.menu;\n\n if (menu){\n const $el = $('')\n .addClass('slick-header-menubutton')\n .data('column', column)\n .data('menu', menu);\n\n if (options.buttonCssClass){\n $el.addClass(options.buttonCssClass);\n }\n\n if (options.buttonImage){\n $el.css('background-image', 'url(' + options.buttonImage + ')');\n }\n\n if (menu.tooltip){\n $el.attr('title', menu.tooltip);\n }\n\n $el\n .bind('click', showMenu)\n .appendTo(args.node);\n }\n }\n\n function handleBeforeHeaderCellDestroy(e, args){\n const column = args.column;\n\n if (column.header && column.header.menu){\n $(args.node).find('.slick-header-menubutton').remove();\n }\n }\n\n function showMenu(e){\n const $menuButton = $(this);\n const menu = $menuButton.data('menu');\n const columnDef = $menuButton.data('column');\n\n // Let the user modify the menu or cancel altogether,\n // or provide alternative menu implementation.\n if (_self.onBeforeMenuShow.notify({\n 'grid': _grid,\n 'column': columnDef,\n 'menu': menu\n }, e, _self) == false){\n return;\n }\n\n if (!$menu){\n $menu = $(\"\")\n .appendTo(_grid.getContainerNode());\n }\n $menu.empty();\n\n // Construct the menu items.\n for (let i = 0; i < menu.items.length; i++){\n const item = menu.items[i];\n\n const $li = $(\"\")\n .data('command', item.command || '')\n .data('column', columnDef)\n .data('item', item)\n .bind('click', handleMenuItemClick)\n .appendTo($menu);\n\n if (item.disabled){\n $li.addClass('slick-header-menuitem-disabled');\n }\n\n if (item.tooltip){\n $li.attr('title', item.tooltip);\n }\n\n const $icon = $(\"\")\n .appendTo($li);\n\n if (item.iconCssClass){\n $icon.addClass(item.iconCssClass);\n }\n\n if (item.iconImage){\n $icon.css('background-image', 'url(' + item.iconImage + ')');\n }\n\n $(\"\")\n .text(item.title)\n .appendTo($li);\n }\n\n // Position the menu.\n $menu\n .offset({ top: $(this).offset().top + $(this).height(), left: $(this).offset().left });\n\n // Mark the header as active to keep the highlighting.\n $activeHeaderColumn = $menuButton.closest('.slick-header-column');\n $activeHeaderColumn\n .addClass('slick-header-column-active');\n\n // Stop propagation so that it doesn't register as a header click event.\n e.preventDefault();\n e.stopPropagation();\n }\n\n function handleMenuItemClick(e){\n const command = $(this).data('command');\n const columnDef = $(this).data('column');\n const item = $(this).data('item');\n\n if (item.disabled){\n return;\n }\n\n hideMenu();\n\n if (command != null && command != ''){\n _self.onCommand.notify({\n 'grid': _grid,\n 'column': columnDef,\n 'command': command,\n 'item': item\n }, e, _self);\n }\n\n // Stop propagation so that it doesn't register as a header click event.\n e.preventDefault();\n e.stopPropagation();\n }\n\n Object.assign(this, {\n init,\n destroy,\n\n 'onBeforeMenuShow': new Slick.Event(),\n 'onCommand': new Slick.Event()\n });\n}\n\n\n\n// WEBPACK FOOTER //\n// ../plugins/slick.headermenu/slick.headermenu.js","import RowMoveManager from './slick.rowmovemanager';\nexport default RowMoveManager;\n\n\n\n// WEBPACK FOOTER //\n// ../plugins/slick.rowmovemanager/index.js","import Slick from '../../src/slick.core';\n\nexport default RowMoveManager;\n\nfunction RowMoveManager(options){\n let _grid;\n let _canvas;\n let _dragging;\n const _self = this;\n const _handler = new Slick.EventHandler();\n const _defaults = {\n cancelEditOnDrag: false\n };\n\n function init(grid){\n options = Object.assign({}, _defaults, options);\n _grid = grid;\n _canvas = _grid.getCanvasNode();\n _handler\n .subscribe(_grid.onDragInit, handleDragInit)\n .subscribe(_grid.onDragStart, handleDragStart)\n .subscribe(_grid.onDrag, handleDrag)\n .subscribe(_grid.onDragEnd, handleDragEnd);\n }\n\n function destroy(){\n _handler.unsubscribeAll();\n }\n\n function handleDragInit(e, dd){\n // prevent the grid from cancelling drag'n'drop by default\n e.stopImmediatePropagation();\n }\n\n function handleDragStart(e, dd){\n const cell = _grid.getCellFromEvent(e);\n\n if (options.cancelEditOnDrag && _grid.getEditorLock().isActive()){\n _grid.getEditorLock().cancelCurrentEdit();\n }\n\n if (_grid.getEditorLock().isActive() || !/move|selectAndMove/.test(_grid.getColumns()[cell.cell].behavior)){\n return false;\n }\n\n _dragging = true;\n e.stopImmediatePropagation();\n\n let selectedRows = _grid.getSelectedRows();\n\n if (selectedRows.length == 0 || $.inArray(cell.row, selectedRows) == -1){\n selectedRows = [cell.row];\n _grid.setSelectedRows(selectedRows);\n }\n\n const rowHeight = _grid.getOptions().rowHeight;\n\n dd.selectedRows = selectedRows;\n\n dd.selectionProxy = $(\"\")\n .css('position', 'absolute')\n .css('zIndex', '99999')\n .css('width', $(_canvas).innerWidth())\n .css('height', rowHeight * selectedRows.length)\n .appendTo(_canvas);\n\n dd.guide = $(\"\")\n .css('position', 'absolute')\n .css('zIndex', '99998')\n .css('width', $(_canvas).innerWidth())\n .css('top', -1000)\n .appendTo(_canvas);\n\n dd.insertBefore = -1;\n }\n\n function handleDrag(e, dd){\n if (!_dragging){\n return;\n }\n\n e.stopImmediatePropagation();\n\n const top = e.pageY - $(_canvas).offset().top;\n dd.selectionProxy.css('top', top - 5);\n\n const insertBefore = Math.max(0, Math.min(Math.round(top / _grid.getOptions().rowHeight), _grid.getDataLength()));\n if (insertBefore !== dd.insertBefore){\n const eventData = {\n 'rows': dd.selectedRows,\n 'insertBefore': insertBefore\n };\n\n if (_self.onBeforeMoveRows.notify(eventData) === false){\n dd.guide.css('top', -1000);\n dd.canMove = false;\n } else {\n dd.guide.css('top', insertBefore * _grid.getOptions().rowHeight);\n dd.canMove = true;\n }\n\n dd.insertBefore = insertBefore;\n }\n }\n\n function handleDragEnd(e, dd){\n if (!_dragging){\n return;\n }\n _dragging = false;\n e.stopImmediatePropagation();\n\n dd.guide.remove();\n dd.selectionProxy.remove();\n\n if (dd.canMove){\n const eventData = {\n 'rows': dd.selectedRows,\n 'insertBefore': dd.insertBefore\n };\n // TODO: _grid.remapCellCssClasses ?\n _self.onMoveRows.notify(eventData);\n }\n }\n\n Object.assign(this, {\n 'onBeforeMoveRows': new Slick.Event(),\n 'onMoveRows': new Slick.Event(),\n init,\n destroy\n });\n}\n\n\n\n// WEBPACK FOOTER //\n// ../plugins/slick.rowmovemanager/slick.rowmovemanager.js","import RowSelectionModel from './slick.rowselectionmodel';\nexport default RowSelectionModel;\n\n\n\n// WEBPACK FOOTER //\n// ../plugins/slick.rowselectionmodel/index.js","import $ from 'jquery';\nimport Slick from '../../src/slick.core';\n\nexport default RowSelectionModel;\n\nfunction RowSelectionModel(options){\n let _grid;\n let _ranges = [];\n const _self = this;\n const _handler = new Slick.EventHandler();\n let _inHandler;\n let _options;\n const _defaults = {\n selectActiveRow: true\n };\n\n function init(grid){\n _options = Object.assign({}, _defaults, options);\n _grid = grid;\n _handler.subscribe(_grid.onActiveCellChanged,\n wrapHandler(handleActiveCellChange));\n _handler.subscribe(_grid.onKeyDown,\n wrapHandler(handleKeyDown));\n _handler.subscribe(_grid.onClick,\n wrapHandler(handleClick));\n }\n\n function destroy(){\n _handler.unsubscribeAll();\n }\n\n function wrapHandler(handler){\n return function(){\n if (!_inHandler){\n _inHandler = true;\n handler.apply(this, arguments);\n _inHandler = false;\n }\n };\n }\n\n function rangesToRows(ranges){\n const rows = [];\n for (let i = 0; i < ranges.length; i++){\n for (let j = ranges[i].fromRow; j <= ranges[i].toRow; j++){\n rows.push(j);\n }\n }\n return rows;\n }\n\n function rowsToRanges(rows){\n const ranges = [];\n const lastCell = _grid.getColumns().length - 1;\n for (let i = 0; i < rows.length; i++){\n ranges.push(new Slick.Range(rows[i], 0, rows[i], lastCell));\n }\n return ranges;\n }\n\n function getRowsRange(from, to){\n let i;\n const rows = [];\n for (i = from; i <= to; i++){\n rows.push(i);\n }\n for (i = to; i < from; i++){\n rows.push(i);\n }\n return rows;\n }\n\n function getSelectedRows(){\n return rangesToRows(_ranges);\n }\n\n function setSelectedRows(rows){\n setSelectedRanges(rowsToRanges(rows));\n }\n\n function setSelectedRanges(ranges){\n // simle check for: empty selection didn't change, prevent firing onSelectedRangesChanged\n if ((!_ranges || _ranges.length === 0) && (!ranges || ranges.length === 0)){\n return;\n }\n _ranges = ranges;\n _self.onSelectedRangesChanged.notify(_ranges);\n }\n\n function getSelectedRanges(){\n return _ranges;\n }\n\n function handleActiveCellChange(e, data){\n if (_options.selectActiveRow && data.row != null){\n setSelectedRanges([new Slick.Range(data.row, 0, data.row, _grid.getColumns().length - 1)]);\n }\n }\n\n function handleKeyDown(e){\n const activeRow = _grid.getActiveCell();\n if (activeRow && e.shiftKey && !e.ctrlKey && !e.altKey && !e.metaKey && (e.which == 38 || e.which == 40)){\n let selectedRows = getSelectedRows();\n selectedRows.sort(function(x, y){\n return x - y;\n });\n\n if (!selectedRows.length){\n selectedRows = [activeRow.row];\n }\n\n let top = selectedRows[0];\n let bottom = selectedRows[selectedRows.length - 1];\n let active;\n\n if (e.which == 40){\n active = activeRow.row < bottom || top == bottom ? ++bottom : ++top;\n } else {\n active = activeRow.row < bottom ? --bottom : --top;\n }\n\n if (active >= 0 && active < _grid.getDataLength()){\n _grid.scrollRowIntoView(active);\n _ranges = rowsToRanges(getRowsRange(top, bottom));\n setSelectedRanges(_ranges);\n }\n\n e.preventDefault();\n e.stopPropagation();\n }\n }\n\n function handleClick(e){\n const cell = _grid.getCellFromEvent(e);\n if (!cell || !_grid.canCellBeActive(cell.row, cell.cell)){\n return false;\n }\n\n if (!_grid.getOptions().multiSelect || (\n !e.ctrlKey && !e.shiftKey && !e.metaKey)){\n return false;\n }\n\n let selection = rangesToRows(_ranges);\n const idx = $.inArray(cell.row, selection);\n\n if (idx === -1 && (e.ctrlKey || e.metaKey)){\n selection.push(cell.row);\n _grid.setActiveCell(cell.row, cell.cell);\n } else if (idx !== -1 && (e.ctrlKey || e.metaKey)){\n selection = $.grep(selection, function(o, i){\n return (o !== cell.row);\n });\n _grid.setActiveCell(cell.row, cell.cell);\n } else if (selection.length && e.shiftKey){\n const last = selection.pop();\n const from = Math.min(cell.row, last);\n const to = Math.max(cell.row, last);\n selection = [];\n for (let i = from; i <= to; i++){\n if (i !== last){\n selection.push(i);\n }\n }\n selection.push(last);\n _grid.setActiveCell(cell.row, cell.cell);\n }\n\n _ranges = rowsToRanges(selection);\n setSelectedRanges(_ranges);\n e.stopImmediatePropagation();\n\n return true;\n }\n\n Object.assign(this, {\n getSelectedRows,\n setSelectedRows,\n\n getSelectedRanges,\n setSelectedRanges,\n\n init,\n destroy,\n\n 'onSelectedRangesChanged': new Slick.Event()\n });\n}\n\n\n\n// WEBPACK FOOTER //\n// ../plugins/slick.rowselectionmodel/slick.rowselectionmodel.js","import Slick from './slick.core';\nimport Editors from './slick.editors';\nimport Data from './slick.dataview';\nimport Grid from './slick.grid';\nimport FrozenGrid from './slick-frozen.grid';\nimport Formatters from './slick.formatters';\nimport * as Plugins from '../plugins';\n\nexport {\n Slick,\n Editors,\n Formatters,\n Data,\n Grid,\n FrozenGrid,\n Plugins\n}\n\n\n\n// WEBPACK FOOTER //\n// ../src/index.js","/**\n * @license\n * (c) 2009-2013 Michael Leibman\n * michael{dot}leibman{at}gmail{dot}com\n * http://github.com/mleibman/slickgrid\n *\n * Distributed under MIT license.\n * All rights reserved.\n *\n * SlickGrid v2.2\n *\n * NOTES:\n * Cell/row DOM manipulations are done directly bypassing jQuery's DOM manipulation methods.\n * This increases the speed dramatically, but can only be done safely because there are no event handlers\n * or data associated with any cell/row DOM nodes. Cell editors must make sure they implement .destroy()\n * and do proper cleanup.\n */\n\nimport $ from 'jquery';\nimport interact from './interact.js';\n\nimport Slick from './slick.core';\n\n// Slick.Grid globals pretense\nSlick.FrozenGrid = SlickGrid;\n\nexport default SlickGrid;\n\n// shared across all grids on the page\nvar scrollbarDimensions;\nvar maxSupportedCssHeight; // browser's breaking point\n\n//////////////////////////////////////////////////////////////////////////////////////////////\n// SlickGrid class implementation (available as Slick.Grid)\n\n/**\n * Creates a new instance of the grid.\n * @class SlickGrid\n * @constructor\n * @param {Node} container Container node to create the grid in.\n * @param {Array,Object} data An array of objects for databinding.\n * @param {Array} columns An array of column definitions.\n * @param {Object} options Grid options.\n **/\nfunction SlickGrid(container, data, columns, options){\n // settings\n var defaults = {\n explicitInitialization: false,\n rowHeight: 25,\n defaultColumnWidth: 80,\n enableAddRow: false,\n leaveSpaceForNewRows: false,\n editable: false,\n autoEdit: true,\n enableCellNavigation: true,\n enableColumnReorder: true,\n asyncEditorLoading: false,\n asyncEditorLoadDelay: 100,\n forceFitColumns: false,\n enableAsyncPostRender: false,\n asyncPostRenderDelay: 50,\n autoHeight: false,\n editorLock: Slick.GlobalEditorLock,\n showHeaderRow: false,\n headerRowHeight: 25,\n showFooterRow: false,\n footerRowHeight: 25,\n showTopPanel: false,\n topPanelHeight: 25,\n formatterFactory: null,\n editorFactory: null,\n cellFlashingCssClass: \"flashing\",\n selectedCellCssClass: \"selected\",\n multiSelect: true,\n enableTextSelectionOnCells: false,\n dataItemColumnValueExtractor: null,\n frozenBottom: false,\n frozenColumn: -1,\n frozenRow: -1,\n fullWidthRows: false,\n multiColumnSort: false,\n defaultFormatter: defaultFormatter,\n forceSyncScrolling: false,\n addNewRowCssClass: \"new-row\"\n };\n\n var columnDefaults = {\n name: \"\",\n resizable: true,\n sortable: false,\n minWidth: 30,\n rerenderOnResize: false,\n headerCssClass: null,\n defaultSortAsc: true,\n focusable: true,\n selectable: true\n };\n\n // scroller\n var th; // virtual height\n var h; // real scrollable height\n var ph; // page height\n var n; // number of pages\n var cj; // \"jumpiness\" coefficient\n\n var page = 0; // current page\n var offset = 0; // current page offset\n var vScrollDir = 1;\n\n // private\n var initialized = false;\n var $container;\n var uid = \"slickgrid_\" + Math.round(1000000 * Math.random());\n var self = this;\n var $focusSink, $focusSink2;\n var $groupHeaders = $();\n var $headerScroller;\n var $headers;\n var $headerRow, $headerRowScroller, $headerRowSpacerL, $headerRowSpacerR;\n var $footerRow, $footerRowScroller, $footerRowSpacerL, $footerRowSpacerR;\n var $topPanelScroller;\n var $topPanel;\n var $viewport;\n var $canvas;\n var $style;\n var $boundAncestors;\n var treeColumns;\n var stylesheet, columnCssRulesL, columnCssRulesR;\n var viewportH, viewportW;\n var canvasWidth, canvasWidthL, canvasWidthR;\n var headersWidth, headersWidthL, headersWidthR;\n var viewportHasHScroll, viewportHasVScroll;\n var headerColumnWidthDiff = 0,\n headerColumnHeightDiff = 0, // border+padding\n cellWidthDiff = 0,\n cellHeightDiff = 0;\n var absoluteColumnMinWidth;\n var hasFrozenRows = false;\n var frozenRowsHeight = 0;\n var actualFrozenRow = -1;\n var paneTopH = 0;\n var paneBottomH = 0;\n var viewportTopH = 0;\n var viewportBottomH = 0;\n var topPanelH = 0;\n var headerRowH = 0;\n var footerRowH = 0;\n\n var tabbingDirection = 1;\n var $activeCanvasNode;\n var $activeViewportNode;\n var activePosX;\n var activeRow, activeCell;\n var activeCellNode = null;\n var currentEditor = null;\n var serializedEditorValue;\n var editController;\n\n var rowsCache = {};\n var renderedRows = 0;\n var numVisibleRows = 0;\n var prevScrollTop = 0;\n var scrollTop = 0;\n var lastRenderedScrollTop = 0;\n var lastRenderedScrollLeft = 0;\n var prevScrollLeft = 0;\n var scrollLeft = 0;\n\n var selectionModel;\n var selectedRows = [];\n\n var plugins = [];\n var cellCssClasses = {};\n\n var columnsById = {};\n var sortColumns = [];\n var columnPosLeft = [];\n var columnPosRight = [];\n\n // async call handles\n var h_editorLoader = null;\n var h_render = null;\n var h_postrender = null;\n var postProcessedRows = {};\n var postProcessToRow = null;\n var postProcessFromRow = null;\n\n // perf counters\n var counter_rows_rendered = 0;\n var counter_rows_removed = 0;\n\n // These two variables work around a bug with inertial scrolling in Webkit/Blink on Mac.\n // See http://crbug.com/312427.\n var rowNodeFromLastMouseWheelEvent; // this node must not be deleted while inertial scrolling\n var zombieRowNodeFromLastMouseWheelEvent; // node that was hidden instead of getting deleted\n\n var $paneHeaderL;\n var $paneHeaderR;\n var $paneTopL;\n var $paneTopR;\n var $paneBottomL;\n var $paneBottomR;\n\n var $headerScrollerL;\n var $headerScrollerR;\n\n var $headerL;\n var $headerR;\n\n var $groupHeadersL;\n var $groupHeadersR;\n\n var $headerRowScrollerL;\n var $headerRowScrollerR;\n\n var $footerRowScrollerL;\n var $footerRowScrollerR;\n\n var $headerRowL;\n var $headerRowR;\n\n var $footerRowL;\n var $footerRowR;\n\n var $topPanelScrollerL;\n var $topPanelScrollerR;\n\n var $topPanelL;\n var $topPanelR;\n\n var $viewportTopL;\n var $viewportTopR;\n var $viewportBottomL;\n var $viewportBottomR;\n\n var $canvasTopL;\n var $canvasTopR;\n var $canvasBottomL;\n var $canvasBottomR;\n\n var $viewportScrollContainerX;\n var $viewportScrollContainerY;\n var $headerScrollContainer;\n var $headerRowScrollContainer;\n var $footerRowScrollContainer;\n\n //////////////////////////////////////////////////////////////////////////////////////////////\n // Initialization\n\n function init(){\n $container = $(container);\n if ($container.length < 1){\n throw new Error(\"SlickGrid requires a valid container, \" + container + \" does not exist in the DOM.\");\n }\n\n // calculate these only once and share between grid instances\n maxSupportedCssHeight = maxSupportedCssHeight || getMaxSupportedCssHeight();\n scrollbarDimensions = scrollbarDimensions || measureScrollbar();\n\n options = $.extend({}, defaults, options);\n validateAndEnforceOptions();\n columnDefaults.width = options.defaultColumnWidth;\n\n treeColumns = new Slick.TreeColumns(columns);\n columns = treeColumns.extractColumns();\n\n columnsById = {};\n for (var i = 0; i < columns.length; i++){\n var m = columns[i] = $.extend({}, columnDefaults, columns[i]);\n columnsById[m.id] = i;\n if (m.minWidth && m.width < m.minWidth){\n m.width = m.minWidth;\n }\n if (m.maxWidth && m.width > m.maxWidth){\n m.width = m.maxWidth;\n }\n }\n\n editController = {\n \"commitCurrentEdit\": commitCurrentEdit,\n \"cancelCurrentEdit\": cancelCurrentEdit\n };\n\n $container.empty()\n .css(\"overflow\", \"hidden\")\n .css(\"outline\", 0)\n .addClass(uid)\n .addClass(\"ui-widget\");\n\n // set up a positioning container if needed\n if (!/relative|absolute|fixed/.test($container.css(\"position\"))){\n $container.css(\"position\", \"relative\");\n }\n\n $focusSink = $(\"\").appendTo($container);\n\n // Containers used for scrolling frozen columns and rows\n $paneHeaderL = $(\"\").appendTo($container);\n $paneHeaderR = $(\"\").appendTo($container);\n $paneTopL = $(\"\").appendTo($container);\n $paneTopR = $(\"\").appendTo($container);\n $paneBottomL = $(\"\").appendTo($container);\n $paneBottomR = $(\"\").appendTo($container);\n\n // Append the header scroller containers\n $headerScrollerL = $(\"\").appendTo($paneHeaderL);\n $headerScrollerR = $(\"\").appendTo($paneHeaderR);\n\n // Cache the header scroller containers\n $headerScroller = $().add($headerScrollerL).add($headerScrollerR);\n\n if (treeColumns.hasDepth()){\n $groupHeadersL = [], $groupHeadersR = [];\n for (var index = 0; index < treeColumns.getDepth() - 1; index++){\n $groupHeadersL[index] = $(\"\").appendTo($headerScrollerL);\n $groupHeadersR[index] = $(\"\").appendTo($headerScrollerR);\n }\n\n $groupHeaders = $().add($groupHeadersL).add($groupHeadersR);\n }\n\n // Append the columnn containers to the headers\n $headerL = $(\"\").appendTo($headerScrollerL);\n $headerR = $(\"\").appendTo($headerScrollerR);\n\n // Cache the header columns\n $headers = $().add($headerL).add($headerR);\n\n $headerRowScrollerL = $(\"\").appendTo($paneTopL);\n $headerRowScrollerR = $(\"\").appendTo($paneTopR);\n\n $headerRowScroller = $().add($headerRowScrollerL).add($headerRowScrollerR);\n\n $headerRowSpacerL = $(\"\")\n .css(\"width\", getCanvasWidth() + scrollbarDimensions.width + \"px\")\n .appendTo($headerRowScrollerL);\n $headerRowSpacerR = $(\"\")\n .css(\"width\", getCanvasWidth() + scrollbarDimensions.width + \"px\")\n .appendTo($headerRowScrollerR);\n\n $headerRowL = $(\"\").appendTo($headerRowScrollerL);\n $headerRowR = $(\"\").appendTo($headerRowScrollerR);\n\n $headerRow = $().add($headerRowL).add($headerRowR);\n\n // Append the top panel scroller\n $topPanelScrollerL = $(\"\").appendTo($paneTopL);\n $topPanelScrollerR = $(\"\").appendTo($paneTopR);\n\n $topPanelScroller = $().add($topPanelScrollerL).add($topPanelScrollerR);\n\n // Append the top panel\n $topPanelL = $(\"\").appendTo($topPanelScrollerL);\n $topPanelR = $(\"\").appendTo($topPanelScrollerR);\n\n $topPanel = $().add($topPanelL).add($topPanelR);\n\n if (!options.showTopPanel){\n $topPanelScroller.hide();\n }\n\n if (!options.showHeaderRow){\n $headerRowScroller.hide();\n }\n\n // Append the viewport containers\n $viewportTopL = $(\"\").appendTo($paneTopL);\n $viewportTopR = $(\"\").appendTo($paneTopR);\n $viewportBottomL = $(\"\").appendTo($paneBottomL);\n $viewportBottomR = $(\"\").appendTo($paneBottomR);\n\n // Cache the viewports\n $viewport = $().add($viewportTopL).add($viewportTopR).add($viewportBottomL).add($viewportBottomR);\n\n // Default the active viewport to the top left\n $activeViewportNode = $viewportTopL;\n\n // Append the canvas containers\n $canvasTopL = $(\"\").appendTo($viewportTopL);\n $canvasTopR = $(\"\").appendTo($viewportTopR);\n $canvasBottomL = $(\"\").appendTo($viewportBottomL);\n $canvasBottomR = $(\"\").appendTo($viewportBottomR);\n\n // Cache the canvases\n $canvas = $().add($canvasTopL).add($canvasTopR).add($canvasBottomL).add($canvasBottomR);\n\n // Default the active canvas to the top left\n $activeCanvasNode = $canvasTopL;\n\n // footer Row\n $footerRowScrollerR = $(\"\").appendTo($paneTopR);\n $footerRowScrollerL = $(\"\").appendTo($paneTopL);\n\n $footerRowScroller = $().add($footerRowScrollerL).add($footerRowScrollerR);\n\n $footerRowSpacerL = $(\"\")\n .css(\"width\", getCanvasWidth() + scrollbarDimensions.width + \"px\")\n .appendTo($footerRowScrollerL);\n $footerRowSpacerR = $(\"\")\n .css(\"width\", getCanvasWidth() + scrollbarDimensions.width + \"px\")\n .appendTo($footerRowScrollerR);\n\n $footerRowL = $(\"\").appendTo($footerRowScrollerL);\n $footerRowR = $(\"\").appendTo($footerRowScrollerR);\n\n $footerRow = $().add($footerRowL).add($footerRowR);\n\n if (!options.showFooterRow){\n $footerRowScroller.hide();\n }\n\n $focusSink2 = $focusSink.clone().appendTo($container);\n\n if (!options.explicitInitialization){\n finishInitialization();\n }\n }\n\n function finishInitialization(){\n if (!initialized){\n initialized = true;\n\n getViewportWidth();\n getViewportHeight();\n\n // header columns and cells may have different padding/border skewing width calculations (box-sizing, hello?)\n // calculate the diff so we can set consistent sizes\n measureCellPaddingAndBorder();\n\n // for usability reasons, all text selection in SlickGrid is disabled\n // with the exception of input and textarea elements (selection must\n // be enabled there so that editors work as expected); note that\n // selection in grid cells (grid body) is already unavailable in\n // all browsers except IE\n disableSelection($headers); // disable all text selection in header (including input and textarea)\n\n if (!options.enableTextSelectionOnCells){\n // disable text selection in grid cells except in input and textarea elements\n // (this is IE-specific, because selectstart event will only fire in IE)\n $viewport.bind(\"selectstart.ui\", function(event){\n return $(event.target).is(\"input,textarea\");\n });\n }\n\n setFrozenOptions();\n setPaneVisibility();\n setScroller();\n setOverflow();\n\n updateColumnCaches();\n createColumnHeaders();\n createColumnGroupHeaders();\n createColumnFooter();\n setupColumnSort();\n createCssRules();\n resizeCanvas();\n bindAncestorScrollEvents();\n\n $container.bind(\"resize.slickgrid\", resizeCanvas);\n $viewport.on(\"scroll\", handleScroll);\n\n if ($.fn.mousewheel && (options.frozenColumn > -1 || hasFrozenRows)){\n $viewport.on(\"mousewheel\", handleMouseWheel);\n }\n\n $headerScroller.bind(\"contextmenu\", handleHeaderContextMenu)\n .bind(\"click\", handleHeaderClick)\n .delegate(\".slick-header-column\", \"mouseenter\", handleHeaderMouseEnter)\n .delegate(\".slick-header-column\", \"mouseleave\", handleHeaderMouseLeave);\n $headerRowScroller.bind(\"scroll\", handleHeaderRowScroll);\n\n $footerRowScroller.bind(\"scroll\", handleFooterRowScroll);\n\n $focusSink.add($focusSink2)\n .bind(\"keydown\", handleKeyDown);\n $canvas.bind(\"keydown\", handleKeyDown)\n .bind(\"click\", handleClick)\n .bind(\"dblclick\", handleDblClick)\n .bind(\"contextmenu\", handleContextMenu)\n .delegate(\".slick-cell\", \"mouseenter\", handleMouseEnter)\n .delegate(\".slick-cell\", \"mouseleave\", handleMouseLeave);\n\n // legacy support for drag events\n interact($canvas[0]).allowFrom('div.slick-cell').draggable({\n onmove: handleDrag,\n onstart: handleDragStart,\n onend: handleDragEnd\n }).styleCursor(false);\n\n // Work around http://crbug.com/312427.\n if (navigator.userAgent.toLowerCase().match(/webkit/) && navigator.userAgent.toLowerCase().match(/macintosh/)){\n $canvas.on(\"mousewheel\", handleMouseWheel);\n }\n }\n }\n\n function hasFrozenColumns(){\n return options.frozenColumn > -1;\n }\n\n function registerPlugin(plugin){\n plugins.unshift(plugin);\n plugin.init(self);\n }\n\n function unregisterPlugin(plugin){\n for (var i = plugins.length; i >= 0; i--){\n if (plugins[i] === plugin){\n if (plugins[i].destroy){\n plugins[i].destroy();\n }\n plugins.splice(i, 1);\n break;\n }\n }\n }\n\n function setSelectionModel(model){\n if (selectionModel){\n selectionModel.onSelectedRangesChanged.unsubscribe(handleSelectedRangesChanged);\n if (selectionModel.destroy){\n selectionModel.destroy();\n }\n }\n\n selectionModel = model;\n if (selectionModel){\n selectionModel.init(self);\n selectionModel.onSelectedRangesChanged.subscribe(handleSelectedRangesChanged);\n }\n }\n\n function getSelectionModel(){\n return selectionModel;\n }\n\n function getCanvasNode(){\n return $canvas[0];\n }\n\n function getActiveCanvasNode(element){\n setActiveCanvasNode(element);\n\n return $activeCanvasNode[0];\n }\n\n function getCanvases(){\n return $canvas;\n }\n\n function setActiveCanvasNode(element){\n if (element){\n $activeCanvasNode = $(element.target).closest('.grid-canvas');\n }\n }\n\n function getViewportNode(){\n return $viewport[0];\n }\n\n function getActiveViewportNode(element){\n setActiveViewPortNode(element);\n\n return $activeViewportNode[0];\n }\n\n function setActiveViewportNode(element){\n if (element){\n $activeViewportNode = $(element.target).closest('.slick-viewport');\n }\n }\n\n function measureScrollbar(){\n var $c = $(\"\").appendTo(document.body);\n var dim = {\n width: $c.width() - $c[0].clientWidth,\n height: $c.height() - $c[0].clientHeight\n };\n $c.remove();\n return dim;\n }\n\n function getHeadersWidth(){\n headersWidth = headersWidthL = headersWidthR = 0;\n\n for (var i = 0, ii = columns.length; i < ii; i++){\n var width = columns[i].width;\n\n if ((options.frozenColumn) > -1 && (i > options.frozenColumn)){\n headersWidthR += width;\n } else {\n headersWidthL += width;\n }\n }\n\n if (hasFrozenColumns()){\n headersWidthL = headersWidthL + 1000;\n\n headersWidthR = Math.max(headersWidthR, viewportW) + headersWidthL;\n headersWidthR += scrollbarDimensions.width;\n } else {\n headersWidthL += scrollbarDimensions.width;\n headersWidthL = Math.max(headersWidthL, viewportW) + 1000;\n }\n\n headersWidth = headersWidthL + headersWidthR;\n }\n\n function getHeadersWidthL(){\n headersWidthL = 0;\n\n columns.forEach(function(column, i){\n if (!((options.frozenColumn) > -1 && (i > options.frozenColumn))) headersWidthL += column.width;\n });\n\n if (hasFrozenColumns()){\n headersWidthL += 1000;\n } else {\n headersWidthL += scrollbarDimensions.width;\n headersWidthL = Math.max(headersWidthL, viewportW) + 1000;\n }\n\n return headersWidthL;\n }\n\n function getHeadersWidthR(){\n headersWidthR = 0;\n\n columns.forEach(function(column, i){\n if ((options.frozenColumn) > -1 && (i > options.frozenColumn)) headersWidthR += column.width;\n });\n\n if (hasFrozenColumns()){\n headersWidthR = Math.max(headersWidthR, viewportW) + getHeadersWidthL();\n headersWidthR += scrollbarDimensions.width;\n }\n\n return headersWidthR;\n }\n\n function getCanvasWidth(){\n var availableWidth = viewportHasVScroll ? viewportW - scrollbarDimensions.width : viewportW;\n\n var i = columns.length;\n\n canvasWidthL = canvasWidthR = 0;\n\n while (i--){\n if (hasFrozenColumns() && (i > options.frozenColumn)){\n canvasWidthR += columns[i].width;\n } else {\n canvasWidthL += columns[i].width;\n }\n }\n\n var totalRowWidth = canvasWidthL + canvasWidthR;\n\n return options.fullWidthRows ? Math.max(totalRowWidth, availableWidth) : totalRowWidth;\n }\n\n function updateCanvasWidth(forceColumnWidthsUpdate){\n var oldCanvasWidth = canvasWidth;\n var oldCanvasWidthL = canvasWidthL;\n var oldCanvasWidthR = canvasWidthR;\n var widthChanged;\n canvasWidth = getCanvasWidth();\n\n widthChanged = canvasWidth !== oldCanvasWidth || canvasWidthL !== oldCanvasWidthL || canvasWidthR !== oldCanvasWidthR;\n\n if (widthChanged || hasFrozenColumns() || hasFrozenRows){\n $canvasTopL.width(canvasWidthL);\n\n getHeadersWidth();\n\n $headerL.width(headersWidthL);\n $headerR.width(headersWidthR);\n\n if (hasFrozenColumns()){\n $canvasTopR.width(canvasWidthR);\n\n $paneHeaderL.width(canvasWidthL);\n $paneHeaderR.css('left', canvasWidthL);\n $paneHeaderR.css('width', viewportW - canvasWidthL);\n\n $paneTopL.width(canvasWidthL);\n $paneTopR.css('left', canvasWidthL);\n $paneTopR.css('width', viewportW - canvasWidthL);\n\n $headerRowScrollerL.width(canvasWidthL);\n $headerRowScrollerR.width(viewportW - canvasWidthL);\n\n $headerRowL.width(canvasWidthL);\n $headerRowR.width(canvasWidthR);\n\n $footerRowScrollerL.width(canvasWidthL);\n $footerRowScrollerR.width(viewportW - canvasWidthL);\n\n $footerRowL.width(canvasWidthL);\n $footerRowR.width(canvasWidthR);\n\n $viewportTopL.width(canvasWidthL);\n $viewportTopR.width(viewportW - canvasWidthL);\n\n if (hasFrozenRows){\n $paneBottomL.width(canvasWidthL);\n $paneBottomR.css('left', canvasWidthL);\n\n $viewportBottomL.width(canvasWidthL);\n $viewportBottomR.width(viewportW - canvasWidthL);\n\n $canvasBottomL.width(canvasWidthL);\n $canvasBottomR.width(canvasWidthR);\n }\n } else {\n $paneHeaderL.width('100%');\n\n $paneTopL.width('100%');\n\n $headerRowScrollerL.width('100%');\n\n $headerRowL.width(canvasWidth);\n\n $footerRowScrollerL.width('100%');\n\n $footerRowL.width(canvasWidth);\n\n $viewportTopL.width('100%');\n\n if (hasFrozenRows){\n $viewportBottomL.width('100%');\n $canvasBottomL.width(canvasWidthL);\n }\n }\n\n viewportHasHScroll = (canvasWidth > viewportW - scrollbarDimensions.width);\n }\n\n $headerRowSpacerL.width(canvasWidth + (viewportHasVScroll ? scrollbarDimensions.width : 0));\n $headerRowSpacerR.width(canvasWidth + (viewportHasVScroll ? scrollbarDimensions.width : 0));\n\n $footerRowSpacerL.width(canvasWidth + (viewportHasVScroll ? scrollbarDimensions.width : 0));\n $footerRowSpacerR.width(canvasWidth + (viewportHasVScroll ? scrollbarDimensions.width : 0));\n\n if (widthChanged || forceColumnWidthsUpdate){\n applyColumnWidths();\n }\n }\n\n function disableSelection($target){\n if ($target && $target.jquery){\n $target.attr(\"unselectable\", \"on\")\n .css(\"MozUserSelect\", \"none\")\n .bind(\"selectstart.ui\", function(){\n return false;\n }); // from jquery:ui.core.js 1.7.2\n }\n }\n\n function getMaxSupportedCssHeight(){\n var supportedHeight = 1000000;\n // FF reports the height back but still renders blank after ~6M px\n var testUpTo = navigator.userAgent.toLowerCase().match(/firefox/) ? 6000000 : 1000000000;\n var div = $(\"\").appendTo(document.body);\n\n while (true){\n var test = supportedHeight * 2;\n div.css(\"height\", test);\n if (test > testUpTo || div.height() !== test){\n break;\n } else {\n supportedHeight = test;\n }\n }\n\n div.remove();\n return supportedHeight;\n }\n\n // TODO: this is static. need to handle page mutation.\n function bindAncestorScrollEvents(){\n var elem = (hasFrozenRows && !options.frozenBottom) ? $canvasBottomL[0] : $canvasTopL[0];\n while ((elem = elem.parentNode) != document.body && elem != null){\n // bind to scroll containers only\n if (elem == $viewportTopL[0] || elem.scrollWidth != elem.clientWidth || elem.scrollHeight != elem.clientHeight){\n var $elem = $(elem);\n if (!$boundAncestors){\n $boundAncestors = $elem;\n } else {\n $boundAncestors = $boundAncestors.add($elem);\n }\n $elem.bind(\"scroll.\" + uid, handleActiveCellPositionChange);\n }\n }\n }\n\n function unbindAncestorScrollEvents(){\n if (!$boundAncestors){\n return;\n }\n $boundAncestors.unbind(\"scroll.\" + uid);\n $boundAncestors = null;\n }\n\n function updateColumnHeader(columnId, title, toolTip){\n if (!initialized){\n return;\n }\n var idx = getColumnIndex(columnId);\n if (idx == null){\n return;\n }\n\n var columnDef = columns[idx];\n var $header = $headers.children().eq(idx);\n if ($header){\n if (title !== undefined){\n columns[idx].name = title;\n }\n if (toolTip !== undefined){\n columns[idx].toolTip = toolTip;\n }\n\n trigger(self.onBeforeHeaderCellDestroy, {\n \"node\": $header[0],\n \"column\": columnDef\n });\n\n $header.attr(\"title\", toolTip || \"\")\n .children().eq(0).html(title);\n\n trigger(self.onHeaderCellRendered, {\n \"node\": $header[0],\n \"column\": columnDef\n });\n }\n }\n\n function getHeaderRow(){\n return hasFrozenColumns() ? $headerRow : $headerRow[0];\n }\n\n function getHeaderRowColumn(columnId){\n var idx = getColumnIndex(columnId);\n\n var $headerRowTarget;\n\n if (hasFrozenColumns()){\n if (idx <= options.frozenColumn){\n $headerRowTarget = $headerRowL;\n } else {\n $headerRowTarget = $headerRowR;\n\n idx -= options.frozenColumn + 1;\n }\n } else {\n $headerRowTarget = $headerRowL;\n }\n\n var $header = $headerRowTarget.children().eq(idx);\n return $header && $header[0];\n }\n\n function getFooterRow(){\n return hasFrozenColumns() ? $footerRow : $footerRow[0];\n }\n\n function getFooterRowColumn(columnId){\n var idx = getColumnIndex(columnId);\n\n var $footerRowTarget;\n\n if (hasFrozenColumns()){\n if (idx <= options.frozenColumn){\n $footerRowTarget = $footerRowL;\n } else {\n $footerRowTarget = $footerRowR;\n\n idx -= options.frozenColumn + 1;\n }\n } else {\n $footerRowTarget = $footerRowL;\n }\n\n var $footer = $footerRowTarget.children().eq(idx);\n return $footer && $footer[0];\n }\n\n function createColumnFooter(){\n $footerRow.find(\".slick-footerrow-column\")\n .each(function(){\n var columnDef = $(this).data(\"column\");\n if (columnDef){\n trigger(self.onBeforeFooterRowCellDestroy, {\n \"node\": this,\n \"column\": columnDef\n });\n }\n });\n\n $footerRowL.empty();\n $footerRowR.empty();\n\n for (var i = 0; i < columns.length; i++){\n var m = columns[i];\n\n var footerRowCell = $(\"\")\n .data(\"column\", m)\n .addClass(hasFrozenColumns() && i <= options.frozenColumn ? 'frozen' : '')\n .appendTo(hasFrozenColumns() && (i > options.frozenColumn) ? $footerRowR : $footerRowL);\n\n trigger(self.onFooterRowCellRendered, {\n \"node\": footerRowCell[0],\n \"column\": m\n });\n }\n }\n\n function createColumnGroupHeaders(){\n var columnsLength = 0;\n var frozenColumnsValid = false;\n\n if (!treeColumns.hasDepth()) return;\n\n for (var index = 0; index < $groupHeadersL.length; index++){\n\n $groupHeadersL[index].empty();\n $groupHeadersR[index].empty();\n\n var groupColumns = treeColumns.getColumnsInDepth(index);\n\n for (var indexGroup in groupColumns){\n var m = groupColumns[indexGroup];\n\n columnsLength += m.extractColumns().length;\n\n if (hasFrozenColumns() && index == 0 && (columnsLength - 1) === options.frozenColumn) frozenColumnsValid = true;\n\n $(\"\")\n .html(\"\" + m.name + \"\")\n .attr(\"id\", \"\" + uid + m.id)\n .attr(\"title\", m.toolTip || \"\")\n .data(\"column\", m)\n .addClass(m.headerCssClass || \"\")\n .addClass(hasFrozenColumns() && (columnsLength - 1) <= options.frozenColumn ? 'frozen' : '')\n .appendTo(hasFrozenColumns() && (columnsLength - 1) > options.frozenColumn ? $groupHeadersR[index] : $groupHeadersL[index]);\n }\n\n if (hasFrozenColumns() && index == 0 && !frozenColumnsValid){\n $groupHeadersL[index].empty();\n $groupHeadersR[index].empty();\n alert(\"All columns of group should to be grouped!\");\n break;\n }\n }\n\n applyColumnGroupHeaderWidths();\n }\n\n function createColumnHeaders(){\n function onMouseEnter(){\n $(this).addClass(\"ui-state-hover\");\n }\n\n function onMouseLeave(){\n $(this).removeClass(\"ui-state-hover\");\n }\n\n $headers.find(\".slick-header-column\")\n .each(function(){\n var columnDef = $(this).data(\"column\");\n if (columnDef){\n trigger(self.onBeforeHeaderCellDestroy, {\n \"node\": this,\n \"column\": columnDef\n });\n }\n });\n\n $headerL.empty();\n $headerR.empty();\n\n getHeadersWidth();\n\n $headerL.width(headersWidthL);\n $headerR.width(headersWidthR);\n\n $headerRow.find(\".slick-headerrow-column\")\n .each(function(){\n var columnDef = $(this).data(\"column\");\n if (columnDef){\n trigger(self.onBeforeHeaderRowCellDestroy, {\n \"node\": this,\n \"column\": columnDef\n });\n }\n });\n\n $headerRowL.empty();\n $headerRowR.empty();\n\n for (var i = 0; i < columns.length; i++){\n var m = columns[i];\n\n var $headerTarget = hasFrozenColumns() ? ((i <= options.frozenColumn) ? $headerL : $headerR) : $headerL;\n var $headerRowTarget = hasFrozenColumns() ? ((i <= options.frozenColumn) ? $headerRowL : $headerRowR) : $headerRowL;\n\n var header = $(\"\")\n .html(\"\" + m.name + \"\")\n .width(m.width - headerColumnWidthDiff)\n .attr(\"id\", \"\" + uid + m.id)\n .attr(\"title\", m.toolTip || \"\")\n .data(\"column\", m)\n .addClass(m.headerCssClass || \"\")\n .addClass(hasFrozenColumns() && i <= options.frozenColumn ? 'frozen' : '')\n .appendTo($headerTarget);\n\n if (options.enableColumnReorder || m.sortable){\n header.on('mouseenter', onMouseEnter)\n .on('mouseleave', onMouseLeave);\n }\n\n if (m.sortable){\n header.addClass(\"slick-header-sortable\");\n header.append(\"\");\n }\n\n trigger(self.onHeaderCellRendered, {\n \"node\": header[0],\n \"column\": m\n });\n\n if (options.showHeaderRow){\n var headerRowCell = $(\"\")\n .data(\"column\", m)\n .appendTo($headerRowTarget);\n\n trigger(self.onHeaderRowCellRendered, {\n \"node\": headerRowCell[0],\n \"column\": m\n });\n }\n }\n\n setSortColumns(sortColumns);\n setupColumnResize();\n if (options.enableColumnReorder){\n setupColumnReorder();\n }\n }\n\n function setupColumnSort(){\n $headers.click(function(e){\n // temporary workaround for a bug in jQuery 1.7.1 (http://bugs.jquery.com/ticket/11328)\n e.metaKey = e.metaKey || e.ctrlKey;\n\n if ($(e.target).hasClass(\"slick-resizable-handle\")){\n return;\n }\n\n var $col = $(e.target).closest(\".slick-header-column\");\n if (!$col.length){\n return;\n }\n\n var column = $col.data(\"column\");\n if (column.sortable){\n if (!getEditorLock().commitCurrentEdit()){\n return;\n }\n\n var sortOpts = null;\n var i = 0;\n for (; i < sortColumns.length; i++){\n if (sortColumns[i].columnId == column.id){\n sortOpts = sortColumns[i];\n sortOpts.sortAsc = !sortOpts.sortAsc;\n break;\n }\n }\n\n if (e.metaKey && options.multiColumnSort){\n if (sortOpts){\n sortColumns.splice(i, 1);\n }\n } else {\n if ((!e.shiftKey && !e.metaKey) || !options.multiColumnSort){\n sortColumns = [];\n }\n\n if (!sortOpts){\n sortOpts = {\n columnId: column.id,\n sortAsc: column.defaultSortAsc\n };\n sortColumns.push(sortOpts);\n } else if (sortColumns.length == 0){\n sortColumns.push(sortOpts);\n }\n }\n\n setSortColumns(sortColumns);\n\n if (!options.multiColumnSort){\n trigger(self.onSort, {\n multiColumnSort: false,\n sortCol: column,\n sortAsc: sortOpts.sortAsc\n }, e);\n } else {\n trigger(self.onSort, {\n multiColumnSort: true,\n sortCols: $.map(sortColumns, function(col){\n return {\n sortCol: columns[getColumnIndex(col.columnId)],\n sortAsc: col.sortAsc\n };\n })\n }, e);\n }\n }\n });\n }\n\n function currentPositionInHeader(id){\n var currentPosition = 0;\n $headers.find('.slick-header-column').each(function(i){\n if (this.id == id){\n currentPosition = i;\n return false;\n }\n });\n\n return currentPosition;\n }\n\n function limitPositionInGroup(idColumn){\n var groupColumnOfPreviousPosition,\n startLimit = 0,\n endLimit = 0;\n\n treeColumns.getColumnsInDepth($groupHeadersL.length - 1)\n .some(function(groupColumn){\n startLimit = endLimit;\n endLimit += groupColumn.columns.length;\n\n groupColumn.columns.some(function(column){\n\n if (column.id === idColumn) groupColumnOfPreviousPosition = groupColumn;\n\n return groupColumnOfPreviousPosition;\n });\n\n return groupColumnOfPreviousPosition;\n });\n\n endLimit--;\n\n return {\n start: startLimit,\n end: endLimit,\n group: groupColumnOfPreviousPosition\n }\n }\n\n function remove(arr, elem){\n var index = arr.lastIndexOf(elem);\n if (index > -1){\n arr.splice(index, 1);\n remove(arr, elem);\n }\n }\n\n function columnPositionValidInGroup($item){\n var currentPosition = currentPositionInHeader($item[0].id);\n var limit = limitPositionInGroup($item.data('column').id);\n var positionValid = limit.start <= currentPosition && currentPosition <= limit.end;\n\n return {\n limit: limit,\n valid: positionValid,\n message: positionValid ? '' : 'Column \"'.concat($item.text(), '\" can be reordered only within the \"', limit.group.name, '\" group!')\n };\n }\n\n function setupColumnReorder(){\n let x = 0;\n let delta = 0;\n let placeholder = document.createElement('div');\n\n placeholder.className = 'interact-placeholder';\n\n interact('.slick-header-column')\n .ignoreFrom('.slick-resizable-handle')\n .draggable({\n inertia: true,\n // keep the element within the area of it's parent\n restrict: {\n restriction: 'parent',\n endOnly: true,\n elementRect: {top: 0, left: 0, bottom: 0, right: 0}\n },\n // enable autoScroll\n autoScroll: true,\n axis: 'x',\n onstart: event => {\n x = 0;\n delta = event.target.offsetWidth;\n\n // get old order\n $headers.find('.slick-header-column').each(function(index){\n $(this).data('index', index);\n });\n\n placeholder.style.height = event.target.offsetHeight + 'px';\n placeholder.style.width = delta + 'px';\n\n $(event.target).after(placeholder).css({\n position: 'absolute',\n zIndex: 1000,\n marginLeft: $(event.target).position().left - 1000\n });\n },\n\n onmove: event => {\n x += event.dx;\n event.target.style.transform = `translate3d(${x}px, -3px, 100px)`;\n // event.target.style.marginLeft = x + 'px';\n },\n\n onend: event => {\n x = 0;\n delta = 0;\n\n if (treeColumns.hasDepth()) {\n var validPositionInGroup = columnPositionValidInGroup($(event.target));\n var limit = validPositionInGroup.limit;\n\n var cancel = !validPositionInGroup.valid;\n\n if (cancel)\n alert(validPositionInGroup.message);\n }\n\n placeholder.parentNode.removeChild(placeholder);\n\n if (cancel){\n event.target.style.transform = 'none';\n setColumns(getColumns());\n return;\n }\n\n $(event.target).css({\n position: 'relative',\n zIndex: '',\n marginLeft: 0,\n transform: 'none'\n });\n\n const newColumns = [];\n $headers.find('.slick-header-column').each(function(index){\n newColumns.push(columns[$(this).data('index')]);\n $(this).removeData('index');\n });\n\n setColumns(newColumns);\n\n trigger(self.onColumnsReordered, { impactedColumns : getImpactedColumns( limit ), grid: self });\n setupColumnResize();\n }\n })\n .dropzone({\n accept: '.slick-header-column',\n\n ondragenter: event => {\n event.target.classList.add('interact-drop-active');\n event.relatedTarget.classList.add('interact-can-drop');\n },\n\n ondragleave: event => {\n event.target.classList.remove('interact-drop-active');\n event.relatedTarget.classList.remove('interact-can-drop');\n },\n\n ondrop: event => {\n event.target.classList.remove('interact-drop-active');\n event.relatedTarget.classList.remove('interact-can-drop');\n $(event.target)[x > 0 ? 'after' : 'before'](event.relatedTarget);\n }\n }).styleCursor(false);\n }\n\n function getImpactedColumns(limit){\n var impactedColumns = [];\n\n if (limit != undefined){\n\n for (var i = limit.start; i <= limit.end; i++){\n impactedColumns.push(columns[i]);\n }\n } else {\n\n impactedColumns = columns;\n }\n\n return impactedColumns;\n }\n\n function setupColumnResize(){\n var $col, j, c, pageX, columnElements, minPageX, maxPageX, firstResizable, lastResizable;\n columnElements = $headers.children();\n columnElements.find('.slick-resizable-handle').remove();\n columnElements.each(function(i, e){\n if (columns[i].resizable){\n if (firstResizable === undefined){\n firstResizable = i;\n }\n lastResizable = i;\n }\n });\n if (firstResizable === undefined){\n return;\n }\n columnElements.each(function(i, element){\n if (i < firstResizable || (options.forceFitColumns && i >= lastResizable)){\n return;\n }\n $col = $(element);\n\n const $handle = $(\"\");\n $handle.appendTo(element);\n\n if ($col.data('resizable'))\n return;\n\n const activeColumn = columns[i];\n if (activeColumn.resizable){\n $col.data('resizable', true);\n interact(element).resizable({\n preserveAspectRatio: false,\n edges: { left: true, right: true, bottom: false, top: false }\n }).on('resizestart', function(event){\n if (!getEditorLock().commitCurrentEdit()){\n return false;\n }\n activeColumn.previousWidth = event.rect.width;\n event.target.classList.add('slick-header-column-active');\n }).on('resizemove', function(event){\n let x = event.dx;\n let width = activeColumn.width += x;\n\n if (activeColumn.minWidth > 0 && activeColumn.minWidth > width)\n width = activeColumn.minWidth;\n else if (activeColumn.maxWidth > 0 && activeColumn.maxWidth < width)\n width = activeColumn.maxWidth;\n\n activeColumn.width = width;\n\n if (options.forceFitColumns){\n autosizeColumns();\n }\n applyColumnHeaderWidths();\n if (options.syncColumnCellResize){\n applyColumnWidths();\n }\n }).on('resizeend', function(event){\n event.target.classList.remove('slick-header-column-active');\n if (treeColumns.hasDepth())\n createColumnGroupHeaders();\n\n invalidateAllRows();\n updateCanvasWidth(true);\n render();\n trigger(self.onColumnsResized, {grid: self});\n });\n }\n });\n }\n\n function getVBoxDelta($el){\n var p = [\"borderTopWidth\", \"borderBottomWidth\", \"paddingTop\", \"paddingBottom\"];\n var delta = 0;\n $.each(p, function(n, val){\n delta += parseFloat($el.css(val)) || 0;\n });\n return delta;\n }\n\n function setFrozenOptions(){\n options.frozenColumn = (options.frozenColumn >= 0 && options.frozenColumn < columns.length) ? parseInt(options.frozenColumn) : -1;\n\n options.frozenRow = (options.frozenRow >= 0 && options.frozenRow < numVisibleRows) ? parseInt(options.frozenRow) : -1;\n\n if (options.frozenRow > -1){\n hasFrozenRows = true;\n frozenRowsHeight = (options.frozenRow) * options.rowHeight;\n\n var dataLength = getDataLength() || this.data.length;\n\n actualFrozenRow = (options.frozenBottom) ? (dataLength - options.frozenRow) : options.frozenRow;\n } else {\n hasFrozenRows = false;\n }\n }\n\n function setPaneVisibility(){\n if (hasFrozenColumns()){\n $paneHeaderR.show();\n $paneTopR.show();\n\n if (hasFrozenRows){\n $paneBottomL.show();\n $paneBottomR.show();\n } else {\n $paneBottomR.hide();\n $paneBottomL.hide();\n }\n } else {\n $paneHeaderR.hide();\n $paneTopR.hide();\n $paneBottomR.hide();\n\n if (hasFrozenRows){\n $paneBottomL.show();\n } else {\n $paneBottomR.hide();\n $paneBottomL.hide();\n }\n }\n }\n\n function setOverflow(){\n $viewportTopL.css({\n 'overflow-x': (hasFrozenColumns()) ? (hasFrozenRows ? 'hidden' : 'scroll') : (hasFrozenRows ? 'hidden' : 'auto'),\n 'overflow-y': (hasFrozenColumns()) ? (hasFrozenRows ? 'hidden' : 'hidden') : (hasFrozenRows ? 'scroll' : 'auto')\n });\n\n $viewportTopR.css({\n 'overflow-x': (hasFrozenColumns()) ? (hasFrozenRows ? 'hidden' : 'scroll') : (hasFrozenRows ? 'hidden' : 'auto'),\n 'overflow-y': (hasFrozenColumns()) ? (hasFrozenRows ? 'scroll' : 'auto') : (hasFrozenRows ? 'scroll' : 'auto')\n });\n\n $viewportBottomL.css({\n 'overflow-x': (hasFrozenColumns()) ? (hasFrozenRows ? 'scroll' : 'auto') : (hasFrozenRows ? 'auto' : 'auto'),\n 'overflow-y': (hasFrozenColumns()) ? (hasFrozenRows ? 'hidden' : 'hidden') : (hasFrozenRows ? 'scroll' : 'auto')\n });\n\n $viewportBottomR.css({\n 'overflow-x': (hasFrozenColumns()) ? (hasFrozenRows ? 'scroll' : 'auto') : (hasFrozenRows ? 'auto' : 'auto'),\n 'overflow-y': (hasFrozenColumns()) ? (hasFrozenRows ? 'auto' : 'auto') : (hasFrozenRows ? 'auto' : 'auto')\n });\n }\n\n function setScroller(){\n if (hasFrozenColumns()){\n $headerScrollContainer = $headerScrollerR;\n $headerRowScrollContainer = $headerRowScrollerR;\n $footerRowScrollContainer = $footerRowScrollerR\n\n if (hasFrozenRows){\n if (options.frozenBottom){\n $viewportScrollContainerX = $viewportBottomR;\n $viewportScrollContainerY = $viewportTopR;\n } else {\n $viewportScrollContainerX = $viewportScrollContainerY = $viewportBottomR;\n }\n } else {\n $viewportScrollContainerX = $viewportScrollContainerY = $viewportTopR;\n }\n } else {\n $headerScrollContainer = $headerScrollerL;\n $headerRowScrollContainer = $headerRowScrollerL;\n $footerRowScrollContainer = $footerRowScrollerL;\n\n if (hasFrozenRows){\n if (options.frozenBottom){\n $viewportScrollContainerX = $viewportBottomL;\n $viewportScrollContainerY = $viewportTopL;\n } else {\n $viewportScrollContainerX = $viewportScrollContainerY = $viewportBottomL;\n }\n } else {\n $viewportScrollContainerX = $viewportScrollContainerY = $viewportTopL;\n }\n }\n }\n\n function measureCellPaddingAndBorder(){\n var el;\n var h = [\"borderLeftWidth\", \"borderRightWidth\", \"paddingLeft\", \"paddingRight\"];\n var v = [\"borderTopWidth\", \"borderBottomWidth\", \"paddingTop\", \"paddingBottom\"];\n\n el = $(\"
\").appendTo(r);\n cellWidthDiff = cellHeightDiff = 0;\n if (el.css(\"box-sizing\") != \"border-box\" && el.css(\"-moz-box-sizing\") != \"border-box\" && el.css(\"-webkit-box-sizing\") != \"border-box\"){\n $.each(h, function(n, val){\n cellWidthDiff += parseFloat(el.css(val)) || 0;\n });\n $.each(v, function(n, val){\n cellHeightDiff += parseFloat(el.css(val)) || 0;\n });\n }\n r.remove();\n\n absoluteColumnMinWidth = Math.max(headerColumnWidthDiff, cellWidthDiff);\n }\n\n function createCssRules(){\n $style = $(\"\").appendTo($(\"head\"));\n var rowHeight = (options.rowHeight - cellHeightDiff);\n var rules = [\".\" + uid + \" .slick-group-header-column { left: 1000px; }\", \".\" + uid + \" .slick-header-column { left: 1000px; }\", \".\" + uid + \" .slick-top-panel { height:\" + options.topPanelHeight + \"px; }\", \".\" + uid + \" .slick-headerrow-columns { height:\" + options.headerRowHeight + \"px; }\", \".\" + uid + \" .slick-cell { height:\" + rowHeight + \"px; }\", \".\" + uid + \" .slick-row { height:\" + options.rowHeight + \"px; }\", \".\" + uid + \" .slick-footerrow-columns { height:\" + options.footerRowHeight + \"px; }\"];\n\n for (var i = 0; i < columns.length; i++){\n rules.push(\".\" + uid + \" .l\" + i + \" { }\");\n rules.push(\".\" + uid + \" .r\" + i + \" { }\");\n }\n\n if ($style[0].styleSheet){ // IE\n $style[0].styleSheet.cssText = rules.join(\" \");\n } else {\n $style[0].appendChild(document.createTextNode(rules.join(\" \")));\n }\n }\n\n function getColumnCssRules(idx){\n if (!stylesheet){\n var sheets = document.styleSheets;\n for (var i = 0; i < sheets.length; i++){\n if ((sheets[i].ownerNode || sheets[i].owningElement) == $style[0]){\n stylesheet = sheets[i];\n break;\n }\n }\n\n if (!stylesheet){\n throw new Error(\"Cannot find stylesheet.\");\n }\n\n // find and cache column CSS rules\n columnCssRulesL = [];\n columnCssRulesR = [];\n var cssRules = (stylesheet.cssRules || stylesheet.rules);\n var matches, columnIdx;\n for (var i = 0; i < cssRules.length; i++){\n var selector = cssRules[i].selectorText;\n if (matches = /\\.l\\d+/.exec(selector)){\n columnIdx = parseInt(matches[0].substr(2, matches[0].length - 2), 10);\n columnCssRulesL[columnIdx] = cssRules[i];\n } else if (matches = /\\.r\\d+/.exec(selector)){\n columnIdx = parseInt(matches[0].substr(2, matches[0].length - 2), 10);\n columnCssRulesR[columnIdx] = cssRules[i];\n }\n }\n }\n\n return {\n \"left\": columnCssRulesL[idx],\n \"right\": columnCssRulesR[idx]\n };\n }\n\n function removeCssRules(){\n $style.remove();\n stylesheet = null;\n }\n\n function destroy(){\n getEditorLock().cancelCurrentEdit();\n\n trigger(self.onBeforeDestroy, {});\n\n var i = plugins.length;\n while (i--){\n unregisterPlugin(plugins[i]);\n }\n\n unbindAncestorScrollEvents();\n $container.unbind(\".slickgrid\");\n removeCssRules();\n\n $container.empty().removeClass(uid);\n }\n\n //////////////////////////////////////////////////////////////////////////////////////////////\n // General\n\n function trigger(evt, args, e){\n e = e || new Slick.EventData();\n args = args || {};\n args.grid = self;\n return evt.notify(args, e, self);\n }\n\n function getEditorLock(){\n return options.editorLock;\n }\n\n function getEditController(){\n return editController;\n }\n\n function getColumnIndex(id){\n return columnsById[id];\n }\n\n function autosizeColumns(){\n var i, c,\n widths = [],\n shrinkLeeway = 0,\n total = 0,\n prevTotal,\n availWidth = viewportHasVScroll ? viewportW - scrollbarDimensions.width : viewportW;\n\n for (i = 0; i < columns.length; i++){\n c = columns[i];\n widths.push(c.width);\n total += c.width;\n if (c.resizable){\n shrinkLeeway += c.width - Math.max(c.minWidth, absoluteColumnMinWidth);\n }\n }\n\n // shrink\n prevTotal = total;\n while (total > availWidth && shrinkLeeway){\n var shrinkProportion = (total - availWidth) / shrinkLeeway;\n for (i = 0; i < columns.length && total > availWidth; i++){\n c = columns[i];\n var width = widths[i];\n if (!c.resizable || width <= c.minWidth || width <= absoluteColumnMinWidth){\n continue;\n }\n var absMinWidth = Math.max(c.minWidth, absoluteColumnMinWidth);\n var shrinkSize = Math.floor(shrinkProportion * (width - absMinWidth)) || 1;\n shrinkSize = Math.min(shrinkSize, width - absMinWidth);\n total -= shrinkSize;\n shrinkLeeway -= shrinkSize;\n widths[i] -= shrinkSize;\n }\n if (prevTotal <= total){ // avoid infinite loop\n break;\n }\n prevTotal = total;\n }\n\n // grow\n prevTotal = total;\n while (total < availWidth){\n var growProportion = availWidth / total;\n for (i = 0; i < columns.length && total < availWidth; i++){\n c = columns[i];\n var currentWidth = widths[i];\n var growSize;\n\n if (!c.resizable || c.maxWidth <= currentWidth){\n growSize = 0;\n } else {\n growSize = Math.min(Math.floor(growProportion * currentWidth) - currentWidth, (c.maxWidth - currentWidth) || 1000000) || 1;\n }\n total += growSize;\n widths[i] += growSize;\n }\n if (prevTotal >= total){ // avoid infinite loop\n break;\n }\n prevTotal = total;\n }\n\n var reRender = false;\n for (i = 0; i < columns.length; i++){\n if (columns[i].rerenderOnResize && columns[i].width != widths[i]){\n reRender = true;\n }\n columns[i].width = widths[i];\n }\n\n applyColumnHeaderWidths();\n applyColumnGroupHeaderWidths();\n updateCanvasWidth(true);\n if (reRender){\n invalidateAllRows();\n render();\n }\n }\n\n function applyColumnGroupHeaderWidths(){\n if (!treeColumns.hasDepth()) return;\n\n for (var depth = $groupHeadersL.length - 1; depth >= 0; depth--){\n\n var groupColumns = treeColumns.getColumnsInDepth(depth);\n\n $().add($groupHeadersL[depth]).add($groupHeadersR[depth]).each(function(i){\n var $groupHeader = $(this),\n currentColumnIndex = 0;\n\n $groupHeader.width(i == 0 ? getHeadersWidthL() : getHeadersWidthR());\n\n $groupHeader.children().each(function(){\n var $groupHeaderColumn = $(this);\n\n var m = $(this).data('column');\n\n m.width = 0;\n\n m.columns.forEach(function(){\n var $headerColumn = $groupHeader.next().children(':eq(' + (currentColumnIndex++) + ')');\n m.width += $headerColumn.outerWidth();\n })\n\n $groupHeaderColumn.width(m.width - headerColumnWidthDiff);\n\n });\n\n })\n\n }\n }\n\n function applyColumnHeaderWidths(){\n if (!initialized){\n return;\n }\n var h;\n for (var i = 0, headers = $headers.children(), ii = headers.length; i < ii; i++){\n h = $(headers[i]);\n if (h.width() !== columns[i].width - headerColumnWidthDiff){\n h.width(columns[i].width - headerColumnWidthDiff);\n }\n }\n\n updateColumnCaches();\n }\n\n function applyColumnWidths(){\n var x = 0,\n w, rule;\n for (var i = 0; i < columns.length; i++){\n w = columns[i].width;\n\n rule = getColumnCssRules(i);\n rule.left.style.left = x + \"px\";\n rule.right.style.right = (((options.frozenColumn != -1 && i > options.frozenColumn) ? canvasWidthR : canvasWidthL) - x - w) + \"px\";\n\n // If this column is frozen, reset the css left value since the\n // column starts in a new viewport.\n if (options.frozenColumn == i){\n x = 0;\n } else {\n x += columns[i].width;\n }\n }\n }\n\n function setSortColumn(columnId, ascending){\n setSortColumns([{\n columnId: columnId,\n sortAsc: ascending\n }]);\n }\n\n function setSortColumns(cols){\n sortColumns = cols;\n\n var headerColumnEls = $headers.children();\n headerColumnEls.removeClass(\"slick-header-column-sorted\")\n .find(\".slick-sort-indicator\")\n .removeClass(\"slick-sort-indicator-asc slick-sort-indicator-desc\");\n\n $.each(sortColumns, function(i, col){\n if (col.sortAsc == null){\n col.sortAsc = true;\n }\n var columnIndex = getColumnIndex(col.columnId);\n if (columnIndex != null){\n headerColumnEls.eq(columnIndex)\n .addClass(\"slick-header-column-sorted\")\n .find(\".slick-sort-indicator\")\n .addClass(col.sortAsc ? \"slick-sort-indicator-asc\" : \"slick-sort-indicator-desc\");\n }\n });\n }\n\n function getSortColumns(){\n return sortColumns;\n }\n\n function handleSelectedRangesChanged(e, ranges){\n selectedRows = [];\n var hash = {};\n for (var i = 0; i < ranges.length; i++){\n for (var j = ranges[i].fromRow; j <= ranges[i].toRow; j++){\n if (!hash[j]){ // prevent duplicates\n selectedRows.push(j);\n hash[j] = {};\n }\n for (var k = ranges[i].fromCell; k <= ranges[i].toCell; k++){\n if (canCellBeSelected(j, k)){\n hash[j][columns[k].id] = options.selectedCellCssClass;\n }\n }\n }\n }\n\n setCellCssStyles(options.selectedCellCssClass, hash);\n\n trigger(self.onSelectedRowsChanged, {\n rows: getSelectedRows()\n }, e);\n }\n\n function getColumns(){\n return columns;\n }\n\n function updateColumnCaches(){\n // Pre-calculate cell boundaries.\n columnPosLeft = [];\n columnPosRight = [];\n var x = 0;\n for (var i = 0, ii = columns.length; i < ii; i++){\n columnPosLeft[i] = x;\n columnPosRight[i] = x + columns[i].width;\n\n if (options.frozenColumn == i){\n x = 0;\n } else {\n x += columns[i].width;\n }\n }\n }\n\n function setColumns(columnDefinitions){\n var _treeColumns = new Slick.TreeColumns(columnDefinitions);\n if (_treeColumns.hasDepth()){\n treeColumns = _treeColumns;\n columns = treeColumns.extractColumns();\n } else {\n columns = columnDefinitions;\n }\n\n columnsById = {};\n for (var i = 0; i < columns.length; i++){\n var m = columns[i] = $.extend({}, columnDefaults, columns[i]);\n columnsById[m.id] = i;\n if (m.minWidth && m.width < m.minWidth){\n m.width = m.minWidth;\n }\n if (m.maxWidth && m.width > m.maxWidth){\n m.width = m.maxWidth;\n }\n }\n\n updateColumnCaches();\n\n if (initialized){\n setPaneVisibility();\n setOverflow();\n\n invalidateAllRows();\n createColumnHeaders();\n createColumnGroupHeaders();\n createColumnFooter();\n removeCssRules();\n createCssRules();\n resizeCanvas();\n updateCanvasWidth();\n applyColumnWidths();\n handleScroll();\n }\n }\n\n function getOptions(){\n return options;\n }\n\n function setOptions(args){\n if (!getEditorLock().commitCurrentEdit()){\n return;\n }\n\n makeActiveCellNormal();\n\n if (options.enableAddRow !== args.enableAddRow){\n invalidateRow(getDataLength());\n }\n\n options = $.extend(options, args);\n validateAndEnforceOptions();\n\n setFrozenOptions();\n setScroller();\n zombieRowNodeFromLastMouseWheelEvent = null;\n\n setColumns(treeColumns.extractColumns());\n render();\n }\n\n function validateAndEnforceOptions(){\n if (options.autoHeight){\n options.leaveSpaceForNewRows = false;\n }\n }\n\n function setData(newData, scrollToTop){\n data = newData;\n invalidateAllRows();\n updateRowCount();\n if (scrollToTop){\n scrollTo(0);\n }\n }\n\n function getData(){\n return data;\n }\n\n function getDataLength(){\n if (data.getLength){\n return data.getLength();\n } else {\n return data.length;\n }\n }\n\n function getDataLengthIncludingAddNew(){\n return getDataLength() + (options.enableAddRow ? 1 : 0);\n }\n\n function getDataItem(i){\n if (data.getItem){\n return data.getItem(i);\n } else {\n return data[i];\n }\n }\n\n function getTopPanel(){\n return $topPanel[0];\n }\n\n function setTopPanelVisibility(visible){\n if (options.showTopPanel != visible){\n options.showTopPanel = visible;\n if (visible){\n $topPanelScroller.slideDown(\"fast\", resizeCanvas);\n } else {\n $topPanelScroller.slideUp(\"fast\", resizeCanvas);\n }\n }\n }\n\n function setHeaderRowVisibility(visible){\n if (options.showHeaderRow != visible){\n options.showHeaderRow = visible;\n if (visible){\n $headerRowScroller.slideDown(\"fast\", resizeCanvas);\n } else {\n $headerRowScroller.slideUp(\"fast\", resizeCanvas);\n }\n }\n }\n\n function setFooterRowVisibility(visible){\n if (options.showFooterRow != visible){\n options.showFooterRow = visible;\n if (visible){\n $footerRowScroller.fadeIn(\"fast\", resizeCanvas);\n } else {\n $footerRowScroller.slideDown(\"fast\", resizeCanvas);\n }\n }\n }\n\n function getContainerNode(){\n return $container.get(0);\n }\n\n //////////////////////////////////////////////////////////////////////////////////////////////\n // Rendering / Scrolling\n\n function getRowTop(row){\n return options.rowHeight * row - offset;\n }\n\n function getRowFromPosition(y){\n return Math.floor((y + offset) / options.rowHeight);\n }\n\n function scrollTo(y){\n y = Math.max(y, 0);\n y = Math.min(y, th - $viewportScrollContainerY.height() + ((viewportHasHScroll || hasFrozenColumns()) ? scrollbarDimensions.height : 0));\n\n var oldOffset = offset;\n\n page = Math.min(n - 1, Math.floor(y / ph));\n offset = Math.round(page * cj);\n var newScrollTop = y - offset;\n\n if (offset != oldOffset){\n var range = getVisibleRange(newScrollTop);\n cleanupRows(range);\n updateRowPositions();\n }\n\n if (prevScrollTop != newScrollTop){\n vScrollDir = (prevScrollTop + oldOffset < newScrollTop + offset) ? 1 : -1;\n\n lastRenderedScrollTop = (scrollTop = prevScrollTop = newScrollTop);\n\n if (hasFrozenColumns()){\n $viewportTopL[0].scrollTop = newScrollTop;\n }\n\n if (hasFrozenRows){\n $viewportBottomL[0].scrollTop = $viewportBottomR[0].scrollTop = newScrollTop;\n }\n\n $viewportScrollContainerY[0].scrollTop = newScrollTop;\n\n trigger(self.onViewportChanged, {});\n }\n }\n\n function defaultFormatter(row, cell, value, columnDef, dataContext){\n if (value == null){\n return \"\";\n } else {\n return (value + \"\").replace(/&/g, \"&\").replace(//g, \">\");\n }\n }\n\n function getFormatter(row, column){\n var rowMetadata = data.getItemMetadata && data.getItemMetadata(row);\n\n // look up by id, then index\n var columnOverrides = rowMetadata && rowMetadata.columns && (rowMetadata.columns[column.id] || rowMetadata.columns[getColumnIndex(column.id)]);\n\n return (columnOverrides && columnOverrides.formatter) || (rowMetadata && rowMetadata.formatter) || column.formatter || (options.formatterFactory && options.formatterFactory.getFormatter(column)) || options.defaultFormatter;\n }\n\n function callFormatter(row, cell, value, m, item){\n\n var result;\n\n // pass metadata to formatter\n var metadata = data.getItemMetadata && data.getItemMetadata(row);\n metadata = metadata && metadata.columns;\n\n if (metadata){\n var columnData = metadata[m.id] || metadata[cell];\n result = getFormatter(row, m)(row, cell, value, m, item, columnData);\n } else {\n result = getFormatter(row, m)(row, cell, value, m, item);\n }\n\n return result;\n }\n\n function getEditor(row, cell){\n var column = columns[cell];\n var rowMetadata = data.getItemMetadata && data.getItemMetadata(row);\n var columnMetadata = rowMetadata && rowMetadata.columns;\n\n if (columnMetadata && columnMetadata[column.id] && columnMetadata[column.id].editor !== undefined){\n return columnMetadata[column.id].editor;\n }\n if (columnMetadata && columnMetadata[cell] && columnMetadata[cell].editor !== undefined){\n return columnMetadata[cell].editor;\n }\n\n return column.editor || (options.editorFactory && options.editorFactory.getEditor(column));\n }\n\n function getDataItemValueForColumn(item, columnDef){\n if (options.dataItemColumnValueExtractor){\n return options.dataItemColumnValueExtractor(item, columnDef);\n }\n return item[columnDef.field];\n }\n\n function appendRowHtml(stringArrayL, stringArrayR, row, range, dataLength){\n var d = getDataItem(row);\n var dataLoading = row < dataLength && !d;\n var rowCss = \"slick-row\" + (hasFrozenRows && row < options.frozenRow ? ' frozen' : '') + (dataLoading ? \" loading\" : \"\") + (row === activeRow ? \" active\" : \"\") + (row % 2 == 1 ? \" odd\" : \" even\");\n\n if (!d){\n rowCss += \" \" + options.addNewRowCssClass;\n }\n\n var metadata = data.getItemMetadata && data.getItemMetadata(row);\n\n if (metadata && metadata.cssClasses){\n rowCss += \" \" + metadata.cssClasses;\n }\n\n var frozenRowOffset = getFrozenRowOffset(row);\n\n var rowHtml = \"
\";\n\n stringArrayL.push(rowHtml);\n\n if (hasFrozenColumns()){\n stringArrayR.push(rowHtml);\n }\n\n var colspan, m;\n for (var i = 0, ii = columns.length; i < ii; i++){\n m = columns[i];\n colspan = 1;\n if (metadata && metadata.columns){\n var columnData = metadata.columns[m.id] || metadata.columns[i];\n colspan = (columnData && columnData.colspan) || 1;\n if (colspan === \"*\"){\n colspan = ii - i;\n }\n }\n\n // Do not render cells outside of the viewport.\n if (columnPosRight[Math.min(ii - 1, i + colspan - 1)] > range.leftPx){\n if (columnPosLeft[i] > range.rightPx){\n // All columns to the right are outside the range.\n break;\n }\n\n if (hasFrozenColumns() && (i > options.frozenColumn)){\n appendCellHtml(stringArrayR, row, i, colspan, d);\n } else {\n appendCellHtml(stringArrayL, row, i, colspan, d);\n }\n } else if (hasFrozenColumns() && (i <= options.frozenColumn)){\n appendCellHtml(stringArrayL, row, i, colspan, d);\n }\n\n if (colspan > 1){\n i += (colspan - 1);\n }\n }\n\n stringArrayL.push(\"
\");\n\n if (hasFrozenColumns()){\n stringArrayR.push(\"
\");\n }\n }\n\n function appendCellHtml(stringArray, row, cell, colspan, item){\n var m = columns[cell];\n var cellCss = \"slick-cell l\" + cell + \" r\" + Math.min(columns.length - 1, cell + colspan - 1) + (m.cssClass ? \" \" + m.cssClass : \"\");\n\n if (hasFrozenColumns() && cell <= options.frozenColumn) cellCss += ' frozen';\n\n if (row === activeRow && cell === activeCell) cellCss += \" active\";\n\n // TODO: merge them together in the setter\n for (var key in cellCssClasses){\n if (cellCssClasses[key][row] && cellCssClasses[key][row][m.id]){\n cellCss += (\" \" + cellCssClasses[key][row][m.id]);\n }\n }\n\n stringArray.push(\"
\");\n\n // if there is a corresponding row (if not, this is the Add New row or this data hasn't been loaded yet)\n if (item){\n var value = getDataItemValueForColumn(item, m);\n stringArray.push(callFormatter(row, cell, value, m, item));\n }\n\n stringArray.push(\"
\");\n\n rowsCache[row].cellRenderQueue.push(cell);\n rowsCache[row].cellColSpans[cell] = colspan;\n }\n\n function cleanupRows(rangeToKeep){\n for (var i in rowsCache){\n var removeFrozenRow = true;\n\n if (hasFrozenRows && ((options.frozenBottom && i >= actualFrozenRow) // Frozen bottom rows\n ||\n (!options.frozenBottom && i <= actualFrozenRow) // Frozen top rows\n )){\n removeFrozenRow = false;\n }\n\n if (((i = parseInt(i, 10)) !== activeRow) && (i < rangeToKeep.top || i > rangeToKeep.bottom) && (removeFrozenRow)){\n removeRowFromCache(i);\n }\n }\n }\n\n function invalidate(){\n updateRowCount();\n invalidateAllRows();\n render();\n }\n\n function invalidateAllRows(){\n if (currentEditor){\n makeActiveCellNormal();\n }\n for (var row in rowsCache){\n removeRowFromCache(row);\n }\n }\n\n function removeRowFromCache(row){\n var cacheEntry = rowsCache[row];\n if (!cacheEntry){\n return;\n }\n\n if (rowNodeFromLastMouseWheelEvent == cacheEntry.rowNode[0] || (hasFrozenColumns() && rowNodeFromLastMouseWheelEvent == cacheEntry.rowNode[1])){\n\n cacheEntry.rowNode.hide();\n\n zombieRowNodeFromLastMouseWheelEvent = cacheEntry.rowNode;\n } else {\n\n cacheEntry.rowNode.each(function(){\n this.parentElement.removeChild(this);\n });\n\n }\n\n delete rowsCache[row];\n delete postProcessedRows[row];\n renderedRows--;\n counter_rows_removed++;\n }\n\n function invalidateRows(rows){\n var i, rl;\n if (!rows || !rows.length){\n return;\n }\n vScrollDir = 0;\n for (i = 0, rl = rows.length; i < rl; i++){\n if (currentEditor && activeRow === rows[i]){\n makeActiveCellNormal();\n }\n if (rowsCache[rows[i]]){\n removeRowFromCache(rows[i]);\n }\n }\n }\n\n function invalidateRow(row){\n invalidateRows([row]);\n }\n\n function updateCell(row, cell){\n var cellNode = getCellNode(row, cell);\n if (!cellNode){\n return;\n }\n\n var m = columns[cell],\n d = getDataItem(row);\n if (currentEditor && activeRow === row && activeCell === cell){\n currentEditor.loadValue(d);\n } else {\n cellNode.innerHTML = d ? callFormatter(row, cell, getDataItemValueForColumn(d, m), m, d) : \"\";\n invalidatePostProcessingResults(row);\n }\n }\n\n function updateRow(row){\n var cacheEntry = rowsCache[row];\n if (!cacheEntry){\n return;\n }\n\n ensureCellNodesInRowsCache(row);\n\n var d = getDataItem(row);\n\n for (var columnIdx in cacheEntry.cellNodesByColumnIdx){\n if (!cacheEntry.cellNodesByColumnIdx.hasOwnProperty(columnIdx)){\n continue;\n }\n\n columnIdx = columnIdx | 0;\n var m = columns[columnIdx],\n node = cacheEntry.cellNodesByColumnIdx[columnIdx][0];\n\n if (row === activeRow && columnIdx === activeCell && currentEditor){\n currentEditor.loadValue(d);\n } else if (d){\n node.innerHTML = callFormatter(row, columnIdx, getDataItemValueForColumn(d, m), m, d);\n } else {\n node.innerHTML = \"\";\n }\n }\n\n invalidatePostProcessingResults(row);\n }\n\n function getViewportHeight(){\n if (options.autoHeight){\n viewportH = options.rowHeight * getDataLengthIncludingAddNew() + ((options.frozenColumn == -1) ? $headers.outerHeight() : 0);\n } else {\n topPanelH = (options.showTopPanel) ? options.topPanelHeight + getVBoxDelta($topPanelScroller) : 0;\n\n headerRowH = (options.showHeaderRow) ? options.headerRowHeight + getVBoxDelta($headerRowScroller) : 0;\n\n footerRowH = (options.showFooterRow) ? options.footerRowHeight + getVBoxDelta($footerRowScroller) : 0;\n\n viewportH = parseFloat($.css($container[0], \"height\", true)) - parseFloat($.css($container[0], \"paddingTop\", true)) - parseFloat($.css($container[0], \"paddingBottom\", true)) - parseFloat($.css($headerScroller[0], \"height\")) - getVBoxDelta($headerScroller) - topPanelH - headerRowH - footerRowH;\n }\n\n numVisibleRows = Math.ceil(viewportH / options.rowHeight);\n }\n\n function getViewportWidth(){\n viewportW = parseFloat($.css($container[0], \"width\", true));\n }\n\n function resizeCanvas(){\n if (!initialized){\n return;\n }\n\n paneTopH = 0\n paneBottomH = 0\n viewportTopH = 0\n viewportBottomH = 0;\n\n getViewportWidth();\n getViewportHeight();\n\n // Account for Frozen Rows\n if (hasFrozenRows){\n if (options.frozenBottom){\n paneTopH = viewportH - frozenRowsHeight - scrollbarDimensions.height;\n\n paneBottomH = frozenRowsHeight + scrollbarDimensions.height;\n } else {\n paneTopH = frozenRowsHeight;\n paneBottomH = viewportH - frozenRowsHeight;\n }\n } else {\n paneTopH = viewportH;\n }\n\n // The top pane includes the top panel and the header row\n paneTopH += topPanelH + headerRowH + footerRowH;\n\n if (hasFrozenColumns() && options.autoHeight){\n paneTopH += scrollbarDimensions.height;\n }\n\n // The top viewport does not contain the top panel or header row\n viewportTopH = paneTopH - topPanelH - headerRowH - footerRowH;\n\n if (options.autoHeight){\n if (hasFrozenColumns()){\n $container.height(\n paneTopH + parseFloat($.css($headerScrollerL[0], \"height\")));\n }\n\n $paneTopL.css('position', 'relative');\n }\n\n $paneTopL.css({\n 'top': $paneHeaderL.height(),\n 'height': paneTopH\n });\n\n var paneBottomTop = $paneTopL.position().top + paneTopH;\n\n $viewportTopL.height(viewportTopH);\n\n if (hasFrozenColumns()){\n $paneTopR.css({\n 'top': $paneHeaderL.height(),\n 'height': paneTopH\n });\n\n $viewportTopR.height(viewportTopH);\n\n if (hasFrozenRows){\n $paneBottomL.css({\n 'top': paneBottomTop,\n 'height': paneBottomH\n });\n\n $paneBottomR.css({\n 'top': paneBottomTop,\n 'height': paneBottomH\n });\n\n $viewportBottomR.height(paneBottomH);\n }\n } else {\n if (hasFrozenRows){\n $paneBottomL.css({\n 'width': '100%',\n 'height': paneBottomH\n });\n\n $paneBottomL.css('top', paneBottomTop);\n }\n }\n\n if (hasFrozenRows){\n $viewportBottomL.height(paneBottomH);\n\n if (options.frozenBottom){\n $canvasBottomL.height(frozenRowsHeight);\n\n if (hasFrozenColumns()){\n $canvasBottomR.height(frozenRowsHeight);\n }\n } else {\n $canvasTopL.height(frozenRowsHeight);\n\n if (hasFrozenColumns()){\n $canvasTopR.height(frozenRowsHeight);\n }\n }\n } else {\n $viewportTopR.height(viewportTopH);\n }\n\n if (options.forceFitColumns){\n autosizeColumns();\n }\n\n updateRowCount();\n handleScroll();\n // Since the width has changed, force the render() to reevaluate virtually rendered cells.\n lastRenderedScrollLeft = -1;\n render();\n }\n\n function updateRowCount(){\n if (!initialized){\n return;\n }\n\n var dataLengthIncludingAddNew = getDataLengthIncludingAddNew();\n var numberOfRows = 0;\n var oldH = (hasFrozenRows && !options.frozenBottom) ? $canvasBottomL.height() : $canvasTopL.height();\n\n if (hasFrozenRows){\n var numberOfRows = getDataLength() - options.frozenRow;\n } else {\n var numberOfRows = dataLengthIncludingAddNew + (options.leaveSpaceForNewRows ? numVisibleRows - 1 : 0);\n }\n\n var tempViewportH = $viewportScrollContainerY.height();\n var oldViewportHasVScroll = viewportHasVScroll;\n // with autoHeight, we do not need to accommodate the vertical scroll bar\n viewportHasVScroll = !options.autoHeight && (numberOfRows * options.rowHeight > tempViewportH);\n\n makeActiveCellNormal();\n\n // remove the rows that are now outside of the data range\n // this helps avoid redundant calls to .removeRow() when the size of the data decreased by thousands of rows\n var l = dataLengthIncludingAddNew - 1;\n for (var i in rowsCache){\n if (i >= l){\n removeRowFromCache(i);\n }\n }\n\n th = Math.max(options.rowHeight * numberOfRows, tempViewportH - scrollbarDimensions.height);\n\n if (activeCellNode && activeRow > l){\n resetActiveCell();\n }\n\n if (th < maxSupportedCssHeight){\n // just one page\n h = ph = th;\n n = 1;\n cj = 0;\n } else {\n // break into pages\n h = maxSupportedCssHeight;\n ph = h / 100;\n n = Math.floor(th / ph);\n cj = (th - h) / (n - 1);\n }\n\n if (h !== oldH){\n if (hasFrozenRows && !options.frozenBottom){\n $canvasBottomL.css(\"height\", h);\n\n if (hasFrozenColumns()){\n $canvasBottomR.css(\"height\", h);\n }\n } else {\n $canvasTopL.css(\"height\", h);\n $canvasTopR.css(\"height\", h);\n }\n\n scrollTop = $viewportScrollContainerY[0].scrollTop;\n }\n\n var oldScrollTopInRange = (scrollTop + offset <= th - tempViewportH);\n\n if (th == 0 || scrollTop == 0){\n page = offset = 0;\n } else if (oldScrollTopInRange){\n // maintain virtual position\n scrollTo(scrollTop + offset);\n } else {\n // scroll to bottom\n scrollTo(th - tempViewportH);\n }\n\n if (h != oldH && options.autoHeight){\n resizeCanvas();\n }\n\n if (options.forceFitColumns && oldViewportHasVScroll != viewportHasVScroll){\n autosizeColumns();\n }\n updateCanvasWidth(false);\n }\n\n function getVisibleRange(viewportTop, viewportLeft){\n if (viewportTop == null){\n viewportTop = scrollTop;\n }\n if (viewportLeft == null){\n viewportLeft = scrollLeft;\n }\n\n return {\n top: getRowFromPosition(viewportTop),\n bottom: getRowFromPosition(viewportTop + viewportH) + 1,\n leftPx: viewportLeft,\n rightPx: viewportLeft + viewportW\n };\n }\n\n function getRenderedRange(viewportTop, viewportLeft){\n var range = getVisibleRange(viewportTop, viewportLeft);\n var buffer = Math.round(viewportH / options.rowHeight);\n var minBuffer = 3;\n\n if (vScrollDir == -1){\n range.top -= buffer;\n range.bottom += minBuffer;\n } else if (vScrollDir == 1){\n range.top -= minBuffer;\n range.bottom += buffer;\n } else {\n range.top -= minBuffer;\n range.bottom += minBuffer;\n }\n\n range.top = Math.max(0, range.top);\n range.bottom = Math.min(getDataLengthIncludingAddNew() - 1, range.bottom);\n\n range.leftPx -= viewportW;\n range.rightPx += viewportW;\n\n range.leftPx = Math.max(0, range.leftPx);\n range.rightPx = Math.min(canvasWidth, range.rightPx);\n\n return range;\n }\n\n function ensureCellNodesInRowsCache(row){\n var cacheEntry = rowsCache[row];\n if (cacheEntry){\n if (cacheEntry.cellRenderQueue.length){\n var $lastNode = cacheEntry.rowNode.children().last();\n while (cacheEntry.cellRenderQueue.length){\n var columnIdx = cacheEntry.cellRenderQueue.pop();\n\n cacheEntry.cellNodesByColumnIdx[columnIdx] = $lastNode;\n $lastNode = $lastNode.prev();\n\n // Hack to retrieve the frozen columns because\n if ($lastNode.length == 0){\n $lastNode = $(cacheEntry.rowNode[0]).children().last();\n }\n }\n }\n }\n }\n\n function cleanUpCells(range, row){\n // Ignore frozen rows\n if (hasFrozenRows && ((options.frozenBottom && row > actualFrozenRow) // Frozen bottom rows\n ||\n (row <= actualFrozenRow) // Frozen top rows\n )){\n return;\n }\n\n var totalCellsRemoved = 0;\n var cacheEntry = rowsCache[row];\n\n // Remove cells outside the range.\n var cellsToRemove = [];\n for (var i in cacheEntry.cellNodesByColumnIdx){\n // I really hate it when people mess with Array.prototype.\n if (!cacheEntry.cellNodesByColumnIdx.hasOwnProperty(i)){\n continue;\n }\n\n // This is a string, so it needs to be cast back to a number.\n i = i | 0;\n\n // Ignore frozen columns\n if (i <= options.frozenColumn){\n continue;\n }\n\n var colspan = cacheEntry.cellColSpans[i];\n if (columnPosLeft[i] > range.rightPx || columnPosRight[Math.min(columns.length - 1, i + colspan - 1)] < range.leftPx){\n if (!(row == activeRow && i == activeCell)){\n cellsToRemove.push(i);\n }\n }\n }\n\n var cellToRemove;\n while ((cellToRemove = cellsToRemove.pop()) != null){\n cacheEntry.cellNodesByColumnIdx[cellToRemove][0].parentElement.removeChild(cacheEntry.cellNodesByColumnIdx[cellToRemove][0]);\n delete cacheEntry.cellColSpans[cellToRemove];\n delete cacheEntry.cellNodesByColumnIdx[cellToRemove];\n if (postProcessedRows[row]){\n delete postProcessedRows[row][cellToRemove];\n }\n totalCellsRemoved++;\n }\n }\n\n function cleanUpAndRenderCells(range){\n var cacheEntry;\n var stringArray = [];\n var processedRows = [];\n var cellsAdded;\n var totalCellsAdded = 0;\n var colspan;\n\n for (var row = range.top, btm = range.bottom; row <= btm; row++){\n cacheEntry = rowsCache[row];\n if (!cacheEntry){\n continue;\n }\n\n // cellRenderQueue populated in renderRows() needs to be cleared first\n ensureCellNodesInRowsCache(row);\n\n cleanUpCells(range, row);\n\n // Render missing cells.\n cellsAdded = 0;\n\n var metadata = data.getItemMetadata && data.getItemMetadata(row);\n metadata = metadata && metadata.columns;\n\n var d = getDataItem(row);\n\n // TODO: shorten this loop (index? heuristics? binary search?)\n for (var i = 0, ii = columns.length; i < ii; i++){\n // Cells to the right are outside the range.\n if (columnPosLeft[i] > range.rightPx){\n break;\n }\n\n // Already rendered.\n if ((colspan = cacheEntry.cellColSpans[i]) != null){\n i += (colspan > 1 ? colspan - 1 : 0);\n continue;\n }\n\n colspan = 1;\n if (metadata){\n var columnData = metadata[columns[i].id] || metadata[i];\n colspan = (columnData && columnData.colspan) || 1;\n if (colspan === \"*\"){\n colspan = ii - i;\n }\n }\n\n if (columnPosRight[Math.min(ii - 1, i + colspan - 1)] > range.leftPx){\n appendCellHtml(stringArray, row, i, colspan, d);\n cellsAdded++;\n }\n\n i += (colspan > 1 ? colspan - 1 : 0);\n }\n\n if (cellsAdded){\n totalCellsAdded += cellsAdded;\n processedRows.push(row);\n }\n }\n\n if (!stringArray.length){\n return;\n }\n\n var x = document.createElement(\"div\");\n x.innerHTML = stringArray.join(\"\");\n\n var processedRow;\n var $node;\n while ((processedRow = processedRows.pop()) != null){\n cacheEntry = rowsCache[processedRow];\n var columnIdx;\n while ((columnIdx = cacheEntry.cellRenderQueue.pop()) != null){\n $node = $(x).children().last();\n\n if (hasFrozenColumns() && (columnIdx > options.frozenColumn)){\n $(cacheEntry.rowNode[1]).append($node);\n } else {\n $(cacheEntry.rowNode[0]).append($node);\n }\n\n cacheEntry.cellNodesByColumnIdx[columnIdx] = $node;\n }\n }\n }\n\n function renderRows(range){\n var stringArrayL = [],\n stringArrayR = [],\n rows = [],\n needToReselectCell = false,\n dataLength = getDataLength();\n\n for (var i = range.top, ii = range.bottom; i <= ii; i++){\n if (rowsCache[i] || (hasFrozenRows && options.frozenBottom && i == getDataLength())){\n continue;\n }\n renderedRows++;\n rows.push(i);\n\n // Create an entry right away so that appendRowHtml() can\n // start populatating it.\n rowsCache[i] = {\n \"rowNode\": null,\n\n // ColSpans of rendered cells (by column idx).\n // Can also be used for checking whether a cell has been rendered.\n \"cellColSpans\": [],\n\n // Cell nodes (by column idx). Lazy-populated by ensureCellNodesInRowsCache().\n \"cellNodesByColumnIdx\": [],\n\n // Column indices of cell nodes that have been rendered, but not yet indexed in\n // cellNodesByColumnIdx. These are in the same order as cell nodes added at the\n // end of the row.\n \"cellRenderQueue\": []\n };\n\n appendRowHtml(stringArrayL, stringArrayR, i, range, dataLength);\n if (activeCellNode && activeRow === i){\n needToReselectCell = true;\n }\n counter_rows_rendered++;\n }\n\n if (!rows.length){\n return;\n }\n\n var x = document.createElement(\"div\"),\n xRight = document.createElement(\"div\");\n\n x.innerHTML = stringArrayL.join(\"\");\n xRight.innerHTML = stringArrayR.join(\"\");\n\n for (var i = 0, ii = rows.length; i < ii; i++){\n if ((hasFrozenRows) && (rows[i] >= actualFrozenRow)){\n if (hasFrozenColumns()){\n rowsCache[rows[i]].rowNode = $()\n .add($(x.firstChild).appendTo($canvasBottomL))\n .add($(xRight.firstChild).appendTo($canvasBottomR));\n } else {\n rowsCache[rows[i]].rowNode = $()\n .add($(x.firstChild).appendTo($canvasBottomL));\n }\n } else if (hasFrozenColumns()){\n rowsCache[rows[i]].rowNode = $()\n .add($(x.firstChild).appendTo($canvasTopL))\n .add($(xRight.firstChild).appendTo($canvasTopR));\n } else {\n rowsCache[rows[i]].rowNode = $()\n .add($(x.firstChild).appendTo($canvasTopL));\n }\n }\n\n if (needToReselectCell){\n activeCellNode = getCellNode(activeRow, activeCell);\n }\n }\n\n function startPostProcessing(){\n if (!options.enableAsyncPostRender){\n return;\n }\n clearTimeout(h_postrender);\n h_postrender = setTimeout(asyncPostProcessRows, options.asyncPostRenderDelay);\n }\n\n function invalidatePostProcessingResults(row){\n delete postProcessedRows[row];\n postProcessFromRow = Math.min(postProcessFromRow, row);\n postProcessToRow = Math.max(postProcessToRow, row);\n startPostProcessing();\n }\n\n function updateRowPositions(){\n for (var row in rowsCache){\n rowsCache[row].rowNode.css('top', getRowTop(row) + \"px\");\n }\n }\n\n function render(){\n if (!initialized){\n return;\n }\n var visible = getVisibleRange();\n var rendered = getRenderedRange();\n\n // remove rows no longer in the viewport\n cleanupRows(rendered);\n\n // add new rows & missing cells in existing rows\n if (lastRenderedScrollLeft != scrollLeft){\n\n if (hasFrozenRows){\n\n var renderedFrozenRows = $.extend(true, {}, rendered);\n\n if (options.frozenBottom){\n\n renderedFrozenRows.top = actualFrozenRow;\n renderedFrozenRows.bottom = getDataLength();\n } else {\n\n renderedFrozenRows.top = 0;\n renderedFrozenRows.bottom = options.frozenRow;\n }\n\n cleanUpAndRenderCells(renderedFrozenRows);\n }\n\n cleanUpAndRenderCells(rendered);\n }\n\n // render missing rows\n renderRows(rendered);\n\n // Render frozen rows\n if (hasFrozenRows){\n if (options.frozenBottom){\n renderRows({\n top: actualFrozenRow,\n bottom: getDataLength() - 1,\n leftPx: rendered.leftPx,\n rightPx: rendered.rightPx\n });\n } else {\n renderRows({\n top: 0,\n bottom: options.frozenRow - 1,\n leftPx: rendered.leftPx,\n rightPx: rendered.rightPx\n });\n }\n }\n\n postProcessFromRow = visible.top;\n postProcessToRow = Math.min(getDataLengthIncludingAddNew() - 1, visible.bottom);\n startPostProcessing();\n\n lastRenderedScrollTop = scrollTop;\n lastRenderedScrollLeft = scrollLeft;\n h_render = null;\n }\n\n function handleHeaderRowScroll(){\n var scrollLeft = $headerRowScrollContainer[0].scrollLeft;\n if (scrollLeft != $viewportScrollContainerX[0].scrollLeft){\n $viewportScrollContainerX[0].scrollLeft = scrollLeft;\n }\n }\n\n function handleFooterRowScroll(){\n var scrollLeft = $footerRowScrollContainer[0].scrollLeft;\n if (scrollLeft != $viewportScrollContainerX[0].scrollLeft){\n $viewportScrollContainerX[0].scrollLeft = scrollLeft;\n }\n }\n\n function handleMouseWheel(e, delta, deltaX, deltaY){\n var $rowNode = $(e.target).closest(\".slick-row\");\n var rowNode = $rowNode[0];\n\n if (rowNode != rowNodeFromLastMouseWheelEvent){\n\n var $gridCanvas = $rowNode.parents('.grid-canvas');\n var left = $gridCanvas.hasClass('grid-canvas-left');\n\n if (zombieRowNodeFromLastMouseWheelEvent && zombieRowNodeFromLastMouseWheelEvent[left ? 0 : 1] != rowNode){\n var zombieRow = zombieRowNodeFromLastMouseWheelEvent[left || zombieRowNodeFromLastMouseWheelEvent.length == 1 ? 0 : 1];\n zombieRow.parentElement.removeChild(zombieRow);\n\n zombieRowNodeFromLastMouseWheelEvent = null;\n }\n\n rowNodeFromLastMouseWheelEvent = rowNode;\n }\n\n scrollTop = Math.max(0, $viewportScrollContainerY[0].scrollTop - (deltaY * options.rowHeight));\n scrollLeft = $viewportScrollContainerX[0].scrollLeft + (deltaX * 10);\n var handled = _handleScroll(true);\n if (handled) e.preventDefault();\n }\n\n function handleScroll(){\n scrollTop = $viewportScrollContainerY[0].scrollTop;\n scrollLeft = $viewportScrollContainerX[0].scrollLeft;\n return _handleScroll(false);\n }\n\n function _handleScroll(isMouseWheel){\n var maxScrollDistanceY = $viewportScrollContainerY[0].scrollHeight - $viewportScrollContainerY[0].clientHeight;\n var maxScrollDistanceX = $viewportScrollContainerY[0].scrollWidth - $viewportScrollContainerY[0].clientWidth;\n var hasFrozenCols = hasFrozenColumns();\n\n // Ceiling the max scroll values\n if (scrollTop > maxScrollDistanceY){\n scrollTop = maxScrollDistanceY;\n }\n if (scrollLeft > maxScrollDistanceX){\n scrollLeft = maxScrollDistanceX;\n }\n\n var vScrollDist = Math.abs(scrollTop - prevScrollTop);\n var hScrollDist = Math.abs(scrollLeft - prevScrollLeft);\n\n if (hScrollDist){\n prevScrollLeft = scrollLeft;\n\n $viewportScrollContainerX[0].scrollLeft = scrollLeft;\n $headerScrollContainer[0].scrollLeft = scrollLeft;\n $topPanelScroller[0].scrollLeft = scrollLeft;\n $headerRowScrollContainer[0].scrollLeft = scrollLeft;\n $footerRowScrollContainer[0].scrollLeft = scrollLeft;\n\n if (hasFrozenCols){\n if (hasFrozenRows){\n $viewportTopR[0].scrollLeft = scrollLeft;\n }\n } else {\n if (hasFrozenRows){\n $viewportTopL[0].scrollLeft = scrollLeft;\n }\n }\n }\n\n if (vScrollDist){\n vScrollDir = prevScrollTop < scrollTop ? 1 : -1;\n prevScrollTop = scrollTop;\n\n if (isMouseWheel){\n $viewportScrollContainerY[0].scrollTop = scrollTop;\n }\n\n if (hasFrozenCols){\n if (hasFrozenRows && !options.frozenBottom){\n $viewportBottomL[0].scrollTop = scrollTop;\n } else {\n $viewportTopL[0].scrollTop = scrollTop;\n }\n }\n\n // switch virtual pages if needed\n if (vScrollDist < viewportH){\n scrollTo(scrollTop + offset);\n } else {\n var oldOffset = offset;\n if (h == viewportH){\n page = 0;\n } else {\n page = Math.min(n - 1, Math.floor(scrollTop * ((th - viewportH) / (h - viewportH)) * (1 / ph)));\n }\n offset = Math.round(page * cj);\n if (oldOffset != offset){\n invalidateAllRows();\n }\n }\n }\n\n if (hScrollDist || vScrollDist){\n if (h_render){\n clearTimeout(h_render);\n }\n\n if (Math.abs(lastRenderedScrollTop - scrollTop) > 20 || Math.abs(lastRenderedScrollLeft - scrollLeft) > 20){\n if (options.forceSyncScrolling || (\n Math.abs(lastRenderedScrollTop - scrollTop) < viewportH && Math.abs(lastRenderedScrollLeft - scrollLeft) < viewportW)){\n render();\n } else {\n h_render = setTimeout(render, 50);\n }\n\n trigger(self.onViewportChanged, {});\n }\n }\n\n trigger(self.onScroll, {\n scrollLeft: scrollLeft,\n scrollTop: scrollTop\n });\n\n if (hScrollDist || vScrollDist) return true;\n return false;\n }\n\n function asyncPostProcessRows(){\n var dataLength = getDataLength();\n while (postProcessFromRow <= postProcessToRow){\n var row = (vScrollDir >= 0) ? postProcessFromRow++ : postProcessToRow--;\n var cacheEntry = rowsCache[row];\n if (!cacheEntry || row >= dataLength){\n continue;\n }\n\n if (!postProcessedRows[row]){\n postProcessedRows[row] = {};\n }\n\n ensureCellNodesInRowsCache(row);\n for (var columnIdx in cacheEntry.cellNodesByColumnIdx){\n if (!cacheEntry.cellNodesByColumnIdx.hasOwnProperty(columnIdx)){\n continue;\n }\n\n columnIdx = columnIdx | 0;\n\n var m = columns[columnIdx];\n if (m.asyncPostRender && !postProcessedRows[row][columnIdx]){\n var node = cacheEntry.cellNodesByColumnIdx[columnIdx];\n if (node){\n m.asyncPostRender(node, row, getDataItem(row), m);\n }\n postProcessedRows[row][columnIdx] = true;\n }\n }\n\n h_postrender = setTimeout(asyncPostProcessRows, options.asyncPostRenderDelay);\n return;\n }\n }\n\n function updateCellCssStylesOnRenderedRows(addedHash, removedHash){\n var node, columnId, addedRowHash, removedRowHash;\n for (var row in rowsCache){\n removedRowHash = removedHash && removedHash[row];\n addedRowHash = addedHash && addedHash[row];\n\n if (removedRowHash){\n for (columnId in removedRowHash){\n if (!addedRowHash || removedRowHash[columnId] != addedRowHash[columnId]){\n node = getCellNode(row, getColumnIndex(columnId));\n if (node){\n $(node).removeClass(removedRowHash[columnId]);\n }\n }\n }\n }\n\n if (addedRowHash){\n for (columnId in addedRowHash){\n if (!removedRowHash || removedRowHash[columnId] != addedRowHash[columnId]){\n node = getCellNode(row, getColumnIndex(columnId));\n if (node){\n $(node).addClass(addedRowHash[columnId]);\n }\n }\n }\n }\n }\n }\n\n function addCellCssStyles(key, hash){\n if (cellCssClasses[key]){\n throw \"addCellCssStyles: cell CSS hash with key '\" + key + \"' already exists.\";\n }\n\n cellCssClasses[key] = hash;\n updateCellCssStylesOnRenderedRows(hash, null);\n\n trigger(self.onCellCssStylesChanged, {\n \"key\": key,\n \"hash\": hash\n });\n }\n\n function removeCellCssStyles(key){\n if (!cellCssClasses[key]){\n return;\n }\n\n updateCellCssStylesOnRenderedRows(null, cellCssClasses[key]);\n delete cellCssClasses[key];\n\n trigger(self.onCellCssStylesChanged, {\n \"key\": key,\n \"hash\": null\n });\n }\n\n function setCellCssStyles(key, hash){\n var prevHash = cellCssClasses[key];\n\n cellCssClasses[key] = hash;\n updateCellCssStylesOnRenderedRows(hash, prevHash);\n\n trigger(self.onCellCssStylesChanged, {\n \"key\": key,\n \"hash\": hash\n });\n }\n\n function getCellCssStyles(key){\n return cellCssClasses[key];\n }\n\n function flashCell(row, cell, speed){\n speed = speed || 100;\n if (rowsCache[row]){\n var $cell = $(getCellNode(row, cell));\n\n function toggleCellClass(times){\n if (!times){\n return;\n }\n setTimeout(function(){\n $cell.queue(function(){\n $cell.toggleClass(options.cellFlashingCssClass).dequeue();\n toggleCellClass(times - 1);\n });\n },\n speed);\n }\n\n toggleCellClass(4);\n }\n }\n\n //////////////////////////////////////////////////////////////////////////////////////////////\n // Interactivity\n\n function handleDragInit(e, dd){\n var cell = getCellFromEvent(e);\n if (!cell || !cellExists(cell.row, cell.cell)){\n return false;\n }\n\n var retval = trigger(self.onDragInit, dd, e);\n if (e.isImmediatePropagationStopped()){\n return retval;\n }\n\n // if nobody claims to be handling drag'n'drop by stopping immediate propagation,\n // cancel out of it\n return false;\n }\n\n function handleDragStart(interactEvent){\n var event = $.Event(interactEvent.originalEvent.type, interactEvent.originalEvent);\n var cell = getCellFromEvent(event);\n if (!cell || !cellExists(cell.row, cell.cell)){\n return false;\n }\n\n var retval = trigger(self.onDragStart, interactEvent, event);\n if (event.isImmediatePropagationStopped()){\n return retval;\n }\n\n return false;\n }\n\n function handleDrag(interactEvent){\n var event = $.Event(interactEvent.originalEvent.type, interactEvent.originalEvent);\n return trigger(self.onDrag, interactEvent, event);\n }\n\n function handleDragEnd(interactEvent){\n trigger(self.onDragEnd, interactEvent, $.Event('mousedown'));\n }\n\n function handleKeyDown(e){\n trigger(self.onKeyDown, {\n row: activeRow,\n cell: activeCell\n }, e);\n var handled = e.isImmediatePropagationStopped();\n\n if (!handled){\n if (!e.shiftKey && !e.altKey && !e.ctrlKey){\n if (e.which == 27){\n if (!getEditorLock().isActive()){\n return; // no editing mode to cancel, allow bubbling and default processing (exit without cancelling the event)\n }\n cancelEditAndSetFocus();\n } else if (e.which == 34){\n navigatePageDown();\n handled = true;\n } else if (e.which == 33){\n navigatePageUp();\n handled = true;\n } else if (e.which == 37){\n handled = navigateLeft();\n } else if (e.which == 39){\n handled = navigateRight();\n } else if (e.which == 38){\n handled = navigateUp();\n } else if (e.which == 40){\n handled = navigateDown();\n } else if (e.which == 9){\n handled = navigateNext();\n } else if (e.which == 13){\n if (options.editable){\n if (currentEditor){\n // adding new row\n if (activeRow === getDataLength()){\n navigateDown();\n } else {\n commitEditAndSetFocus();\n }\n } else {\n if (getEditorLock().commitCurrentEdit()){\n makeActiveCellEditable();\n }\n }\n }\n handled = true;\n }\n } else if (e.which == 9 && e.shiftKey && !e.ctrlKey && !e.altKey){\n handled = navigatePrev();\n }\n }\n\n if (handled){\n // the event has been handled so don't let parent element (bubbling/propagation) or browser (default) handle it\n e.stopPropagation();\n e.preventDefault();\n try {\n e.originalEvent.keyCode = 0; // prevent default behaviour for special keys in IE browsers (F3, F5, etc.)\n }\n // ignore exceptions - setting the original event's keycode throws access denied exception for \"Ctrl\"\n // (hitting control key only, nothing else), \"Shift\" (maybe others)\n catch (error) {\n }\n }\n }\n\n function handleClick(e){\n if (!currentEditor){\n // if this click resulted in some cell child node getting focus,\n // don't steal it back - keyboard events will still bubble up\n // IE9+ seems to default DIVs to tabIndex=0 instead of -1, so check for cell clicks directly.\n if (e.target != document.activeElement || $(e.target).hasClass(\"slick-cell\")){\n setFocus();\n }\n }\n\n var cell = getCellFromEvent(e);\n if (!cell || (currentEditor !== null && activeRow == cell.row && activeCell == cell.cell)){\n return;\n }\n\n trigger(self.onClick, {\n row: cell.row,\n cell: cell.cell\n }, e);\n if (e.isImmediatePropagationStopped()){\n return;\n }\n\n if ((activeCell != cell.cell || activeRow != cell.row) && canCellBeActive(cell.row, cell.cell)){\n if (!getEditorLock().isActive() || getEditorLock().commitCurrentEdit()){\n\n scrollRowIntoView(cell.row, false);\n setActiveCellInternal(getCellNode(cell.row, cell.cell));\n }\n }\n }\n\n function handleContextMenu(e){\n var $cell = $(e.target).closest(\".slick-cell\", $canvas);\n if ($cell.length === 0){\n return;\n }\n\n // are we editing this cell?\n if (activeCellNode === $cell[0] && currentEditor !== null){\n return;\n }\n\n trigger(self.onContextMenu, {}, e);\n }\n\n function handleDblClick(e){\n var cell = getCellFromEvent(e);\n if (!cell || (currentEditor !== null && activeRow == cell.row && activeCell == cell.cell)){\n return;\n }\n\n trigger(self.onDblClick, {\n row: cell.row,\n cell: cell.cell\n }, e);\n if (e.isImmediatePropagationStopped()){\n return;\n }\n\n if (options.editable){\n gotoCell(cell.row, cell.cell, true);\n }\n }\n\n function handleHeaderMouseEnter(e){\n trigger(self.onHeaderMouseEnter, {\n \"column\": $(this).data(\"column\")\n }, e);\n }\n\n function handleHeaderMouseLeave(e){\n trigger(self.onHeaderMouseLeave, {\n \"column\": $(this).data(\"column\")\n }, e);\n }\n\n function handleHeaderContextMenu(e){\n var $header = $(e.target).closest(\".slick-header-column\", \".slick-header-columns\");\n var column = $header && $header.data(\"column\");\n trigger(self.onHeaderContextMenu, {\n column: column\n }, e);\n }\n\n function handleHeaderClick(e){\n var $header = $(e.target).closest(\".slick-header-column\", \".slick-header-columns\");\n var column = $header && $header.data(\"column\");\n if (column){\n trigger(self.onHeaderClick, {\n column: column\n }, e);\n }\n }\n\n function handleMouseEnter(e){\n trigger(self.onMouseEnter, {}, e);\n }\n\n function handleMouseLeave(e){\n trigger(self.onMouseLeave, {}, e);\n }\n\n function cellExists(row, cell){\n return !(row < 0 || row >= getDataLength() || cell < 0 || cell >= columns.length);\n }\n\n function getCellFromPoint(x, y){\n var row = getRowFromPosition(y);\n var cell = 0;\n\n var w = 0;\n for (var i = 0; i < columns.length && w < x; i++){\n w += columns[i].width;\n cell++;\n }\n\n if (cell < 0){\n cell = 0;\n }\n\n return {\n row: row,\n cell: cell - 1\n };\n }\n\n function getCellFromNode(cellNode){\n // read column number from .l CSS class\n var cls = /l\\d+/.exec(cellNode.className);\n if (!cls){\n throw \"getCellFromNode: cannot get cell - \" + cellNode.className;\n }\n return parseInt(cls[0].substr(1, cls[0].length - 1), 10);\n }\n\n function getRowFromNode(rowNode){\n for (var row in rowsCache)\n for (var i in rowsCache[row].rowNode)\n if (rowsCache[row].rowNode[i] === rowNode) return row | 0;\n\n return null;\n }\n\n function getFrozenRowOffset(row){\n var offset = (hasFrozenRows) ? (options.frozenBottom) ? (row >= actualFrozenRow) ? (h < viewportTopH) ? (actualFrozenRow * options.rowHeight) : h : 0 : (row >= actualFrozenRow) ? frozenRowsHeight : 0 : 0;\n\n return offset;\n }\n\n function getCellFromEvent(e){\n var row, cell;\n var $cell = $(e.target).closest(\".slick-cell\", $canvas);\n if (!$cell.length){\n return null;\n }\n\n row = getRowFromNode($cell[0].parentNode);\n\n if (hasFrozenRows){\n\n var c = $cell.parents('.grid-canvas').offset();\n\n var rowOffset = 0;\n var isBottom = $cell.parents('.grid-canvas-bottom').length;\n\n if (isBottom){\n rowOffset = (options.frozenBottom) ? $canvasTopL.height() : frozenRowsHeight;\n }\n\n row = getCellFromPoint(e.clientX - c.left, e.clientY - c.top + rowOffset + $(document).scrollTop()).row;\n }\n\n cell = getCellFromNode($cell[0]);\n\n if (row == null || cell == null){\n return null;\n } else {\n return {\n \"row\": row,\n \"cell\": cell\n };\n }\n }\n\n function getCellNodeBox(row, cell){\n if (!cellExists(row, cell)){\n return null;\n }\n\n var frozenRowOffset = getFrozenRowOffset(row);\n\n var y1 = getRowTop(row) - frozenRowOffset;\n var y2 = y1 + options.rowHeight - 1;\n var x1 = 0;\n for (var i = 0; i < cell; i++){\n x1 += columns[i].width;\n\n if (options.frozenColumn == i){\n x1 = 0;\n }\n }\n var x2 = x1 + columns[cell].width;\n\n return {\n top: y1,\n left: x1,\n bottom: y2,\n right: x2\n };\n }\n\n //////////////////////////////////////////////////////////////////////////////////////////////\n // Cell switching\n\n function resetActiveCell(){\n setActiveCellInternal(null, false);\n }\n\n function setFocus(){\n if (tabbingDirection == -1){\n $focusSink[0].focus();\n } else {\n $focusSink2[0].focus();\n }\n }\n\n function scrollCellIntoView(row, cell, doPaging){\n // Don't scroll to frozen cells\n if (cell <= options.frozenColumn){\n return;\n }\n\n if (row < actualFrozenRow){\n scrollRowIntoView(row, doPaging);\n }\n\n var colspan = getColspan(row, cell);\n var left = columnPosLeft[cell],\n right = columnPosRight[cell + (colspan > 1 ? colspan - 1 : 0)],\n scrollRight = scrollLeft + $viewportScrollContainerX.width();\n\n if (left < scrollLeft){\n $viewportScrollContainerX.scrollLeft(left);\n handleScroll();\n render();\n } else if (right > scrollRight){\n $viewportScrollContainerX.scrollLeft(Math.min(left, right - $viewportScrollContainerX[0].clientWidth));\n handleScroll();\n render();\n }\n }\n\n function setActiveCellInternal(newCell, opt_editMode){\n if (activeCellNode !== null){\n makeActiveCellNormal();\n $(activeCellNode).removeClass(\"active\");\n if (rowsCache[activeRow]){\n $(rowsCache[activeRow].rowNode).removeClass(\"active\");\n }\n }\n\n var activeCellChanged = (activeCellNode !== newCell);\n activeCellNode = newCell;\n\n if (activeCellNode != null){\n var $activeCellNode = $(activeCellNode);\n var $activeCellOffset = $activeCellNode.offset();\n\n var rowOffset = Math.floor($activeCellNode.parents('.grid-canvas').offset().top);\n var isBottom = $activeCellNode.parents('.grid-canvas-bottom').length;\n\n if (hasFrozenRows && isBottom){\n rowOffset -= (options.frozenBottom) ? $canvasTopL.height() : frozenRowsHeight;\n }\n\n var cell = getCellFromPoint($activeCellOffset.left, Math.ceil($activeCellOffset.top) - rowOffset);\n\n activeRow = cell.row;\n activeCell = activePosX = activeCell = activePosX = getCellFromNode(activeCellNode[0]);\n\n $activeCellNode.addClass(\"active\");\n if (rowsCache[activeRow]){\n $(rowsCache[activeRow].rowNode).addClass('active');\n }\n\n if (opt_editMode == null){\n opt_editMode = (activeRow == getDataLength()) || options.autoEdit;\n }\n\n if (options.editable && opt_editMode && isCellPotentiallyEditable(activeRow, activeCell)){\n clearTimeout(h_editorLoader);\n\n if (options.asyncEditorLoading){\n h_editorLoader = setTimeout(function(){\n makeActiveCellEditable();\n }, options.asyncEditorLoadDelay);\n } else {\n makeActiveCellEditable();\n }\n }\n } else {\n activeRow = activeCell = null;\n }\n\n if (activeCellChanged){\n setTimeout(scrollActiveCellIntoView, 50);\n trigger(self.onActiveCellChanged, getActiveCell());\n }\n }\n\n function clearTextSelection(){\n if (document.selection && document.selection.empty){\n try {\n //IE fails here if selected element is not in dom\n document.selection.empty();\n } catch (e) {\n }\n } else if (window.getSelection){\n var sel = window.getSelection();\n if (sel && sel.removeAllRanges){\n sel.removeAllRanges();\n }\n }\n }\n\n function isCellPotentiallyEditable(row, cell){\n var dataLength = getDataLength();\n // is the data for this row loaded?\n if (row < dataLength && !getDataItem(row)){\n return false;\n }\n\n // are we in the Add New row? can we create new from this cell?\n if (columns[cell].cannotTriggerInsert && row >= dataLength){\n return false;\n }\n\n // does this cell have an editor?\n if (!getEditor(row, cell)){\n return false;\n }\n\n return true;\n }\n\n function makeActiveCellNormal(){\n if (!currentEditor){\n return;\n }\n trigger(self.onBeforeCellEditorDestroy, {\n editor: currentEditor\n });\n currentEditor.destroy();\n currentEditor = null;\n\n if (activeCellNode){\n var d = getDataItem(activeRow);\n $(activeCellNode).removeClass(\"editable invalid\");\n if (d){\n var column = columns[activeCell];\n activeCellNode[0].innerHTML = callFormatter(activeRow, activeCell, getDataItemValueForColumn(d, column), column, d);\n invalidatePostProcessingResults(activeRow);\n }\n }\n\n // if there previously was text selected on a page (such as selected text in the edit cell just removed),\n // IE can't set focus to anything else correctly\n if (navigator.userAgent.toLowerCase().match(/msie/)){\n clearTextSelection();\n }\n\n getEditorLock().deactivate(editController);\n }\n\n function makeActiveCellEditable(editor){\n if (!activeCellNode){\n return;\n }\n if (!options.editable){\n throw \"Grid : makeActiveCellEditable : should never get called when options.editable is false\";\n }\n\n // cancel pending async call if there is one\n clearTimeout(h_editorLoader);\n\n if (!isCellPotentiallyEditable(activeRow, activeCell)){\n return;\n }\n\n var columnDef = columns[activeCell];\n var item = getDataItem(activeRow);\n\n if (trigger(self.onBeforeEditCell, {\n row: activeRow,\n cell: activeCell,\n item: item,\n column: columnDef\n }) === false){\n setFocus();\n return;\n }\n\n getEditorLock().activate(editController);\n $(activeCellNode).addClass(\"editable\");\n\n // don't clear the cell if a custom editor is passed through\n if (!editor){\n activeCellNode[0].innerHTML = \"\";\n }\n\n currentEditor = new (editor || getEditor(activeRow, activeCell))({\n grid: self,\n gridPosition: absBox($container[0]),\n position: absBox(activeCellNode[0]),\n container: activeCellNode,\n column: columnDef,\n item: item || {},\n commitChanges: commitEditAndSetFocus,\n cancelChanges: cancelEditAndSetFocus\n });\n\n if (item){\n currentEditor.loadValue(item);\n }\n\n serializedEditorValue = currentEditor.serializeValue();\n\n if (currentEditor.position){\n handleActiveCellPositionChange();\n }\n }\n\n function commitEditAndSetFocus(){\n // if the commit fails, it would do so due to a validation error\n // if so, do not steal the focus from the editor\n if (getEditorLock().commitCurrentEdit()){\n setFocus();\n if (options.autoEdit){\n navigateDown();\n }\n }\n }\n\n function cancelEditAndSetFocus(){\n if (getEditorLock().cancelCurrentEdit()){\n setFocus();\n }\n }\n\n function absBox(elem){\n var box = {\n top: elem.offsetTop,\n left: elem.offsetLeft,\n bottom: 0,\n right: 0,\n width: $(elem).outerWidth(),\n height: $(elem).outerHeight(),\n visible: true\n };\n box.bottom = box.top + box.height;\n box.right = box.left + box.width;\n\n // walk up the tree\n var offsetParent = elem.offsetParent;\n while ((elem = elem.parentNode) != document.body){\n if (box.visible && elem.scrollHeight != elem.offsetHeight && $(elem).css(\"overflowY\") != \"visible\"){\n box.visible = box.bottom > elem.scrollTop && box.top < elem.scrollTop + elem.clientHeight;\n }\n\n if (box.visible && elem.scrollWidth != elem.offsetWidth && $(elem).css(\"overflowX\") != \"visible\"){\n box.visible = box.right > elem.scrollLeft && box.left < elem.scrollLeft + elem.clientWidth;\n }\n\n box.left -= elem.scrollLeft;\n box.top -= elem.scrollTop;\n\n if (elem === offsetParent){\n box.left += elem.offsetLeft;\n box.top += elem.offsetTop;\n offsetParent = elem.offsetParent;\n }\n\n box.bottom = box.top + box.height;\n box.right = box.left + box.width;\n }\n\n return box;\n }\n\n function getActiveCellPosition(){\n return absBox(activeCellNode[0]);\n }\n\n function getGridPosition(){\n return absBox($container[0])\n }\n\n function handleActiveCellPositionChange(){\n if (!activeCellNode){\n return;\n }\n\n trigger(self.onActiveCellPositionChanged, {});\n\n if (currentEditor){\n var cellBox = getActiveCellPosition();\n if (currentEditor.show && currentEditor.hide){\n if (!cellBox.visible){\n currentEditor.hide();\n } else {\n currentEditor.show();\n }\n }\n\n if (currentEditor.position){\n currentEditor.position(cellBox);\n }\n }\n }\n\n function getCellEditor(){\n return currentEditor;\n }\n\n function getActiveCell(){\n if (!activeCellNode){\n return null;\n } else {\n return {\n row: activeRow,\n cell: activeCell\n };\n }\n }\n\n function getActiveCellNode(){\n return activeCellNode;\n }\n\n function scrollActiveCellIntoView(){\n if (activeRow != null && activeCell != null){\n scrollCellIntoView(activeRow, activeCell);\n }\n }\n\n function scrollRowIntoView(row, doPaging){\n\n if (!hasFrozenRows || (!options.frozenBottom && row > actualFrozenRow - 1) || (options.frozenBottom && row < actualFrozenRow - 1)){\n\n var viewportScrollH = $viewportScrollContainerY.height();\n\n var rowAtTop = row * options.rowHeight;\n var rowAtBottom = (row + 1) * options.rowHeight - viewportScrollH + (viewportHasHScroll ? scrollbarDimensions.height : 0);\n\n // need to page down?\n if ((row + 1) * options.rowHeight > scrollTop + viewportScrollH + offset){\n scrollTo(doPaging ? rowAtTop : rowAtBottom);\n render();\n }\n // or page up?\n else if (row * options.rowHeight < scrollTop + offset){\n scrollTo(doPaging ? rowAtBottom : rowAtTop);\n render();\n }\n }\n }\n\n function scrollRowToTop(row){\n scrollTo(row * options.rowHeight);\n render();\n }\n\n function scrollPage(dir){\n var deltaRows = dir * numVisibleRows;\n scrollTo((getRowFromPosition(scrollTop) + deltaRows) * options.rowHeight);\n render();\n\n if (options.enableCellNavigation && activeRow != null){\n var row = activeRow + deltaRows;\n var dataLengthIncludingAddNew = getDataLengthIncludingAddNew();\n if (row >= dataLengthIncludingAddNew){\n row = dataLengthIncludingAddNew - 1;\n }\n if (row < 0){\n row = 0;\n }\n\n var cell = 0,\n prevCell = null;\n var prevActivePosX = activePosX;\n while (cell <= activePosX){\n if (canCellBeActive(row, cell)){\n prevCell = cell;\n }\n cell += getColspan(row, cell);\n }\n\n if (prevCell !== null){\n setActiveCellInternal(getCellNode(row, prevCell));\n activePosX = prevActivePosX;\n } else {\n resetActiveCell();\n }\n }\n }\n\n function navigatePageDown(){\n scrollPage(1);\n }\n\n function navigatePageUp(){\n scrollPage(-1);\n }\n\n function getColspan(row, cell){\n var metadata = data.getItemMetadata && data.getItemMetadata(row);\n if (!metadata || !metadata.columns){\n return 1;\n }\n\n var columnData = columns[cell] && (metadata.columns[columns[cell].id] || metadata.columns[cell]);\n var colspan = (columnData && columnData.colspan);\n if (colspan === \"*\"){\n colspan = columns.length - cell;\n } else {\n colspan = colspan || 1;\n }\n\n return colspan;\n }\n\n function findFirstFocusableCell(row){\n var cell = 0;\n while (cell < columns.length){\n if (canCellBeActive(row, cell)){\n return cell;\n }\n cell += getColspan(row, cell);\n }\n return null;\n }\n\n function findLastFocusableCell(row){\n var cell = 0;\n var lastFocusableCell = null;\n while (cell < columns.length){\n if (canCellBeActive(row, cell)){\n lastFocusableCell = cell;\n }\n cell += getColspan(row, cell);\n }\n return lastFocusableCell;\n }\n\n function gotoRight(row, cell, posX){\n if (cell >= columns.length){\n return null;\n }\n\n do {\n cell += getColspan(row, cell);\n }\n while (cell < columns.length && !canCellBeActive(row, cell));\n\n if (cell < columns.length){\n return {\n \"row\": row,\n \"cell\": cell,\n \"posX\": cell\n };\n }\n return null;\n }\n\n function gotoLeft(row, cell, posX){\n if (cell <= 0){\n return null;\n }\n\n var firstFocusableCell = findFirstFocusableCell(row);\n if (firstFocusableCell === null || firstFocusableCell >= cell){\n return null;\n }\n\n var prev = {\n \"row\": row,\n \"cell\": firstFocusableCell,\n \"posX\": firstFocusableCell\n };\n var pos;\n while (true){\n pos = gotoRight(prev.row, prev.cell, prev.posX);\n if (!pos){\n return null;\n }\n if (pos.cell >= cell){\n return prev;\n }\n prev = pos;\n }\n }\n\n function gotoDown(row, cell, posX){\n var prevCell;\n var dataLengthIncludingAddNew = getDataLengthIncludingAddNew();\n while (true){\n if (++row >= dataLengthIncludingAddNew){\n return null;\n }\n\n prevCell = cell = 0;\n while (cell <= posX){\n prevCell = cell;\n cell += getColspan(row, cell);\n }\n\n if (canCellBeActive(row, prevCell)){\n return {\n \"row\": row,\n \"cell\": prevCell,\n \"posX\": posX\n };\n }\n }\n }\n\n function gotoUp(row, cell, posX){\n var prevCell;\n while (true){\n if (--row < 0){\n return null;\n }\n\n prevCell = cell = 0;\n while (cell <= posX){\n prevCell = cell;\n cell += getColspan(row, cell);\n }\n\n if (canCellBeActive(row, prevCell)){\n return {\n \"row\": row,\n \"cell\": prevCell,\n \"posX\": posX\n };\n }\n }\n }\n\n function gotoNext(row, cell, posX){\n if (row == null && cell == null){\n row = cell = posX = 0;\n if (canCellBeActive(row, cell)){\n return {\n \"row\": row,\n \"cell\": cell,\n \"posX\": cell\n };\n }\n }\n\n var pos = gotoRight(row, cell, posX);\n if (pos){\n return pos;\n }\n\n var firstFocusableCell = null;\n var dataLengthIncludingAddNew = getDataLengthIncludingAddNew();\n while (++row < dataLengthIncludingAddNew){\n firstFocusableCell = findFirstFocusableCell(row);\n if (firstFocusableCell !== null){\n return {\n \"row\": row,\n \"cell\": firstFocusableCell,\n \"posX\": firstFocusableCell\n };\n }\n }\n return null;\n }\n\n function gotoPrev(row, cell, posX){\n if (row == null && cell == null){\n row = getDataLengthIncludingAddNew() - 1;\n cell = posX = columns.length - 1;\n if (canCellBeActive(row, cell)){\n return {\n \"row\": row,\n \"cell\": cell,\n \"posX\": cell\n };\n }\n }\n\n var pos;\n var lastSelectableCell;\n while (!pos){\n pos = gotoLeft(row, cell, posX);\n if (pos){\n break;\n }\n if (--row < 0){\n return null;\n }\n\n cell = 0;\n lastSelectableCell = findLastFocusableCell(row);\n if (lastSelectableCell !== null){\n pos = {\n \"row\": row,\n \"cell\": lastSelectableCell,\n \"posX\": lastSelectableCell\n };\n }\n }\n return pos;\n }\n\n function navigateRight(){\n return navigate(\"right\");\n }\n\n function navigateLeft(){\n return navigate(\"left\");\n }\n\n function navigateDown(){\n return navigate(\"down\");\n }\n\n function navigateUp(){\n return navigate(\"up\");\n }\n\n function navigateNext(){\n return navigate(\"next\");\n }\n\n function navigatePrev(){\n return navigate(\"prev\");\n }\n\n /**\n * @param {string} dir Navigation direction.\n * @return {boolean} Whether navigation resulted in a change of active cell.\n */\n function navigate(dir){\n if (!options.enableCellNavigation){\n return false;\n }\n\n if (!activeCellNode && dir != \"prev\" && dir != \"next\"){\n return false;\n }\n\n if (!getEditorLock().commitCurrentEdit()){\n return true;\n }\n setFocus();\n\n var tabbingDirections = {\n \"up\": -1,\n \"down\": 1,\n \"left\": -1,\n \"right\": 1,\n \"prev\": -1,\n \"next\": 1\n };\n tabbingDirection = tabbingDirections[dir];\n\n var stepFunctions = {\n \"up\": gotoUp,\n \"down\": gotoDown,\n \"left\": gotoLeft,\n \"right\": gotoRight,\n \"prev\": gotoPrev,\n \"next\": gotoNext\n };\n var stepFn = stepFunctions[dir];\n var pos = stepFn(activeRow, activeCell, activePosX);\n if (pos){\n if (hasFrozenRows && options.frozenBottom & pos.row == getDataLength()){\n return;\n }\n\n var isAddNewRow = (pos.row == getDataLength());\n\n if ((!options.frozenBottom && pos.row >= actualFrozenRow) || (options.frozenBottom && pos.row < actualFrozenRow)){\n scrollCellIntoView(pos.row, pos.cell, !isAddNewRow);\n }\n\n setActiveCellInternal(getCellNode(pos.row, pos.cell))\n activePosX = pos.posX;\n return true;\n } else {\n setActiveCellInternal(getCellNode(activeRow, activeCell));\n return false;\n }\n }\n\n function getCellNode(row, cell){\n if (rowsCache[row]){\n ensureCellNodesInRowsCache(row);\n return rowsCache[row].cellNodesByColumnIdx[cell];\n }\n return null;\n }\n\n function setActiveCell(row, cell){\n if (!initialized){\n return;\n }\n if (row > getDataLength() || row < 0 || cell >= columns.length || cell < 0){\n return;\n }\n\n if (!options.enableCellNavigation){\n return;\n }\n\n scrollCellIntoView(row, cell, false);\n setActiveCellInternal(getCellNode(row, cell), false);\n }\n\n function canCellBeActive(row, cell){\n if (!options.enableCellNavigation || row >= getDataLengthIncludingAddNew() || row < 0 || cell >= columns.length || cell < 0){\n return false;\n }\n\n var rowMetadata = data.getItemMetadata && data.getItemMetadata(row);\n if (rowMetadata && typeof rowMetadata.focusable === \"boolean\"){\n return rowMetadata.focusable;\n }\n\n var columnMetadata = rowMetadata && rowMetadata.columns;\n if (columnMetadata && columns[cell] && columnMetadata[columns[cell].id] && typeof columnMetadata[columns[cell].id].focusable === \"boolean\"){\n return columnMetadata[columns[cell].id].focusable;\n }\n if (columnMetadata && columnMetadata[cell] && typeof columnMetadata[cell].focusable === \"boolean\"){\n return columnMetadata[cell].focusable;\n }\n\n return columns[cell] && columns[cell].focusable;\n }\n\n function canCellBeSelected(row, cell){\n if (row >= getDataLength() || row < 0 || cell >= columns.length || cell < 0){\n return false;\n }\n\n var rowMetadata = data.getItemMetadata && data.getItemMetadata(row);\n if (rowMetadata && typeof rowMetadata.selectable === \"boolean\"){\n return rowMetadata.selectable;\n }\n\n var columnMetadata = rowMetadata && rowMetadata.columns && (rowMetadata.columns[columns[cell].id] || rowMetadata.columns[cell]);\n if (columnMetadata && typeof columnMetadata.selectable === \"boolean\"){\n return columnMetadata.selectable;\n }\n\n return columns[cell].selectable;\n }\n\n function gotoCell(row, cell, forceEdit){\n if (!initialized){\n return;\n }\n if (!canCellBeActive(row, cell)){\n return;\n }\n\n if (!getEditorLock().commitCurrentEdit()){\n return;\n }\n\n scrollCellIntoView(row, cell, false);\n\n var newCell = getCellNode(row, cell);\n\n // if selecting the 'add new' row, start editing right away\n setActiveCellInternal(newCell, forceEdit || (row === getDataLength()) || options.autoEdit);\n\n // if no editor was created, set the focus back on the grid\n if (!currentEditor){\n setFocus();\n }\n }\n\n //////////////////////////////////////////////////////////////////////////////////////////////\n // IEditor implementation for the editor lock\n\n function commitCurrentEdit(){\n var item = getDataItem(activeRow);\n var column = columns[activeCell];\n\n if (currentEditor){\n if (currentEditor.isValueChanged()){\n var validationResults = currentEditor.validate();\n\n if (validationResults.valid){\n if (activeRow < getDataLength()){\n var editCommand = {\n row: activeRow,\n cell: activeCell,\n editor: currentEditor,\n serializedValue: currentEditor.serializeValue(),\n prevSerializedValue: serializedEditorValue,\n execute: function(){\n this.editor.applyValue(item, this.serializedValue);\n updateRow(this.row);\n trigger(self.onCellChange, {\n row: activeRow,\n cell: activeCell,\n item: item\n });\n },\n undo: function(){\n this.editor.applyValue(item, this.prevSerializedValue);\n updateRow(this.row);\n trigger(self.onCellChange, {\n row: activeRow,\n cell: activeCell,\n item: item\n });\n }\n };\n\n if (options.editCommandHandler){\n makeActiveCellNormal();\n options.editCommandHandler(item, column, editCommand);\n } else {\n editCommand.execute();\n makeActiveCellNormal();\n }\n\n } else {\n var newItem = {};\n currentEditor.applyValue(newItem, currentEditor.serializeValue());\n makeActiveCellNormal();\n trigger(self.onAddNewRow, {\n item: newItem,\n column: column\n });\n }\n\n // check whether the lock has been re-acquired by event handlers\n return !getEditorLock().isActive();\n } else {\n // Re-add the CSS class to trigger transitions, if any.\n $(activeCellNode).removeClass(\"invalid\");\n $(activeCellNode).width(); // force layout\n $(activeCellNode).addClass(\"invalid\");\n\n trigger(self.onValidationError, {\n editor: currentEditor,\n cellNode: activeCellNode,\n validationResults: validationResults,\n row: activeRow,\n cell: activeCell,\n column: column\n });\n\n currentEditor.focus();\n return false;\n }\n }\n\n makeActiveCellNormal();\n }\n return true;\n }\n\n function cancelCurrentEdit(){\n makeActiveCellNormal();\n return true;\n }\n\n function rowsToRanges(rows){\n var ranges = [];\n var lastCell = columns.length - 1;\n for (var i = 0; i < rows.length; i++){\n ranges.push(new Slick.Range(rows[i], 0, rows[i], lastCell));\n }\n return ranges;\n }\n\n function getSelectedRows(){\n if (!selectionModel){\n throw \"Selection model is not set\";\n }\n return selectedRows;\n }\n\n function setSelectedRows(rows){\n if (!selectionModel){\n throw \"Selection model is not set\";\n }\n selectionModel.setSelectedRanges(rowsToRanges(rows));\n }\n\n //////////////////////////////////////////////////////////////////////////////////////////////\n // Debug\n\n this.debug = function(){\n var s = \"\";\n\n s += (\"\\n\" + \"counter_rows_rendered: \" + counter_rows_rendered);\n s += (\"\\n\" + \"counter_rows_removed: \" + counter_rows_removed);\n s += (\"\\n\" + \"renderedRows: \" + renderedRows);\n s += (\"\\n\" + \"numVisibleRows: \" + numVisibleRows);\n s += (\"\\n\" + \"maxSupportedCssHeight: \" + maxSupportedCssHeight);\n s += (\"\\n\" + \"n(umber of pages): \" + n);\n s += (\"\\n\" + \"(current) page: \" + page);\n s += (\"\\n\" + \"page height (ph): \" + ph);\n s += (\"\\n\" + \"vScrollDir: \" + vScrollDir);\n\n alert(s);\n };\n\n // a debug helper to be able to access private members\n this.eval = function(expr){\n return eval(expr);\n };\n\n //////////////////////////////////////////////////////////////////////////////////////////////\n // Public API\n\n $.extend(this, {\n \"slickGridVersion\": \"2.1\",\n\n // Events\n \"onScroll\": new Slick.Event(),\n \"onSort\": new Slick.Event(),\n \"onHeaderMouseEnter\": new Slick.Event(),\n \"onHeaderMouseLeave\": new Slick.Event(),\n \"onHeaderContextMenu\": new Slick.Event(),\n \"onHeaderClick\": new Slick.Event(),\n \"onHeaderCellRendered\": new Slick.Event(),\n \"onBeforeHeaderCellDestroy\": new Slick.Event(),\n \"onHeaderRowCellRendered\": new Slick.Event(),\n \"onFooterRowCellRendered\": new Slick.Event(),\n \"onBeforeHeaderRowCellDestroy\": new Slick.Event(),\n \"onBeforeFooterRowCellDestroy\": new Slick.Event(),\n \"onMouseEnter\": new Slick.Event(),\n \"onMouseLeave\": new Slick.Event(),\n \"onClick\": new Slick.Event(),\n \"onDblClick\": new Slick.Event(),\n \"onContextMenu\": new Slick.Event(),\n \"onKeyDown\": new Slick.Event(),\n \"onAddNewRow\": new Slick.Event(),\n \"onValidationError\": new Slick.Event(),\n \"onViewportChanged\": new Slick.Event(),\n \"onColumnsReordered\": new Slick.Event(),\n \"onColumnsResized\": new Slick.Event(),\n \"onCellChange\": new Slick.Event(),\n \"onBeforeEditCell\": new Slick.Event(),\n \"onBeforeCellEditorDestroy\": new Slick.Event(),\n \"onBeforeDestroy\": new Slick.Event(),\n \"onActiveCellChanged\": new Slick.Event(),\n \"onActiveCellPositionChanged\": new Slick.Event(),\n \"onDragInit\": new Slick.Event(),\n \"onDragStart\": new Slick.Event(),\n \"onDrag\": new Slick.Event(),\n \"onDragEnd\": new Slick.Event(),\n \"onSelectedRowsChanged\": new Slick.Event(),\n \"onCellCssStylesChanged\": new Slick.Event(),\n\n // Methods\n \"registerPlugin\": registerPlugin,\n \"unregisterPlugin\": unregisterPlugin,\n \"getColumns\": getColumns,\n \"setColumns\": setColumns,\n \"getColumnIndex\": getColumnIndex,\n \"updateColumnHeader\": updateColumnHeader,\n \"setSortColumn\": setSortColumn,\n \"setSortColumns\": setSortColumns,\n \"getSortColumns\": getSortColumns,\n \"autosizeColumns\": autosizeColumns,\n \"getOptions\": getOptions,\n \"setOptions\": setOptions,\n \"getData\": getData,\n \"getDataLength\": getDataLength,\n \"getDataItem\": getDataItem,\n \"setData\": setData,\n \"getSelectionModel\": getSelectionModel,\n \"setSelectionModel\": setSelectionModel,\n \"getSelectedRows\": getSelectedRows,\n \"setSelectedRows\": setSelectedRows,\n \"getContainerNode\": getContainerNode,\n\n \"render\": render,\n \"invalidate\": invalidate,\n \"invalidateRow\": invalidateRow,\n \"invalidateRows\": invalidateRows,\n \"invalidateAllRows\": invalidateAllRows,\n \"updateCell\": updateCell,\n \"updateRow\": updateRow,\n \"getViewport\": getVisibleRange,\n \"getRenderedRange\": getRenderedRange,\n \"resizeCanvas\": resizeCanvas,\n \"updateRowCount\": updateRowCount,\n \"scrollRowIntoView\": scrollRowIntoView,\n \"scrollRowToTop\": scrollRowToTop,\n \"scrollCellIntoView\": scrollCellIntoView,\n \"getCanvasNode\": getCanvasNode,\n \"getCanvases\": getCanvases,\n \"getActiveCanvasNode\": getActiveCanvasNode,\n \"setActiveCanvasNode\": setActiveCanvasNode,\n \"getViewportNode\": getViewportNode,\n \"getActiveViewportNode\": getActiveViewportNode,\n \"setActiveViewportNode\": setActiveViewportNode,\n \"focus\": setFocus,\n\n \"getCellFromPoint\": getCellFromPoint,\n \"getCellFromEvent\": getCellFromEvent,\n \"getActiveCell\": getActiveCell,\n \"setActiveCell\": setActiveCell,\n \"getActiveCellNode\": getActiveCellNode,\n \"getActiveCellPosition\": getActiveCellPosition,\n \"resetActiveCell\": resetActiveCell,\n \"editActiveCell\": makeActiveCellEditable,\n \"getCellEditor\": getCellEditor,\n \"getCellNode\": getCellNode,\n \"getCellNodeBox\": getCellNodeBox,\n \"canCellBeSelected\": canCellBeSelected,\n \"canCellBeActive\": canCellBeActive,\n \"navigatePrev\": navigatePrev,\n \"navigateNext\": navigateNext,\n \"navigateUp\": navigateUp,\n \"navigateDown\": navigateDown,\n \"navigateLeft\": navigateLeft,\n \"navigateRight\": navigateRight,\n \"navigatePageUp\": navigatePageUp,\n \"navigatePageDown\": navigatePageDown,\n \"gotoCell\": gotoCell,\n \"getTopPanel\": getTopPanel,\n \"setTopPanelVisibility\": setTopPanelVisibility,\n \"setHeaderRowVisibility\": setHeaderRowVisibility,\n \"getHeaderRow\": getHeaderRow,\n \"getHeaderRowColumn\": getHeaderRowColumn,\n \"setFooterRowVisibility\": setFooterRowVisibility,\n \"getFooterRow\": getFooterRow,\n \"getFooterRowColumn\": getFooterRowColumn,\n \"getGridPosition\": getGridPosition,\n \"flashCell\": flashCell,\n \"addCellCssStyles\": addCellCssStyles,\n \"setCellCssStyles\": setCellCssStyles,\n \"removeCellCssStyles\": removeCellCssStyles,\n \"getCellCssStyles\": getCellCssStyles,\n \"getFrozenRowOffset\": getFrozenRowOffset,\n\n \"init\": finishInitialization,\n \"destroy\": destroy,\n\n // IEditor implementation\n \"getEditorLock\": getEditorLock,\n \"getEditController\": getEditController\n });\n\n init();\n}\n\n\n\n// WEBPACK FOOTER //\n// ../src/slick-frozen.grid.js","import Slick from './slick.core';\nimport $ from 'jquery';\nimport GroupMetaDataProvider from './slick.groupmetadataprovider';\n\nconst Aggregators = {\n Avg: AvgAggregator,\n Min: MinAggregator,\n Max: MaxAggregator,\n Sum: SumAggregator\n};\n\nconst Data = {\n DataView,\n GroupMetaDataProvider,\n Aggregators\n};\n\nexport default Data;\n\n/** *\n * A sample Model implementation.\n * Provides a filtered view of the underlying data.\n *\n * Relies on the data item having an \"id\" property uniquely identifying it.\n */\nfunction DataView(options){\n let self = this;\n\n let defaults = {\n groupItemMetadataProvider: null,\n inlineFilters: false\n };\n\n // private\n let idProperty = 'id'; // property holding a unique row id\n let items = []; // data by index\n let rows = []; // data by row\n let idxById = {}; // indexes by id\n let rowsById = null; // rows by id; lazy-calculated\n let filter = null; // filter function\n let updated = null; // updated item ids\n let suspend = false; // suspends the recalculation\n let sortAsc = true;\n let fastSortField;\n let sortComparer;\n let refreshHints = {};\n let prevRefreshHints = {};\n let filterArgs;\n let filteredItems = [];\n let compiledFilter;\n let compiledFilterWithCaching;\n let filterCache = [];\n\n // grouping\n let groupingInfoDefaults = {\n getter: null,\n formatter: null,\n comparer: function(a, b){\n return (a.value === b.value ? 0 :\n (a.value > b.value ? 1 : -1)\n );\n },\n predefinedValues: [],\n aggregators: [],\n aggregateEmpty: false,\n aggregateCollapsed: false,\n aggregateChildGroups: false,\n collapsed: false,\n displayTotalsRow: true,\n lazyTotalsCalculation: false\n };\n let groupingInfos = [];\n let groups = [];\n let toggledGroupsByLevel = [];\n let groupingDelimiter = ':|:';\n\n let pagesize = 0;\n let pagenum = 0;\n let totalRows = 0;\n\n // events\n let onRowCountChanged = new Slick.Event();\n let onRowsChanged = new Slick.Event();\n let onPagingInfoChanged = new Slick.Event();\n\n options = $.extend(true, {}, defaults, options);\n\n function beginUpdate(){\n suspend = true;\n }\n\n function endUpdate(){\n suspend = false;\n refresh();\n }\n\n function setRefreshHints(hints){\n refreshHints = hints;\n }\n\n function setFilterArgs(args){\n filterArgs = args;\n }\n\n function updateIdxById(startingIndex){\n startingIndex = startingIndex || 0;\n let id;\n for (let i = startingIndex, l = items.length; i < l; i++){\n id = items[i][idProperty];\n if (id === undefined){\n throw \"Each data element must implement a unique 'id' property\";\n }\n idxById[id] = i;\n }\n }\n\n function ensureIdUniqueness(){\n let id;\n for (let i = 0, l = items.length; i < l; i++){\n id = items[i][idProperty];\n if (id === undefined || idxById[id] !== i){\n throw \"Each data element must implement a unique 'id' property\";\n }\n }\n }\n\n function getItems(){\n return items;\n }\n\n function setItems(data, objectIdProperty){\n if (objectIdProperty !== undefined){\n idProperty = objectIdProperty;\n }\n items = filteredItems = data;\n idxById = {};\n updateIdxById();\n ensureIdUniqueness();\n refresh();\n }\n\n function setPagingOptions(args){\n if (args.pageSize != undefined){\n pagesize = args.pageSize;\n pagenum = pagesize ? Math.min(pagenum, Math.max(0, Math.ceil(totalRows / pagesize) - 1)) : 0;\n }\n\n if (args.pageNum != undefined){\n pagenum = Math.min(args.pageNum, Math.max(0, Math.ceil(totalRows / pagesize) - 1));\n }\n\n onPagingInfoChanged.notify(getPagingInfo(), null, self);\n\n refresh();\n }\n\n function getPagingInfo(){\n let totalPages = pagesize ? Math.max(1, Math.ceil(totalRows / pagesize)) : 1;\n return {pageSize: pagesize, pageNum: pagenum, totalRows: totalRows, totalPages: totalPages, dataView: self};\n }\n\n function sort(comparer, ascending){\n sortAsc = ascending;\n sortComparer = comparer;\n fastSortField = null;\n if (ascending === false){\n items.reverse();\n }\n items.sort(comparer);\n if (ascending === false){\n items.reverse();\n }\n idxById = {};\n updateIdxById();\n refresh();\n }\n\n /** *\n * Provides a workaround for the extremely slow sorting in IE.\n * Does a [lexicographic] sort on a give column by temporarily overriding Object.prototype.toString\n * to return the value of that field and then doing a native Array.sort().\n */\n function fastSort(field, ascending){\n sortAsc = ascending;\n fastSortField = field;\n sortComparer = null;\n let oldToString = Object.prototype.toString;\n Object.prototype.toString = (typeof field == 'function') ? field : function(){\n return this[field];\n };\n // an extra reversal for descending sort keeps the sort stable\n // (assuming a stable native sort implementation, which isn't true in some cases)\n if (ascending === false){\n items.reverse();\n }\n items.sort();\n Object.prototype.toString = oldToString;\n if (ascending === false){\n items.reverse();\n }\n idxById = {};\n updateIdxById();\n refresh();\n }\n\n function reSort(){\n if (sortComparer){\n sort(sortComparer, sortAsc);\n } else if (fastSortField){\n fastSort(fastSortField, sortAsc);\n }\n }\n\n function setFilter(filterFn){\n filter = filterFn;\n if (options.inlineFilters){\n compiledFilter = compileFilter();\n compiledFilterWithCaching = compileFilterWithCaching();\n }\n refresh();\n }\n\n function getGrouping(){\n return groupingInfos;\n }\n\n function setGrouping(groupingInfo){\n if (!options.groupItemMetadataProvider){\n options.groupItemMetadataProvider = new Data.GroupItemMetadataProvider();\n }\n\n groups = [];\n toggledGroupsByLevel = [];\n groupingInfo = groupingInfo || [];\n groupingInfos = (groupingInfo instanceof Array) ? groupingInfo : [groupingInfo];\n\n for (let i = 0; i < groupingInfos.length; i++){\n let gi = groupingInfos[i] = $.extend(true, {}, groupingInfoDefaults, groupingInfos[i]);\n gi.getterIsAFn = typeof gi.getter === 'function';\n\n // pre-compile accumulator loops\n gi.compiledAccumulators = [];\n let idx = gi.aggregators.length;\n while (idx--){\n gi.compiledAccumulators[idx] = compileAccumulatorLoop(gi.aggregators[idx]);\n }\n\n toggledGroupsByLevel[i] = {};\n }\n\n refresh();\n }\n\n /**\n * @deprecated Please use {@link setGrouping}.\n */\n function groupBy(valueGetter, valueFormatter, sortComparer){\n if (valueGetter == null){\n setGrouping([]);\n return;\n }\n\n setGrouping({\n getter: valueGetter,\n formatter: valueFormatter,\n comparer: sortComparer\n });\n }\n\n /**\n * @deprecated Please use {@link setGrouping}.\n */\n function setAggregators(groupAggregators, includeCollapsed){\n if (!groupingInfos.length){\n throw new Error('At least one grouping must be specified before calling setAggregators().');\n }\n\n groupingInfos[0].aggregators = groupAggregators;\n groupingInfos[0].aggregateCollapsed = includeCollapsed;\n\n setGrouping(groupingInfos);\n }\n\n function getItemByIdx(i){\n return items[i];\n }\n\n function getIdxById(id){\n return idxById[id];\n }\n\n function ensureRowsByIdCache(){\n if (!rowsById){\n rowsById = {};\n for (let i = 0, l = rows.length; i < l; i++){\n rowsById[rows[i][idProperty]] = i;\n }\n }\n }\n\n function getRowById(id){\n ensureRowsByIdCache();\n return rowsById[id];\n }\n\n function getItemById(id){\n return items[idxById[id]];\n }\n\n function mapIdsToRows(idArray){\n let rows = [];\n ensureRowsByIdCache();\n for (let i = 0, l = idArray.length; i < l; i++){\n let row = rowsById[idArray[i]];\n if (row != null){\n rows[rows.length] = row;\n }\n }\n return rows;\n }\n\n function mapRowsToIds(rowArray){\n let ids = [];\n for (let i = 0, l = rowArray.length; i < l; i++){\n if (rowArray[i] < rows.length){\n ids[ids.length] = rows[rowArray[i]][idProperty];\n }\n }\n return ids;\n }\n\n function updateItem(id, item){\n if (idxById[id] === undefined || id !== item[idProperty]){\n throw 'Invalid or non-matching id';\n }\n items[idxById[id]] = item;\n if (!updated){\n updated = {};\n }\n updated[id] = true;\n refresh();\n }\n\n function insertItem(insertBefore, item){\n items.splice(insertBefore, 0, item);\n updateIdxById(insertBefore);\n refresh();\n }\n\n function addItem(item){\n items.push(item);\n updateIdxById(items.length - 1);\n refresh();\n }\n\n function deleteItem(id){\n let idx = idxById[id];\n if (idx === undefined){\n throw 'Invalid id';\n }\n delete idxById[id];\n items.splice(idx, 1);\n updateIdxById(idx);\n refresh();\n }\n\n function getLength(){\n return rows.length;\n }\n\n function getItem(i){\n let item = rows[i];\n\n // if this is a group row, make sure totals are calculated and update the title\n if (item && item.__group && item.totals && !item.totals.initialized){\n let gi = groupingInfos[item.level];\n if (!gi.displayTotalsRow){\n calculateTotals(item.totals);\n item.title = gi.formatter ? gi.formatter(item) : item.value;\n }\n }\n // if this is a totals row, make sure it's calculated\n else if (item && item.__groupTotals && !item.initialized){\n calculateTotals(item);\n }\n\n return item;\n }\n\n function getItemMetadata(i){\n let item = rows[i];\n if (item === undefined){\n return null;\n }\n\n // overrides for grouping rows\n if (item.__group){\n return options.groupItemMetadataProvider.getGroupRowMetadata(item);\n }\n\n // overrides for totals rows\n if (item.__groupTotals){\n return options.groupItemMetadataProvider.getTotalsRowMetadata(item);\n }\n\n return null;\n }\n\n function expandCollapseAllGroups(level, collapse){\n if (level == null){\n for (let i = 0; i < groupingInfos.length; i++){\n toggledGroupsByLevel[i] = {};\n groupingInfos[i].collapsed = collapse;\n }\n } else {\n toggledGroupsByLevel[level] = {};\n groupingInfos[level].collapsed = collapse;\n }\n refresh();\n }\n\n /**\n * @param level {Number} Optional level to collapse. If not specified, applies to all levels.\n */\n function collapseAllGroups(level){\n expandCollapseAllGroups(level, true);\n }\n\n /**\n * @param level {Number} Optional level to expand. If not specified, applies to all levels.\n */\n function expandAllGroups(level){\n expandCollapseAllGroups(level, false);\n }\n\n function expandCollapseGroup(level, groupingKey, collapse){\n toggledGroupsByLevel[level][groupingKey] = groupingInfos[level].collapsed ^ collapse;\n refresh();\n }\n\n /**\n * @param letArgs Either a Slick.Group's \"groupingKey\" property, or a\n * letiable argument list of grouping values denoting a unique path to the row. For\n * example, calling collapseGroup('high', '10%') will collapse the '10%' subgroup of\n * the 'high' group.\n */\n function collapseGroup(letArgs){\n let args = Array.prototype.slice.call(arguments);\n let arg0 = args[0];\n if (args.length == 1 && arg0.indexOf(groupingDelimiter) != -1){\n expandCollapseGroup(arg0.split(groupingDelimiter).length - 1, arg0, true);\n } else {\n expandCollapseGroup(args.length - 1, args.join(groupingDelimiter), true);\n }\n }\n\n /**\n * @param letArgs Either a Slick.Group's \"groupingKey\" property, or a\n * letiable argument list of grouping values denoting a unique path to the row. For\n * example, calling expandGroup('high', '10%') will expand the '10%' subgroup of\n * the 'high' group.\n */\n function expandGroup(letArgs){\n let args = Array.prototype.slice.call(arguments);\n let arg0 = args[0];\n if (args.length == 1 && arg0.indexOf(groupingDelimiter) != -1){\n expandCollapseGroup(arg0.split(groupingDelimiter).length - 1, arg0, false);\n } else {\n expandCollapseGroup(args.length - 1, args.join(groupingDelimiter), false);\n }\n }\n\n function getGroups(){\n return groups;\n }\n\n function extractGroups(rows, parentGroup){\n let group;\n let val;\n let groups = [];\n let groupsByVal = {};\n let r;\n let level = parentGroup ? parentGroup.level + 1 : 0;\n let gi = groupingInfos[level];\n\n for (let i = 0, l = gi.predefinedValues.length; i < l; i++){\n val = gi.predefinedValues[i];\n group = groupsByVal[val];\n if (!group){\n group = new Slick.Group();\n group.value = val;\n group.level = level;\n group.groupingKey = (parentGroup ? parentGroup.groupingKey + groupingDelimiter : '') + val;\n groups[groups.length] = group;\n groupsByVal[val] = group;\n }\n }\n\n for (let i = 0, l = rows.length; i < l; i++){\n r = rows[i];\n val = gi.getterIsAFn ? gi.getter(r) : r[gi.getter];\n group = groupsByVal[val];\n if (!group){\n group = new Slick.Group();\n group.value = val;\n group.level = level;\n group.groupingKey = (parentGroup ? parentGroup.groupingKey + groupingDelimiter : '') + val;\n groups[groups.length] = group;\n groupsByVal[val] = group;\n }\n\n group.rows[group.count++] = r;\n }\n\n if (level < groupingInfos.length - 1){\n for (let i = 0; i < groups.length; i++){\n group = groups[i];\n group.groups = extractGroups(group.rows, group);\n }\n }\n\n groups.sort(groupingInfos[level].comparer);\n\n return groups;\n }\n\n function calculateTotals(totals){\n let group = totals.group;\n let gi = groupingInfos[group.level];\n let isLeafLevel = (group.level == groupingInfos.length);\n let agg, idx = gi.aggregators.length;\n\n if (!isLeafLevel && gi.aggregateChildGroups){\n // make sure all the subgroups are calculated\n let i = group.groups.length;\n while (i--){\n if (!group.groups[i].totals.initialized){\n calculateTotals(group.groups[i].totals);\n }\n }\n }\n\n while (idx--){\n agg = gi.aggregators[idx];\n agg.init();\n if (!isLeafLevel && gi.aggregateChildGroups){\n gi.compiledAccumulators[idx].call(agg, group.groups);\n } else {\n gi.compiledAccumulators[idx].call(agg, group.rows);\n }\n agg.storeResult(totals);\n }\n totals.initialized = true;\n }\n\n function addGroupTotals(group){\n let gi = groupingInfos[group.level];\n let totals = new Slick.GroupTotals();\n totals.group = group;\n group.totals = totals;\n if (!gi.lazyTotalsCalculation){\n calculateTotals(totals);\n }\n }\n\n function addTotals(groups, level){\n level = level || 0;\n let gi = groupingInfos[level];\n let groupCollapsed = gi.collapsed;\n let toggledGroups = toggledGroupsByLevel[level];\n let idx = groups.length, g;\n while (idx--){\n g = groups[idx];\n\n if (g.collapsed && !gi.aggregateCollapsed){\n continue;\n }\n\n // Do a depth-first aggregation so that parent group aggregators can access subgroup totals.\n if (g.groups){\n addTotals(g.groups, level + 1);\n }\n\n if (gi.aggregators.length && (\n gi.aggregateEmpty || g.rows.length || (g.groups && g.groups.length))){\n addGroupTotals(g);\n }\n\n g.collapsed = groupCollapsed ^ toggledGroups[g.groupingKey];\n g.title = gi.formatter ? gi.formatter(g) : g.value;\n }\n }\n\n function flattenGroupedRows(groups, level){\n level = level || 0;\n let gi = groupingInfos[level];\n let groupedRows = [], rows, gl = 0, g;\n for (let i = 0, l = groups.length; i < l; i++){\n g = groups[i];\n groupedRows[gl++] = g;\n\n if (!g.collapsed){\n rows = g.groups ? flattenGroupedRows(g.groups, level + 1) : g.rows;\n for (let j = 0, jj = rows.length; j < jj; j++){\n groupedRows[gl++] = rows[j];\n }\n }\n\n if (g.totals && gi.displayTotalsRow && (!g.collapsed || gi.aggregateCollapsed)){\n groupedRows[gl++] = g.totals;\n }\n }\n return groupedRows;\n }\n\n function getFunctionInfo(fn){\n let fnRegex = /^function[^(]*\\(([^)]*)\\)\\s*{([\\s\\S]*)}$/;\n let matches = fn.toString().match(fnRegex);\n return {\n params: matches[1].split(','),\n body: matches[2]\n };\n }\n\n function compileAccumulatorLoop(aggregator){\n let accumulatorInfo = getFunctionInfo(aggregator.accumulate);\n let fn = new Function(\n '_items',\n 'for (let ' + accumulatorInfo.params[0] + ', _i=0, _il=_items.length; _i<_il; _i++) {' +\n accumulatorInfo.params[0] + ' = _items[_i]; ' +\n accumulatorInfo.body +\n '}'\n );\n fn.displayName = 'compiledAccumulatorLoop';\n return fn;\n }\n\n function compileFilter(){\n let filterInfo = getFunctionInfo(filter);\n\n let filterPath1 = '{ continue _coreloop; }$1';\n let filterPath2 = '{ _retval[_idx++] = $item$; continue _coreloop; }$1';\n // make some allowances for minification - there's only so far we can go with RegEx\n let filterBody = filterInfo.body\n .replace(/return false\\s*([;}]|\\}|$)/gi, filterPath1)\n .replace(/return!1([;}]|\\}|$)/gi, filterPath1)\n .replace(/return true\\s*([;}]|\\}|$)/gi, filterPath2)\n .replace(/return!0([;}]|\\}|$)/gi, filterPath2)\n .replace(/return ([^;}]+?)\\s*([;}]|$)/gi,\n '{ if ($1) { _retval[_idx++] = $item$; }; continue _coreloop; }$2');\n\n // This preserves the function template code after JS compression,\n // so that replace() commands still work as expected.\n let tpl = [\n // \"function(_items, _args) { \",\n 'let _retval = [], _idx = 0; ',\n 'let $item$, $args$ = _args; ',\n '_coreloop: ',\n 'for (let _i = 0, _il = _items.length; _i < _il; _i++) { ',\n '$item$ = _items[_i]; ',\n '$filter$; ',\n '} ',\n 'return _retval; '\n // \"}\"\n ].join('');\n tpl = tpl.replace(/\\$filter\\$/gi, filterBody);\n tpl = tpl.replace(/\\$item\\$/gi, filterInfo.params[0]);\n tpl = tpl.replace(/\\$args\\$/gi, filterInfo.params[1]);\n\n let fn = new Function('_items,_args', tpl);\n fn.displayName = 'compiledFilter';\n\n return fn;\n }\n\n function compileFilterWithCaching(){\n let filterInfo = getFunctionInfo(filter);\n\n let filterPath1 = '{ continue _coreloop; }$1';\n let filterPath2 = '{ _cache[_i] = true;_retval[_idx++] = $item$; continue _coreloop; }$1';\n // make some allowances for minification - there's only so far we can go with RegEx\n let filterBody = filterInfo.body\n .replace(/return false\\s*([;}]|\\}|$)/gi, filterPath1)\n .replace(/return!1([;}]|\\}|$)/gi, filterPath1)\n .replace(/return true\\s*([;}]|\\}|$)/gi, filterPath2)\n .replace(/return!0([;}]|\\}|$)/gi, filterPath2)\n .replace(/return ([^;}]+?)\\s*([;}]|$)/gi,\n '{ if ((_cache[_i] = $1)) { _retval[_idx++] = $item$; }; continue _coreloop; }$2');\n\n // This preserves the function template code after JS compression,\n // so that replace() commands still work as expected.\n let tpl = [\n // \"function(_items, _args, _cache) { \",\n 'let _retval = [], _idx = 0; ',\n 'let $item$, $args$ = _args; ',\n '_coreloop: ',\n 'for (let _i = 0, _il = _items.length; _i < _il; _i++) { ',\n '$item$ = _items[_i]; ',\n 'if (_cache[_i]) { ',\n '_retval[_idx++] = $item$; ',\n 'continue _coreloop; ',\n '} ',\n '$filter$; ',\n '} ',\n 'return _retval; '\n // \"}\"\n ].join('');\n tpl = tpl.replace(/\\$filter\\$/gi, filterBody);\n tpl = tpl.replace(/\\$item\\$/gi, filterInfo.params[0]);\n tpl = tpl.replace(/\\$args\\$/gi, filterInfo.params[1]);\n\n let fn = new Function('_items,_args,_cache', tpl);\n fn.displayName = 'compiledFilterWithCaching';\n return fn;\n }\n\n function uncompiledFilter(items, args){\n let retval = [], idx = 0;\n\n for (let i = 0, ii = items.length; i < ii; i++){\n if (filter(items[i], args)){\n retval[idx++] = items[i];\n }\n }\n\n return retval;\n }\n\n function uncompiledFilterWithCaching(items, args, cache){\n let retval = [], idx = 0, item;\n\n for (let i = 0, ii = items.length; i < ii; i++){\n item = items[i];\n if (cache[i]){\n retval[idx++] = item;\n } else if (filter(item, args)){\n retval[idx++] = item;\n cache[i] = true;\n }\n }\n\n return retval;\n }\n\n function getFilteredAndPagedItems(items){\n if (filter){\n let batchFilter = options.inlineFilters ? compiledFilter : uncompiledFilter;\n let batchFilterWithCaching = options.inlineFilters ? compiledFilterWithCaching : uncompiledFilterWithCaching;\n\n if (refreshHints.isFilterNarrowing){\n filteredItems = batchFilter(filteredItems, filterArgs);\n } else if (refreshHints.isFilterExpanding){\n filteredItems = batchFilterWithCaching(items, filterArgs, filterCache);\n } else if (!refreshHints.isFilterUnchanged){\n filteredItems = batchFilter(items, filterArgs);\n }\n } else {\n // special case: if not filtering and not paging, the resulting\n // rows collection needs to be a copy so that changes due to sort\n // can be caught\n filteredItems = pagesize ? items : items.concat();\n }\n\n // get the current page\n let paged;\n if (pagesize){\n if (filteredItems.length < pagenum * pagesize){\n pagenum = Math.floor(filteredItems.length / pagesize);\n }\n paged = filteredItems.slice(pagesize * pagenum, pagesize * pagenum + pagesize);\n } else {\n paged = filteredItems;\n }\n\n return {totalRows: filteredItems.length, rows: paged};\n }\n\n function getRowDiffs(rows, newRows){\n let item, r, eitherIsNonData, diff = [];\n let from = 0, to = newRows.length;\n\n if (refreshHints && refreshHints.ignoreDiffsBefore){\n from = Math.max(0,\n Math.min(newRows.length, refreshHints.ignoreDiffsBefore));\n }\n\n if (refreshHints && refreshHints.ignoreDiffsAfter){\n to = Math.min(newRows.length,\n Math.max(0, refreshHints.ignoreDiffsAfter));\n }\n\n for (let i = from, rl = rows.length; i < to; i++){\n if (i >= rl){\n diff[diff.length] = i;\n } else {\n item = newRows[i];\n r = rows[i];\n\n if ((groupingInfos.length && (eitherIsNonData = (item.__nonDataRow) || (r.__nonDataRow)) &&\n item.__group !== r.__group ||\n item.__group && !item.equals(r))\n || (eitherIsNonData &&\n // no good way to compare totals since they are arbitrary DTOs\n // deep object comparison is pretty expensive\n // always considering them 'dirty' seems easier for the time being\n (item.__groupTotals || r.__groupTotals))\n || item[idProperty] != r[idProperty]\n || (updated && updated[item[idProperty]])\n ){\n diff[diff.length] = i;\n }\n }\n }\n return diff;\n }\n\n function recalc(_items){\n rowsById = null;\n\n if (refreshHints.isFilterNarrowing != prevRefreshHints.isFilterNarrowing ||\n refreshHints.isFilterExpanding != prevRefreshHints.isFilterExpanding){\n filterCache = [];\n }\n\n let filteredItems = getFilteredAndPagedItems(_items);\n totalRows = filteredItems.totalRows;\n let newRows = filteredItems.rows;\n\n groups = [];\n if (groupingInfos.length){\n groups = extractGroups(newRows);\n if (groups.length){\n addTotals(groups);\n newRows = flattenGroupedRows(groups);\n }\n }\n\n let diff = getRowDiffs(rows, newRows);\n\n rows = newRows;\n\n return diff;\n }\n\n function refresh(){\n if (suspend){\n return;\n }\n\n let countBefore = rows.length;\n let totalRowsBefore = totalRows;\n\n let diff = recalc(items, filter); // pass as direct refs to avoid closure perf hit\n\n // if the current page is no longer valid, go to last page and recalc\n // we suffer a performance penalty here, but the main loop (recalc) remains highly optimized\n if (pagesize && totalRows < pagenum * pagesize){\n pagenum = Math.max(0, Math.ceil(totalRows / pagesize) - 1);\n diff = recalc(items, filter);\n }\n\n updated = null;\n prevRefreshHints = refreshHints;\n refreshHints = {};\n\n if (totalRowsBefore !== totalRows){\n onPagingInfoChanged.notify(getPagingInfo(), null, self);\n }\n if (countBefore !== rows.length){\n onRowCountChanged.notify({previous: countBefore, current: rows.length, dataView: self}, null, self);\n }\n if (diff.length > 0){\n onRowsChanged.notify({rows: diff, dataView: self}, null, self);\n }\n }\n\n /** *\n * Wires the grid and the DataView together to keep row selection tied to item ids.\n * This is useful since, without it, the grid only knows about rows, so if the items\n * move around, the same rows stay selected instead of the selection moving along\n * with the items.\n *\n * NOTE: This doesn't work with cell selection model.\n *\n * @param grid {Slick.Grid} The grid to sync selection with.\n * @param preserveHidden {Boolean} Whether to keep selected items that go out of the\n * view due to them getting filtered out.\n * @param preserveHiddenOnSelectionChange {Boolean} Whether to keep selected items\n * that are currently out of the view (see preserveHidden) as selected when selection\n * changes.\n * @return {Slick.Event} An event that notifies when an internal list of selected row ids\n * changes. This is useful since, in combination with the above two options, it allows\n * access to the full list selected row ids, and not just the ones visible to the grid.\n * @method syncGridSelection\n */\n function syncGridSelection(grid, preserveHidden, preserveHiddenOnSelectionChange){\n let self = this;\n let inHandler;\n let selectedRowIds = self.mapRowsToIds(grid.getSelectedRows());\n let onSelectedRowIdsChanged = new Slick.Event();\n\n function setSelectedRowIds(rowIds){\n if (selectedRowIds.join(',') == rowIds.join(',')){\n return;\n }\n\n selectedRowIds = rowIds;\n\n onSelectedRowIdsChanged.notify({\n 'grid': grid,\n 'ids': selectedRowIds,\n 'dataView': self\n }, new Slick.EventData(), self);\n }\n\n function update(){\n if (selectedRowIds.length > 0){\n inHandler = true;\n let selectedRows = self.mapIdsToRows(selectedRowIds);\n if (!preserveHidden){\n setSelectedRowIds(self.mapRowsToIds(selectedRows));\n }\n grid.setSelectedRows(selectedRows);\n inHandler = false;\n }\n }\n\n grid.onSelectedRowsChanged.subscribe(function(e, args){\n if (inHandler){\n return;\n }\n let newSelectedRowIds = self.mapRowsToIds(grid.getSelectedRows());\n if (!preserveHiddenOnSelectionChange || !grid.getOptions().multiSelect){\n setSelectedRowIds(newSelectedRowIds);\n } else {\n // keep the ones that are hidden\n let existing = $.grep(selectedRowIds, function(id){\n return self.getRowById(id) === undefined;\n });\n // add the newly selected ones\n setSelectedRowIds(existing.concat(newSelectedRowIds));\n }\n });\n\n this.onRowsChanged.subscribe(update);\n\n this.onRowCountChanged.subscribe(update);\n\n return onSelectedRowIdsChanged;\n }\n\n function syncGridCellCssStyles(grid, key){\n let hashById;\n let inHandler;\n\n // since this method can be called after the cell styles have been set,\n // get the existing ones right away\n storeCellCssStyles(grid.getCellCssStyles(key));\n\n function storeCellCssStyles(hash){\n hashById = {};\n for (let row in hash){\n let id = rows[row][idProperty];\n hashById[id] = hash[row];\n }\n }\n\n function update(){\n if (hashById){\n inHandler = true;\n ensureRowsByIdCache();\n let newHash = {};\n for (let id in hashById){\n let row = rowsById[id];\n if (row != undefined){\n newHash[row] = hashById[id];\n }\n }\n grid.setCellCssStyles(key, newHash);\n inHandler = false;\n }\n }\n\n grid.onCellCssStylesChanged.subscribe(function(e, args){\n if (inHandler){\n return;\n }\n if (key != args.key){\n return;\n }\n if (args.hash){\n storeCellCssStyles(args.hash);\n }\n });\n\n this.onRowsChanged.subscribe(update);\n\n this.onRowCountChanged.subscribe(update);\n }\n\n $.extend(this, {\n // methods\n 'beginUpdate': beginUpdate,\n 'endUpdate': endUpdate,\n 'setPagingOptions': setPagingOptions,\n 'getPagingInfo': getPagingInfo,\n 'getItems': getItems,\n 'setItems': setItems,\n 'setFilter': setFilter,\n 'sort': sort,\n 'fastSort': fastSort,\n 'reSort': reSort,\n 'setGrouping': setGrouping,\n 'getGrouping': getGrouping,\n 'groupBy': groupBy,\n 'setAggregators': setAggregators,\n 'collapseAllGroups': collapseAllGroups,\n 'expandAllGroups': expandAllGroups,\n 'collapseGroup': collapseGroup,\n 'expandGroup': expandGroup,\n 'getGroups': getGroups,\n 'getIdxById': getIdxById,\n 'getRowById': getRowById,\n 'getItemById': getItemById,\n 'getItemByIdx': getItemByIdx,\n 'mapRowsToIds': mapRowsToIds,\n 'mapIdsToRows': mapIdsToRows,\n 'setRefreshHints': setRefreshHints,\n 'setFilterArgs': setFilterArgs,\n 'refresh': refresh,\n 'updateItem': updateItem,\n 'insertItem': insertItem,\n 'addItem': addItem,\n 'deleteItem': deleteItem,\n 'syncGridSelection': syncGridSelection,\n 'syncGridCellCssStyles': syncGridCellCssStyles,\n\n // data provider methods\n 'getLength': getLength,\n 'getItem': getItem,\n 'getItemMetadata': getItemMetadata,\n\n // events\n 'onRowCountChanged': onRowCountChanged,\n 'onRowsChanged': onRowsChanged,\n 'onPagingInfoChanged': onPagingInfoChanged\n });\n}\n\nfunction AvgAggregator(field){\n this.field_ = field;\n\n this.init = function(){\n this.count_ = 0;\n this.nonNullCount_ = 0;\n this.sum_ = 0;\n };\n\n this.accumulate = function(item){\n let val = item[this.field_];\n this.count_++;\n if (val != null && val !== '' && !isNaN(val)){\n this.nonNullCount_++;\n this.sum_ += parseFloat(val);\n }\n };\n\n this.storeResult = function(groupTotals){\n if (!groupTotals.avg){\n groupTotals.avg = {};\n }\n if (this.nonNullCount_ != 0){\n groupTotals.avg[this.field_] = this.sum_ / this.nonNullCount_;\n }\n };\n}\n\nfunction MinAggregator(field){\n this.field_ = field;\n\n this.init = function(){\n this.min_ = null;\n };\n\n this.accumulate = function(item){\n let val = item[this.field_];\n if (val != null && val !== '' && !isNaN(val)){\n if (this.min_ == null || val < this.min_){\n this.min_ = val;\n }\n }\n };\n\n this.storeResult = function(groupTotals){\n if (!groupTotals.min){\n groupTotals.min = {};\n }\n groupTotals.min[this.field_] = this.min_;\n };\n}\n\nfunction MaxAggregator(field){\n this.field_ = field;\n\n this.init = function(){\n this.max_ = null;\n };\n\n this.accumulate = function(item){\n let val = item[this.field_];\n if (val != null && val !== '' && !isNaN(val)){\n if (this.max_ == null || val > this.max_){\n this.max_ = val;\n }\n }\n };\n\n this.storeResult = function(groupTotals){\n if (!groupTotals.max){\n groupTotals.max = {};\n }\n groupTotals.max[this.field_] = this.max_;\n };\n}\n\nfunction SumAggregator(field){\n this.field_ = field;\n\n this.init = function(){\n this.sum_ = null;\n };\n\n this.accumulate = function(item){\n let val = item[this.field_];\n if (val != null && val !== '' && !isNaN(val)){\n this.sum_ += parseFloat(val);\n }\n };\n\n this.storeResult = function(groupTotals){\n if (!groupTotals.sum){\n groupTotals.sum = {};\n }\n groupTotals.sum[this.field_] = this.sum_;\n };\n}\n\n\n\n// WEBPACK FOOTER //\n// ../src/slick.dataview.js","import Slick from './slick.core';\nimport flatpickr from 'flatpickr';\n//import 'flatpickr/dist/flatpickr.min.css';\nimport $ from 'jquery';\n\nconst { keyCode } = Slick;\n\n/** *\n * Contains basic SlickGrid editors.\n * @module Editors\n * @namespace Slick\n */\n\nconst Editors = {\n Text: TextEditor,\n Integer: IntegerEditor,\n Float: FloatEditor,\n Date: DateEditor,\n YesNoSelect: YesNoSelectEditor,\n Checkbox: CheckboxEditor,\n LongText: LongTextEditor\n};\n\nSlick.Editors = Editors;\nexport default Editors;\n\nfunction TextEditor(args){\n let $input;\n let defaultValue;\n\n this.init = function(){\n $input = $(\"\")\n .appendTo(args.container)\n .bind('keydown.nav', function(e){\n if (e.keyCode === keyCode.LEFT || e.keyCode === keyCode.RIGHT){\n e.stopImmediatePropagation();\n }\n })\n .focus()\n .select();\n };\n\n this.destroy = function(){\n $input.remove();\n };\n\n this.focus = function(){\n $input.focus();\n };\n\n this.getValue = function(){\n return $input.val();\n };\n\n this.setValue = function(val){\n $input.val(val);\n };\n\n this.loadValue = function(item){\n defaultValue = item[args.column.field] || '';\n $input.val(defaultValue);\n $input[0].defaultValue = defaultValue;\n $input.select();\n };\n\n this.serializeValue = function(){\n return $input.val();\n };\n\n this.applyValue = function(item, state){\n item[args.column.field] = state;\n };\n\n this.isValueChanged = function(){\n return (!($input.val() == '' && defaultValue == null)) && ($input.val() != defaultValue);\n };\n\n this.validate = function(){\n let valid = true;\n let msg = null;\n if (args.column.validator){\n let validationResults = args.column.validator($input.val(), args);\n valid = validationResults.valid;\n msg = validationResults.msg;\n }\n\n return {\n valid: true,\n msg: null\n };\n };\n\n this.init();\n}\n\nfunction IntegerEditor(args){\n let $input;\n let defaultValue;\n\n this.init = function(){\n $input = $(\"\");\n\n $input.bind('keydown.nav', function(e){\n if (e.keyCode === keyCode.LEFT || e.keyCode === keyCode.RIGHT){\n e.stopImmediatePropagation();\n }\n });\n\n $input.appendTo(args.container);\n $input.focus().select();\n };\n\n this.destroy = function(){\n $input.remove();\n };\n\n this.focus = function(){\n $input.focus();\n };\n\n this.loadValue = function(item){\n defaultValue = item[args.column.field];\n $input.val(defaultValue);\n $input[0].defaultValue = defaultValue;\n $input.select();\n };\n\n this.serializeValue = function(){\n return parseInt($input.val(), 10) || 0;\n };\n\n this.applyValue = function(item, state){\n item[args.column.field] = state;\n };\n\n this.isValueChanged = function(){\n return (!($input.val() == '' && defaultValue == null)) && ($input.val() != defaultValue);\n };\n\n this.validate = function(){\n if (isNaN($input.val())){\n return {\n valid: false,\n msg: 'Please enter a valid integer'\n };\n }\n\n if (args.column.validator){\n let validationResults = args.column.validator($input.val());\n if (!validationResults.valid){\n return validationResults;\n }\n }\n\n return {\n valid: true,\n msg: null\n };\n };\n\n this.init();\n}\n\nfunction FloatEditor(args){\n let $input;\n let defaultValue;\n let scope = this;\n\n this.init = function(){\n $input = $(\"\");\n\n $input.bind('keydown.nav', function(e){\n if (e.keyCode === keyCode.LEFT || e.keyCode === keyCode.RIGHT){\n e.stopImmediatePropagation();\n }\n });\n\n $input.appendTo(args.container);\n $input.focus().select();\n };\n\n this.destroy = function(){\n $input.remove();\n };\n\n this.focus = function(){\n $input.focus();\n };\n\n function getDecimalPlaces(){\n // returns the number of fixed decimal places or null\n let rtn = args.column.editorFixedDecimalPlaces;\n if (typeof rtn == 'undefined'){\n rtn = FloatEditor.DefaultDecimalPlaces;\n }\n return (!rtn && rtn !== 0 ? null : rtn);\n }\n\n this.loadValue = function(item){\n defaultValue = item[args.column.field];\n\n let decPlaces = getDecimalPlaces();\n if (decPlaces !== null\n && (defaultValue || defaultValue === 0)\n && defaultValue.toFixed){\n defaultValue = defaultValue.toFixed(decPlaces);\n }\n\n $input.val(defaultValue);\n $input[0].defaultValue = defaultValue;\n $input.select();\n };\n\n this.serializeValue = function(){\n let rtn = parseFloat($input.val()) || 0;\n\n let decPlaces = getDecimalPlaces();\n if (decPlaces !== null\n && (rtn || rtn === 0)\n && rtn.toFixed){\n rtn = parseFloat(rtn.toFixed(decPlaces));\n }\n\n return rtn;\n };\n\n this.applyValue = function(item, state){\n item[args.column.field] = state;\n };\n\n this.isValueChanged = function(){\n return (!($input.val() == '' && defaultValue == null)) && ($input.val() != defaultValue);\n };\n\n this.validate = function(){\n if (isNaN($input.val())){\n return {\n valid: false,\n msg: 'Please enter a valid number'\n };\n }\n\n if (args.column.validator){\n let validationResults = args.column.validator($input.val(), args);\n if (!validationResults.valid){\n return validationResults;\n }\n }\n\n return {\n valid: true,\n msg: null\n };\n };\n\n this.init();\n}\n\nFloatEditor.DefaultDecimalPlaces = null;\n\n/**\n * see https://chmln.github.io/flatpickr/#options - pass as column.options.date = {}\n * @param args\n * @constructor\n */\nfunction DateEditor(args){\n let $input,\n flatInstance,\n defaultDate,\n options = args.column.options && args.column.options.date ? args.column.options.date : {};\n\n this.init = function(){\n defaultDate = options.defaultDate = args.item[args.column.field];\n\n $input = $('');\n $input.appendTo(args.container);\n $input.focus().val(defaultDate).select();\n flatInstance = flatpickr($input[0], options);\n };\n\n this.destroy = function(){\n flatInstance.destroy();\n $input.remove();\n };\n\n this.show = function(){\n flatInstance.open();\n flatInstance.positionCalendar();\n };\n\n this.hide = function(){\n flatInstance.close();\n };\n\n this.position = function(position){\n //todo: fix how scrolling is affected\n flatInstance.positionCalendar();\n };\n\n this.focus = function(){\n $input.focus();\n };\n\n this.loadValue = function(item){\n defaultDate = item[args.column.field];\n $input.val(defaultDate);\n $input.select();\n };\n\n this.serializeValue = function(){\n return $input.val();\n };\n\n this.applyValue = function(item, state){\n item[args.column.field] = state;\n };\n\n this.isValueChanged = function(){\n return (!($input.val() == '' && defaultDate == null)) && ($input.val() != defaultDate);\n };\n\n this.validate = function(){\n if (args.column.validator){\n let validationResults = args.column.validator($input.val(), args);\n if (!validationResults.valid){\n return validationResults;\n }\n }\n\n return {\n valid: true,\n msg: null\n };\n };\n\n this.init();\n}\n\nfunction YesNoSelectEditor(args){\n let $select;\n let defaultValue;\n let scope = this;\n\n this.init = function(){\n $select = $(\"\");\n $select.appendTo(args.container);\n $select.focus();\n };\n\n this.destroy = function(){\n $select.remove();\n };\n\n this.focus = function(){\n $select.focus();\n };\n\n this.loadValue = function(item){\n $select.val((defaultValue = item[args.column.field]) ? 'yes' : 'no');\n $select.select();\n };\n\n this.serializeValue = function(){\n return ($select.val() == 'yes');\n };\n\n this.applyValue = function(item, state){\n item[args.column.field] = state;\n };\n\n this.isValueChanged = function(){\n return ($select.val() != defaultValue);\n };\n\n this.validate = function(){\n let valid = true;\n let msg = null;\n if (args.column.validator){\n let validationResults = args.column.validator($select.val(), args);\n valid = validationResults.valid;\n msg = validationResults.msg;\n }\n\n return {\n valid: true,\n msg: null\n };\n };\n\n this.init();\n}\n\nfunction CheckboxEditor(args){\n let $select;\n let defaultValue;\n let scope = this;\n\n this.init = function(){\n $select = $(\"\");\n $select.appendTo(args.container);\n $select.focus();\n };\n\n this.destroy = function(){\n $select.remove();\n };\n\n this.focus = function(){\n $select.focus();\n };\n\n this.loadValue = function(item){\n defaultValue = !!item[args.column.field];\n if (defaultValue){\n $select.prop('checked', true);\n } else {\n $select.prop('checked', false);\n }\n };\n\n this.serializeValue = function(){\n return $select.prop('checked');\n };\n\n this.applyValue = function(item, state){\n item[args.column.field] = state;\n };\n\n this.isValueChanged = function(){\n return (this.serializeValue() !== defaultValue);\n };\n\n this.validate = function(){\n let valid = true;\n let msg = null;\n if (args.column.validator){\n let validationResults = args.column.validator($select.val(), args);\n valid = validationResults.valid;\n msg = validationResults.msg;\n }\n\n return {\n valid: true,\n msg: null\n };\n };\n\n this.init();\n}\n\nfunction PercentCompleteEditor(args){\n console.error('PercentCompleteEditor is derecated');\n}\n\n/*\n * An example of a \"detached\" editor.\n * The UI is added onto document BODY and .position(), .show() and .hide() are implemented.\n * KeyDown events are also handled to provide handling for Tab, Shift-Tab, Esc and Ctrl-Enter.\n */\nfunction LongTextEditor(args){\n let $input, $wrapper;\n let defaultValue;\n let scope = this;\n\n this.init = function(){\n let $container = $('body');\n\n $wrapper = $(\"\").appendTo($container);\n $input = $(\"\").appendTo($wrapper);\n\n $(\"
\").appendTo($wrapper);\n\n $wrapper.find('button:first').bind('click', this.save);\n $wrapper.find('button:last').bind('click', this.cancel);\n $input.bind('keydown', this.handleKeyDown);\n\n scope.position(args.position);\n $input.focus().select();\n };\n\n this.handleKeyDown = function(e){\n if (e.which == keyCode.ENTER && e.ctrlKey){\n scope.save();\n } else if (e.which == keyCode.ESCAPE){\n e.preventDefault();\n scope.cancel();\n } else if (e.which == keyCode.TAB && e.shiftKey){\n e.preventDefault();\n args.grid.navigatePrev();\n } else if (e.which == keyCode.TAB){\n e.preventDefault();\n args.grid.navigateNext();\n }\n };\n\n this.save = function(){\n args.commitChanges();\n };\n\n this.cancel = function(){\n $input.val(defaultValue);\n args.cancelChanges();\n };\n\n this.hide = function(){\n $wrapper.hide();\n };\n\n this.show = function(){\n $wrapper.show();\n };\n\n this.position = function(position){\n $wrapper\n .css('top', position.top - 5)\n .css('left', position.left - 5);\n };\n\n this.destroy = function(){\n $wrapper.remove();\n };\n\n this.focus = function(){\n $input.focus();\n };\n\n this.loadValue = function(item){\n $input.val(defaultValue = item[args.column.field]);\n $input.select();\n };\n\n this.serializeValue = function(){\n return $input.val();\n };\n\n this.applyValue = function(item, state){\n item[args.column.field] = state;\n };\n\n this.isValueChanged = function(){\n return (!($input.val() == '' && defaultValue == null)) && ($input.val() != defaultValue);\n };\n\n this.validate = function(){\n let valid = true;\n let msg = null;\n if (args.column.validator){\n let validationResults = args.column.validator($select.val(), args);\n valid = validationResults.valid;\n msg = validationResults.msg;\n }\n\n return {\n valid: true,\n msg: null\n };\n };\n\n this.init();\n}\n\n\n\n// WEBPACK FOOTER //\n// ../src/slick.editors.js","function PercentCompleteFormatter(row, cell, value, columnDef, dataContext){\n if (value == null || value === ''){\n return '-';\n } else if (value < 50){\n return `${value}%`;\n } else {\n return `${value}%`;\n }\n}\n\nfunction PercentCompleteBarFormatter(row, cell, value, columnDef, dataContext){\n if (value == null || value === ''){\n return '';\n }\n\n let color;\n\n if (value < 30){\n color = 'red';\n } else if (value < 70){\n color = 'silver';\n } else {\n color = 'green';\n }\n\n return \"\";\n}\n\nfunction YesNoFormatter(row, cell, value, columnDef, dataContext){\n return value ? 'Yes' : 'No';\n}\n\nfunction CheckmarkFormatter(row, cell, value, columnDef, dataContext){\n return value ? '✔' : '';\n}\n\nexport default {\n PercentComplete: PercentCompleteFormatter,\n PercentCompleteBar: PercentCompleteBarFormatter,\n YesNo: YesNoFormatter,\n Checkmark: CheckmarkFormatter\n};\n\n\n\n// WEBPACK FOOTER //\n// ../src/slick.formatters.js","/**\n * @license\n * (c) 2009-2013 Michael Leibman\n * michael{dot}leibman{at}gmail{dot}com\n * http://github.com/mleibman/slickgrid\n *\n * Distributed under MIT license.\n * All rights reserved.\n *\n * SlickGrid v2.2\n *\n * NOTES:\n * Cell/row DOM manipulations are done directly bypassing jQuery's DOM manipulation methods.\n * This increases the speed dramatically, but can only be done safely because there are no event handlers\n * or data associated with any cell/row DOM nodes. Cell editors must make sure they implement .destroy()\n * and do proper cleanup.\n */\n\nimport $ from 'jquery';\nimport interact from './interact.js';\n\nimport Slick from './slick.core';\n\n// Slick.Grid globals pretense\nSlick.Grid = SlickGrid;\n\nexport default SlickGrid;\n\n// shared across all grids on the page\nvar scrollbarDimensions;\nvar maxSupportedCssHeight; // browser's breaking point\n\n// ////////////////////////////////////////////////////////////////////////////////////////////\n// SlickGrid class implementation (available as Slick.Grid)\n\n/**\n * Creates a new instance of the grid.\n * @class SlickGrid\n * @constructor\n * @param {Node} container Container node to create the grid in.\n * @param {Array,Object} data An array of objects for databinding.\n * @param {Array} columns An array of column definitions.\n * @param {Object} options Grid options.\n **/\nfunction SlickGrid(container, data, columns, options){\n // settings\n var defaults = {\n explicitInitialization: false,\n rowHeight: 25,\n defaultColumnWidth: 80,\n enableAddRow: false,\n leaveSpaceForNewRows: false,\n editable: false,\n autoEdit: true,\n enableCellNavigation: true,\n enableColumnReorder: true,\n asyncEditorLoading: false,\n asyncEditorLoadDelay: 100,\n forceFitColumns: false,\n enableAsyncPostRender: false,\n asyncPostRenderDelay: 50,\n enableAsyncPostRenderCleanup: false,\n asyncPostRenderCleanupDelay: 40,\n autoHeight: false,\n editorLock: Slick.GlobalEditorLock,\n showHeaderRow: false,\n headerRowHeight: 25,\n createFooterRow: false,\n showFooterRow: false,\n footerRowHeight: 25,\n showTopPanel: false,\n topPanelHeight: 25,\n formatterFactory: null,\n editorFactory: null,\n cellFlashingCssClass: 'flashing',\n selectedCellCssClass: 'selected',\n multiSelect: true,\n enableTextSelectionOnCells: false,\n dataItemColumnValueExtractor: null,\n fullWidthRows: false,\n multiColumnSort: false,\n defaultFormatter: defaultFormatter,\n forceSyncScrolling: false,\n addNewRowCssClass: 'new-row'\n };\n\n var columnDefaults = {\n name: '',\n resizable: true,\n sortable: false,\n minWidth: 30,\n rerenderOnResize: false,\n headerCssClass: null,\n defaultSortAsc: true,\n focusable: true,\n selectable: true\n };\n\n // scroller\n var th; // virtual height\n var h; // real scrollable height\n var ph; // page height\n var n; // number of pages\n var cj; // \"jumpiness\" coefficient\n\n var page = 0; // current page\n var offset = 0; // current page offset\n var vScrollDir = 1;\n\n // private\n var initialized = false;\n var $container;\n var uid = 'slickgrid_' + Math.round(1000000 * Math.random());\n var self = this;\n var $focusSink, $focusSink2;\n var $headerScroller;\n var $headers;\n var $headerRow, $headerRowScroller, $headerRowSpacer;\n var $footerRow, $footerRowScroller, $footerRowSpacer;\n var $topPanelScroller;\n var $topPanel;\n var $viewport;\n var $canvas;\n var $style;\n var $boundAncestors;\n var stylesheet, columnCssRulesL, columnCssRulesR;\n var viewportH, viewportW;\n var canvasWidth;\n var viewportHasHScroll, viewportHasVScroll;\n var headerColumnWidthDiff = 0, headerColumnHeightDiff = 0, // border+padding\n cellWidthDiff = 0, cellHeightDiff = 0, jQueryNewWidthBehaviour = false;\n var absoluteColumnMinWidth;\n\n var tabbingDirection = 1;\n var activePosX;\n var activeRow, activeCell;\n var activeCellNode = null;\n var currentEditor = null;\n var serializedEditorValue;\n var editController;\n\n var rowsCache = {};\n var renderedRows = 0;\n var numVisibleRows;\n var prevScrollTop = 0;\n var scrollTop = 0;\n var lastRenderedScrollTop = 0;\n var lastRenderedScrollLeft = 0;\n var prevScrollLeft = 0;\n var scrollLeft = 0;\n\n var selectionModel;\n var selectedRows = [];\n\n var plugins = [];\n var cellCssClasses = {};\n\n var columnsById = {};\n var sortColumns = [];\n var columnPosLeft = [];\n var columnPosRight = [];\n\n // async call handles\n var h_editorLoader = null;\n var h_render = null;\n var h_postrender = null;\n var h_postrenderCleanup = null;\n var postProcessedRows = {};\n var postProcessToRow = null;\n var postProcessFromRow = null;\n var postProcessedCleanupQueue = [];\n var postProcessgroupId = 0;\n\n // perf counters\n var counter_rows_rendered = 0;\n var counter_rows_removed = 0;\n\n // These two variables work around a bug with inertial scrolling in Webkit/Blink on Mac.\n // See http://crbug.com/312427.\n var rowNodeFromLastMouseWheelEvent; // this node must not be deleted while inertial scrolling\n var zombieRowNodeFromLastMouseWheelEvent; // node that was hidden instead of getting deleted\n var zombieRowCacheFromLastMouseWheelEvent; // row cache for above node\n var zombieRowPostProcessedFromLastMouseWheelEvent; // post processing references for above node\n\n // store css attributes if display:none is active in container or parent\n var cssShow = {position: 'absolute', visibility: 'hidden', display: 'block'};\n var $hiddenParents;\n var oldProps = [];\n\n // ////////////////////////////////////////////////////////////////////////////////////////////\n // Initialization\n\n function init(){\n $container = $(container);\n if ($container.length < 1){\n throw new Error('SlickGrid requires a valid container, ' + container + ' does not exist in the DOM.');\n }\n\n cacheCssForHiddenInit();\n\n // calculate these only once and share between grid instances\n maxSupportedCssHeight = maxSupportedCssHeight || getMaxSupportedCssHeight();\n scrollbarDimensions = scrollbarDimensions || measureScrollbar();\n\n options = $.extend({}, defaults, options);\n validateAndEnforceOptions();\n columnDefaults.width = options.defaultColumnWidth;\n\n columnsById = {};\n for (var i = 0; i < columns.length; i++){\n var m = columns[i] = $.extend({}, columnDefaults, columns[i]);\n columnsById[m.id] = i;\n if (m.minWidth && m.width < m.minWidth){\n m.width = m.minWidth;\n }\n if (m.maxWidth && m.width > m.maxWidth){\n m.width = m.maxWidth;\n }\n }\n\n editController = {\n 'commitCurrentEdit': commitCurrentEdit,\n 'cancelCurrentEdit': cancelCurrentEdit\n };\n\n $container\n .empty()\n .css('overflow', 'hidden')\n .css('outline', 0)\n .addClass(uid)\n .addClass('ui-widget');\n\n // set up a positioning container if needed\n if (!/relative|absolute|fixed/.test($container.css('position'))){\n $container.css('position', 'relative');\n }\n\n $focusSink = $(\"\").appendTo($container);\n\n $headerScroller = $(\"\").appendTo($container);\n $headers = $(\"\").appendTo($headerScroller);\n $headers.width(getHeadersWidth());\n\n $headerRowScroller = $(\"\").appendTo($container);\n $headerRow = $(\"\").appendTo($headerRowScroller);\n $headerRowSpacer = $(\"\")\n .css('width', getCanvasWidth() + scrollbarDimensions.width + 'px')\n .appendTo($headerRowScroller);\n\n $topPanelScroller = $(\"\").appendTo($container);\n $topPanel = $(\"\").appendTo($topPanelScroller);\n\n if (!options.showTopPanel){\n $topPanelScroller.hide();\n }\n\n if (!options.showHeaderRow){\n $headerRowScroller.hide();\n }\n\n $viewport = $(\"
\").appendTo($container);\n $viewport.css('overflow-y', options.autoHeight ? 'hidden' : 'auto');\n\n $canvas = $(\"\").appendTo($viewport);\n\n if (options.createFooterRow){\n $footerRowScroller = $(\"\").appendTo($container);\n $footerRow = $(\"\").appendTo($footerRowScroller);\n $footerRowSpacer = $(\"\")\n .css('width', getCanvasWidth() + scrollbarDimensions.width + 'px')\n .appendTo($footerRowScroller);\n\n if (!options.showFooterRow){\n $footerRowScroller.hide();\n }\n }\n\n $focusSink2 = $focusSink.clone().appendTo($container);\n\n if (!options.explicitInitialization){\n finishInitialization();\n }\n }\n\n function finishInitialization(){\n if (!initialized){\n initialized = true;\n\n viewportW = parseFloat($.css($container[0], 'width', true));\n\n // header columns and cells may have different padding/border skewing width calculations (box-sizing, hello?)\n // calculate the diff so we can set consistent sizes\n measureCellPaddingAndBorder();\n\n // for usability reasons, all text selection in SlickGrid is disabled\n // with the exception of input and textarea elements (selection must\n // be enabled there so that editors work as expected); note that\n // selection in grid cells (grid body) is already unavailable in\n // all browsers except IE\n disableSelection($headers); // disable all text selection in header (including input and textarea)\n\n if (!options.enableTextSelectionOnCells){\n // disable text selection in grid cells except in input and textarea elements\n // (this is IE-specific, because selectstart event will only fire in IE)\n $viewport.bind('selectstart.ui', function(event){\n return $(event.target).is('input,textarea');\n });\n }\n\n updateColumnCaches();\n createColumnHeaders();\n setupColumnSort();\n createCssRules();\n resizeCanvas();\n bindAncestorScrollEvents();\n\n $container\n .bind('resize.slickgrid', resizeCanvas);\n $viewport\n // .bind(\"click\", handleClick)\n .bind('scroll', handleScroll);\n $headerScroller\n .bind('contextmenu', handleHeaderContextMenu)\n .bind('click', handleHeaderClick)\n .delegate('.slick-header-column', 'mouseenter', handleHeaderMouseEnter)\n .delegate('.slick-header-column', 'mouseleave', handleHeaderMouseLeave);\n $headerRowScroller\n .bind('scroll', handleHeaderRowScroll);\n\n if (options.createFooterRow){\n $footerRowScroller\n .bind('scroll', handleFooterRowScroll);\n }\n\n $focusSink.add($focusSink2)\n .bind('keydown', handleKeyDown);\n $canvas\n .bind('keydown', handleKeyDown)\n .bind('click', handleClick)\n .bind('dblclick', handleDblClick)\n .bind('contextmenu', handleContextMenu)\n .delegate('.slick-cell', 'mouseenter', handleMouseEnter)\n .delegate('.slick-cell', 'mouseleave', handleMouseLeave);\n\n // legacy support for drag events\n interact($canvas[0]).allowFrom('div.slick-cell').draggable({\n onmove: handleDrag,\n onstart: handleDragStart,\n onend: handleDragEnd\n }).styleCursor(false);\n\n // Work around http://crbug.com/312427.\n if (navigator.userAgent.toLowerCase().match(/webkit/) &&\n navigator.userAgent.toLowerCase().match(/macintosh/)){\n $canvas.bind('mousewheel', handleMouseWheel);\n }\n restoreCssFromHiddenInit();\n }\n }\n\n function cacheCssForHiddenInit(){\n // handle display:none on container or container parents\n $hiddenParents = $container.parents().addBack().not(':visible');\n $hiddenParents.each(function(){\n var old = {};\n for (var name in cssShow){\n old[name] = this.style[name];\n this.style[name] = cssShow[name];\n }\n oldProps.push(old);\n });\n }\n\n function restoreCssFromHiddenInit(){\n // finish handle display:none on container or container parents\n // - put values back the way they were\n $hiddenParents.each(function(i){\n var old = oldProps[i];\n for (var name in cssShow){\n this.style[name] = old[name];\n }\n });\n }\n\n function registerPlugin(plugin){\n plugins.unshift(plugin);\n plugin.init(self);\n }\n\n function unregisterPlugin(plugin){\n for (var i = plugins.length; i >= 0; i--){\n if (plugins[i] === plugin){\n if (plugins[i].destroy){\n plugins[i].destroy();\n }\n plugins.splice(i, 1);\n break;\n }\n }\n }\n\n function setSelectionModel(model){\n if (selectionModel){\n selectionModel.onSelectedRangesChanged.unsubscribe(handleSelectedRangesChanged);\n if (selectionModel.destroy){\n selectionModel.destroy();\n }\n }\n\n selectionModel = model;\n if (selectionModel){\n selectionModel.init(self);\n selectionModel.onSelectedRangesChanged.subscribe(handleSelectedRangesChanged);\n }\n }\n\n function getSelectionModel(){\n return selectionModel;\n }\n\n function getCanvasNode(){\n return $canvas[0];\n }\n\n function measureScrollbar(){\n var $c = $(\"\").appendTo('body');\n var dim = {\n width: $c.width() - $c[0].clientWidth,\n height: $c.height() - $c[0].clientHeight\n };\n $c.remove();\n return dim;\n }\n\n function getHeadersWidth(){\n var headersWidth = 0;\n for (var i = 0, ii = columns.length; i < ii; i++){\n var width = columns[i].width;\n headersWidth += width;\n }\n headersWidth += scrollbarDimensions.width;\n return Math.max(headersWidth, viewportW) + 1000;\n }\n\n function getCanvasWidth(){\n var availableWidth = viewportHasVScroll ? viewportW - scrollbarDimensions.width : viewportW;\n var rowWidth = 0;\n var i = columns.length;\n while (i--){\n rowWidth += columns[i].width;\n }\n return options.fullWidthRows ? Math.max(rowWidth, availableWidth) : rowWidth;\n }\n\n function updateCanvasWidth(forceColumnWidthsUpdate){\n var oldCanvasWidth = canvasWidth;\n canvasWidth = getCanvasWidth();\n\n if (canvasWidth != oldCanvasWidth){\n $canvas.width(canvasWidth);\n $headerRow.width(canvasWidth);\n if (options.createFooterRow){\n $footerRow.width(canvasWidth);\n }\n $headers.width(getHeadersWidth());\n viewportHasHScroll = (canvasWidth > viewportW - scrollbarDimensions.width);\n }\n\n var w = canvasWidth + (viewportHasVScroll ? scrollbarDimensions.width : 0);\n $headerRowSpacer.width(w);\n if (options.createFooterRow){\n $footerRowSpacer.width(w);\n }\n\n if (canvasWidth != oldCanvasWidth || forceColumnWidthsUpdate){\n applyColumnWidths();\n }\n }\n\n function disableSelection($target){\n if ($target && $target.jquery){\n $target\n .attr('unselectable', 'on')\n .css('MozUserSelect', 'none')\n .bind('selectstart.ui', function(){\n return false;\n }); // from jquery:ui.core.js 1.7.2\n }\n }\n\n function getMaxSupportedCssHeight(){\n var supportedHeight = 1000000;\n // FF reports the height back but still renders blank after ~6M px\n var testUpTo = navigator.userAgent.toLowerCase().match(/firefox/) ? 6000000 : 1000000000;\n var div = $(\"\").appendTo(document.body);\n\n while (true){\n var test = supportedHeight * 2;\n div.css('height', test);\n if (test > testUpTo || div.height() !== test){\n break;\n } else {\n supportedHeight = test;\n }\n }\n\n div.remove();\n return supportedHeight;\n }\n\n // TODO: this is static. need to handle page mutation.\n function bindAncestorScrollEvents(){\n var elem = $canvas[0];\n while ((elem = elem.parentNode) != document.body && elem != null){\n // bind to scroll containers only\n if (elem == $viewport[0] || elem.scrollWidth != elem.clientWidth || elem.scrollHeight != elem.clientHeight){\n var $elem = $(elem);\n if (!$boundAncestors){\n $boundAncestors = $elem;\n } else {\n $boundAncestors = $boundAncestors.add($elem);\n }\n $elem.bind('scroll.' + uid, handleActiveCellPositionChange);\n }\n }\n }\n\n function unbindAncestorScrollEvents(){\n if (!$boundAncestors){\n return;\n }\n $boundAncestors.unbind('scroll.' + uid);\n $boundAncestors = null;\n }\n\n function updateColumnHeader(columnId, title, toolTip){\n if (!initialized){\n return;\n }\n var idx = getColumnIndex(columnId);\n if (idx == null){\n return;\n }\n\n var columnDef = columns[idx];\n var $header = $headers.children().eq(idx);\n if ($header){\n if (title !== undefined){\n columns[idx].name = title;\n }\n if (toolTip !== undefined){\n columns[idx].toolTip = toolTip;\n }\n\n trigger(self.onBeforeHeaderCellDestroy, {\n 'node': $header[0],\n 'column': columnDef,\n 'grid': self\n });\n\n $header\n .attr('title', toolTip || '')\n .children().eq(0).html(title);\n\n trigger(self.onHeaderCellRendered, {\n 'node': $header[0],\n 'column': columnDef,\n 'grid': self\n });\n }\n }\n\n function getHeaderRow(){\n return $headerRow[0];\n }\n\n function getFooterRow(){\n return $footerRow[0];\n }\n\n function getHeaderRowColumn(columnId){\n var idx = getColumnIndex(columnId);\n var $header = $headerRow.children().eq(idx);\n return $header && $header[0];\n }\n\n function getFooterRowColumn(columnId){\n var idx = getColumnIndex(columnId);\n var $footer = $footerRow.children().eq(idx);\n return $footer && $footer[0];\n }\n\n function createColumnHeaders(){\n function onMouseEnter(){\n $(this).addClass('ui-state-hover');\n }\n\n function onMouseLeave(){\n $(this).removeClass('ui-state-hover');\n }\n\n $headers.find('.slick-header-column')\n .each(function(){\n var columnDef = $(this).data('column');\n if (columnDef){\n trigger(self.onBeforeHeaderCellDestroy, {\n 'node': this,\n 'column': columnDef,\n 'grid': self\n });\n }\n });\n $headers.empty();\n $headers.width(getHeadersWidth());\n\n $headerRow.find('.slick-headerrow-column')\n .each(function(){\n var columnDef = $(this).data('column');\n if (columnDef){\n trigger(self.onBeforeHeaderRowCellDestroy, {\n 'node': this,\n 'column': columnDef,\n 'grid': self\n });\n }\n });\n $headerRow.empty();\n\n if (options.createFooterRow){\n $footerRow.find('.slick-footerrow-column')\n .each(function(){\n var columnDef = $(this).data('column');\n if (columnDef){\n trigger(self.onBeforeFooterRowCellDestroy, {\n 'node': this,\n 'column': columnDef\n });\n }\n });\n $footerRow.empty();\n }\n\n for (var i = 0; i < columns.length; i++){\n var m = columns[i];\n\n var header = $(\"\")\n .html(\"\" + m.name + '')\n .width(m.width - headerColumnWidthDiff)\n .attr('id', '' + uid + m.id)\n .attr('title', m.toolTip || '')\n .data('column', m)\n .addClass(m.headerCssClass || '')\n .appendTo($headers);\n\n if (options.enableColumnReorder || m.sortable){\n header\n .on('mouseenter', onMouseEnter)\n .on('mouseleave', onMouseLeave);\n }\n\n if (m.sortable){\n header.addClass('slick-header-sortable');\n header.append(\"\");\n }\n\n trigger(self.onHeaderCellRendered, {\n 'node': header[0],\n 'column': m,\n 'grid': self\n });\n\n if (options.showHeaderRow){\n var headerRowCell = $(\"\")\n .data('column', m)\n .appendTo($headerRow);\n\n trigger(self.onHeaderRowCellRendered, {\n 'node': headerRowCell[0],\n 'column': m,\n 'grid': self\n });\n }\n if (options.createFooterRow && options.showFooterRow){\n var footerRowCell = $(\"\")\n .data('column', m)\n .appendTo($footerRow);\n\n trigger(self.onFooterRowCellRendered, {\n 'node': footerRowCell[0],\n 'column': m\n });\n }\n }\n\n setSortColumns(sortColumns);\n setupColumnResize();\n if (options.enableColumnReorder){\n setupColumnReorder();\n }\n }\n\n function setupColumnSort(){\n $headers.click(function(e){\n // temporary workaround for a bug in jQuery 1.7.1 (http://bugs.jquery.com/ticket/11328)\n e.metaKey = e.metaKey || e.ctrlKey;\n\n if ($(e.target).hasClass('slick-resizable-handle')){\n return;\n }\n\n var $col = $(e.target).closest('.slick-header-column');\n if (!$col.length){\n return;\n }\n\n var column = $col.data('column');\n if (column.sortable){\n if (!getEditorLock().commitCurrentEdit()){\n return;\n }\n\n var sortOpts = null;\n var i = 0;\n for (; i < sortColumns.length; i++){\n if (sortColumns[i].columnId == column.id){\n sortOpts = sortColumns[i];\n sortOpts.sortAsc = !sortOpts.sortAsc;\n break;\n }\n }\n\n if (e.metaKey && options.multiColumnSort){\n if (sortOpts){\n sortColumns.splice(i, 1);\n }\n }\n else {\n if ((!e.shiftKey && !e.metaKey) || !options.multiColumnSort){\n sortColumns = [];\n }\n\n if (!sortOpts){\n sortOpts = {columnId: column.id, sortAsc: column.defaultSortAsc};\n sortColumns.push(sortOpts);\n } else if (sortColumns.length == 0){\n sortColumns.push(sortOpts);\n }\n }\n\n setSortColumns(sortColumns);\n\n if (!options.multiColumnSort){\n trigger(self.onSort, {\n multiColumnSort: false,\n sortCol: column,\n sortAsc: sortOpts.sortAsc,\n grid: self\n }, e);\n } else {\n trigger(self.onSort, {\n multiColumnSort: true,\n sortCols: $.map(sortColumns, function(col){\n return {sortCol: columns[getColumnIndex(col.columnId)], sortAsc: col.sortAsc};\n }),\n grid: self\n }, e);\n }\n }\n });\n }\n\n /**\n * Refactored to use interactjs\n */\n function setupColumnReorder(){\n let x = 0;\n let delta = 0;\n let placeholder = document.createElement('div');\n\n placeholder.className = 'interact-placeholder';\n\n interact('.slick-header-column')\n .ignoreFrom('.slick-resizable-handle')\n .draggable({\n inertia: true,\n // keep the element within the area of it's parent\n restrict: {\n restriction: 'parent',\n endOnly: true,\n elementRect: {top: 0, left: 0, bottom: 0, right: 0}\n },\n // enable autoScroll\n autoScroll: true,\n axis: 'x',\n onstart: event => {\n x = 0;\n delta = event.target.offsetWidth;\n\n // get old order\n $headers.find('.slick-header-column').each(function(index){\n $(this).data('index', index);\n });\n\n placeholder.style.height = event.target.offsetHeight + 'px';\n placeholder.style.width = delta + 'px';\n\n $(event.target).after(placeholder).css({\n position: 'absolute',\n zIndex: 1000,\n marginLeft: $(event.target).position().left\n });\n },\n\n onmove: event => {\n x += event.dx;\n event.target.style.transform = `translate3d(${x}px, -3px, 100px)`;\n // event.target.style.marginLeft = x + 'px';\n },\n\n onend: event => {\n x = 0;\n delta = 0;\n $(event.target).css({\n position: 'relative',\n zIndex: '',\n marginLeft: 0,\n transform: 'none'\n });\n\n placeholder.parentNode.removeChild(placeholder);\n const newColumns = [];\n\n $headers.find('.slick-header-column').each(function(index){\n newColumns.push(columns[$(this).data('index')]);\n $(this).removeData('index');\n });\n\n setColumns(newColumns);\n trigger(self.onColumnsReordered, {grid: self});\n setupColumnResize();\n }\n })\n .dropzone({\n accept: '.slick-header-column',\n\n ondragenter: event => {\n event.target.classList.add('interact-drop-active');\n event.relatedTarget.classList.add('interact-can-drop');\n },\n\n ondragleave: event => {\n event.target.classList.remove('interact-drop-active');\n event.relatedTarget.classList.remove('interact-can-drop');\n },\n\n ondrop: event => {\n event.target.classList.remove('interact-drop-active');\n event.relatedTarget.classList.remove('interact-can-drop');\n $(event.target)[x > 0 ? 'after' : 'before'](event.relatedTarget);\n }\n }).styleCursor(false);\n }\n\n function setupColumnResize(){\n var $col, j, c, pageX, columnElements, minPageX, maxPageX, firstResizable, lastResizable;\n columnElements = $headers.children();\n columnElements.find('.slick-resizable-handle').remove();\n columnElements.each(function(i, e){\n if (columns[i].resizable){\n if (firstResizable === undefined){\n firstResizable = i;\n }\n lastResizable = i;\n }\n });\n if (firstResizable === undefined){\n return;\n }\n columnElements.each(function(i, element){\n if (i < firstResizable || (options.forceFitColumns && i >= lastResizable)){\n return;\n }\n $col = $(element);\n\n const $handle = $(\"\");\n $handle.appendTo(element);\n\n if ($col.data('resizable'))\n return;\n\n const activeColumn = columns[i];\n if (activeColumn.resizable){\n $col.data('resizable', true);\n interact(element).resizable({\n preserveAspectRatio: false,\n edges: { left: true, right: true, bottom: false, top: false }\n }).on('resizestart', function(event){\n if (!getEditorLock().commitCurrentEdit()){\n return false;\n }\n activeColumn.previousWidth = event.rect.width;\n event.target.classList.add('slick-header-column-active');\n }).on('resizemove', function(event){\n let x = event.dx;\n let width = activeColumn.width += x;\n\n if (activeColumn.minWidth > 0 && activeColumn.minWidth > width)\n width = activeColumn.minWidth;\n else if (activeColumn.maxWidth > 0 && activeColumn.maxWidth < width)\n width = activeColumn.maxWidth;\n\n activeColumn.width = width;\n\n if (options.forceFitColumns){\n autosizeColumns();\n }\n applyColumnHeaderWidths();\n if (options.syncColumnCellResize){\n applyColumnWidths();\n }\n }).on('resizeend', function(event){\n event.target.classList.remove('slick-header-column-active');\n invalidateAllRows();\n updateCanvasWidth(true);\n render();\n trigger(self.onColumnsResized, {grid: self});\n });\n }\n });\n }\n\n function getVBoxDelta($el){\n var p = ['borderTopWidth', 'borderBottomWidth', 'paddingTop', 'paddingBottom'];\n var delta = 0;\n $.each(p, function(n, val){\n delta += parseFloat($el.css(val)) || 0;\n });\n return delta;\n }\n\n function measureCellPaddingAndBorder(){\n var el;\n var h = ['borderLeftWidth', 'borderRightWidth', 'paddingLeft', 'paddingRight'];\n var v = ['borderTopWidth', 'borderBottomWidth', 'paddingTop', 'paddingBottom'];\n\n // jquery prior to version 1.8 handles .width setter/getter as a direct css write/read\n // jquery 1.8 changed .width to read the true inner element width if box-sizing is set to border-box, and introduced a setter for .outerWidth\n // so for equivalent functionality, prior to 1.8 use .width, and after use .outerWidth\n var verArray = $.fn.jquery.split('.');\n jQueryNewWidthBehaviour = (verArray[0] == 1 && verArray[1] >= 8) || verArray[0] >= 2;\n\n el = $(\"
\").appendTo(r);\n cellWidthDiff = cellHeightDiff = 0;\n if (el.css('box-sizing') != 'border-box' && el.css('-moz-box-sizing') != 'border-box' && el.css('-webkit-box-sizing') != 'border-box'){\n $.each(h, function(n, val){\n cellWidthDiff += parseFloat(el.css(val)) || 0;\n });\n $.each(v, function(n, val){\n cellHeightDiff += parseFloat(el.css(val)) || 0;\n });\n }\n r.remove();\n\n absoluteColumnMinWidth = Math.max(headerColumnWidthDiff, cellWidthDiff);\n }\n\n function createCssRules(){\n $style = $(\"\").appendTo($('head'));\n var rowHeight = (options.rowHeight - cellHeightDiff);\n var rules = [\n '.' + uid + ' .slick-header-column { left: 0; }',\n '.' + uid + ' .slick-top-panel { height:' + options.topPanelHeight + 'px; }',\n '.' + uid + ' .slick-headerrow-columns { height:' + options.headerRowHeight + 'px; }',\n '.' + uid + ' .slick-footerrow-columns { height:' + options.footerRowHeight + 'px; }',\n '.' + uid + ' .slick-cell { height:' + rowHeight + 'px; }',\n '.' + uid + ' .slick-row { height:' + options.rowHeight + 'px; }'\n ];\n\n for (var i = 0; i < columns.length; i++){\n rules.push('.' + uid + ' .l' + i + ' { }');\n rules.push('.' + uid + ' .r' + i + ' { }');\n }\n\n if ($style[0].styleSheet){ // IE\n $style[0].styleSheet.cssText = rules.join(' ');\n } else {\n $style[0].appendChild(document.createTextNode(rules.join(' ')));\n }\n }\n\n function getColumnCssRules(idx){\n if (!stylesheet){\n var sheets = document.styleSheets;\n for (var i = 0; i < sheets.length; i++){\n if ((sheets[i].ownerNode || sheets[i].owningElement) == $style[0]){\n stylesheet = sheets[i];\n break;\n }\n }\n\n if (!stylesheet){\n throw new Error('Cannot find stylesheet.');\n }\n\n // find and cache column CSS rules\n columnCssRulesL = [];\n columnCssRulesR = [];\n var cssRules = (stylesheet.cssRules || stylesheet.rules);\n var matches, columnIdx;\n for (var i = 0; i < cssRules.length; i++){\n var selector = cssRules[i].selectorText;\n if (matches = /\\.l\\d+/.exec(selector)){\n columnIdx = parseInt(matches[0].substr(2, matches[0].length - 2), 10);\n columnCssRulesL[columnIdx] = cssRules[i];\n } else if (matches = /\\.r\\d+/.exec(selector)){\n columnIdx = parseInt(matches[0].substr(2, matches[0].length - 2), 10);\n columnCssRulesR[columnIdx] = cssRules[i];\n }\n }\n }\n\n return {\n 'left': columnCssRulesL[idx],\n 'right': columnCssRulesR[idx]\n };\n }\n\n function removeCssRules(){\n $style.remove();\n stylesheet = null;\n }\n\n function destroy(){\n getEditorLock().cancelCurrentEdit();\n\n trigger(self.onBeforeDestroy, {grid: self});\n\n var i = plugins.length;\n while (i--){\n unregisterPlugin(plugins[i]);\n }\n\n unbindAncestorScrollEvents();\n $container.unbind('.slickgrid');\n removeCssRules();\n\n $container.empty().removeClass(uid);\n }\n\n // ////////////////////////////////////////////////////////////////////////////////////////////\n // General\n\n function trigger(evt, args, e){\n e = e || new Slick.EventData();\n args = args || {};\n args.grid = self;\n return evt.notify(args, e, self);\n }\n\n function getEditorLock(){\n return options.editorLock;\n }\n\n function getEditController(){\n return editController;\n }\n\n function getColumnIndex(id){\n return columnsById[id];\n }\n\n function autosizeColumns(){\n var i, c,\n widths = [],\n shrinkLeeway = 0,\n total = 0,\n prevTotal,\n availWidth = viewportHasVScroll ? viewportW - scrollbarDimensions.width : viewportW;\n\n for (i = 0; i < columns.length; i++){\n c = columns[i];\n widths.push(c.width);\n total += c.width;\n if (c.resizable){\n shrinkLeeway += c.width - Math.max(c.minWidth, absoluteColumnMinWidth);\n }\n }\n\n // shrink\n prevTotal = total;\n while (total > availWidth && shrinkLeeway){\n var shrinkProportion = (total - availWidth) / shrinkLeeway;\n for (i = 0; i < columns.length && total > availWidth; i++){\n c = columns[i];\n var width = widths[i];\n if (!c.resizable || width <= c.minWidth || width <= absoluteColumnMinWidth){\n continue;\n }\n var absMinWidth = Math.max(c.minWidth, absoluteColumnMinWidth);\n var shrinkSize = Math.floor(shrinkProportion * (width - absMinWidth)) || 1;\n shrinkSize = Math.min(shrinkSize, width - absMinWidth);\n total -= shrinkSize;\n shrinkLeeway -= shrinkSize;\n widths[i] -= shrinkSize;\n }\n if (prevTotal <= total){ // avoid infinite loop\n break;\n }\n prevTotal = total;\n }\n\n // grow\n prevTotal = total;\n while (total < availWidth){\n var growProportion = availWidth / total;\n for (i = 0; i < columns.length && total < availWidth; i++){\n c = columns[i];\n var currentWidth = widths[i];\n var growSize;\n\n if (!c.resizable || c.maxWidth <= currentWidth){\n growSize = 0;\n } else {\n growSize = Math.min(Math.floor(growProportion * currentWidth) - currentWidth, (c.maxWidth - currentWidth) || 1000000) || 1;\n }\n total += growSize;\n widths[i] += (total <= availWidth ? growSize : 0);\n }\n if (prevTotal >= total){ // avoid infinite loop\n break;\n }\n prevTotal = total;\n }\n\n var reRender = false;\n for (i = 0; i < columns.length; i++){\n if (columns[i].rerenderOnResize && columns[i].width != widths[i]){\n reRender = true;\n }\n columns[i].width = widths[i];\n }\n\n applyColumnHeaderWidths();\n updateCanvasWidth(true);\n if (reRender){\n invalidateAllRows();\n render();\n }\n }\n\n function applyColumnHeaderWidths(){\n if (!initialized){\n return;\n }\n var h;\n for (var i = 0, headers = $headers.children('[id]'), ii = headers.length; i < ii; i++){\n h = $(headers[i]);\n if (jQueryNewWidthBehaviour){\n if (h.outerWidth() !== columns[i].width){\n h.outerWidth(columns[i].width);\n }\n } else {\n if (h.width() !== columns[i].width - headerColumnWidthDiff){\n h.width(columns[i].width - headerColumnWidthDiff);\n }\n }\n }\n\n updateColumnCaches();\n }\n\n function applyColumnWidths(){\n var x = 0, w, rule;\n for (var i = 0; i < columns.length; i++){\n w = columns[i].width;\n\n rule = getColumnCssRules(i);\n rule.left.style.left = x + 'px';\n rule.right.style.right = (canvasWidth - x - w) + 'px';\n\n x += columns[i].width;\n }\n }\n\n function setSortColumn(columnId, ascending){\n setSortColumns([{columnId: columnId, sortAsc: ascending}]);\n }\n\n function setSortColumns(cols){\n sortColumns = cols;\n\n var headerColumnEls = $headers.children();\n headerColumnEls\n .removeClass('slick-header-column-sorted')\n .find('.slick-sort-indicator')\n .removeClass('slick-sort-indicator-asc slick-sort-indicator-desc');\n\n $.each(sortColumns, function(i, col){\n if (col.sortAsc == null){\n col.sortAsc = true;\n }\n var columnIndex = getColumnIndex(col.columnId);\n if (columnIndex != null){\n headerColumnEls.eq(columnIndex)\n .addClass('slick-header-column-sorted')\n .find('.slick-sort-indicator')\n .addClass(col.sortAsc ? 'slick-sort-indicator-asc' : 'slick-sort-indicator-desc');\n }\n });\n }\n\n function getSortColumns(){\n return sortColumns;\n }\n\n function handleSelectedRangesChanged(e, ranges){\n selectedRows = [];\n var hash = {};\n for (var i = 0; i < ranges.length; i++){\n for (var j = ranges[i].fromRow; j <= ranges[i].toRow; j++){\n if (!hash[j]){ // prevent duplicates\n selectedRows.push(j);\n hash[j] = {};\n }\n for (var k = ranges[i].fromCell; k <= ranges[i].toCell; k++){\n if (canCellBeSelected(j, k)){\n hash[j][columns[k].id] = options.selectedCellCssClass;\n }\n }\n }\n }\n\n setCellCssStyles(options.selectedCellCssClass, hash);\n\n trigger(self.onSelectedRowsChanged, {rows: getSelectedRows(), grid: self}, e);\n }\n\n function getColumns(){\n return columns;\n }\n\n function updateColumnCaches(){\n // Pre-calculate cell boundaries.\n columnPosLeft = [];\n columnPosRight = [];\n var x = 0;\n for (var i = 0, ii = columns.length; i < ii; i++){\n columnPosLeft[i] = x;\n columnPosRight[i] = x + columns[i].width;\n x += columns[i].width;\n }\n }\n\n function setColumns(columnDefinitions){\n columns = columnDefinitions;\n\n columnsById = {};\n for (var i = 0; i < columns.length; i++){\n var m = columns[i] = $.extend({}, columnDefaults, columns[i]);\n columnsById[m.id] = i;\n if (m.minWidth && m.width < m.minWidth){\n m.width = m.minWidth;\n }\n if (m.maxWidth && m.width > m.maxWidth){\n m.width = m.maxWidth;\n }\n }\n\n updateColumnCaches();\n\n if (initialized){\n invalidateAllRows();\n createColumnHeaders();\n removeCssRules();\n createCssRules();\n resizeCanvas();\n applyColumnWidths();\n handleScroll();\n }\n }\n\n function getOptions(){\n return options;\n }\n\n function setOptions(args){\n if (!getEditorLock().commitCurrentEdit()){\n return;\n }\n\n makeActiveCellNormal();\n\n if (options.enableAddRow !== args.enableAddRow){\n invalidateRow(getDataLength());\n }\n\n options = $.extend(options, args);\n validateAndEnforceOptions();\n\n $viewport.css('overflow-y', options.autoHeight ? 'hidden' : 'auto');\n render();\n }\n\n function validateAndEnforceOptions(){\n if (options.autoHeight){\n options.leaveSpaceForNewRows = false;\n }\n }\n\n function setData(newData, scrollToTop){\n data = newData;\n invalidateAllRows();\n updateRowCount();\n if (scrollToTop){\n scrollTo(0);\n }\n }\n\n function getData(){\n return data;\n }\n\n function getDataLength(){\n if (data.getLength){\n return data.getLength();\n } else {\n return data.length;\n }\n }\n\n function getDataLengthIncludingAddNew(){\n return getDataLength() + (options.enableAddRow ? 1 : 0);\n }\n\n function getDataItem(i){\n if (data.getItem){\n return data.getItem(i);\n } else {\n return data[i];\n }\n }\n\n function getTopPanel(){\n return $topPanel[0];\n }\n\n function setTopPanelVisibility(visible){\n if (options.showTopPanel != visible){\n options.showTopPanel = visible;\n if (visible){\n $topPanelScroller.slideDown('fast', resizeCanvas);\n } else {\n $topPanelScroller.slideUp('fast', resizeCanvas);\n }\n }\n }\n\n function setHeaderRowVisibility(visible){\n if (options.showHeaderRow != visible){\n options.showHeaderRow = visible;\n if (visible){\n $headerRowScroller.slideDown('fast', resizeCanvas);\n } else {\n $headerRowScroller.slideUp('fast', resizeCanvas);\n }\n }\n }\n\n function setFooterRowVisibility(visible){\n if (options.showFooterRow != visible){\n options.showFooterRow = visible;\n if (visible){\n $footerRowScroller.slideDown('fast', resizeCanvas);\n } else {\n $footerRowScroller.slideUp('fast', resizeCanvas);\n }\n }\n }\n\n function getContainerNode(){\n return $container.get(0);\n }\n\n // ////////////////////////////////////////////////////////////////////////////////////////////\n // Rendering / Scrolling\n\n function getRowTop(row){\n return options.rowHeight * row - offset;\n }\n\n function getRowFromPosition(y){\n return Math.floor((y + offset) / options.rowHeight);\n }\n\n function scrollTo(y){\n y = Math.max(y, 0);\n y = Math.min(y, th - viewportH + (viewportHasHScroll ? scrollbarDimensions.height : 0));\n\n var oldOffset = offset;\n\n page = Math.min(n - 1, Math.floor(y / ph));\n offset = Math.round(page * cj);\n var newScrollTop = y - offset;\n\n if (offset != oldOffset){\n var range = getVisibleRange(newScrollTop);\n cleanupRows(range);\n updateRowPositions();\n }\n\n if (prevScrollTop != newScrollTop){\n vScrollDir = (prevScrollTop + oldOffset < newScrollTop + offset) ? 1 : -1;\n $viewport[0].scrollTop = (lastRenderedScrollTop = scrollTop = prevScrollTop = newScrollTop);\n\n trigger(self.onViewportChanged, {grid: self});\n }\n }\n\n function defaultFormatter(row, cell, value, columnDef, dataContext){\n if (value == null){\n return '';\n } else {\n return (value + '').replace(/&/g, '&').replace(//g, '>');\n }\n }\n\n function getFormatter(row, column){\n var rowMetadata = data.getItemMetadata && data.getItemMetadata(row);\n\n // look up by id, then index\n var columnOverrides = rowMetadata &&\n rowMetadata.columns &&\n (rowMetadata.columns[column.id] || rowMetadata.columns[getColumnIndex(column.id)]);\n\n return (columnOverrides && columnOverrides.formatter) ||\n (rowMetadata && rowMetadata.formatter) ||\n column.formatter ||\n (options.formatterFactory && options.formatterFactory.getFormatter(column)) ||\n options.defaultFormatter;\n }\n\n function getEditor(row, cell){\n var column = columns[cell];\n var rowMetadata = data.getItemMetadata && data.getItemMetadata(row);\n var columnMetadata = rowMetadata && rowMetadata.columns;\n\n if (columnMetadata && columnMetadata[column.id] && columnMetadata[column.id].editor !== undefined){\n return columnMetadata[column.id].editor;\n }\n if (columnMetadata && columnMetadata[cell] && columnMetadata[cell].editor !== undefined){\n return columnMetadata[cell].editor;\n }\n\n return column.editor || (options.editorFactory && options.editorFactory.getEditor(column));\n }\n\n function getDataItemValueForColumn(item, columnDef){\n if (options.dataItemColumnValueExtractor){\n return options.dataItemColumnValueExtractor(item, columnDef);\n }\n return item[columnDef.field];\n }\n\n function appendRowHtml(stringArray, row, range, dataLength){\n var d = getDataItem(row);\n var dataLoading = row < dataLength && !d;\n var rowCss = 'slick-row' +\n (dataLoading ? ' loading' : '') +\n (row === activeRow ? ' active' : '') +\n (row % 2 == 1 ? ' odd' : ' even');\n\n if (!d){\n rowCss += ' ' + options.addNewRowCssClass;\n }\n\n var metadata = data.getItemMetadata && data.getItemMetadata(row);\n\n if (metadata && metadata.cssClasses){\n rowCss += ' ' + metadata.cssClasses;\n }\n\n stringArray.push(\"
\");\n\n var colspan, m;\n for (var i = 0, ii = columns.length; i < ii; i++){\n m = columns[i];\n colspan = 1;\n if (metadata && metadata.columns){\n var columnData = metadata.columns[m.id] || metadata.columns[i];\n colspan = (columnData && columnData.colspan) || 1;\n if (colspan === '*'){\n colspan = ii - i;\n }\n }\n\n // Do not render cells outside of the viewport.\n if (columnPosRight[Math.min(ii - 1, i + colspan - 1)] > range.leftPx){\n if (columnPosLeft[i] > range.rightPx){\n // All columns to the right are outside the range.\n break;\n }\n\n appendCellHtml(stringArray, row, i, colspan, d);\n }\n\n if (colspan > 1){\n i += (colspan - 1);\n }\n }\n\n stringArray.push('
');\n }\n\n function appendCellHtml(stringArray, row, cell, colspan, item){\n // stringArray: stringBuilder containing the HTML parts\n // row, cell: row and column index\n // colspan: HTML colspan\n // item: grid data for row\n\n var m = columns[cell];\n var cellCss = 'slick-cell l' + cell + ' r' + Math.min(columns.length - 1, cell + colspan - 1) +\n (m.cssClass ? ' ' + m.cssClass : '');\n if (row === activeRow && cell === activeCell){\n cellCss += (' active');\n }\n\n // TODO: merge them together in the setter\n for (var key in cellCssClasses){\n if (cellCssClasses[key][row] && cellCssClasses[key][row][m.id]){\n cellCss += (' ' + cellCssClasses[key][row][m.id]);\n }\n }\n\n stringArray.push(\"
\");\n\n // if there is a corresponding row (if not, this is the Add New row or this data hasn't been loaded yet)\n if (item){\n var value = getDataItemValueForColumn(item, m);\n stringArray.push(getFormatter(row, m)(row, cell, value, m, item));\n }\n\n stringArray.push('
');\n\n rowsCache[row].cellRenderQueue.push(cell);\n rowsCache[row].cellColSpans[cell] = colspan;\n }\n\n function cleanupRows(rangeToKeep){\n for (var i in rowsCache){\n if (((i = parseInt(i, 10)) !== activeRow) && (i < rangeToKeep.top || i > rangeToKeep.bottom)){\n removeRowFromCache(i);\n }\n }\n if (options.enableAsyncPostRenderCleanup){\n startPostProcessingCleanup();\n }\n }\n\n function invalidate(){\n updateRowCount();\n invalidateAllRows();\n render();\n }\n\n function invalidateAllRows(){\n if (currentEditor){\n makeActiveCellNormal();\n }\n for (var row in rowsCache){\n removeRowFromCache(row);\n }\n if (options.enableAsyncPostRenderCleanup){\n startPostProcessingCleanup();\n }\n }\n\n function queuePostProcessedRowForCleanup(cacheEntry, postProcessedRow, rowIdx){\n postProcessgroupId++;\n\n // store and detach node for later async cleanup\n for (var columnIdx in postProcessedRow){\n if (postProcessedRow.hasOwnProperty(columnIdx)){\n postProcessedCleanupQueue.push({\n actionType: 'C',\n groupId: postProcessgroupId,\n node: cacheEntry.cellNodesByColumnIdx[columnIdx | 0],\n columnIdx: columnIdx | 0,\n rowIdx: rowIdx\n });\n }\n }\n postProcessedCleanupQueue.push({\n actionType: 'R',\n groupId: postProcessgroupId,\n node: cacheEntry.rowNode\n });\n $(cacheEntry.rowNode).detach();\n }\n\n function queuePostProcessedCellForCleanup(cellnode, columnIdx, rowIdx){\n postProcessedCleanupQueue.push({\n actionType: 'C',\n groupId: postProcessgroupId,\n node: cellnode,\n columnIdx: columnIdx,\n rowIdx: rowIdx\n });\n $(cellnode).detach();\n }\n\n function removeRowFromCache(row){\n var cacheEntry = rowsCache[row];\n if (!cacheEntry){\n return;\n }\n\n if (rowNodeFromLastMouseWheelEvent === cacheEntry.rowNode){\n cacheEntry.rowNode.style.display = 'none';\n zombieRowNodeFromLastMouseWheelEvent = rowNodeFromLastMouseWheelEvent;\n zombieRowCacheFromLastMouseWheelEvent = cacheEntry;\n zombieRowPostProcessedFromLastMouseWheelEvent = postProcessedRows[row];\n // ignore post processing cleanup in this case - it will be dealt with later\n } else {\n if (options.enableAsyncPostRenderCleanup && postProcessedRows[row]){\n queuePostProcessedRowForCleanup(cacheEntry, postProcessedRows[row], row);\n } else {\n $canvas[0].removeChild(cacheEntry.rowNode);\n }\n }\n\n delete rowsCache[row];\n delete postProcessedRows[row];\n renderedRows--;\n counter_rows_removed++;\n }\n\n function invalidateRows(rows){\n var i, rl;\n if (!rows || !rows.length){\n return;\n }\n vScrollDir = 0;\n for (i = 0, rl = rows.length; i < rl; i++){\n if (currentEditor && activeRow === rows[i]){\n makeActiveCellNormal();\n }\n if (rowsCache[rows[i]]){\n removeRowFromCache(rows[i]);\n }\n }\n if (options.enableAsyncPostRenderCleanup){\n startPostProcessingCleanup();\n }\n }\n\n function invalidateRow(row){\n invalidateRows([row]);\n }\n\n function updateCell(row, cell){\n var cellNode = getCellNode(row, cell);\n if (!cellNode){\n return;\n }\n\n var m = columns[cell], d = getDataItem(row);\n if (currentEditor && activeRow === row && activeCell === cell){\n currentEditor.loadValue(d);\n } else {\n cellNode.innerHTML = d ? getFormatter(row, m)(row, cell, getDataItemValueForColumn(d, m), m, d) : '';\n invalidatePostProcessingResults(row);\n }\n }\n\n function updateRow(row){\n var cacheEntry = rowsCache[row];\n if (!cacheEntry){\n return;\n }\n\n ensureCellNodesInRowsCache(row);\n\n var d = getDataItem(row);\n\n for (var columnIdx in cacheEntry.cellNodesByColumnIdx){\n if (!cacheEntry.cellNodesByColumnIdx.hasOwnProperty(columnIdx)){\n continue;\n }\n\n columnIdx = columnIdx | 0;\n var m = columns[columnIdx],\n node = cacheEntry.cellNodesByColumnIdx[columnIdx];\n\n if (row === activeRow && columnIdx === activeCell && currentEditor){\n currentEditor.loadValue(d);\n } else if (d){\n node.innerHTML = getFormatter(row, m)(row, columnIdx, getDataItemValueForColumn(d, m), m, d);\n } else {\n node.innerHTML = '';\n }\n }\n\n invalidatePostProcessingResults(row);\n }\n\n function getViewportHeight(){\n return parseFloat($.css($container[0], 'height', true)) -\n parseFloat($.css($container[0], 'paddingTop', true)) -\n parseFloat($.css($container[0], 'paddingBottom', true)) -\n parseFloat($.css($headerScroller[0], 'height')) - getVBoxDelta($headerScroller) -\n (options.showTopPanel ? options.topPanelHeight + getVBoxDelta($topPanelScroller) : 0) -\n (options.showHeaderRow ? options.headerRowHeight + getVBoxDelta($headerRowScroller) : 0) -\n (options.createFooterRow && options.showFooterRow ? options.footerRowHeight + getVBoxDelta($footerRowScroller) : 0);\n }\n\n function resizeCanvas(){\n if (!initialized){\n return;\n }\n if (options.autoHeight){\n viewportH = options.rowHeight * getDataLengthIncludingAddNew();\n } else {\n viewportH = getViewportHeight();\n }\n\n numVisibleRows = Math.ceil(viewportH / options.rowHeight);\n viewportW = parseFloat($.css($container[0], 'width', true));\n if (!options.autoHeight){\n $viewport.height(viewportH);\n }\n\n if (options.forceFitColumns){\n autosizeColumns();\n }\n\n updateRowCount();\n handleScroll();\n // Since the width has changed, force the render() to reevaluate virtually rendered cells.\n lastRenderedScrollLeft = -1;\n render();\n }\n\n function updateRowCount(){\n if (!initialized){\n return;\n }\n\n var dataLengthIncludingAddNew = getDataLengthIncludingAddNew();\n var numberOfRows = dataLengthIncludingAddNew +\n (options.leaveSpaceForNewRows ? numVisibleRows - 1 : 0);\n\n var oldViewportHasVScroll = viewportHasVScroll;\n // with autoHeight, we do not need to accommodate the vertical scroll bar\n viewportHasVScroll = !options.autoHeight && (numberOfRows * options.rowHeight > viewportH);\n viewportHasHScroll = (canvasWidth > viewportW - scrollbarDimensions.width);\n\n makeActiveCellNormal();\n\n // remove the rows that are now outside of the data range\n // this helps avoid redundant calls to .removeRow() when the size of the data decreased by thousands of rows\n var l = dataLengthIncludingAddNew - 1;\n for (var i in rowsCache){\n if (i > l){\n removeRowFromCache(i);\n }\n }\n if (options.enableAsyncPostRenderCleanup){\n startPostProcessingCleanup();\n }\n\n if (activeCellNode && activeRow > l){\n resetActiveCell();\n }\n\n var oldH = h;\n th = Math.max(options.rowHeight * numberOfRows, viewportH - scrollbarDimensions.height);\n if (th < maxSupportedCssHeight){\n // just one page\n h = ph = th;\n n = 1;\n cj = 0;\n } else {\n // break into pages\n h = maxSupportedCssHeight;\n ph = h / 100;\n n = Math.floor(th / ph);\n cj = (th - h) / (n - 1);\n }\n\n if (h !== oldH){\n $canvas.css('height', h);\n scrollTop = $viewport[0].scrollTop;\n }\n\n var oldScrollTopInRange = (scrollTop + offset <= th - viewportH);\n\n if (th == 0 || scrollTop == 0){\n page = offset = 0;\n } else if (oldScrollTopInRange){\n // maintain virtual position\n scrollTo(scrollTop + offset);\n } else {\n // scroll to bottom\n scrollTo(th - viewportH);\n }\n\n if (h != oldH && options.autoHeight){\n resizeCanvas();\n }\n\n if (options.forceFitColumns && oldViewportHasVScroll != viewportHasVScroll){\n autosizeColumns();\n }\n updateCanvasWidth(false);\n }\n\n function getVisibleRange(viewportTop, viewportLeft){\n if (viewportTop == null){\n viewportTop = scrollTop;\n }\n if (viewportLeft == null){\n viewportLeft = scrollLeft;\n }\n\n return {\n top: getRowFromPosition(viewportTop),\n bottom: getRowFromPosition(viewportTop + viewportH) + 1,\n leftPx: viewportLeft,\n rightPx: viewportLeft + viewportW\n };\n }\n\n function getRenderedRange(viewportTop, viewportLeft){\n var range = getVisibleRange(viewportTop, viewportLeft);\n var buffer = Math.round(viewportH / options.rowHeight);\n var minBuffer = 3;\n\n if (vScrollDir == -1){\n range.top -= buffer;\n range.bottom += minBuffer;\n } else if (vScrollDir == 1){\n range.top -= minBuffer;\n range.bottom += buffer;\n } else {\n range.top -= minBuffer;\n range.bottom += minBuffer;\n }\n\n range.top = Math.max(0, range.top);\n range.bottom = Math.min(getDataLengthIncludingAddNew() - 1, range.bottom);\n\n range.leftPx -= viewportW;\n range.rightPx += viewportW;\n\n range.leftPx = Math.max(0, range.leftPx);\n range.rightPx = Math.min(canvasWidth, range.rightPx);\n\n return range;\n }\n\n function ensureCellNodesInRowsCache(row){\n var cacheEntry = rowsCache[row];\n if (cacheEntry){\n if (cacheEntry.cellRenderQueue.length){\n var lastChild = cacheEntry.rowNode.lastChild;\n while (cacheEntry.cellRenderQueue.length){\n var columnIdx = cacheEntry.cellRenderQueue.pop();\n cacheEntry.cellNodesByColumnIdx[columnIdx] = lastChild;\n lastChild = lastChild.previousSibling;\n }\n }\n }\n }\n\n function cleanUpCells(range, row){\n var totalCellsRemoved = 0;\n var cacheEntry = rowsCache[row];\n\n // Remove cells outside the range.\n var cellsToRemove = [];\n for (var i in cacheEntry.cellNodesByColumnIdx){\n // I really hate it when people mess with Array.prototype.\n if (!cacheEntry.cellNodesByColumnIdx.hasOwnProperty(i)){\n continue;\n }\n\n // This is a string, so it needs to be cast back to a number.\n i = i | 0;\n\n var colspan = cacheEntry.cellColSpans[i];\n if (columnPosLeft[i] > range.rightPx ||\n columnPosRight[Math.min(columns.length - 1, i + colspan - 1)] < range.leftPx){\n if (!(row == activeRow && i == activeCell)){\n cellsToRemove.push(i);\n }\n }\n }\n\n var cellToRemove, node;\n postProcessgroupId++;\n while ((cellToRemove = cellsToRemove.pop()) != null){\n node = cacheEntry.cellNodesByColumnIdx[cellToRemove];\n if (options.enableAsyncPostRenderCleanup && postProcessedRows[row] && postProcessedRows[row][cellToRemove]){\n queuePostProcessedCellForCleanup(node, cellToRemove, row);\n } else {\n cacheEntry.rowNode.removeChild(node);\n }\n\n delete cacheEntry.cellColSpans[cellToRemove];\n delete cacheEntry.cellNodesByColumnIdx[cellToRemove];\n if (postProcessedRows[row]){\n delete postProcessedRows[row][cellToRemove];\n }\n totalCellsRemoved++;\n }\n }\n\n function cleanUpAndRenderCells(range){\n var cacheEntry;\n var stringArray = [];\n var processedRows = [];\n var cellsAdded;\n var totalCellsAdded = 0;\n var colspan;\n\n for (var row = range.top, btm = range.bottom; row <= btm; row++){\n cacheEntry = rowsCache[row];\n if (!cacheEntry){\n continue;\n }\n\n // cellRenderQueue populated in renderRows() needs to be cleared first\n ensureCellNodesInRowsCache(row);\n\n cleanUpCells(range, row);\n\n // Render missing cells.\n cellsAdded = 0;\n\n var metadata = data.getItemMetadata && data.getItemMetadata(row);\n metadata = metadata && metadata.columns;\n\n var d = getDataItem(row);\n\n // TODO: shorten this loop (index? heuristics? binary search?)\n for (var i = 0, ii = columns.length; i < ii; i++){\n // Cells to the right are outside the range.\n if (columnPosLeft[i] > range.rightPx){\n break;\n }\n\n // Already rendered.\n if ((colspan = cacheEntry.cellColSpans[i]) != null){\n i += (colspan > 1 ? colspan - 1 : 0);\n continue;\n }\n\n colspan = 1;\n if (metadata){\n var columnData = metadata[columns[i].id] || metadata[i];\n colspan = (columnData && columnData.colspan) || 1;\n if (colspan === '*'){\n colspan = ii - i;\n }\n }\n\n if (columnPosRight[Math.min(ii - 1, i + colspan - 1)] > range.leftPx){\n appendCellHtml(stringArray, row, i, colspan, d);\n cellsAdded++;\n }\n\n i += (colspan > 1 ? colspan - 1 : 0);\n }\n\n if (cellsAdded){\n totalCellsAdded += cellsAdded;\n processedRows.push(row);\n }\n }\n\n if (!stringArray.length){\n return;\n }\n\n var x = document.createElement('div');\n x.innerHTML = stringArray.join('');\n\n var processedRow;\n var node;\n while ((processedRow = processedRows.pop()) != null){\n cacheEntry = rowsCache[processedRow];\n var columnIdx;\n while ((columnIdx = cacheEntry.cellRenderQueue.pop()) != null){\n node = x.lastChild;\n cacheEntry.rowNode.appendChild(node);\n cacheEntry.cellNodesByColumnIdx[columnIdx] = node;\n }\n }\n }\n\n function renderRows(range){\n var parentNode = $canvas[0],\n stringArray = [],\n rows = [],\n needToReselectCell = false,\n dataLength = getDataLength();\n\n for (var i = range.top, ii = range.bottom; i <= ii; i++){\n if (rowsCache[i]){\n continue;\n }\n renderedRows++;\n rows.push(i);\n\n // Create an entry right away so that appendRowHtml() can\n // start populatating it.\n rowsCache[i] = {\n 'rowNode': null,\n\n // ColSpans of rendered cells (by column idx).\n // Can also be used for checking whether a cell has been rendered.\n 'cellColSpans': [],\n\n // Cell nodes (by column idx). Lazy-populated by ensureCellNodesInRowsCache().\n 'cellNodesByColumnIdx': [],\n\n // Column indices of cell nodes that have been rendered, but not yet indexed in\n // cellNodesByColumnIdx. These are in the same order as cell nodes added at the\n // end of the row.\n 'cellRenderQueue': []\n };\n\n appendRowHtml(stringArray, i, range, dataLength);\n if (activeCellNode && activeRow === i){\n needToReselectCell = true;\n }\n counter_rows_rendered++;\n }\n\n if (!rows.length){\n return;\n }\n\n var x = document.createElement('div');\n x.innerHTML = stringArray.join('');\n\n for (var i = 0, ii = rows.length; i < ii; i++){\n rowsCache[rows[i]].rowNode = parentNode.appendChild(x.firstChild);\n }\n\n if (needToReselectCell){\n activeCellNode = getCellNode(activeRow, activeCell);\n }\n }\n\n function startPostProcessing(){\n if (!options.enableAsyncPostRender){\n return;\n }\n clearTimeout(h_postrender);\n h_postrender = setTimeout(asyncPostProcessRows, options.asyncPostRenderDelay);\n }\n\n function startPostProcessingCleanup(){\n if (!options.enableAsyncPostRenderCleanup){\n return;\n }\n clearTimeout(h_postrenderCleanup);\n h_postrenderCleanup = setTimeout(asyncPostProcessCleanupRows, options.asyncPostRenderCleanupDelay);\n }\n\n function invalidatePostProcessingResults(row){\n // change status of columns to be re-rendered\n for (var columnIdx in postProcessedRows[row]){\n if (postProcessedRows[row].hasOwnProperty(columnIdx)){\n postProcessedRows[row][columnIdx] = 'C';\n }\n }\n postProcessFromRow = Math.min(postProcessFromRow, row);\n postProcessToRow = Math.max(postProcessToRow, row);\n startPostProcessing();\n }\n\n function updateRowPositions(){\n for (var row in rowsCache){\n rowsCache[row].rowNode.style.top = getRowTop(row) + 'px';\n }\n }\n\n function render(){\n if (!initialized){\n return;\n }\n var visible = getVisibleRange();\n var rendered = getRenderedRange();\n\n // remove rows no longer in the viewport\n cleanupRows(rendered);\n\n // add new rows & missing cells in existing rows\n if (lastRenderedScrollLeft != scrollLeft){\n cleanUpAndRenderCells(rendered);\n }\n\n // render missing rows\n renderRows(rendered);\n\n postProcessFromRow = visible.top;\n postProcessToRow = Math.min(getDataLengthIncludingAddNew() - 1, visible.bottom);\n startPostProcessing();\n\n lastRenderedScrollTop = scrollTop;\n lastRenderedScrollLeft = scrollLeft;\n h_render = null;\n }\n\n function handleHeaderRowScroll(){\n var scrollLeft = $headerRowScroller[0].scrollLeft;\n if (scrollLeft != $viewport[0].scrollLeft){\n $viewport[0].scrollLeft = scrollLeft;\n }\n }\n\n function handleFooterRowScroll(){\n var scrollLeft = $footerRowScroller[0].scrollLeft;\n if (scrollLeft != $viewport[0].scrollLeft){\n $viewport[0].scrollLeft = scrollLeft;\n }\n }\n\n function handleScroll(){\n scrollTop = $viewport[0].scrollTop;\n scrollLeft = $viewport[0].scrollLeft;\n var vScrollDist = Math.abs(scrollTop - prevScrollTop);\n var hScrollDist = Math.abs(scrollLeft - prevScrollLeft);\n\n if (hScrollDist){\n prevScrollLeft = scrollLeft;\n $headerScroller[0].scrollLeft = scrollLeft;\n $topPanelScroller[0].scrollLeft = scrollLeft;\n $headerRowScroller[0].scrollLeft = scrollLeft;\n if (options.createFooterRow){\n $footerRowScroller[0].scrollLeft = scrollLeft;\n }\n }\n\n if (vScrollDist){\n vScrollDir = prevScrollTop < scrollTop ? 1 : -1;\n prevScrollTop = scrollTop;\n\n // switch virtual pages if needed\n if (vScrollDist < viewportH){\n scrollTo(scrollTop + offset);\n } else {\n var oldOffset = offset;\n if (h == viewportH){\n page = 0;\n } else {\n page = Math.min(n - 1, Math.floor(scrollTop * ((th - viewportH) / (h - viewportH)) * (1 / ph)));\n }\n offset = Math.round(page * cj);\n if (oldOffset != offset){\n invalidateAllRows();\n }\n }\n }\n\n if (hScrollDist || vScrollDist){\n if (h_render){\n clearTimeout(h_render);\n }\n\n if (Math.abs(lastRenderedScrollTop - scrollTop) > 20 ||\n Math.abs(lastRenderedScrollLeft - scrollLeft) > 20){\n if (options.forceSyncScrolling || (\n Math.abs(lastRenderedScrollTop - scrollTop) < viewportH &&\n Math.abs(lastRenderedScrollLeft - scrollLeft) < viewportW)){\n render();\n } else {\n h_render = setTimeout(render, 50);\n }\n\n trigger(self.onViewportChanged, {grid: self});\n }\n }\n\n trigger(self.onScroll, {scrollLeft: scrollLeft, scrollTop: scrollTop, grid: self});\n }\n\n function asyncPostProcessRows(){\n var dataLength = getDataLength();\n while (postProcessFromRow <= postProcessToRow){\n var row = (vScrollDir >= 0) ? postProcessFromRow++ : postProcessToRow--;\n var cacheEntry = rowsCache[row];\n if (!cacheEntry || row >= dataLength){\n continue;\n }\n\n if (!postProcessedRows[row]){\n postProcessedRows[row] = {};\n }\n\n ensureCellNodesInRowsCache(row);\n for (var columnIdx in cacheEntry.cellNodesByColumnIdx){\n if (!cacheEntry.cellNodesByColumnIdx.hasOwnProperty(columnIdx)){\n continue;\n }\n\n columnIdx = columnIdx | 0;\n\n var m = columns[columnIdx];\n var processedStatus = postProcessedRows[row][columnIdx]; // C=cleanup and re-render, R=rendered\n if (m.asyncPostRender && processedStatus !== 'R'){\n var node = cacheEntry.cellNodesByColumnIdx[columnIdx];\n if (node){\n m.asyncPostRender(node, row, getDataItem(row), m, (processedStatus === 'C'));\n }\n postProcessedRows[row][columnIdx] = 'R';\n }\n }\n\n h_postrender = setTimeout(asyncPostProcessRows, options.asyncPostRenderDelay);\n return;\n }\n }\n\n function asyncPostProcessCleanupRows(){\n if (postProcessedCleanupQueue.length > 0){\n var groupId = postProcessedCleanupQueue[0].groupId;\n\n // loop through all queue members with this groupID\n while (postProcessedCleanupQueue.length > 0 && postProcessedCleanupQueue[0].groupId == groupId){\n var entry = postProcessedCleanupQueue.shift();\n if (entry.actionType == 'R'){\n $(entry.node).remove();\n }\n if (entry.actionType == 'C'){\n var column = columns[entry.columnIdx];\n if (column.asyncPostRenderCleanup && entry.node){\n // cleanup must also remove element\n column.asyncPostRenderCleanup(entry.node, entry.rowIdx, column);\n }\n }\n }\n\n // call this function again after the specified delay\n h_postrenderCleanup = setTimeout(asyncPostProcessCleanupRows, options.asyncPostRenderCleanupDelay);\n }\n }\n\n function updateCellCssStylesOnRenderedRows(addedHash, removedHash){\n var node, columnId, addedRowHash, removedRowHash;\n for (var row in rowsCache){\n removedRowHash = removedHash && removedHash[row];\n addedRowHash = addedHash && addedHash[row];\n\n if (removedRowHash){\n for (columnId in removedRowHash){\n if (!addedRowHash || removedRowHash[columnId] != addedRowHash[columnId]){\n node = getCellNode(row, getColumnIndex(columnId));\n if (node){\n $(node).removeClass(removedRowHash[columnId]);\n }\n }\n }\n }\n\n if (addedRowHash){\n for (columnId in addedRowHash){\n if (!removedRowHash || removedRowHash[columnId] != addedRowHash[columnId]){\n node = getCellNode(row, getColumnIndex(columnId));\n if (node){\n $(node).addClass(addedRowHash[columnId]);\n }\n }\n }\n }\n }\n }\n\n function addCellCssStyles(key, hash){\n if (cellCssClasses[key]){\n throw \"addCellCssStyles: cell CSS hash with key '\" + key + \"' already exists.\";\n }\n\n cellCssClasses[key] = hash;\n updateCellCssStylesOnRenderedRows(hash, null);\n\n trigger(self.onCellCssStylesChanged, {'key': key, 'hash': hash, 'grid': self});\n }\n\n function removeCellCssStyles(key){\n if (!cellCssClasses[key]){\n return;\n }\n\n updateCellCssStylesOnRenderedRows(null, cellCssClasses[key]);\n delete cellCssClasses[key];\n\n trigger(self.onCellCssStylesChanged, {'key': key, 'hash': null, 'grid': self});\n }\n\n function setCellCssStyles(key, hash){\n var prevHash = cellCssClasses[key];\n\n cellCssClasses[key] = hash;\n updateCellCssStylesOnRenderedRows(hash, prevHash);\n\n trigger(self.onCellCssStylesChanged, {'key': key, 'hash': hash, 'grid': self});\n }\n\n function getCellCssStyles(key){\n return cellCssClasses[key];\n }\n\n function flashCell(row, cell, speed){\n speed = speed || 100;\n if (rowsCache[row]){\n var $cell = $(getCellNode(row, cell));\n\n function toggleCellClass(times){\n if (!times){\n return;\n }\n setTimeout(function(){\n $cell.queue(function(){\n $cell.toggleClass(options.cellFlashingCssClass).dequeue();\n toggleCellClass(times - 1);\n });\n },\n speed);\n }\n\n toggleCellClass(4);\n }\n }\n\n // ////////////////////////////////////////////////////////////////////////////////////////////\n // Interactivity\n\n function handleMouseWheel(e){\n var rowNode = $(e.target).closest('.slick-row')[0];\n if (rowNode != rowNodeFromLastMouseWheelEvent){\n if (zombieRowNodeFromLastMouseWheelEvent && zombieRowNodeFromLastMouseWheelEvent != rowNode){\n if (options.enableAsyncPostRenderCleanup && zombieRowPostProcessedFromLastMouseWheelEvent){\n queuePostProcessedRowForCleanup(zombieRowCacheFromLastMouseWheelEvent,\n zombieRowPostProcessedFromLastMouseWheelEvent);\n } else {\n $canvas[0].removeChild(zombieRowNodeFromLastMouseWheelEvent);\n }\n zombieRowNodeFromLastMouseWheelEvent = null;\n zombieRowCacheFromLastMouseWheelEvent = null;\n zombieRowPostProcessedFromLastMouseWheelEvent = null;\n\n if (options.enableAsyncPostRenderCleanup){\n startPostProcessingCleanup();\n }\n }\n rowNodeFromLastMouseWheelEvent = rowNode;\n }\n }\n\n function handleDragStart(interactEvent){\n var event = $.Event(interactEvent.originalEvent.type, interactEvent.originalEvent);\n var cell = getCellFromEvent(event);\n if (!cell || !cellExists(cell.row, cell.cell)){\n return false;\n }\n\n var retval = trigger(self.onDragStart, interactEvent, event);\n if (event.isImmediatePropagationStopped()){\n return retval;\n }\n\n return false;\n }\n\n function handleDrag(interactEvent){\n var event = $.Event(interactEvent.originalEvent.type, interactEvent.originalEvent);\n return trigger(self.onDrag, interactEvent, event);\n }\n\n function handleDragEnd(interactEvent){\n trigger(self.onDragEnd, interactEvent, $.Event('mousedown'));\n }\n\n function handleKeyDown(e){\n trigger(self.onKeyDown, {row: activeRow, cell: activeCell, grid: self}, e);\n var handled = e.isImmediatePropagationStopped();\n var keyCode = Slick.keyCode;\n\n if (!handled){\n if (!e.shiftKey && !e.altKey && !e.ctrlKey){\n // editor may specify an array of keys to bubble\n if (options.editable && currentEditor && currentEditor.keyCaptureList){\n if (currentEditor.keyCaptureList.indexOf(e.which) > -1){\n return;\n }\n }\n if (e.which == keyCode.ESCAPE){\n if (!getEditorLock().isActive()){\n return; // no editing mode to cancel, allow bubbling and default processing (exit without cancelling the event)\n }\n cancelEditAndSetFocus();\n } else if (e.which == keyCode.PAGE_DOWN){\n navigatePageDown();\n handled = true;\n } else if (e.which == keyCode.PAGE_UP){\n navigatePageUp();\n handled = true;\n } else if (e.which == keyCode.LEFT){\n handled = navigateLeft();\n } else if (e.which == keyCode.RIGHT){\n handled = navigateRight();\n } else if (e.which == keyCode.UP){\n handled = navigateUp();\n } else if (e.which == keyCode.DOWN){\n handled = navigateDown();\n } else if (e.which == keyCode.TAB){\n handled = navigateNext();\n } else if (e.which == keyCode.ENTER){\n if (options.editable){\n if (currentEditor){\n // adding new row\n if (activeRow === getDataLength()){\n navigateDown();\n } else {\n commitEditAndSetFocus();\n }\n } else {\n if (getEditorLock().commitCurrentEdit()){\n makeActiveCellEditable();\n }\n }\n }\n handled = true;\n }\n } else if (e.which == keyCode.TAB && e.shiftKey && !e.ctrlKey && !e.altKey){\n handled = navigatePrev();\n }\n }\n\n if (handled){\n // the event has been handled so don't let parent element (bubbling/propagation) or browser (default) handle it\n e.stopPropagation();\n e.preventDefault();\n try {\n e.originalEvent.keyCode = 0; // prevent default behaviour for special keys in IE browsers (F3, F5, etc.)\n }\n // ignore exceptions - setting the original event's keycode throws access denied exception for \"Ctrl\"\n // (hitting control key only, nothing else), \"Shift\" (maybe others)\n catch (error){\n }\n }\n }\n\n function handleClick(e){\n if (!currentEditor){\n // if this click resulted in some cell child node getting focus,\n // don't steal it back - keyboard events will still bubble up\n // IE9+ seems to default DIVs to tabIndex=0 instead of -1, so check for cell clicks directly.\n if (e.target != document.activeElement || $(e.target).hasClass('slick-cell')){\n setFocus();\n }\n }\n\n var cell = getCellFromEvent(e);\n if (!cell || (currentEditor !== null && activeRow == cell.row && activeCell == cell.cell)){\n return;\n }\n\n trigger(self.onClick, {row: cell.row, cell: cell.cell, grid: self}, e);\n if (e.isImmediatePropagationStopped()){\n return;\n }\n\n if ((activeCell != cell.cell || activeRow != cell.row) && canCellBeActive(cell.row, cell.cell)){\n if (!getEditorLock().isActive() || getEditorLock().commitCurrentEdit()){\n scrollRowIntoView(cell.row, false);\n setActiveCellInternal(getCellNode(cell.row, cell.cell));\n }\n }\n }\n\n function handleContextMenu(e){\n var $cell = $(e.target).closest('.slick-cell', $canvas);\n if ($cell.length === 0){\n return;\n }\n\n // are we editing this cell?\n if (activeCellNode === $cell[0] && currentEditor !== null){\n return;\n }\n\n trigger(self.onContextMenu, {grid: self}, e);\n }\n\n function handleDblClick(e){\n var cell = getCellFromEvent(e);\n if (!cell || (currentEditor !== null && activeRow == cell.row && activeCell == cell.cell)){\n return;\n }\n\n trigger(self.onDblClick, {row: cell.row, cell: cell.cell, grid: self}, e);\n if (e.isImmediatePropagationStopped()){\n return;\n }\n\n if (options.editable){\n gotoCell(cell.row, cell.cell, true);\n }\n }\n\n function handleHeaderMouseEnter(e){\n trigger(self.onHeaderMouseEnter, {\n 'column': $(this).data('column'),\n 'grid': self\n }, e);\n }\n\n function handleHeaderMouseLeave(e){\n trigger(self.onHeaderMouseLeave, {\n 'column': $(this).data('column'),\n 'grid': self\n }, e);\n }\n\n function handleHeaderContextMenu(e){\n var $header = $(e.target).closest('.slick-header-column', '.slick-header-columns');\n var column = $header && $header.data('column');\n trigger(self.onHeaderContextMenu, {column: column, grid: self}, e);\n }\n\n function handleHeaderClick(e){\n var $header = $(e.target).closest('.slick-header-column', '.slick-header-columns');\n var column = $header && $header.data('column');\n if (column){\n trigger(self.onHeaderClick, {column: column, grid: self}, e);\n }\n }\n\n function handleMouseEnter(e){\n trigger(self.onMouseEnter, {grid: self}, e);\n }\n\n function handleMouseLeave(e){\n trigger(self.onMouseLeave, {grid: self}, e);\n }\n\n function cellExists(row, cell){\n return !(row < 0 || row >= getDataLength() || cell < 0 || cell >= columns.length);\n }\n\n function getCellFromPoint(x, y){\n var row = getRowFromPosition(y);\n var cell = 0;\n\n var w = 0;\n for (var i = 0; i < columns.length && w < x; i++){\n w += columns[i].width;\n cell++;\n }\n\n if (cell < 0){\n cell = 0;\n }\n\n return {row: row, cell: cell - 1};\n }\n\n function getCellFromNode(cellNode){\n // read column number from .l CSS class\n var cls = /l\\d+/.exec(cellNode.className);\n if (!cls){\n throw 'getCellFromNode: cannot get cell - ' + cellNode.className;\n }\n return parseInt(cls[0].substr(1, cls[0].length - 1), 10);\n }\n\n function getRowFromNode(rowNode){\n for (var row in rowsCache){\n if (rowsCache[row].rowNode === rowNode){\n return row | 0;\n }\n }\n\n return null;\n }\n\n function getCellFromEvent(e){\n var $cell = $(e.target).closest('.slick-cell', $canvas);\n if (!$cell.length){\n return null;\n }\n\n var row = getRowFromNode($cell[0].parentNode);\n var cell = getCellFromNode($cell[0]);\n\n if (row == null || cell == null){\n return null;\n } else {\n return {\n 'row': row,\n 'cell': cell\n };\n }\n }\n\n function getCellNodeBox(row, cell){\n if (!cellExists(row, cell)){\n return null;\n }\n\n var y1 = getRowTop(row);\n var y2 = y1 + options.rowHeight - 1;\n var x1 = 0;\n for (var i = 0; i < cell; i++){\n x1 += columns[i].width;\n }\n var x2 = x1 + columns[cell].width;\n\n return {\n top: y1,\n left: x1,\n bottom: y2,\n right: x2\n };\n }\n\n // ////////////////////////////////////////////////////////////////////////////////////////////\n // Cell switching\n\n function resetActiveCell(){\n setActiveCellInternal(null, false);\n }\n\n function setFocus(){\n if (tabbingDirection == -1){\n $focusSink[0].focus();\n } else {\n $focusSink2[0].focus();\n }\n }\n\n function scrollCellIntoView(row, cell, doPaging){\n scrollRowIntoView(row, doPaging);\n\n var colspan = getColspan(row, cell);\n var left = columnPosLeft[cell],\n right = columnPosRight[cell + (colspan > 1 ? colspan - 1 : 0)],\n scrollRight = scrollLeft + viewportW;\n\n if (left < scrollLeft){\n $viewport.scrollLeft(left);\n handleScroll();\n render();\n } else if (right > scrollRight){\n $viewport.scrollLeft(Math.min(left, right - $viewport[0].clientWidth));\n handleScroll();\n render();\n }\n }\n\n function setActiveCellInternal(newCell, opt_editMode){\n if (activeCellNode !== null){\n makeActiveCellNormal();\n $(activeCellNode).removeClass('active');\n if (rowsCache[activeRow]){\n $(rowsCache[activeRow].rowNode).removeClass('active');\n }\n }\n\n var activeCellChanged = (activeCellNode !== newCell);\n activeCellNode = newCell;\n\n if (activeCellNode != null){\n activeRow = getRowFromNode(activeCellNode.parentNode);\n activeCell = activePosX = getCellFromNode(activeCellNode);\n\n if (opt_editMode == null){\n opt_editMode = (activeRow == getDataLength()) || options.autoEdit;\n }\n\n $(activeCellNode).addClass('active');\n $(rowsCache[activeRow].rowNode).addClass('active');\n\n if (options.editable && opt_editMode && isCellPotentiallyEditable(activeRow, activeCell)){\n clearTimeout(h_editorLoader);\n\n if (options.asyncEditorLoading){\n h_editorLoader = setTimeout(function(){\n makeActiveCellEditable();\n }, options.asyncEditorLoadDelay);\n } else {\n makeActiveCellEditable();\n }\n }\n } else {\n activeRow = activeCell = null;\n }\n\n if (activeCellChanged){\n trigger(self.onActiveCellChanged, getActiveCell());\n }\n }\n\n function clearTextSelection(){\n if (document.selection && document.selection.empty){\n try {\n // IE fails here if selected element is not in dom\n document.selection.empty();\n } catch (e){\n }\n } else if (window.getSelection){\n var sel = window.getSelection();\n if (sel && sel.removeAllRanges){\n sel.removeAllRanges();\n }\n }\n }\n\n function isCellPotentiallyEditable(row, cell){\n var dataLength = getDataLength();\n // is the data for this row loaded?\n if (row < dataLength && !getDataItem(row)){\n return false;\n }\n\n // are we in the Add New row? can we create new from this cell?\n if (columns[cell].cannotTriggerInsert && row >= dataLength){\n return false;\n }\n\n // does this cell have an editor?\n if (!getEditor(row, cell)){\n return false;\n }\n\n return true;\n }\n\n function makeActiveCellNormal(){\n if (!currentEditor){\n return;\n }\n trigger(self.onBeforeCellEditorDestroy, {editor: currentEditor, grid: self});\n currentEditor.destroy();\n currentEditor = null;\n\n if (activeCellNode){\n var d = getDataItem(activeRow);\n $(activeCellNode).removeClass('editable invalid');\n if (d){\n var column = columns[activeCell];\n var formatter = getFormatter(activeRow, column);\n activeCellNode.innerHTML = formatter(activeRow, activeCell, getDataItemValueForColumn(d, column), column, d, self);\n invalidatePostProcessingResults(activeRow);\n }\n }\n\n // if there previously was text selected on a page (such as selected text in the edit cell just removed),\n // IE can't set focus to anything else correctly\n if (navigator.userAgent.toLowerCase().match(/msie/)){\n clearTextSelection();\n }\n\n getEditorLock().deactivate(editController);\n }\n\n function makeActiveCellEditable(editor){\n if (!activeCellNode){\n return;\n }\n if (!options.editable){\n throw 'Grid : makeActiveCellEditable : should never get called when options.editable is false';\n }\n\n // cancel pending async call if there is one\n clearTimeout(h_editorLoader);\n\n if (!isCellPotentiallyEditable(activeRow, activeCell)){\n return;\n }\n\n var columnDef = columns[activeCell];\n var item = getDataItem(activeRow);\n\n if (trigger(self.onBeforeEditCell, {\n row: activeRow,\n cell: activeCell,\n item: item,\n column: columnDef,\n grid: self\n }) === false){\n setFocus();\n return;\n }\n\n getEditorLock().activate(editController);\n $(activeCellNode).addClass('editable');\n\n var useEditor = editor || getEditor(activeRow, activeCell);\n\n // don't clear the cell if a custom editor is passed through\n if (!editor && !useEditor.suppressClearOnEdit){\n activeCellNode.innerHTML = '';\n }\n\n currentEditor = new useEditor({\n grid: self,\n gridPosition: absBox($container[0]),\n position: absBox(activeCellNode),\n container: activeCellNode,\n column: columnDef,\n item: item || {},\n commitChanges: commitEditAndSetFocus,\n cancelChanges: cancelEditAndSetFocus\n });\n\n if (item){\n currentEditor.loadValue(item);\n }\n\n serializedEditorValue = currentEditor.serializeValue();\n\n if (currentEditor.position){\n handleActiveCellPositionChange();\n }\n }\n\n function commitEditAndSetFocus(){\n // if the commit fails, it would do so due to a validation error\n // if so, do not steal the focus from the editor\n if (getEditorLock().commitCurrentEdit()){\n setFocus();\n if (options.autoEdit){\n navigateDown();\n }\n }\n }\n\n function cancelEditAndSetFocus(){\n if (getEditorLock().cancelCurrentEdit()){\n setFocus();\n }\n }\n\n function absBox(elem){\n var box = {\n top: elem.offsetTop,\n left: elem.offsetLeft,\n bottom: 0,\n right: 0,\n width: $(elem).outerWidth(),\n height: $(elem).outerHeight(),\n visible: true\n };\n box.bottom = box.top + box.height;\n box.right = box.left + box.width;\n\n // walk up the tree\n var offsetParent = elem.offsetParent;\n while ((elem = elem.parentNode) != document.body){\n if (elem == null) break;\n\n if (box.visible && elem.scrollHeight != elem.offsetHeight && $(elem).css('overflowY') != 'visible'){\n box.visible = box.bottom > elem.scrollTop && box.top < elem.scrollTop + elem.clientHeight;\n }\n\n if (box.visible && elem.scrollWidth != elem.offsetWidth && $(elem).css('overflowX') != 'visible'){\n box.visible = box.right > elem.scrollLeft && box.left < elem.scrollLeft + elem.clientWidth;\n }\n\n box.left -= elem.scrollLeft;\n box.top -= elem.scrollTop;\n\n if (elem === offsetParent){\n box.left += elem.offsetLeft;\n box.top += elem.offsetTop;\n offsetParent = elem.offsetParent;\n }\n\n box.bottom = box.top + box.height;\n box.right = box.left + box.width;\n }\n\n return box;\n }\n\n function getActiveCellPosition(){\n return absBox(activeCellNode);\n }\n\n function getGridPosition(){\n return absBox($container[0]);\n }\n\n function handleActiveCellPositionChange(){\n if (!activeCellNode){\n return;\n }\n\n trigger(self.onActiveCellPositionChanged, {grid: self});\n\n if (currentEditor){\n var cellBox = getActiveCellPosition();\n if (currentEditor.show && currentEditor.hide){\n if (!cellBox.visible){\n currentEditor.hide();\n } else {\n currentEditor.show();\n }\n }\n\n if (currentEditor.position){\n currentEditor.position(cellBox);\n }\n }\n }\n\n function getCellEditor(){\n return currentEditor;\n }\n\n function getActiveCell(){\n if (!activeCellNode){\n return null;\n } else {\n return {row: activeRow, cell: activeCell, grid: self};\n }\n }\n\n function getActiveCellNode(){\n return activeCellNode;\n }\n\n function scrollRowIntoView(row, doPaging){\n var rowAtTop = row * options.rowHeight;\n var rowAtBottom = (row + 1) * options.rowHeight - viewportH + (viewportHasHScroll ? scrollbarDimensions.height : 0);\n\n // need to page down?\n if ((row + 1) * options.rowHeight > scrollTop + viewportH + offset){\n scrollTo(doPaging ? rowAtTop : rowAtBottom);\n render();\n }\n // or page up?\n else if (row * options.rowHeight < scrollTop + offset){\n scrollTo(doPaging ? rowAtBottom : rowAtTop);\n render();\n }\n }\n\n function scrollRowToTop(row){\n scrollTo(row * options.rowHeight);\n render();\n }\n\n function scrollPage(dir){\n var deltaRows = dir * numVisibleRows;\n scrollTo((getRowFromPosition(scrollTop) + deltaRows) * options.rowHeight);\n render();\n\n if (options.enableCellNavigation && activeRow != null){\n var row = activeRow + deltaRows;\n var dataLengthIncludingAddNew = getDataLengthIncludingAddNew();\n if (row >= dataLengthIncludingAddNew){\n row = dataLengthIncludingAddNew - 1;\n }\n if (row < 0){\n row = 0;\n }\n\n var cell = 0, prevCell = null;\n var prevActivePosX = activePosX;\n while (cell <= activePosX){\n if (canCellBeActive(row, cell)){\n prevCell = cell;\n }\n cell += getColspan(row, cell);\n }\n\n if (prevCell !== null){\n setActiveCellInternal(getCellNode(row, prevCell));\n activePosX = prevActivePosX;\n } else {\n resetActiveCell();\n }\n }\n }\n\n function navigatePageDown(){\n scrollPage(1);\n }\n\n function navigatePageUp(){\n scrollPage(-1);\n }\n\n function getColspan(row, cell){\n var metadata = data.getItemMetadata && data.getItemMetadata(row);\n if (!metadata || !metadata.columns){\n return 1;\n }\n\n var columnData = metadata.columns[columns[cell].id] || metadata.columns[cell];\n var colspan = (columnData && columnData.colspan);\n if (colspan === '*'){\n colspan = columns.length - cell;\n } else {\n colspan = colspan || 1;\n }\n\n return colspan;\n }\n\n function findFirstFocusableCell(row){\n var cell = 0;\n while (cell < columns.length){\n if (canCellBeActive(row, cell)){\n return cell;\n }\n cell += getColspan(row, cell);\n }\n return null;\n }\n\n function findLastFocusableCell(row){\n var cell = 0;\n var lastFocusableCell = null;\n while (cell < columns.length){\n if (canCellBeActive(row, cell)){\n lastFocusableCell = cell;\n }\n cell += getColspan(row, cell);\n }\n return lastFocusableCell;\n }\n\n function gotoRight(row, cell, posX){\n if (cell >= columns.length){\n return null;\n }\n\n do {\n cell += getColspan(row, cell);\n }\n while (cell < columns.length && !canCellBeActive(row, cell));\n\n if (cell < columns.length){\n return {\n 'row': row,\n 'cell': cell,\n 'posX': cell\n };\n }\n return null;\n }\n\n function gotoLeft(row, cell, posX){\n if (cell <= 0){\n return null;\n }\n\n var firstFocusableCell = findFirstFocusableCell(row);\n if (firstFocusableCell === null || firstFocusableCell >= cell){\n return null;\n }\n\n var prev = {\n 'row': row,\n 'cell': firstFocusableCell,\n 'posX': firstFocusableCell\n };\n var pos;\n while (true){\n pos = gotoRight(prev.row, prev.cell, prev.posX);\n if (!pos){\n return null;\n }\n if (pos.cell >= cell){\n return prev;\n }\n prev = pos;\n }\n }\n\n function gotoDown(row, cell, posX){\n var prevCell;\n var dataLengthIncludingAddNew = getDataLengthIncludingAddNew();\n while (true){\n if (++row >= dataLengthIncludingAddNew){\n return null;\n }\n\n prevCell = cell = 0;\n while (cell <= posX){\n prevCell = cell;\n cell += getColspan(row, cell);\n }\n\n if (canCellBeActive(row, prevCell)){\n return {\n 'row': row,\n 'cell': prevCell,\n 'posX': posX\n };\n }\n }\n }\n\n function gotoUp(row, cell, posX){\n var prevCell;\n while (true){\n if (--row < 0){\n return null;\n }\n\n prevCell = cell = 0;\n while (cell <= posX){\n prevCell = cell;\n cell += getColspan(row, cell);\n }\n\n if (canCellBeActive(row, prevCell)){\n return {\n 'row': row,\n 'cell': prevCell,\n 'posX': posX\n };\n }\n }\n }\n\n function gotoNext(row, cell, posX){\n if (row == null && cell == null){\n row = cell = posX = 0;\n if (canCellBeActive(row, cell)){\n return {\n 'row': row,\n 'cell': cell,\n 'posX': cell\n };\n }\n }\n\n var pos = gotoRight(row, cell, posX);\n if (pos){\n return pos;\n }\n\n var firstFocusableCell = null;\n var dataLengthIncludingAddNew = getDataLengthIncludingAddNew();\n while (++row < dataLengthIncludingAddNew){\n firstFocusableCell = findFirstFocusableCell(row);\n if (firstFocusableCell !== null){\n return {\n 'row': row,\n 'cell': firstFocusableCell,\n 'posX': firstFocusableCell\n };\n }\n }\n return null;\n }\n\n function gotoPrev(row, cell, posX){\n if (row == null && cell == null){\n row = getDataLengthIncludingAddNew() - 1;\n cell = posX = columns.length - 1;\n if (canCellBeActive(row, cell)){\n return {\n 'row': row,\n 'cell': cell,\n 'posX': cell\n };\n }\n }\n\n var pos;\n var lastSelectableCell;\n while (!pos){\n pos = gotoLeft(row, cell, posX);\n if (pos){\n break;\n }\n if (--row < 0){\n return null;\n }\n\n cell = 0;\n lastSelectableCell = findLastFocusableCell(row);\n if (lastSelectableCell !== null){\n pos = {\n 'row': row,\n 'cell': lastSelectableCell,\n 'posX': lastSelectableCell\n };\n }\n }\n return pos;\n }\n\n function navigateRight(){\n return navigate('right');\n }\n\n function navigateLeft(){\n return navigate('left');\n }\n\n function navigateDown(){\n return navigate('down');\n }\n\n function navigateUp(){\n return navigate('up');\n }\n\n function navigateNext(){\n return navigate('next');\n }\n\n function navigatePrev(){\n return navigate('prev');\n }\n\n /**\n * @param {string} dir Navigation direction.\n * @return {boolean} Whether navigation resulted in a change of active cell.\n */\n function navigate(dir){\n if (!options.enableCellNavigation){\n return false;\n }\n\n if (!activeCellNode && dir != 'prev' && dir != 'next'){\n return false;\n }\n\n if (!getEditorLock().commitCurrentEdit()){\n return true;\n }\n setFocus();\n\n var tabbingDirections = {\n 'up': -1,\n 'down': 1,\n 'left': -1,\n 'right': 1,\n 'prev': -1,\n 'next': 1\n };\n tabbingDirection = tabbingDirections[dir];\n\n var stepFunctions = {\n 'up': gotoUp,\n 'down': gotoDown,\n 'left': gotoLeft,\n 'right': gotoRight,\n 'prev': gotoPrev,\n 'next': gotoNext\n };\n var stepFn = stepFunctions[dir];\n var pos = stepFn(activeRow, activeCell, activePosX);\n if (pos){\n var isAddNewRow = (pos.row == getDataLength());\n scrollCellIntoView(pos.row, pos.cell, !isAddNewRow);\n setActiveCellInternal(getCellNode(pos.row, pos.cell));\n activePosX = pos.posX;\n return true;\n } else {\n setActiveCellInternal(getCellNode(activeRow, activeCell));\n return false;\n }\n }\n\n function getCellNode(row, cell){\n if (rowsCache[row]){\n ensureCellNodesInRowsCache(row);\n return rowsCache[row].cellNodesByColumnIdx[cell];\n }\n return null;\n }\n\n function setActiveCell(row, cell){\n if (!initialized){\n return;\n }\n if (row > getDataLength() || row < 0 || cell >= columns.length || cell < 0){\n return;\n }\n\n if (!options.enableCellNavigation){\n return;\n }\n\n scrollCellIntoView(row, cell, false);\n setActiveCellInternal(getCellNode(row, cell), false);\n }\n\n function canCellBeActive(row, cell){\n if (!options.enableCellNavigation || row >= getDataLengthIncludingAddNew() ||\n row < 0 || cell >= columns.length || cell < 0){\n return false;\n }\n\n var rowMetadata = data.getItemMetadata && data.getItemMetadata(row);\n if (rowMetadata && typeof rowMetadata.focusable === 'boolean'){\n return rowMetadata.focusable;\n }\n\n var columnMetadata = rowMetadata && rowMetadata.columns;\n if (columnMetadata && columnMetadata[columns[cell].id] && typeof columnMetadata[columns[cell].id].focusable === 'boolean'){\n return columnMetadata[columns[cell].id].focusable;\n }\n if (columnMetadata && columnMetadata[cell] && typeof columnMetadata[cell].focusable === 'boolean'){\n return columnMetadata[cell].focusable;\n }\n\n return columns[cell].focusable;\n }\n\n function canCellBeSelected(row, cell){\n if (row >= getDataLength() || row < 0 || cell >= columns.length || cell < 0){\n return false;\n }\n\n var rowMetadata = data.getItemMetadata && data.getItemMetadata(row);\n if (rowMetadata && typeof rowMetadata.selectable === 'boolean'){\n return rowMetadata.selectable;\n }\n\n var columnMetadata = rowMetadata && rowMetadata.columns && (rowMetadata.columns[columns[cell].id] || rowMetadata.columns[cell]);\n if (columnMetadata && typeof columnMetadata.selectable === 'boolean'){\n return columnMetadata.selectable;\n }\n\n return columns[cell].selectable;\n }\n\n function gotoCell(row, cell, forceEdit){\n if (!initialized){\n return;\n }\n if (!canCellBeActive(row, cell)){\n return;\n }\n\n if (!getEditorLock().commitCurrentEdit()){\n return;\n }\n\n scrollCellIntoView(row, cell, false);\n\n var newCell = getCellNode(row, cell);\n\n // if selecting the 'add new' row, start editing right away\n setActiveCellInternal(newCell, forceEdit || (row === getDataLength()) || options.autoEdit);\n\n // if no editor was created, set the focus back on the grid\n if (!currentEditor){\n setFocus();\n }\n }\n\n // ////////////////////////////////////////////////////////////////////////////////////////////\n // IEditor implementation for the editor lock\n\n function commitCurrentEdit(){\n var item = getDataItem(activeRow);\n var column = columns[activeCell];\n\n if (currentEditor){\n if (currentEditor.isValueChanged()){\n var validationResults = currentEditor.validate();\n\n if (validationResults.valid){\n if (activeRow < getDataLength()){\n var editCommand = {\n row: activeRow,\n cell: activeCell,\n editor: currentEditor,\n serializedValue: currentEditor.serializeValue(),\n prevSerializedValue: serializedEditorValue,\n execute: function(){\n this.editor.applyValue(item, this.serializedValue);\n updateRow(this.row);\n trigger(self.onCellChange, {\n row: activeRow,\n cell: activeCell,\n item: item,\n grid: self\n });\n },\n undo: function(){\n this.editor.applyValue(item, this.prevSerializedValue);\n updateRow(this.row);\n trigger(self.onCellChange, {\n row: activeRow,\n cell: activeCell,\n item: item,\n grid: self\n });\n }\n };\n\n if (options.editCommandHandler){\n makeActiveCellNormal();\n options.editCommandHandler(item, column, editCommand);\n } else {\n editCommand.execute();\n makeActiveCellNormal();\n }\n } else {\n var newItem = {};\n currentEditor.applyValue(newItem, currentEditor.serializeValue());\n makeActiveCellNormal();\n trigger(self.onAddNewRow, {item: newItem, column: column, grid: self});\n }\n\n // check whether the lock has been re-acquired by event handlers\n return !getEditorLock().isActive();\n } else {\n // Re-add the CSS class to trigger transitions, if any.\n $(activeCellNode).removeClass('invalid');\n $(activeCellNode).width(); // force layout\n $(activeCellNode).addClass('invalid');\n\n trigger(self.onValidationError, {\n editor: currentEditor,\n cellNode: activeCellNode,\n validationResults: validationResults,\n row: activeRow,\n cell: activeCell,\n column: column,\n grid: self\n });\n\n currentEditor.focus();\n return false;\n }\n }\n\n makeActiveCellNormal();\n }\n return true;\n }\n\n function cancelCurrentEdit(){\n makeActiveCellNormal();\n return true;\n }\n\n function rowsToRanges(rows){\n var ranges = [];\n var lastCell = columns.length - 1;\n for (var i = 0; i < rows.length; i++){\n ranges.push(new Slick.Range(rows[i], 0, rows[i], lastCell));\n }\n return ranges;\n }\n\n function getSelectedRows(){\n if (!selectionModel){\n throw 'Selection model is not set';\n }\n return selectedRows;\n }\n\n function setSelectedRows(rows){\n if (!selectionModel){\n throw 'Selection model is not set';\n }\n selectionModel.setSelectedRanges(rowsToRanges(rows));\n }\n\n // ////////////////////////////////////////////////////////////////////////////////////////////\n // Debug\n\n this.debug = function(){\n var s = '';\n\n s += ('\\n' + 'counter_rows_rendered: ' + counter_rows_rendered);\n s += ('\\n' + 'counter_rows_removed: ' + counter_rows_removed);\n s += ('\\n' + 'renderedRows: ' + renderedRows);\n s += ('\\n' + 'numVisibleRows: ' + numVisibleRows);\n s += ('\\n' + 'maxSupportedCssHeight: ' + maxSupportedCssHeight);\n s += ('\\n' + 'n(umber of pages): ' + n);\n s += ('\\n' + '(current) page: ' + page);\n s += ('\\n' + 'page height (ph): ' + ph);\n s += ('\\n' + 'vScrollDir: ' + vScrollDir);\n\n alert(s);\n };\n\n // a debug helper to be able to access private members\n this.eval = function(expr){\n return eval(expr);\n };\n\n // ////////////////////////////////////////////////////////////////////////////////////////////\n // Public API\n\n $.extend(this, {\n 'slickGridVersion': '2.2.4',\n\n // Events\n 'onScroll': new Slick.Event(),\n 'onSort': new Slick.Event(),\n 'onHeaderMouseEnter': new Slick.Event(),\n 'onHeaderMouseLeave': new Slick.Event(),\n 'onHeaderContextMenu': new Slick.Event(),\n 'onHeaderClick': new Slick.Event(),\n 'onHeaderCellRendered': new Slick.Event(),\n 'onBeforeHeaderCellDestroy': new Slick.Event(),\n 'onHeaderRowCellRendered': new Slick.Event(),\n 'onFooterRowCellRendered': new Slick.Event(),\n 'onBeforeHeaderRowCellDestroy': new Slick.Event(),\n 'onBeforeFooterRowCellDestroy': new Slick.Event(),\n 'onMouseEnter': new Slick.Event(),\n 'onMouseLeave': new Slick.Event(),\n 'onClick': new Slick.Event(),\n 'onDblClick': new Slick.Event(),\n 'onContextMenu': new Slick.Event(),\n 'onKeyDown': new Slick.Event(),\n 'onAddNewRow': new Slick.Event(),\n 'onValidationError': new Slick.Event(),\n 'onViewportChanged': new Slick.Event(),\n 'onColumnsReordered': new Slick.Event(),\n 'onColumnsResized': new Slick.Event(),\n 'onCellChange': new Slick.Event(),\n 'onBeforeEditCell': new Slick.Event(),\n 'onBeforeCellEditorDestroy': new Slick.Event(),\n 'onBeforeDestroy': new Slick.Event(),\n 'onActiveCellChanged': new Slick.Event(),\n 'onActiveCellPositionChanged': new Slick.Event(),\n 'onDragInit': new Slick.Event(),\n 'onDragStart': new Slick.Event(),\n 'onDrag': new Slick.Event(),\n 'onDragEnd': new Slick.Event(),\n 'onSelectedRowsChanged': new Slick.Event(),\n 'onCellCssStylesChanged': new Slick.Event(),\n\n // Methods\n 'registerPlugin': registerPlugin,\n 'unregisterPlugin': unregisterPlugin,\n 'getColumns': getColumns,\n 'setColumns': setColumns,\n 'getColumnIndex': getColumnIndex,\n 'updateColumnHeader': updateColumnHeader,\n 'setSortColumn': setSortColumn,\n 'setSortColumns': setSortColumns,\n 'getSortColumns': getSortColumns,\n 'autosizeColumns': autosizeColumns,\n 'getOptions': getOptions,\n 'setOptions': setOptions,\n 'getData': getData,\n 'getDataLength': getDataLength,\n 'getDataItem': getDataItem,\n 'setData': setData,\n 'getSelectionModel': getSelectionModel,\n 'setSelectionModel': setSelectionModel,\n 'getSelectedRows': getSelectedRows,\n 'setSelectedRows': setSelectedRows,\n 'getContainerNode': getContainerNode,\n\n 'render': render,\n 'invalidate': invalidate,\n 'invalidateRow': invalidateRow,\n 'invalidateRows': invalidateRows,\n 'invalidateAllRows': invalidateAllRows,\n 'updateCell': updateCell,\n 'updateRow': updateRow,\n 'getViewport': getVisibleRange,\n 'getRenderedRange': getRenderedRange,\n 'resizeCanvas': resizeCanvas,\n 'updateRowCount': updateRowCount,\n 'scrollRowIntoView': scrollRowIntoView,\n 'scrollRowToTop': scrollRowToTop,\n 'scrollCellIntoView': scrollCellIntoView,\n 'getCanvasNode': getCanvasNode,\n 'focus': setFocus,\n\n 'getCellFromPoint': getCellFromPoint,\n 'getCellFromEvent': getCellFromEvent,\n 'getActiveCell': getActiveCell,\n 'setActiveCell': setActiveCell,\n 'getActiveCellNode': getActiveCellNode,\n 'getActiveCellPosition': getActiveCellPosition,\n 'resetActiveCell': resetActiveCell,\n 'editActiveCell': makeActiveCellEditable,\n 'getCellEditor': getCellEditor,\n 'getCellNode': getCellNode,\n 'getCellNodeBox': getCellNodeBox,\n 'canCellBeSelected': canCellBeSelected,\n 'canCellBeActive': canCellBeActive,\n 'navigatePrev': navigatePrev,\n 'navigateNext': navigateNext,\n 'navigateUp': navigateUp,\n 'navigateDown': navigateDown,\n 'navigateLeft': navigateLeft,\n 'navigateRight': navigateRight,\n 'navigatePageUp': navigatePageUp,\n 'navigatePageDown': navigatePageDown,\n 'gotoCell': gotoCell,\n 'getTopPanel': getTopPanel,\n 'setTopPanelVisibility': setTopPanelVisibility,\n 'setHeaderRowVisibility': setHeaderRowVisibility,\n 'getHeaderRow': getHeaderRow,\n 'getHeaderRowColumn': getHeaderRowColumn,\n 'setFooterRowVisibility': setFooterRowVisibility,\n 'getFooterRow': getFooterRow,\n 'getFooterRowColumn': getFooterRowColumn,\n 'getGridPosition': getGridPosition,\n 'flashCell': flashCell,\n 'addCellCssStyles': addCellCssStyles,\n 'setCellCssStyles': setCellCssStyles,\n 'removeCellCssStyles': removeCellCssStyles,\n 'getCellCssStyles': getCellCssStyles,\n\n 'init': finishInitialization,\n 'destroy': destroy,\n\n // IEditor implementation\n 'getEditorLock': getEditorLock,\n 'getEditController': getEditController\n });\n\n init();\n}\n\n\n\n// WEBPACK FOOTER //\n// ../src/slick.grid.js","import $ from 'jquery';\nimport Slick from './slick.core';\n\nexport default GroupItemMetadataProvider;\n\n/***\n * Provides item metadata for group (Slick.Group) and totals (Slick.Totals) rows produced by the DataView.\n * This metadata overrides the default behavior and formatting of those rows so that they appear and function\n * correctly when processed by the grid.\n *\n * This class also acts as a grid plugin providing event handlers to expand & collapse groups.\n * If \"grid.registerPlugin(...)\" is not called, expand & collapse will not work.\n *\n * @class GroupItemMetadataProvider\n * @module Data\n * @namespace Slick.Data\n * @constructor\n * @param options\n */\nfunction GroupItemMetadataProvider(options){\n let _grid;\n let _defaults = {\n groupCssClass: \"slick-group\",\n groupTitleCssClass: \"slick-group-title\",\n totalsCssClass: \"slick-group-totals\",\n groupFocusable: true,\n totalsFocusable: false,\n toggleCssClass: \"slick-group-toggle\",\n toggleExpandedCssClass: \"expanded\",\n toggleCollapsedCssClass: \"collapsed\",\n enableExpandCollapse: true,\n groupFormatter: defaultGroupCellFormatter,\n totalsFormatter: defaultTotalsCellFormatter\n };\n\n options = $.extend(true, {}, _defaults, options);\n\n function defaultGroupCellFormatter(row, cell, value, columnDef, item){\n if (!options.enableExpandCollapse){\n return item.title;\n }\n\n let indentation = item.level * 15 + \"px\";\n\n return \"\" +\n \"\" +\n \"\" +\n item.title +\n \"\";\n }\n\n function defaultTotalsCellFormatter(row, cell, value, columnDef, item){\n return (columnDef.groupTotalsFormatter && columnDef.groupTotalsFormatter(item, columnDef)) || \"\";\n }\n\n function init(grid){\n _grid = grid;\n _grid.onClick.subscribe(handleGridClick);\n _grid.onKeyDown.subscribe(handleGridKeyDown);\n }\n\n function destroy(){\n if (_grid){\n _grid.onClick.unsubscribe(handleGridClick);\n _grid.onKeyDown.unsubscribe(handleGridKeyDown);\n }\n }\n\n function handleGridClick(e, args){\n let item = this.getDataItem(args.row);\n if (item && item instanceof Slick.Group && $(e.target).hasClass(options.toggleCssClass)){\n let range = _grid.getRenderedRange();\n this.getData().setRefreshHints({\n ignoreDiffsBefore: range.top,\n ignoreDiffsAfter: range.bottom + 1\n });\n\n if (item.collapsed){\n this.getData().expandGroup(item.groupingKey);\n } else {\n this.getData().collapseGroup(item.groupingKey);\n }\n\n e.stopImmediatePropagation();\n e.preventDefault();\n }\n }\n\n // TODO: add -/+ handling\n function handleGridKeyDown(e){\n if (options.enableExpandCollapse && (e.which == Slick.keyCode.SPACE)){\n let activeCell = this.getActiveCell();\n if (activeCell){\n let item = this.getDataItem(activeCell.row);\n if (item && item instanceof Slick.Group){\n let range = _grid.getRenderedRange();\n this.getData().setRefreshHints({\n ignoreDiffsBefore: range.top,\n ignoreDiffsAfter: range.bottom + 1\n });\n\n if (item.collapsed){\n this.getData().expandGroup(item.groupingKey);\n } else {\n this.getData().collapseGroup(item.groupingKey);\n }\n\n e.stopImmediatePropagation();\n e.preventDefault();\n }\n }\n }\n }\n\n function getGroupRowMetadata(item){\n return {\n selectable: false,\n focusable: options.groupFocusable,\n cssClasses: options.groupCssClass,\n columns: {\n 0: {\n colspan: \"*\",\n formatter: options.groupFormatter,\n editor: null\n }\n }\n };\n }\n\n function getTotalsRowMetadata(item){\n return {\n selectable: false,\n focusable: options.totalsFocusable,\n cssClasses: options.totalsCssClass,\n formatter: options.totalsFormatter,\n editor: null\n };\n }\n\n return {\n init,\n destroy,\n getGroupRowMetadata,\n getTotalsRowMetadata\n };\n}\n\n\n\n// WEBPACK FOOTER //\n// ../src/slick.groupmetadataprovider.js","module.exports = require(\"flatpickr\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"flatpickr\"\n// module id = 32\n// module chunks = 0"],"sourceRoot":""}
\ No newline at end of file
+{"version":3,"sources":["webpack:///slick.es6.min.js","webpack:///webpack/bootstrap 8c7bca7696891a656754","webpack:///../src/slick.core.js","webpack:///external \"jquery\"","webpack:///../plugins/slick.cellrangedecorator/slick.cellrangedecorator.js","webpack:///../plugins/slick.cellrangeselector/slick.cellrangeselector.js","webpack:///../src/interact.js","webpack:///../plugins/index.js","webpack:///../plugins/slick.autotooltips/index.js","webpack:///../plugins/slick.autotooltips/slick.autotooltips.js","webpack:///../plugins/slick.cellcopymanager/index.js","webpack:///../plugins/slick.cellcopymanager/slick.cellcopymanager.js","webpack:///../plugins/slick.cellrangedecorator/index.js","webpack:///../plugins/slick.cellrangeselector/index.js","webpack:///../plugins/slick.cellselectionmodel/index.js","webpack:///../plugins/slick.cellselectionmodel/slick.cellselectionmodel.js","webpack:///../plugins/slick.checkboxselectcolumn/index.js","webpack:///../plugins/slick.checkboxselectcolumn/slick.checkboxselectcolumn.js","webpack:///../plugins/slick.headerbuttons/index.js","webpack:///../plugins/slick.headerbuttons/slick.headerbuttons.js","webpack:///../plugins/slick.headermenu/index.js","webpack:///../plugins/slick.headermenu/slick.headermenu.js","webpack:///../plugins/slick.rowmovemanager/index.js","webpack:///../plugins/slick.rowmovemanager/slick.rowmovemanager.js","webpack:///../plugins/slick.rowselectionmodel/index.js","webpack:///../plugins/slick.rowselectionmodel/slick.rowselectionmodel.js","webpack:///../src/index.js","webpack:///../src/slick-frozen.grid.js","webpack:///../src/slick.dataview.js","webpack:///../src/slick.editors.js","webpack:///../src/slick.formatters.js","webpack:///../src/slick.grid.js","webpack:///../src/slick.groupmetadataprovider.js","webpack:///external \"flatpickr\""],"names":["e","a","i","exports","modules","__webpack_require__","moduleId","installedModules","module","id","loaded","call","m","c","p","EventData","isPropagationStopped","isImmediatePropagationStopped","this","stopPropagation","stopImmediatePropagation","Event","handlers","subscribe","fn","push","unsubscribe","length","splice","notify","args","scope","returnValue","EventHandler","event","handler","unsubscribeAll","Range","fromRow","fromCell","toRow","toCell","undefined","Math","min","max","isSingleRow","isSingleCell","contains","row","cell","toString","NonDataItem","__nonDataRow","Group","__group","level","count","value","title","collapsed","totals","rows","groups","groupingKey","GroupTotals","__groupTotals","group","initialized","EditorLock","activeEditController","isActive","editController","activate","commitCurrentEdit","cancelCurrentEdit","deactivate","TreeColumns","treeColumns","init","mapToId","columns","forEach","column","columnsById","filter","node","condition","valid","sort","grid","b","indexA","getOrDefault","getColumnIndex","indexB","getDepth","getColumnsInDepth","depth","current","n","extractColumns","concat","result","hasOwnProperty","cloneTreeColumns","$","extend","hasDepth","getTreeColumns","getColumnsInGroup","visibleColumns","visible","reOrder","getById","getInIds","ids","map","Object","defineProperty","Slick","NonDataRow","GlobalEditorLock","keyCode","BACKSPACE","DELETE","DOWN","END","ENTER","ESCAPE","HOME","INSERT","LEFT","PAGE_DOWN","PAGE_UP","RIGHT","TAB","UP","SPACE","default","prototype","equals","require","_interopRequireDefault","obj","__esModule","CellRangeDecorator","options","show","range","_elem","_jquery2","css","selectionCss","addClass","selectionCssClass","appendTo","getCanvasNode","from","getCellNodeBox","to","top","left","height","bottom","width","right","hide","remove","_defaults","zIndex","border","assign","_jquery","_slick","CellRangeSelector","_decorator","_slick4","_grid","_canvas","_handler","onDragInit","handleDragInit","onDragStart","handleDragStart","onDrag","handleDrag","onDragEnd","handleDragEnd","destroy","dd","jqueryEvent","interactEvent","getCellFromEvent","originalEvent","_self","onBeforeCellRangeSelected","canCellBeSelected","_dragging","focus","start","getCellFromPoint","x0","offset","y0","_range","end","_slick2","pageX","pageY","onCellRangeSelected","_slick3","_typeof","Symbol","iterator","constructor","realWindow","blank","isElement","o","_window","getWindow","window","test","Element","nodeType","nodeName","isWindow","thing","Window","isDocFrag","DocumentFragment","isArray","isObject","isFunction","isNumber","isBool","isString","trySelector","document","querySelector","dest","source","prop","pointerExtend","deprecated","vendor","prefixedPropREs","indexOf","copyCoords","src","page","x","y","client","timeStamp","setEventXY","targetObj","pointers","interaction","pointer","pointerAverage","getPageXY","tmpXY","getClientXY","Date","getTime","setEventDeltas","prev","cur","dt","speed","hypot","vx","vy","isNativePointer","supportsTouch","Touch","getXY","type","xy","isOperaMobile","scrollX","scrollY","getScrollXY","win","documentElement","scrollLeft","scrollTop","getPointerId","pointerId","identifier","getActualElement","element","SVGElementInstance","correspondingUseElement","rootNode","ownerDocument","defaultView","parentWindow","getElementClientRect","clientRect","SVGElement","getBoundingClientRect","getClientRects","getElementRect","isIOS7","scroll","getTouchPair","touches","changedTouches","average","clientX","clientY","screenX","screenY","touchBBox","minX","minY","maxX","maxY","touchDistance","deltaSource","defaultOptions","sourceX","sourceY","dx","dy","touchAngle","prevAngle","angle","atan","PI","dr","drClamped","getOriginXY","interactable","origin","parentElement","getRect","closest","_getQBezierValue","t","p1","p2","p3","iT","getQuadraticCurvePoint","startX","startY","cpX","cpY","endX","endY","position","easeOutQuad","d","nodeContains","parent","child","parentNode","selector","matchesSelector","host","inContext","_context","testIgnore","interactableElement","ignoreFrom","matchesUpTo","testAllow","allowFrom","checkAxis","axis","thisAxis","drag","checkSnap","action","snap","enabled","checkRestrict","restrict","checkAutoScroll","autoScroll","withinInteractionLimit","maxActions","name","maxPerElement","activeInteractions","targetCount","targetElementCount","len","interactions","otherAction","prepared","active","interacting","maxInteractions","target","indexOfDeepestElement","elements","dropzone","deepestZone","index","deepestZoneParents","dropzoneParents","unshift","HTMLElement","SVGSVGElement","ownerSVGElement","parents","lastChild","previousSibling","Interaction","dropTarget","dropElement","prevDropTarget","prevDropElement","edges","matches","matchElements","inertiaStatus","smoothEnd","ending","startEvent","upCoords","xe","ye","sx","sy","t0","vx0","vys","duration","resumeDx","resumeDy","lambda_v0","one_ve_v0","Function","bind","boundInertiaFrame","inertiaFrame","boundSmoothEndFrame","smoothEndFrame","that","activeDrops","dropzones","rects","pointerIds","downTargets","downTimes","holdTimers","prevCoords","curCoords","startCoords","pointerDelta","downEvent","downPointer","_eventTarget","_curEventTarget","prevEvent","tapTime","prevTap","startOffset","restrictOffset","snapOffsets","gesture","startDistance","prevDistance","distance","scale","startAngle","snapStatus","realX","realY","snappedX","snappedY","targets","locked","changed","restrictStatus","restrictedX","restrictedY","restricted","pointerIsDown","pointerWasMoved","gesturing","dragging","resizing","resizeAxes","mouse","getInteractionFromPointer","eventType","eventTarget","mouseEvent","pointerType","inertia","allowResume","supportsPointerEvent","doOnInteractions","method","path","curEventTarget","currentTarget","prevTouchTime","_updateEventTargets","InteractEvent","phase","related","starting","coords","relativePoints","elementRect","clientX0","clientY0","ctrlKey","altKey","shiftKey","metaKey","button","buttons","detail","relatedTarget","zeroResumeDelta","resize","square","axes","box","ds","da","prevScale","velocityX","velocityY","atan2","overlap","up","down","swipe","velocity","preventOriginalDefault","preventDefault","getActionCursor","cursor","actionCursors","cursorKey","edgeNames","checkResizeEdge","rect","margin","defaultActionChecker","resizeEdges","shouldResize","actionIsEnabled","resizeOptions","edge","validateAction","actionName","delegateListener","useCapture","fakeEvent","delegated","delegatedEvents","selectors","context","contexts","listeners","j","delegateUseCapture","interact","interactables","get","Interactable","_element","_iEvents","Node","events","add","pEventTypes","pointerDown","move","pointerHover","_doc","documents","listenToDocument","set","warnOnce","message","warned","console","warn","apply","arguments","endAllInteractions","pointerEnd","doc","PointerEvent","MSPointerEvent","over","out","cancel","selectorDown","pointerMove","pointerOver","pointerOut","pointerUp","pointerCancel","autoScrollMove","frameElement","parentDoc","error","windowParentError","checkAndPreventDefault","useAttachEvent","currentAction","array","nodeList","ie8MatchesSelector","replace","prefixedMatchesSelector","limit","el","createTextNode","wrap","sqrt","dynamicDrop","base","accept","actionChecker","styleCursor","dropChecker","manualStart","Infinity","drop","preserveAspectRatio","NaN","invert","perAction","endOnly","offsets","container","resistance","minSpeed","endSpeed","smoothEndDuration","_holdDuration","now","dtx","prevTimeX","dty","prevTimeY","scrollBy","isScrolling","cancelFrame","reqFrame","stop","DocumentTouch","navigator","userAgent","pointerMoveTolerance","all","atob","resizex","resizey","resizexy","resizetop","resizeleft","resizebottom","resizeright","resizetopleft","resizebottomright","resizetopright","resizebottomleft","wheelEvent","eventTypes","globalEvents","appName","match","platform","appVersion","requestAnimationFrame","cancelAnimationFrame","listener","elementIndex","typeCount","attachedListeners","supplied","wrapped","useCount","ret","listenerIndex","immediatePropagationStopped","srcElement","preventDef","stopProp","stopImmProp","addEvent","on","Boolean","removeEvent","cancelBubble","_elements","_targets","_attachedListeners","webkit","ptr","pushCurMatches","curMatches","curMatchElements","prevTargetElement","addPointer","elementInteractable","elementAction","getAction","forEachSelector","validateSelector","style","pushMatches","querySelectorAll","eventCopy","pointerIndex","setTimeout","pointerHold","collectEventTargets","forceAction","newAction","setModifications","preEnd","shouldMove","shouldSnap","shouldRestrict","setSnapping","setRestriction","setStartOffsets","snapOffset","pageUp","clientUp","inertiaPosition","recordPointer","duplicateMove","clearTimeout","absX","abs","absY","targetAxis","thisInteraction","getDraggable","selectorInteractable","dragStart","dragEvent","fire","setActiveDrops","dropEvents","getDropEvents","fireActiveDrops","dragMove","draggableElement","getDrop","leave","enter","resizeStart","resizeEvent","startRect","linkedEdges","_linkedEdges","resizeStartAspectRatio","resizeRects","previous","delta","deltaRect","resizeMove","invertible","originalEdges","swap","gestureStart","gestureEvent","gestureMove","isNaN","removePointer","ie8Dblclick","endEvent","inertiaOptions","pointerSpeed","inertiaPossible","endSnap","endRestrict","snapRestrict","vy0","v0","calcInertia","statusObject","useStatusXY","modifiedXe","modifiedYe","collectDrops","drops","dropElements","currentElement","prevElement","dragElement","possibleDrops","validDrops","dropCheck","dropIndex","pointerEvent","draggable","dragLeave","prevDropzone","dragEnter","dragmove","clearTargets","lambda","te","progress","exp","quadPoint","collectSelectors","els","isSet","firePointers","interval","createNewDoubleTap","originalPointer","double","propagationStopped","doubleTap","matchElement","pageCoords","status","relIndex","relative","inRange","snapChanged","restriction","prevent","inertiaDur","log","innerWidth","innerHeight","interactionListeners","indexOfElement","callback","setOnEvents","phases","ondrop","ondropactivate","ondropdeactivate","ondragenter","ondragleave","ondropmove","onstart","onmove","onend","oninertiastart","setPerAction","option","checker","dropped","dropOverlap","horizontal","vertical","dragRect","cx","cy","overlapArea","overlapRatio","newValue","resizable","squareResize","gesturable","actions","setOptions","thisOption","mode","createSnapGrid","gridOffset","anchors","paths","elementOrigin","allActions","rectChecker","iEvent","onEvent","funcName","search","trim","split","off","eventList","matchFound","useCap","methods","perActions","settings","setting","unset","enableDragging","enableResizing","enableGesturing","debug","downTime","getPointerAverage","getTouchBBox","getTouchDistance","getTouchAngle","newvalue","offsetX","offsetY","gridx","round","gridy","newX","newY","elems","lastTime","vendors","currTime","timeToCall","RowSelectionModel","RowMoveManager","HeaderMenu","HeaderButtons","CheckboxSelectColumn","CellSelectionModel","CellCopyManager","AutoTooltips","_slick5","_slick6","_slick7","_slick8","_slick9","_slick10","_slick11","_slick12","_slick13","_slick14","_slick15","_slick16","_slick17","_slick18","_slick19","_slick20","enableForCells","onMouseEnter","handleMouseEnter","enableForHeaderCells","onHeaderMouseEnter","handleHeaderMouseEnter","$node","getCellNode","text","scrollWidth","maxToolTipLength","substr","attr","toolTip","onKeyDown","handleKeyDown","ranges","getEditorLock","which","_copiedRanges","clearCopySelection","onCopyCancelled","getSelectionModel","getSelectedRanges","markCopySelection","onCopyCells","onPasteCells","getColumns","hash","k","setCellCssStyles","removeCellCssStyles","_options","onActiveCellChanged","handleActiveCellChange","registerPlugin","_selector","handleCellRangeSelected","handleBeforeCellRangeSelected","unregisterPlugin","removeInvalidRanges","r","setSelectedRanges","_ranges","onSelectedRangesChanged","selectActiveCell","last","getActiveCell","pop","dRow","dCell","dirRow","dirCell","new_last","viewRow","viewCell","scrollRowIntoView","scrollCellIntoView","onSelectedRowsChanged","handleSelectedRowsChanged","onClick","handleClick","onHeaderClick","handleHeaderClick","selectedRows","getSelectedRows","lookup","_selectedRowsLookup","invalidateRow","render","getDataLength","updateColumnHeader","columnId","toggleRowSelection","is","setSelectedRows","grep","getColumnDefinition","field","sortable","cssClass","formatter","checkboxSelectionFormatter","columnDef","dataContext","onHeaderCellRendered","handleHeaderCellRendered","onBeforeHeaderCellDestroy","handleBeforeHeaderCellDestroy","setColumns","header","btn","buttonCssClass","data","showOnHover","image","tooltip","command","handleButtonClick","classList","find","onCommand","body","handleBodyMouseDown","unbind","$menu","hideMenu","$activeHeaderColumn","removeClass","menu","$el","buttonImage","showMenu","$menuButton","onBeforeMenuShow","getContainerNode","empty","items","item","$li","handleMenuItemClick","disabled","$icon","iconCssClass","iconImage","cancelEditOnDrag","behavior","inArray","rowHeight","getOptions","selectionProxy","guide","insertBefore","eventData","onBeforeMoveRows","canMove","onMoveRows","wrapHandler","_inHandler","rangesToRows","rowsToRanges","lastCell","getRowsRange","selectActiveRow","activeRow","canCellBeActive","multiSelect","selection","idx","setActiveCell","_interopRequireWildcard","newObj","key","Plugins","FrozenGrid","Grid","Data","Formatters","Editors","_slickFrozen","_slickFrozen2","_plugins","SlickGrid","$container","Error","maxSupportedCssHeight","getMaxSupportedCssHeight","scrollbarDimensions","measureScrollbar","defaults","validateAndEnforceOptions","columnDefaults","defaultColumnWidth","minWidth","maxWidth","uid","$focusSink","$paneHeaderL","$paneHeaderR","$paneTopL","$paneTopR","$paneBottomL","$paneBottomR","$headerScrollerL","$headerScrollerR","$headerScroller","$groupHeadersL","$groupHeadersR","$groupHeaders","$headerL","$headerR","$headers","$headerRowScrollerL","$headerRowScrollerR","$headerRowScroller","$headerRowSpacerL","getCanvasWidth","$headerRowSpacerR","$headerRowL","$headerRowR","$headerRow","$topPanelScrollerL","$topPanelScrollerR","$topPanelScroller","$topPanelL","$topPanelR","$topPanel","showTopPanel","showHeaderRow","$viewportTopL","$viewportTopR","$viewportBottomL","$viewportBottomR","$viewport","$activeViewportNode","$canvasTopL","$canvasTopR","$canvasBottomL","$canvasBottomR","$canvas","$activeCanvasNode","$footerRowScrollerR","$footerRowScrollerL","$footerRowScroller","$footerRowSpacerL","$footerRowSpacerR","$footerRowL","$footerRowR","$footerRow","showFooterRow","$focusSink2","clone","explicitInitialization","finishInitialization","getViewportWidth","getViewportHeight","measureCellPaddingAndBorder","disableSelection","enableTextSelectionOnCells","setFrozenOptions","setPaneVisibility","setScroller","setOverflow","updateColumnCaches","createColumnHeaders","createColumnGroupHeaders","createColumnFooter","setupColumnSort","createCssRules","resizeCanvas","bindAncestorScrollEvents","handleScroll","mousewheel","frozenColumn","hasFrozenRows","handleMouseWheel","handleHeaderContextMenu","delegate","handleHeaderMouseLeave","handleHeaderRowScroll","handleFooterRowScroll","handleDblClick","handleContextMenu","handleMouseLeave","_interact2","toLowerCase","hasFrozenColumns","plugin","plugins","self","setSelectionModel","model","selectionModel","handleSelectedRangesChanged","getActiveCanvasNode","setActiveCanvasNode","getCanvases","getViewportNode","getActiveViewportNode","setActiveViewPortNode","setActiveViewportNode","$c","dim","clientWidth","clientHeight","getHeadersWidth","headersWidth","headersWidthL","headersWidthR","ii","viewportW","getHeadersWidthL","getHeadersWidthR","availableWidth","viewportHasVScroll","canvasWidthL","canvasWidthR","totalRowWidth","fullWidthRows","updateCanvasWidth","forceColumnWidthsUpdate","widthChanged","oldCanvasWidth","canvasWidth","oldCanvasWidthL","oldCanvasWidthR","viewportHasHScroll","applyColumnWidths","$target","jquery","supportedHeight","testUpTo","div","elem","frozenBottom","scrollHeight","$elem","$boundAncestors","handleActiveCellPositionChange","unbindAncestorScrollEvents","$header","children","eq","trigger","html","getHeaderRow","getHeaderRowColumn","$headerRowTarget","getFooterRow","getFooterRowColumn","$footerRowTarget","$footer","each","onBeforeFooterRowCellDestroy","footerRowCell","onFooterRowCellRendered","columnsLength","frozenColumnsValid","groupColumns","indexGroup","headerCssClass","alert","applyColumnGroupHeaderWidths","onMouseLeave","onBeforeHeaderRowCellDestroy","$headerTarget","headerColumnWidthDiff","enableColumnReorder","append","headerRowCell","onHeaderRowCellRendered","setSortColumns","sortColumns","setupColumnResize","setupColumnReorder","click","hasClass","$col","sortOpts","sortAsc","multiColumnSort","defaultSortAsc","onSort","sortCols","col","sortCol","currentPositionInHeader","currentPosition","limitPositionInGroup","idColumn","groupColumnOfPreviousPosition","startLimit","endLimit","some","groupColumn","arr","lastIndexOf","columnPositionValidInGroup","$item","positionValid","placeholder","createElement","className","offsetWidth","offsetHeight","after","marginLeft","transform","validPositionInGroup","removeChild","newColumns","removeData","onColumnsReordered","impactedColumns","getImpactedColumns","columnElements","firstResizable","lastResizable","forceFitColumns","$handle","activeColumn","previousWidth","autosizeColumns","applyColumnHeaderWidths","syncColumnCellResize","invalidateAllRows","onColumnsResized","getVBoxDelta","val","parseFloat","parseInt","frozenRow","numVisibleRows","frozenRowsHeight","dataLength","actualFrozenRow","overflow-x","overflow-y","$headerScrollContainer","$headerRowScrollContainer","$footerRowScrollContainer","$viewportScrollContainerX","$viewportScrollContainerY","h","v","headerColumnHeightDiff","cellWidthDiff","cellHeightDiff","absoluteColumnMinWidth","$style","rules","topPanelHeight","headerRowHeight","footerRowHeight","styleSheet","cssText","join","appendChild","getColumnCssRules","stylesheet","sheets","styleSheets","ownerNode","owningElement","columnCssRulesL","columnCssRulesR","columnIdx","cssRules","selectorText","exec","removeCssRules","onBeforeDestroy","evt","editorLock","getEditController","prevTotal","widths","shrinkLeeway","total","availWidth","shrinkProportion","absMinWidth","shrinkSize","floor","growProportion","growSize","currentWidth","reRender","rerenderOnResize","$groupHeader","currentColumnIndex","$groupHeaderColumn","$headerColumn","next","outerWidth","headers","w","rule","setSortColumn","ascending","cols","headerColumnEls","columnIndex","getSortColumns","selectedCellCssClass","columnPosLeft","columnPosRight","columnDefinitions","_treeColumns","makeActiveCellNormal","enableAddRow","zombieRowNodeFromLastMouseWheelEvent","autoHeight","leaveSpaceForNewRows","setData","newData","scrollToTop","updateRowCount","scrollTo","getData","getLength","getDataLengthIncludingAddNew","getDataItem","getItem","getTopPanel","setTopPanelVisibility","slideDown","slideUp","setHeaderRowVisibility","setFooterRowVisibility","fadeIn","getRowTop","getRowFromPosition","th","oldOffset","ph","cj","newScrollTop","getVisibleRange","cleanupRows","updateRowPositions","prevScrollTop","vScrollDir","lastRenderedScrollTop","onViewportChanged","defaultFormatter","getFormatter","rowMetadata","getItemMetadata","columnOverrides","formatterFactory","callFormatter","metadata","columnData","getEditor","columnMetadata","editor","editorFactory","getDataItemValueForColumn","dataItemColumnValueExtractor","appendRowHtml","stringArrayL","stringArrayR","dataLoading","rowCss","addNewRowCssClass","cssClasses","frozenRowOffset","getFrozenRowOffset","rowHtml","colspan","leftPx","rightPx","appendCellHtml","stringArray","cellCss","activeCell","cellCssClasses","rowsCache","cellRenderQueue","cellColSpans","rangeToKeep","removeFrozenRow","removeRowFromCache","invalidate","currentEditor","cacheEntry","rowNodeFromLastMouseWheelEvent","rowNode","postProcessedRows","renderedRows","counter_rows_removed","invalidateRows","rl","updateCell","cellNode","loadValue","innerHTML","invalidatePostProcessingResults","updateRow","ensureCellNodesInRowsCache","cellNodesByColumnIdx","viewportH","outerHeight","topPanelH","headerRowH","footerRowH","ceil","paneTopH","paneBottomH","viewportTopH","viewportBottomH","paneBottomTop","lastRenderedScrollLeft","dataLengthIncludingAddNew","numberOfRows","oldH","tempViewportH","oldViewportHasVScroll","l","activeCellNode","resetActiveCell","oldScrollTopInRange","viewportTop","viewportLeft","getRenderedRange","buffer","minBuffer","$lastNode","cleanUpCells","totalCellsRemoved","cellsToRemove","cellToRemove","cleanUpAndRenderCells","cellsAdded","processedRows","totalCellsAdded","btm","processedRow","renderRows","needToReselectCell","counter_rows_rendered","xRight","firstChild","startPostProcessing","enableAsyncPostRender","h_postrender","asyncPostProcessRows","asyncPostRenderDelay","postProcessFromRow","postProcessToRow","rendered","renderedFrozenRows","h_render","deltaX","deltaY","$rowNode","$gridCanvas","zombieRow","handled","_handleScroll","isMouseWheel","maxScrollDistanceY","maxScrollDistanceX","hasFrozenCols","vScrollDist","hScrollDist","prevScrollLeft","forceSyncScrolling","onScroll","asyncPostRender","updateCellCssStylesOnRenderedRows","addedHash","removedHash","addedRowHash","removedRowHash","addCellCssStyles","onCellCssStylesChanged","prevHash","getCellCssStyles","flashCell","toggleCellClass","times","$cell","queue","toggleClass","cellFlashingCssClass","dequeue","cellExists","retval","navigatePrev","cancelEditAndSetFocus","navigatePageDown","navigatePageUp","navigateLeft","navigateRight","navigateUp","navigateDown","navigateNext","editable","commitEditAndSetFocus","makeActiveCellEditable","activeElement","setFocus","setActiveCellInternal","onContextMenu","onDblClick","gotoCell","onHeaderMouseLeave","onHeaderContextMenu","getCellFromNode","cls","getRowFromNode","rowOffset","isBottom","y1","y2","x1","x2","tabbingDirection","doPaging","getColspan","scrollRight","newCell","opt_editMode","activeCellChanged","$activeCellNode","$activeCellOffset","activePosX","autoEdit","isCellPotentiallyEditable","h_editorLoader","asyncEditorLoading","asyncEditorLoadDelay","scrollActiveCellIntoView","clearTextSelection","getSelection","sel","removeAllRanges","cannotTriggerInsert","onBeforeCellEditorDestroy","onBeforeEditCell","gridPosition","absBox","commitChanges","cancelChanges","serializedEditorValue","serializeValue","offsetTop","offsetLeft","offsetParent","getActiveCellPosition","getGridPosition","onActiveCellPositionChanged","cellBox","getCellEditor","getActiveCellNode","viewportScrollH","rowAtTop","rowAtBottom","scrollRowToTop","scrollPage","dir","deltaRows","enableCellNavigation","prevCell","prevActivePosX","findFirstFocusableCell","findLastFocusableCell","lastFocusableCell","gotoRight","posX","gotoLeft","firstFocusableCell","pos","gotoDown","gotoUp","gotoNext","gotoPrev","lastSelectableCell","navigate","tabbingDirections","stepFunctions","stepFn","isAddNewRow","focusable","selectable","forceEdit","isValueChanged","validationResults","validate","editCommand","serializedValue","prevSerializedValue","execute","applyValue","onCellChange","undo","editCommandHandler","newItem","onAddNewRow","onValidationError","random","s","eval","expr","slickGridVersion","getViewport","editActiveCell","_interact","DataView","beginUpdate","suspend","endUpdate","refresh","setRefreshHints","hints","refreshHints","setFilterArgs","filterArgs","updateIdxById","startingIndex","idProperty","idxById","ensureIdUniqueness","getItems","setItems","objectIdProperty","filteredItems","setPagingOptions","pageSize","pagesize","pagenum","totalRows","pageNum","onPagingInfoChanged","getPagingInfo","totalPages","dataView","comparer","sortComparer","fastSortField","reverse","fastSort","oldToString","reSort","setFilter","filterFn","inlineFilters","compiledFilter","compileFilter","compiledFilterWithCaching","compileFilterWithCaching","getGrouping","groupingInfos","setGrouping","groupingInfo","groupItemMetadataProvider","GroupItemMetadataProvider","toggledGroupsByLevel","Array","gi","groupingInfoDefaults","getterIsAFn","getter","compiledAccumulators","aggregators","compileAccumulatorLoop","groupBy","valueGetter","valueFormatter","setAggregators","groupAggregators","includeCollapsed","aggregateCollapsed","getItemByIdx","getIdxById","ensureRowsByIdCache","rowsById","getRowById","getItemById","mapIdsToRows","idArray","mapRowsToIds","rowArray","updateItem","updated","insertItem","addItem","deleteItem","displayTotalsRow","calculateTotals","getGroupRowMetadata","getTotalsRowMetadata","expandCollapseAllGroups","collapse","collapseAllGroups","expandAllGroups","expandCollapseGroup","collapseGroup","letArgs","slice","arg0","groupingDelimiter","expandGroup","getGroups","extractGroups","parentGroup","groupsByVal","predefinedValues","isLeafLevel","agg","aggregateChildGroups","storeResult","addGroupTotals","lazyTotalsCalculation","addTotals","groupCollapsed","toggledGroups","g","aggregateEmpty","flattenGroupedRows","groupedRows","gl","jj","getFunctionInfo","fnRegex","params","aggregator","accumulatorInfo","accumulate","displayName","filterInfo","filterPath1","filterPath2","filterBody","tpl","uncompiledFilter","uncompiledFilterWithCaching","cache","getFilteredAndPagedItems","batchFilter","batchFilterWithCaching","isFilterNarrowing","isFilterExpanding","filterCache","isFilterUnchanged","paged","getRowDiffs","newRows","eitherIsNonData","diff","ignoreDiffsBefore","ignoreDiffsAfter","recalc","_items","prevRefreshHints","countBefore","totalRowsBefore","onRowCountChanged","onRowsChanged","syncGridSelection","preserveHidden","preserveHiddenOnSelectionChange","setSelectedRowIds","rowIds","selectedRowIds","onSelectedRowIdsChanged","update","inHandler","newSelectedRowIds","existing","syncGridCellCssStyles","storeCellCssStyles","hashById","newHash","AvgAggregator","field_","count_","nonNullCount_","sum_","groupTotals","avg","MinAggregator","min_","MaxAggregator","max_","SumAggregator","sum","Aggregators","Avg","Min","Max","Sum","GroupMetaDataProvider","TextEditor","$input","defaultValue","select","getValue","setValue","state","msg","validator","IntegerEditor","FloatEditor","getDecimalPlaces","rtn","editorFixedDecimalPlaces","DefaultDecimalPlaces","decPlaces","toFixed","DateEditor","flatInstance","defaultDate","date","_flatpickr2","open","positionCalendar","close","YesNoSelectEditor","$select","CheckboxEditor","LongTextEditor","$wrapper","save","_flatpickr","Text","Integer","Float","YesNoSelect","Checkbox","LongText","PercentCompleteFormatter","PercentCompleteBarFormatter","color","YesNoFormatter","CheckmarkFormatter","PercentComplete","PercentCompleteBar","YesNo","Checkmark","cacheCssForHiddenInit","$headerRowSpacer","createFooterRow","$footerRowSpacer","restoreCssFromHiddenInit","$hiddenParents","addBack","not","old","cssShow","oldProps","rowWidth","verArray","jQueryNewWidthBehaviour","sheet","addCSSRule","insertRule","addRule","enableAsyncPostRenderCleanup","startPostProcessingCleanup","queuePostProcessedRowForCleanup","postProcessedRow","rowIdx","postProcessgroupId","postProcessedCleanupQueue","actionType","groupId","detach","queuePostProcessedCellForCleanup","cellnode","display","zombieRowCacheFromLastMouseWheelEvent","zombieRowPostProcessedFromLastMouseWheelEvent","h_postrenderCleanup","asyncPostProcessCleanupRows","asyncPostRenderCleanupDelay","processedStatus","entry","shift","asyncPostRenderCleanup","keyCaptureList","useEditor","suppressClearOnEdit","visibility","defaultGroupCellFormatter","enableExpandCollapse","indentation","toggleCssClass","toggleCollapsedCssClass","toggleExpandedCssClass","groupTitleCssClass","defaultTotalsCellFormatter","groupTotalsFormatter","handleGridClick","handleGridKeyDown","groupFocusable","groupCssClass","0","groupFormatter","totalsFocusable","totalsCssClass","totalsFormatter"],"mappings":"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","file":"slick.es6.min.js","sourcesContent":["(function(e, a) { for(var i in a) e[i] = a[i]; }(exports, /******/ (function(modules) { // webpackBootstrap\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n/******/\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId])\n/******/ \t\t\treturn installedModules[moduleId].exports;\n/******/\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\texports: {},\n/******/ \t\t\tid: moduleId,\n/******/ \t\t\tloaded: false\n/******/ \t\t};\n/******/\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.loaded = true;\n/******/\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/\n/******/\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n/******/\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n/******/\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = \"/\";\n/******/\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(0);\n/******/ })\n/************************************************************************/\n/******/ ([\n/* 0 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\tmodule.exports = __webpack_require__(25);\n\n\n/***/ }),\n/* 1 */\n/***/ (function(module, exports) {\n\n\t\"use strict\";\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t/** *\r\n\t * Contains core SlickGrid classes.\r\n\t * @module Core\r\n\t * @namespace Slick\r\n\t */\n\tvar Slick = {\n\t Event: Event,\n\t EventData: EventData,\n\t EventHandler: EventHandler,\n\t Range: Range,\n\t NonDataRow: NonDataItem,\n\t Group: Group,\n\t GroupTotals: GroupTotals,\n\t EditorLock: EditorLock,\n\t /** *\r\n\t * A global singleton editor lock.\r\n\t * @class GlobalEditorLock\r\n\t * @static\r\n\t * @constructor\r\n\t */\n\t GlobalEditorLock: new EditorLock(),\n\t TreeColumns: TreeColumns,\n\t\n\t keyCode: {\n\t BACKSPACE: 8,\n\t DELETE: 46,\n\t DOWN: 40,\n\t END: 35,\n\t ENTER: 13,\n\t ESCAPE: 27,\n\t HOME: 36,\n\t INSERT: 45,\n\t LEFT: 37,\n\t PAGE_DOWN: 34,\n\t PAGE_UP: 33,\n\t RIGHT: 39,\n\t TAB: 9,\n\t UP: 38,\n\t SPACE: 32\n\t }\n\t};\n\t\n\texports.default = Slick;\n\t\n\t/***\r\n\t * An event object for passing data to event handlers and letting them control propagation.\r\n\t *
This is pretty much identical to how W3C and jQuery implement events.
\r\n\t * @class EventData\r\n\t * @constructor\r\n\t */\n\t\n\tfunction EventData() {\n\t var isPropagationStopped = false;\n\t var isImmediatePropagationStopped = false;\n\t\n\t /***\r\n\t * Stops event from propagating up the DOM tree.\r\n\t * @method stopPropagation\r\n\t */\n\t this.stopPropagation = function () {\n\t isPropagationStopped = true;\n\t };\n\t\n\t /***\r\n\t * Returns whether stopPropagation was called on this event object.\r\n\t * @method isPropagationStopped\r\n\t * @return {Boolean}\r\n\t */\n\t this.isPropagationStopped = function () {\n\t return isPropagationStopped;\n\t };\n\t\n\t /***\r\n\t * Prevents the rest of the handlers from being executed.\r\n\t * @method stopImmediatePropagation\r\n\t */\n\t this.stopImmediatePropagation = function () {\n\t isImmediatePropagationStopped = true;\n\t };\n\t\n\t /***\r\n\t * Returns whether stopImmediatePropagation was called on this event object.\\\r\n\t * @method isImmediatePropagationStopped\r\n\t * @return {Boolean}\r\n\t */\n\t this.isImmediatePropagationStopped = function () {\n\t return isImmediatePropagationStopped;\n\t };\n\t}\n\t\n\t/***\r\n\t * A simple publisher-subscriber implementation.\r\n\t * @class Event\r\n\t * @constructor\r\n\t */\n\tfunction Event() {\n\t var handlers = [];\n\t\n\t /***\r\n\t * Adds an event handler to be called when the event is fired.\r\n\t *
Event handler will receive two arguments - an EventData and the data\r\n\t * object the event was fired with.
\r\n\t * @method subscribe\r\n\t * @param fn {Function} Event handler.\r\n\t */\n\t this.subscribe = function (fn) {\n\t handlers.push(fn);\n\t };\n\t\n\t /***\r\n\t * Removes an event handler added with subscribe(fn).\r\n\t * @method unsubscribe\r\n\t * @param fn {Function} Event handler to be removed.\r\n\t */\n\t this.unsubscribe = function (fn) {\n\t for (var i = handlers.length - 1; i >= 0; i--) {\n\t if (handlers[i] === fn) {\n\t handlers.splice(i, 1);\n\t }\n\t }\n\t };\n\t\n\t /***\r\n\t * Fires an event notifying all subscribers.\r\n\t * @method notify\r\n\t * @param args {Object} Additional data object to be passed to all handlers.\r\n\t * @param e {EventData}\r\n\t * Optional.\r\n\t * An EventData object to be passed to all handlers.\r\n\t * For DOM events, an existing W3C/jQuery event object can be passed in.\r\n\t * @param scope {Object}\r\n\t * Optional.\r\n\t * The scope (\"this\") within which the handler will be executed.\r\n\t * If not specified, the scope will be set to the Event instance.\r\n\t */\n\t this.notify = function (args, e, scope) {\n\t e = e || new EventData();\n\t scope = scope || this;\n\t\n\t var returnValue;\n\t for (var i = 0; i < handlers.length && !(e.isPropagationStopped() || e.isImmediatePropagationStopped()); i++) {\n\t returnValue = handlers[i].call(scope, e, args);\n\t }\n\t\n\t return returnValue;\n\t };\n\t}\n\t\n\tfunction EventHandler() {\n\t var handlers = [];\n\t\n\t this.subscribe = function (event, handler) {\n\t handlers.push({\n\t event: event,\n\t handler: handler\n\t });\n\t event.subscribe(handler);\n\t\n\t return this; // allow chaining\n\t };\n\t\n\t this.unsubscribe = function (event, handler) {\n\t var i = handlers.length;\n\t while (i--) {\n\t if (handlers[i].event === event && handlers[i].handler === handler) {\n\t handlers.splice(i, 1);\n\t event.unsubscribe(handler);\n\t return;\n\t }\n\t }\n\t\n\t return this; // allow chaining\n\t };\n\t\n\t this.unsubscribeAll = function () {\n\t var i = handlers.length;\n\t while (i--) {\n\t handlers[i].event.unsubscribe(handlers[i].handler);\n\t }\n\t handlers = [];\n\t\n\t return this; // allow chaining\n\t };\n\t}\n\t\n\t/***\r\n\t * A structure containing a range of cells.\r\n\t * @class Range\r\n\t * @constructor\r\n\t * @param fromRow {Integer} Starting row.\r\n\t * @param fromCell {Integer} Starting cell.\r\n\t * @param toRow {Integer} Optional. Ending row. Defaults to fromRow.\r\n\t * @param toCell {Integer} Optional. Ending cell. Defaults to fromCell.\r\n\t */\n\tfunction Range(fromRow, fromCell, toRow, toCell) {\n\t if (toRow === undefined && toCell === undefined) {\n\t toRow = fromRow;\n\t toCell = fromCell;\n\t }\n\t\n\t /***\r\n\t * @property fromRow\r\n\t * @type {Integer}\r\n\t */\n\t this.fromRow = Math.min(fromRow, toRow);\n\t\n\t /***\r\n\t * @property fromCell\r\n\t * @type {Integer}\r\n\t */\n\t this.fromCell = Math.min(fromCell, toCell);\n\t\n\t /***\r\n\t * @property toRow\r\n\t * @type {Integer}\r\n\t */\n\t this.toRow = Math.max(fromRow, toRow);\n\t\n\t /***\r\n\t * @property toCell\r\n\t * @type {Integer}\r\n\t */\n\t this.toCell = Math.max(fromCell, toCell);\n\t\n\t /***\r\n\t * Returns whether a range represents a single row.\r\n\t * @method isSingleRow\r\n\t * @return {Boolean}\r\n\t */\n\t this.isSingleRow = function () {\n\t return this.fromRow == this.toRow;\n\t };\n\t\n\t /***\r\n\t * Returns whether a range represents a single cell.\r\n\t * @method isSingleCell\r\n\t * @return {Boolean}\r\n\t */\n\t this.isSingleCell = function () {\n\t return this.fromRow == this.toRow && this.fromCell == this.toCell;\n\t };\n\t\n\t /***\r\n\t * Returns whether a range contains a given cell.\r\n\t * @method contains\r\n\t * @param row {Integer}\r\n\t * @param cell {Integer}\r\n\t * @return {Boolean}\r\n\t */\n\t this.contains = function (row, cell) {\n\t return row >= this.fromRow && row <= this.toRow && cell >= this.fromCell && cell <= this.toCell;\n\t };\n\t\n\t /***\r\n\t * Returns a readable representation of a range.\r\n\t * @method toString\r\n\t * @return {String}\r\n\t */\n\t this.toString = function () {\n\t if (this.isSingleCell()) {\n\t return \"(\" + this.fromRow + \":\" + this.fromCell + \")\";\n\t } else {\n\t return \"(\" + this.fromRow + \":\" + this.fromCell + \" - \" + this.toRow + \":\" + this.toCell + \")\";\n\t }\n\t };\n\t}\n\t\n\t/***\r\n\t * A base class that all special / non-data rows (like Group and GroupTotals) derive from.\r\n\t * @class NonDataItem\r\n\t * @constructor\r\n\t */\n\tfunction NonDataItem() {\n\t this.__nonDataRow = true;\n\t}\n\t\n\t/***\r\n\t * Information about a group of rows.\r\n\t * @class Group\r\n\t * @extends Slick.NonDataItem\r\n\t * @constructor\r\n\t */\n\tfunction Group() {\n\t this.__group = true;\n\t\n\t /**\r\n\t * Grouping level, starting with 0.\r\n\t * @property level\r\n\t * @type {Number}\r\n\t */\n\t this.level = 0;\n\t\n\t /***\r\n\t * Number of rows in the group.\r\n\t * @property count\r\n\t * @type {Integer}\r\n\t */\n\t this.count = 0;\n\t\n\t /***\r\n\t * Grouping value.\r\n\t * @property value\r\n\t * @type {Object}\r\n\t */\n\t this.value = null;\n\t\n\t /***\r\n\t * Formatted display value of the group.\r\n\t * @property title\r\n\t * @type {String}\r\n\t */\n\t this.title = null;\n\t\n\t /***\r\n\t * Whether a group is collapsed.\r\n\t * @property collapsed\r\n\t * @type {Boolean}\r\n\t */\n\t this.collapsed = false;\n\t\n\t /***\r\n\t * GroupTotals, if any.\r\n\t * @property totals\r\n\t * @type {GroupTotals}\r\n\t */\n\t this.totals = null;\n\t\n\t /**\r\n\t * Rows that are part of the group.\r\n\t * @property rows\r\n\t * @type {Array}\r\n\t */\n\t this.rows = [];\n\t\n\t /**\r\n\t * Sub-groups that are part of the group.\r\n\t * @property groups\r\n\t * @type {Array}\r\n\t */\n\t this.groups = null;\n\t\n\t /**\r\n\t * A unique key used to identify the group. This key can be used in calls to DataView\r\n\t * collapseGroup() or expandGroup().\r\n\t * @property groupingKey\r\n\t * @type {Object}\r\n\t */\n\t this.groupingKey = null;\n\t}\n\t\n\tGroup.prototype = new NonDataItem();\n\t\n\t/***\r\n\t * Compares two Group instances.\r\n\t * @method equals\r\n\t * @return {Boolean}\r\n\t * @param group {Group} Group instance to compare to.\r\n\t */\n\tGroup.prototype.equals = function (group) {\n\t return this.value === group.value && this.count === group.count && this.collapsed === group.collapsed && this.title === group.title;\n\t};\n\t\n\t/***\r\n\t * Information about group totals.\r\n\t * An instance of GroupTotals will be created for each totals row and passed to the aggregators\r\n\t * so that they can store arbitrary data in it. That data can later be accessed by group totals\r\n\t * formatters during the display.\r\n\t * @class GroupTotals\r\n\t * @extends Slick.NonDataItem\r\n\t * @constructor\r\n\t */\n\tfunction GroupTotals() {\n\t this.__groupTotals = true;\n\t\n\t /***\r\n\t * Parent Group.\r\n\t * @param group\r\n\t * @type {Group}\r\n\t */\n\t this.group = null;\n\t\n\t /***\r\n\t * Whether the totals have been fully initialized / calculated.\r\n\t * Will be set to false for lazy-calculated group totals.\r\n\t * @param initialized\r\n\t * @type {Boolean}\r\n\t */\n\t this.initialized = false;\n\t}\n\t\n\tGroupTotals.prototype = new NonDataItem();\n\t\n\t/***\r\n\t * A locking helper to track the active edit controller and ensure that only a single controller\r\n\t * can be active at a time. This prevents a whole class of state and validation synchronization\r\n\t * issues. An edit controller (such as SlickGrid) can query if an active edit is in progress\r\n\t * and attempt a commit or cancel before proceeding.\r\n\t * @class EditorLock\r\n\t * @constructor\r\n\t */\n\tfunction EditorLock() {\n\t var activeEditController = null;\n\t\n\t /***\r\n\t * Returns true if a specified edit controller is active (has the edit lock).\r\n\t * If the parameter is not specified, returns true if any edit controller is active.\r\n\t * @method isActive\r\n\t * @param editController {EditController}\r\n\t * @return {Boolean}\r\n\t */\n\t this.isActive = function (editController) {\n\t return editController ? activeEditController === editController : activeEditController !== null;\n\t };\n\t\n\t /***\r\n\t * Sets the specified edit controller as the active edit controller (acquire edit lock).\r\n\t * If another edit controller is already active, and exception will be thrown.\r\n\t * @method activate\r\n\t * @param editController {EditController} edit controller acquiring the lock\r\n\t */\n\t this.activate = function (editController) {\n\t if (editController === activeEditController) {\n\t // already activated?\n\t return;\n\t }\n\t if (activeEditController !== null) {\n\t throw \"SlickGrid.EditorLock.activate: an editController is still active, can't activate another editController\";\n\t }\n\t if (!editController.commitCurrentEdit) {\n\t throw \"SlickGrid.EditorLock.activate: editController must implement .commitCurrentEdit()\";\n\t }\n\t if (!editController.cancelCurrentEdit) {\n\t throw \"SlickGrid.EditorLock.activate: editController must implement .cancelCurrentEdit()\";\n\t }\n\t activeEditController = editController;\n\t };\n\t\n\t /***\r\n\t * Unsets the specified edit controller as the active edit controller (release edit lock).\r\n\t * If the specified edit controller is not the active one, an exception will be thrown.\r\n\t * @method deactivate\r\n\t * @param editController {EditController} edit controller releasing the lock\r\n\t */\n\t this.deactivate = function (editController) {\n\t if (activeEditController !== editController) {\n\t throw \"SlickGrid.EditorLock.deactivate: specified editController is not the currently active one\";\n\t }\n\t activeEditController = null;\n\t };\n\t\n\t /***\r\n\t * Attempts to commit the current edit by calling \"commitCurrentEdit\" method on the active edit\r\n\t * controller and returns whether the commit attempt was successful (commit may fail due to validation\r\n\t * errors, etc.). Edit controller's \"commitCurrentEdit\" must return true if the commit has succeeded\r\n\t * and false otherwise. If no edit controller is active, returns true.\r\n\t * @method commitCurrentEdit\r\n\t * @return {Boolean}\r\n\t */\n\t this.commitCurrentEdit = function () {\n\t return activeEditController ? activeEditController.commitCurrentEdit() : true;\n\t };\n\t\n\t /***\r\n\t * Attempts to cancel the current edit by calling \"cancelCurrentEdit\" method on the active edit\r\n\t * controller and returns whether the edit was successfully cancelled. If no edit controller is\r\n\t * active, returns true.\r\n\t * @method cancelCurrentEdit\r\n\t * @return {Boolean}\r\n\t */\n\t this.cancelCurrentEdit = function cancelCurrentEdit() {\n\t return activeEditController ? activeEditController.cancelCurrentEdit() : true;\n\t };\n\t}\n\t\n\t/**\r\n\t *\r\n\t * @param {Array} treeColumns Array com levels of columns\r\n\t * @returns {{hasDepth: 'hasDepth', getTreeColumns: 'getTreeColumns', extractColumns: 'extractColumns', getDepth: 'getDepth', getColumnsInDepth: 'getColumnsInDepth', getColumnsInGroup: 'getColumnsInGroup', visibleColumns: 'visibleColumns', filter: 'filter', reOrder: reOrder}}\r\n\t * @constructor\r\n\t */\n\tfunction TreeColumns(treeColumns) {\n\t\n\t var columnsById = {};\n\t\n\t function init() {\n\t mapToId(treeColumns);\n\t }\n\t\n\t function mapToId(columns) {\n\t columns.forEach(function (column) {\n\t columnsById[column.id] = column;\n\t\n\t if (column.columns) mapToId(column.columns);\n\t });\n\t }\n\t\n\t function filter(node, condition) {\n\t\n\t return node.filter(function (column) {\n\t\n\t var valid = condition.call(column);\n\t\n\t if (valid && column.columns) column.columns = filter(column.columns, condition);\n\t\n\t return valid && (!column.columns || column.columns.length);\n\t });\n\t }\n\t\n\t function sort(columns, grid) {\n\t columns.sort(function (a, b) {\n\t var indexA = getOrDefault(grid.getColumnIndex(a.id)),\n\t indexB = getOrDefault(grid.getColumnIndex(b.id));\n\t\n\t return indexA - indexB;\n\t }).forEach(function (column) {\n\t if (column.columns) sort(column.columns, grid);\n\t });\n\t }\n\t\n\t function getOrDefault(value) {\n\t return typeof value === 'undefined' ? -1 : value;\n\t }\n\t\n\t function getDepth(node) {\n\t if (node.length) for (var i in node) {\n\t return getDepth(node[i]);\n\t } else if (node.columns) return 1 + getDepth(node.columns);else return 1;\n\t }\n\t\n\t function getColumnsInDepth(node, depth, current) {\n\t var columns = [];\n\t current = current || 0;\n\t\n\t if (depth == current) {\n\t\n\t if (node.length) node.forEach(function (n) {\n\t if (n.columns) n.extractColumns = function () {\n\t return extractColumns(n);\n\t };\n\t });\n\t\n\t return node;\n\t } else for (var i in node) {\n\t if (node[i].columns) {\n\t columns = columns.concat(getColumnsInDepth(node[i].columns, depth, current + 1));\n\t }\n\t }return columns;\n\t }\n\t\n\t function extractColumns(node) {\n\t var result = [];\n\t\n\t if (node.hasOwnProperty('length')) {\n\t\n\t for (var i = 0; i < node.length; i++) {\n\t result = result.concat(extractColumns(node[i]));\n\t }\n\t } else {\n\t\n\t if (node.hasOwnProperty('columns')) result = result.concat(extractColumns(node.columns));else return node;\n\t }\n\t\n\t return result;\n\t }\n\t\n\t function cloneTreeColumns() {\n\t return $.extend(true, [], treeColumns);\n\t }\n\t\n\t init();\n\t\n\t this.hasDepth = function () {\n\t\n\t for (var i in treeColumns) {\n\t if (treeColumns[i].hasOwnProperty('columns')) return true;\n\t }return false;\n\t };\n\t\n\t this.getTreeColumns = function () {\n\t return treeColumns;\n\t };\n\t\n\t this.extractColumns = function () {\n\t return this.hasDepth() ? extractColumns(treeColumns) : treeColumns;\n\t };\n\t\n\t this.getDepth = function () {\n\t return getDepth(treeColumns);\n\t };\n\t\n\t this.getColumnsInDepth = function (depth) {\n\t return getColumnsInDepth(treeColumns, depth);\n\t };\n\t\n\t this.getColumnsInGroup = function (groups) {\n\t return extractColumns(groups);\n\t };\n\t\n\t this.visibleColumns = function () {\n\t return filter(cloneTreeColumns(), function () {\n\t return this.visible;\n\t });\n\t };\n\t\n\t this.filter = function (condition) {\n\t return filter(cloneTreeColumns(), condition);\n\t };\n\t\n\t this.reOrder = function (grid) {\n\t return sort(treeColumns, grid);\n\t };\n\t\n\t this.getById = function (id) {\n\t return columnsById[id];\n\t };\n\t\n\t this.getInIds = function (ids) {\n\t return ids.map(function (id) {\n\t return columnsById[id];\n\t });\n\t };\n\t}\n\n/***/ }),\n/* 2 */\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"jquery\");\n\n/***/ }),\n/* 3 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _jquery = __webpack_require__(2);\n\t\n\tvar _jquery2 = _interopRequireDefault(_jquery);\n\t\n\tvar _slick = __webpack_require__(1);\n\t\n\tvar _slick2 = _interopRequireDefault(_slick);\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\t\n\texports.default = CellRangeDecorator;\n\t\n\t/** *\r\n\t * Displays an overlay on top of a given cell range.\r\n\t *\r\n\t * TODO:\r\n\t * Currently, it blocks mouse events to DOM nodes behind it.\r\n\t * Use FF and WebKit-specific 'pointer-events' CSS style, or some kind of event forwarding.\r\n\t * Could also construct the borders separately using 4 individual DIVs.\r\n\t *\r\n\t * @param {Grid} grid\r\n\t * @param {Object} options\r\n\t */\n\t\n\tfunction CellRangeDecorator(grid, options) {\n\t var _elem = void 0;\n\t var _defaults = {\n\t selectionCssClass: 'slick-range-decorator',\n\t selectionCss: {\n\t zIndex: '9999',\n\t border: '2px dashed red'\n\t }\n\t };\n\t\n\t options = Object.assign({}, _defaults, options);\n\t\n\t function show(range) {\n\t if (!_elem) {\n\t _elem = (0, _jquery2.default)('
', { css: options.selectionCss }).addClass(options.selectionCssClass).css('position', 'absolute').appendTo(grid.getCanvasNode());\n\t }\n\t\n\t var from = grid.getCellNodeBox(range.fromRow, range.fromCell);\n\t var to = grid.getCellNodeBox(range.toRow, range.toCell);\n\t\n\t _elem.css({\n\t top: from.top - 1,\n\t left: from.left - 1,\n\t height: to.bottom - from.top - 2,\n\t width: to.right - from.left - 2\n\t });\n\t\n\t return _elem;\n\t }\n\t\n\t function hide() {\n\t if (_elem) {\n\t _elem.remove();\n\t _elem = null;\n\t }\n\t }\n\t\n\t Object.assign(this, {\n\t show: show,\n\t hide: hide\n\t });\n\t}\n\n/***/ }),\n/* 4 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _jquery = __webpack_require__(2);\n\t\n\tvar _jquery2 = _interopRequireDefault(_jquery);\n\t\n\tvar _slick = __webpack_require__(1);\n\t\n\tvar _slick2 = _interopRequireDefault(_slick);\n\t\n\tvar _slick3 = __webpack_require__(3);\n\t\n\tvar _slick4 = _interopRequireDefault(_slick3);\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\t\n\texports.default = CellRangeSelector;\n\t\n\t\n\tfunction CellRangeSelector(options) {\n\t var _grid = void 0;\n\t var _canvas = void 0;\n\t var _dragging = void 0;\n\t var _decorator = void 0;\n\t var _range = {};\n\t\n\t var _self = this;\n\t var _handler = new _slick2.default.EventHandler();\n\t var _defaults = {\n\t selectionCss: {\n\t // 'border': '2px dashed blue'\n\t }\n\t };\n\t\n\t function init(grid) {\n\t options = Object.assign({}, _defaults, options);\n\t _decorator = new _slick4.default(grid, options);\n\t _grid = grid;\n\t _canvas = _grid.getCanvasNode();\n\t _handler.subscribe(_grid.onDragInit, handleDragInit).subscribe(_grid.onDragStart, handleDragStart).subscribe(_grid.onDrag, handleDrag).subscribe(_grid.onDragEnd, handleDragEnd);\n\t }\n\t\n\t function destroy() {\n\t _handler.unsubscribeAll();\n\t }\n\t\n\t function handleDragInit(e, dd) {\n\t // prevent the grid from cancelling drag'n'drop by default\n\t e.stopImmediatePropagation();\n\t }\n\t\n\t function handleDragStart(jqueryEvent, interactEvent) {\n\t var cell = _grid.getCellFromEvent(interactEvent.originalEvent);\n\t if (_self.onBeforeCellRangeSelected.notify(cell) !== false) {\n\t if (_grid.canCellBeSelected(cell.row, cell.cell)) {\n\t _dragging = true;\n\t // jqueryEvent.stopImmediatePropagation();\n\t }\n\t }\n\t if (!_dragging) {\n\t return;\n\t }\n\t\n\t _grid.focus();\n\t\n\t var start = _grid.getCellFromPoint(interactEvent.x0 - (0, _jquery2.default)(_canvas).offset().left, interactEvent.y0 - (0, _jquery2.default)(_canvas).offset().top);\n\t\n\t _range = {\n\t start: start,\n\t end: {}\n\t };\n\t\n\t return _decorator.show(new _slick2.default.Range(start.row, start.cell));\n\t }\n\t\n\t function handleDrag(e, interactEvent) {\n\t if (!_dragging) {\n\t return;\n\t }\n\t // e.stopImmediatePropagation();\n\t\n\t var end = _grid.getCellFromPoint(interactEvent.pageX - (0, _jquery2.default)(_canvas).offset().left, interactEvent.pageY - (0, _jquery2.default)(_canvas).offset().top);\n\t\n\t if (!_grid.canCellBeSelected(end.row, end.cell)) {\n\t return;\n\t }\n\t\n\t _range.end = end;\n\t _decorator.show(new _slick2.default.Range(_range.start.row, _range.start.cell, end.row, end.cell));\n\t }\n\t\n\t function handleDragEnd(e) {\n\t if (!_dragging) {\n\t return;\n\t }\n\t\n\t _dragging = false;\n\t // e.stopImmediatePropagation();\n\t\n\t _decorator.hide();\n\t _self.onCellRangeSelected.notify({\n\t range: new _slick2.default.Range(_range.start.row, _range.start.cell, _range.end.row, _range.end.cell)\n\t });\n\t _range = {};\n\t }\n\t\n\t Object.assign(this, {\n\t init: init,\n\t destroy: destroy,\n\t\n\t onBeforeCellRangeSelected: new _slick2.default.Event(),\n\t onCellRangeSelected: new _slick2.default.Event()\n\t });\n\t}\n\n/***/ }),\n/* 5 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tvar _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; };\n\t\n\t/**\r\n\t * interact.js v1.2.6\r\n\t *\r\n\t * Copyright (c) 2012-2015 Taye Adeyemi \r\n\t * Open source under the MIT License.\r\n\t * https://raw.github.com/taye/interact.js/master/LICENSE\r\n\t *\r\n\t * This file has been monkey patched to pass the originalEvent on to drag events\r\n\t */\n\t(function (realWindow) {\n\t 'use strict';\n\t\n\t // return early if there's no window to work with (eg. Node.js)\n\t\n\t if (!realWindow) {\n\t return;\n\t }\n\t\n\t var // get wrapped window if using Shadow DOM polyfill\n\t window = function () {\n\t // create a TextNode\n\t var el = realWindow.document.createTextNode('');\n\t\n\t // check if it's wrapped by a polyfill\n\t if (el.ownerDocument !== realWindow.document && typeof realWindow.wrap === 'function' && realWindow.wrap(el) === el) {\n\t // return wrapped window\n\t return realWindow.wrap(realWindow);\n\t }\n\t\n\t // no Shadow DOM polyfil or native implementation\n\t return realWindow;\n\t }(),\n\t document = window.document,\n\t DocumentFragment = window.DocumentFragment || blank,\n\t SVGElement = window.SVGElement || blank,\n\t SVGSVGElement = window.SVGSVGElement || blank,\n\t SVGElementInstance = window.SVGElementInstance || blank,\n\t HTMLElement = window.HTMLElement || window.Element,\n\t PointerEvent = window.PointerEvent || window.MSPointerEvent,\n\t pEventTypes,\n\t hypot = Math.hypot || function (x, y) {\n\t return Math.sqrt(x * x + y * y);\n\t },\n\t tmpXY = {},\n\t // reduce object creation in getXY()\n\t\n\t documents = [],\n\t // all documents being listened to\n\t\n\t interactables = [],\n\t // all set interactables\n\t interactions = [],\n\t // all interactions\n\t\n\t dynamicDrop = false,\n\t\n\t\n\t // {\n\t // type: {\n\t // selectors: ['selector', ...],\n\t // contexts : [document, ...],\n\t // listeners: [[listener, useCapture], ...]\n\t // }\n\t // }\n\t delegatedEvents = {},\n\t defaultOptions = {\n\t base: {\n\t accept: null,\n\t actionChecker: null,\n\t styleCursor: true,\n\t preventDefault: 'auto',\n\t origin: { x: 0, y: 0 },\n\t deltaSource: 'page',\n\t allowFrom: null,\n\t ignoreFrom: null,\n\t _context: document,\n\t dropChecker: null\n\t },\n\t\n\t drag: {\n\t enabled: false,\n\t manualStart: true,\n\t max: Infinity,\n\t maxPerElement: 1,\n\t\n\t snap: null,\n\t restrict: null,\n\t inertia: null,\n\t autoScroll: null,\n\t\n\t axis: 'xy'\n\t },\n\t\n\t drop: {\n\t enabled: false,\n\t accept: null,\n\t overlap: 'pointer'\n\t },\n\t\n\t resize: {\n\t enabled: false,\n\t manualStart: false,\n\t max: Infinity,\n\t maxPerElement: 1,\n\t\n\t snap: null,\n\t restrict: null,\n\t inertia: null,\n\t autoScroll: null,\n\t\n\t square: false,\n\t preserveAspectRatio: false,\n\t axis: 'xy',\n\t\n\t // use default margin\n\t margin: NaN,\n\t\n\t // object with props left, right, top, bottom which are\n\t // true/false values to resize when the pointer is over that edge,\n\t // CSS selectors to match the handles for each direction\n\t // or the Elements for each handle\n\t edges: null,\n\t\n\t // a value of 'none' will limit the resize rect to a minimum of 0x0\n\t // 'negate' will alow the rect to have negative width/height\n\t // 'reposition' will keep the width/height positive by swapping\n\t // the top and bottom edges and/or swapping the left and right edges\n\t invert: 'none'\n\t },\n\t\n\t gesture: {\n\t manualStart: false,\n\t enabled: false,\n\t max: Infinity,\n\t maxPerElement: 1,\n\t\n\t restrict: null\n\t },\n\t\n\t perAction: {\n\t manualStart: false,\n\t max: Infinity,\n\t maxPerElement: 1,\n\t\n\t snap: {\n\t enabled: false,\n\t endOnly: false,\n\t range: Infinity,\n\t targets: null,\n\t offsets: null,\n\t\n\t relativePoints: null\n\t },\n\t\n\t restrict: {\n\t enabled: false,\n\t endOnly: false\n\t },\n\t\n\t autoScroll: {\n\t enabled: false,\n\t container: null, // the item that is scrolled (Window or HTMLElement)\n\t margin: 60,\n\t speed: 300 // the scroll speed in pixels per second\n\t },\n\t\n\t inertia: {\n\t enabled: false,\n\t resistance: 10, // the lambda in exponential decay\n\t minSpeed: 100, // target speed must be above this for inertia to start\n\t endSpeed: 10, // the speed at which inertia is slow enough to stop\n\t allowResume: true, // allow resuming an action in inertia phase\n\t zeroResumeDelta: true, // if an action is resumed after launch, set dx/dy to 0\n\t smoothEndDuration: 300 // animate to snap/restrict endOnly if there's no inertia\n\t }\n\t },\n\t\n\t _holdDuration: 600\n\t },\n\t\n\t\n\t // Things related to autoScroll\n\t autoScroll = {\n\t interaction: null,\n\t i: null, // the handle returned by window.setInterval\n\t x: 0, y: 0, // Direction each pulse is to scroll in\n\t\n\t // scroll the window by the values in scroll.x/y\n\t scroll: function scroll() {\n\t var options = autoScroll.interaction.target.options[autoScroll.interaction.prepared.name].autoScroll,\n\t container = options.container || getWindow(autoScroll.interaction.element),\n\t now = new Date().getTime(),\n\t\n\t // change in time in seconds\n\t dtx = (now - autoScroll.prevTimeX) / 1000,\n\t dty = (now - autoScroll.prevTimeY) / 1000,\n\t vx,\n\t vy,\n\t sx,\n\t sy;\n\t\n\t // displacement\n\t if (options.velocity) {\n\t vx = options.velocity.x;\n\t vy = options.velocity.y;\n\t } else {\n\t vx = vy = options.speed;\n\t }\n\t\n\t sx = vx * dtx;\n\t sy = vy * dty;\n\t\n\t if (sx >= 1 || sy >= 1) {\n\t if (isWindow(container)) {\n\t container.scrollBy(autoScroll.x * sx, autoScroll.y * sy);\n\t } else if (container) {\n\t container.scrollLeft += autoScroll.x * sx;\n\t container.scrollTop += autoScroll.y * sy;\n\t }\n\t\n\t if (sx >= 1) autoScroll.prevTimeX = now;\n\t if (sy >= 1) autoScroll.prevTimeY = now;\n\t }\n\t\n\t if (autoScroll.isScrolling) {\n\t cancelFrame(autoScroll.i);\n\t autoScroll.i = reqFrame(autoScroll.scroll);\n\t }\n\t },\n\t\n\t isScrolling: false,\n\t prevTimeX: 0,\n\t prevTimeY: 0,\n\t\n\t start: function start(interaction) {\n\t autoScroll.isScrolling = true;\n\t cancelFrame(autoScroll.i);\n\t\n\t autoScroll.interaction = interaction;\n\t autoScroll.prevTimeX = new Date().getTime();\n\t autoScroll.prevTimeY = new Date().getTime();\n\t autoScroll.i = reqFrame(autoScroll.scroll);\n\t },\n\t\n\t stop: function stop() {\n\t autoScroll.isScrolling = false;\n\t cancelFrame(autoScroll.i);\n\t }\n\t },\n\t\n\t\n\t // Does the browser support touch input?\n\t supportsTouch = 'ontouchstart' in window || window.DocumentTouch && document instanceof window.DocumentTouch,\n\t\n\t\n\t // Does the browser support PointerEvents\n\t supportsPointerEvent = PointerEvent && !/Chrome/.test(navigator.userAgent),\n\t\n\t\n\t // Less Precision with touch input\n\t margin = supportsTouch || supportsPointerEvent ? 20 : 10,\n\t pointerMoveTolerance = 1,\n\t\n\t\n\t // for ignoring browser's simulated mouse events\n\t prevTouchTime = 0,\n\t\n\t\n\t // Allow this many interactions to happen simultaneously\n\t maxInteractions = Infinity,\n\t\n\t\n\t // Check if is IE9 or older\n\t actionCursors = document.all && !window.atob ? {\n\t drag: 'move',\n\t resizex: 'e-resize',\n\t resizey: 's-resize',\n\t resizexy: 'se-resize',\n\t\n\t resizetop: 'n-resize',\n\t resizeleft: 'w-resize',\n\t resizebottom: 's-resize',\n\t resizeright: 'e-resize',\n\t resizetopleft: 'se-resize',\n\t resizebottomright: 'se-resize',\n\t resizetopright: 'ne-resize',\n\t resizebottomleft: 'ne-resize',\n\t\n\t gesture: ''\n\t } : {\n\t drag: 'move',\n\t resizex: 'ew-resize',\n\t resizey: 'ns-resize',\n\t resizexy: 'nwse-resize',\n\t\n\t resizetop: 'ns-resize',\n\t resizeleft: 'ew-resize',\n\t resizebottom: 'ns-resize',\n\t resizeright: 'ew-resize',\n\t resizetopleft: 'nwse-resize',\n\t resizebottomright: 'nwse-resize',\n\t resizetopright: 'nesw-resize',\n\t resizebottomleft: 'nesw-resize',\n\t\n\t gesture: ''\n\t },\n\t actionIsEnabled = {\n\t drag: true,\n\t resize: true,\n\t gesture: true\n\t },\n\t\n\t\n\t // because Webkit and Opera still use 'mousewheel' event type\n\t wheelEvent = 'onmousewheel' in document ? 'mousewheel' : 'wheel',\n\t eventTypes = ['dragstart', 'dragmove', 'draginertiastart', 'dragend', 'dragenter', 'dragleave', 'dropactivate', 'dropdeactivate', 'dropmove', 'drop', 'resizestart', 'resizemove', 'resizeinertiastart', 'resizeend', 'gesturestart', 'gesturemove', 'gestureinertiastart', 'gestureend', 'down', 'move', 'up', 'cancel', 'tap', 'doubletap', 'hold'],\n\t globalEvents = {},\n\t\n\t\n\t // Opera Mobile must be handled differently\n\t isOperaMobile = navigator.appName == 'Opera' && supportsTouch && navigator.userAgent.match('Presto'),\n\t\n\t\n\t // scrolling doesn't change the result of getClientRects on iOS 7\n\t isIOS7 = /iP(hone|od|ad)/.test(navigator.platform) && /OS 7[^\\d]/.test(navigator.appVersion),\n\t\n\t\n\t // prefix matchesSelector\n\t prefixedMatchesSelector = 'matches' in Element.prototype ? 'matches' : 'webkitMatchesSelector' in Element.prototype ? 'webkitMatchesSelector' : 'mozMatchesSelector' in Element.prototype ? 'mozMatchesSelector' : 'oMatchesSelector' in Element.prototype ? 'oMatchesSelector' : 'msMatchesSelector',\n\t\n\t\n\t // will be polyfill function if browser is IE8\n\t ie8MatchesSelector,\n\t\n\t\n\t // native requestAnimationFrame or polyfill\n\t reqFrame = realWindow.requestAnimationFrame,\n\t cancelFrame = realWindow.cancelAnimationFrame,\n\t\n\t\n\t // Events wrapper\n\t events = function () {\n\t var useAttachEvent = 'attachEvent' in window && !('addEventListener' in window),\n\t addEvent = useAttachEvent ? 'attachEvent' : 'addEventListener',\n\t removeEvent = useAttachEvent ? 'detachEvent' : 'removeEventListener',\n\t on = useAttachEvent ? 'on' : '',\n\t elements = [],\n\t targets = [],\n\t attachedListeners = [];\n\t\n\t function add(element, type, listener, useCapture) {\n\t var elementIndex = indexOf(elements, element),\n\t target = targets[elementIndex];\n\t\n\t if (!target) {\n\t target = {\n\t events: {},\n\t typeCount: 0\n\t };\n\t\n\t elementIndex = elements.push(element) - 1;\n\t targets.push(target);\n\t\n\t attachedListeners.push(useAttachEvent ? {\n\t supplied: [],\n\t wrapped: [],\n\t useCount: []\n\t } : null);\n\t }\n\t\n\t if (!target.events[type]) {\n\t target.events[type] = [];\n\t target.typeCount++;\n\t }\n\t\n\t if (!contains(target.events[type], listener)) {\n\t var ret;\n\t\n\t if (useAttachEvent) {\n\t var listeners = attachedListeners[elementIndex],\n\t listenerIndex = indexOf(listeners.supplied, listener);\n\t\n\t var wrapped = listeners.wrapped[listenerIndex] || function (event) {\n\t if (!event.immediatePropagationStopped) {\n\t event.target = event.srcElement;\n\t event.currentTarget = element;\n\t\n\t event.preventDefault = event.preventDefault || preventDef;\n\t event.stopPropagation = event.stopPropagation || stopProp;\n\t event.stopImmediatePropagation = event.stopImmediatePropagation || stopImmProp;\n\t\n\t if (/mouse|click/.test(event.type)) {\n\t event.pageX = event.clientX + getWindow(element).document.documentElement.scrollLeft;\n\t event.pageY = event.clientY + getWindow(element).document.documentElement.scrollTop;\n\t }\n\t\n\t listener(event);\n\t }\n\t };\n\t\n\t ret = element[addEvent](on + type, wrapped, Boolean(useCapture));\n\t\n\t if (listenerIndex === -1) {\n\t listeners.supplied.push(listener);\n\t listeners.wrapped.push(wrapped);\n\t listeners.useCount.push(1);\n\t } else {\n\t listeners.useCount[listenerIndex]++;\n\t }\n\t } else {\n\t ret = element[addEvent](type, listener, useCapture || false);\n\t }\n\t target.events[type].push(listener);\n\t\n\t return ret;\n\t }\n\t }\n\t\n\t function remove(element, type, listener, useCapture) {\n\t var i,\n\t elementIndex = indexOf(elements, element),\n\t target = targets[elementIndex],\n\t listeners,\n\t listenerIndex,\n\t wrapped = listener;\n\t\n\t if (!target || !target.events) {\n\t return;\n\t }\n\t\n\t if (useAttachEvent) {\n\t listeners = attachedListeners[elementIndex];\n\t listenerIndex = indexOf(listeners.supplied, listener);\n\t wrapped = listeners.wrapped[listenerIndex];\n\t }\n\t\n\t if (type === 'all') {\n\t for (type in target.events) {\n\t if (target.events.hasOwnProperty(type)) {\n\t remove(element, type, 'all');\n\t }\n\t }\n\t return;\n\t }\n\t\n\t if (target.events[type]) {\n\t var len = target.events[type].length;\n\t\n\t if (listener === 'all') {\n\t for (i = 0; i < len; i++) {\n\t remove(element, type, target.events[type][i], Boolean(useCapture));\n\t }\n\t return;\n\t } else {\n\t for (i = 0; i < len; i++) {\n\t if (target.events[type][i] === listener) {\n\t element[removeEvent](on + type, wrapped, useCapture || false);\n\t target.events[type].splice(i, 1);\n\t\n\t if (useAttachEvent && listeners) {\n\t listeners.useCount[listenerIndex]--;\n\t if (listeners.useCount[listenerIndex] === 0) {\n\t listeners.supplied.splice(listenerIndex, 1);\n\t listeners.wrapped.splice(listenerIndex, 1);\n\t listeners.useCount.splice(listenerIndex, 1);\n\t }\n\t }\n\t\n\t break;\n\t }\n\t }\n\t }\n\t\n\t if (target.events[type] && target.events[type].length === 0) {\n\t target.events[type] = null;\n\t target.typeCount--;\n\t }\n\t }\n\t\n\t if (!target.typeCount) {\n\t targets.splice(elementIndex, 1);\n\t elements.splice(elementIndex, 1);\n\t attachedListeners.splice(elementIndex, 1);\n\t }\n\t }\n\t\n\t function preventDef() {\n\t this.returnValue = false;\n\t }\n\t\n\t function stopProp() {\n\t this.cancelBubble = true;\n\t }\n\t\n\t function stopImmProp() {\n\t this.cancelBubble = true;\n\t this.immediatePropagationStopped = true;\n\t }\n\t\n\t return {\n\t add: add,\n\t remove: remove,\n\t useAttachEvent: useAttachEvent,\n\t\n\t _elements: elements,\n\t _targets: targets,\n\t _attachedListeners: attachedListeners\n\t };\n\t }();\n\t\n\t function blank() {}\n\t\n\t function isElement(o) {\n\t if (!o || (typeof o === 'undefined' ? 'undefined' : _typeof(o)) !== 'object') {\n\t return false;\n\t }\n\t\n\t var _window = getWindow(o) || window;\n\t\n\t return (/object|function/.test(_typeof(_window.Element)) ? o instanceof _window.Element // DOM2\n\t : o.nodeType === 1 && typeof o.nodeName === 'string'\n\t );\n\t }\n\t function isWindow(thing) {\n\t return thing === window || !!(thing && thing.Window) && thing instanceof thing.Window;\n\t }\n\t function isDocFrag(thing) {\n\t return !!thing && thing instanceof DocumentFragment;\n\t }\n\t function isArray(thing) {\n\t return isObject(thing) && _typeof(thing.length) !== undefined && isFunction(thing.splice);\n\t }\n\t function isObject(thing) {\n\t return !!thing && (typeof thing === 'undefined' ? 'undefined' : _typeof(thing)) === 'object';\n\t }\n\t function isFunction(thing) {\n\t return typeof thing === 'function';\n\t }\n\t function isNumber(thing) {\n\t return typeof thing === 'number';\n\t }\n\t function isBool(thing) {\n\t return typeof thing === 'boolean';\n\t }\n\t function isString(thing) {\n\t return typeof thing === 'string';\n\t }\n\t\n\t function trySelector(value) {\n\t if (!isString(value)) {\n\t return false;\n\t }\n\t\n\t // an exception will be raised if it is invalid\n\t document.querySelector(value);\n\t return true;\n\t }\n\t\n\t function extend(dest, source) {\n\t for (var prop in source) {\n\t dest[prop] = source[prop];\n\t }\n\t return dest;\n\t }\n\t\n\t var prefixedPropREs = {\n\t webkit: /(Movement[XY]|Radius[XY]|RotationAngle|Force)$/\n\t };\n\t\n\t function pointerExtend(dest, source) {\n\t for (var prop in source) {\n\t var deprecated = false;\n\t\n\t // skip deprecated prefixed properties\n\t for (var vendor in prefixedPropREs) {\n\t if (prop.indexOf(vendor) === 0 && prefixedPropREs[vendor].test(prop)) {\n\t deprecated = true;\n\t break;\n\t }\n\t }\n\t\n\t if (!deprecated) {\n\t dest[prop] = source[prop];\n\t }\n\t }\n\t return dest;\n\t }\n\t\n\t function copyCoords(dest, src) {\n\t dest.page = dest.page || {};\n\t dest.page.x = src.page.x;\n\t dest.page.y = src.page.y;\n\t\n\t dest.client = dest.client || {};\n\t dest.client.x = src.client.x;\n\t dest.client.y = src.client.y;\n\t\n\t dest.timeStamp = src.timeStamp;\n\t }\n\t\n\t function _setEventXY(targetObj, pointers, interaction) {\n\t var pointer = pointers.length > 1 ? pointerAverage(pointers) : pointers[0];\n\t\n\t _getPageXY(pointer, tmpXY, interaction);\n\t targetObj.page.x = tmpXY.x;\n\t targetObj.page.y = tmpXY.y;\n\t\n\t _getClientXY(pointer, tmpXY, interaction);\n\t targetObj.client.x = tmpXY.x;\n\t targetObj.client.y = tmpXY.y;\n\t\n\t targetObj.timeStamp = new Date().getTime();\n\t }\n\t\n\t function setEventDeltas(targetObj, prev, cur) {\n\t targetObj.page.x = cur.page.x - prev.page.x;\n\t targetObj.page.y = cur.page.y - prev.page.y;\n\t targetObj.client.x = cur.client.x - prev.client.x;\n\t targetObj.client.y = cur.client.y - prev.client.y;\n\t targetObj.timeStamp = new Date().getTime() - prev.timeStamp;\n\t\n\t // set pointer velocity\n\t var dt = Math.max(targetObj.timeStamp / 1000, 0.001);\n\t targetObj.page.speed = hypot(targetObj.page.x, targetObj.page.y) / dt;\n\t targetObj.page.vx = targetObj.page.x / dt;\n\t targetObj.page.vy = targetObj.page.y / dt;\n\t\n\t targetObj.client.speed = hypot(targetObj.client.x, targetObj.page.y) / dt;\n\t targetObj.client.vx = targetObj.client.x / dt;\n\t targetObj.client.vy = targetObj.client.y / dt;\n\t }\n\t\n\t function isNativePointer(pointer) {\n\t return pointer instanceof window.Event || supportsTouch && window.Touch && pointer instanceof window.Touch;\n\t }\n\t\n\t // Get specified X/Y coords for mouse or event.touches[0]\n\t function getXY(type, pointer, xy) {\n\t xy = xy || {};\n\t type = type || 'page';\n\t\n\t xy.x = pointer[type + 'X'];\n\t xy.y = pointer[type + 'Y'];\n\t\n\t return xy;\n\t }\n\t\n\t function _getPageXY(pointer, page) {\n\t page = page || {};\n\t\n\t // Opera Mobile handles the viewport and scrolling oddly\n\t if (isOperaMobile && isNativePointer(pointer)) {\n\t getXY('screen', pointer, page);\n\t\n\t page.x += window.scrollX;\n\t page.y += window.scrollY;\n\t } else {\n\t getXY('page', pointer, page);\n\t }\n\t\n\t return page;\n\t }\n\t\n\t function _getClientXY(pointer, client) {\n\t client = client || {};\n\t\n\t if (isOperaMobile && isNativePointer(pointer)) {\n\t // Opera Mobile handles the viewport and scrolling oddly\n\t getXY('screen', pointer, client);\n\t } else {\n\t getXY('client', pointer, client);\n\t }\n\t\n\t return client;\n\t }\n\t\n\t function getScrollXY(win) {\n\t win = win || window;\n\t return {\n\t x: win.scrollX || win.document.documentElement.scrollLeft,\n\t y: win.scrollY || win.document.documentElement.scrollTop\n\t };\n\t }\n\t\n\t function getPointerId(pointer) {\n\t return isNumber(pointer.pointerId) ? pointer.pointerId : pointer.identifier;\n\t }\n\t\n\t function getActualElement(element) {\n\t return element instanceof SVGElementInstance ? element.correspondingUseElement : element;\n\t }\n\t\n\t function getWindow(node) {\n\t if (isWindow(node)) {\n\t return node;\n\t }\n\t\n\t var rootNode = node.ownerDocument || node;\n\t\n\t return rootNode.defaultView || rootNode.parentWindow || window;\n\t }\n\t\n\t function getElementClientRect(element) {\n\t var clientRect = element instanceof SVGElement ? element.getBoundingClientRect() : element.getClientRects()[0];\n\t\n\t return clientRect && {\n\t left: clientRect.left,\n\t right: clientRect.right,\n\t top: clientRect.top,\n\t bottom: clientRect.bottom,\n\t width: clientRect.width || clientRect.right - clientRect.left,\n\t height: clientRect.height || clientRect.bottom - clientRect.top\n\t };\n\t }\n\t\n\t function getElementRect(element) {\n\t var clientRect = getElementClientRect(element);\n\t\n\t if (!isIOS7 && clientRect) {\n\t var scroll = getScrollXY(getWindow(element));\n\t\n\t clientRect.left += scroll.x;\n\t clientRect.right += scroll.x;\n\t clientRect.top += scroll.y;\n\t clientRect.bottom += scroll.y;\n\t }\n\t\n\t return clientRect;\n\t }\n\t\n\t function getTouchPair(event) {\n\t var touches = [];\n\t\n\t // array of touches is supplied\n\t if (isArray(event)) {\n\t touches[0] = event[0];\n\t touches[1] = event[1];\n\t }\n\t // an event\n\t else {\n\t if (event.type === 'touchend') {\n\t if (event.touches.length === 1) {\n\t touches[0] = event.touches[0];\n\t touches[1] = event.changedTouches[0];\n\t } else if (event.touches.length === 0) {\n\t touches[0] = event.changedTouches[0];\n\t touches[1] = event.changedTouches[1];\n\t }\n\t } else {\n\t touches[0] = event.touches[0];\n\t touches[1] = event.touches[1];\n\t }\n\t }\n\t\n\t return touches;\n\t }\n\t\n\t function pointerAverage(pointers) {\n\t var average = {\n\t pageX: 0,\n\t pageY: 0,\n\t clientX: 0,\n\t clientY: 0,\n\t screenX: 0,\n\t screenY: 0\n\t };\n\t var prop;\n\t\n\t for (var i = 0; i < pointers.length; i++) {\n\t for (prop in average) {\n\t average[prop] += pointers[i][prop];\n\t }\n\t }\n\t for (prop in average) {\n\t average[prop] /= pointers.length;\n\t }\n\t\n\t return average;\n\t }\n\t\n\t function touchBBox(event) {\n\t if (!event.length && !(event.touches && event.touches.length > 1)) {\n\t return;\n\t }\n\t\n\t var touches = getTouchPair(event),\n\t minX = Math.min(touches[0].pageX, touches[1].pageX),\n\t minY = Math.min(touches[0].pageY, touches[1].pageY),\n\t maxX = Math.max(touches[0].pageX, touches[1].pageX),\n\t maxY = Math.max(touches[0].pageY, touches[1].pageY);\n\t\n\t return {\n\t x: minX,\n\t y: minY,\n\t left: minX,\n\t top: minY,\n\t width: maxX - minX,\n\t height: maxY - minY\n\t };\n\t }\n\t\n\t function touchDistance(event, deltaSource) {\n\t deltaSource = deltaSource || defaultOptions.deltaSource;\n\t\n\t var sourceX = deltaSource + 'X',\n\t sourceY = deltaSource + 'Y',\n\t touches = getTouchPair(event);\n\t\n\t var dx = touches[0][sourceX] - touches[1][sourceX],\n\t dy = touches[0][sourceY] - touches[1][sourceY];\n\t\n\t return hypot(dx, dy);\n\t }\n\t\n\t function touchAngle(event, prevAngle, deltaSource) {\n\t deltaSource = deltaSource || defaultOptions.deltaSource;\n\t\n\t var sourceX = deltaSource + 'X',\n\t sourceY = deltaSource + 'Y',\n\t touches = getTouchPair(event),\n\t dx = touches[0][sourceX] - touches[1][sourceX],\n\t dy = touches[0][sourceY] - touches[1][sourceY],\n\t angle = 180 * Math.atan(dy / dx) / Math.PI;\n\t\n\t if (isNumber(prevAngle)) {\n\t var dr = angle - prevAngle,\n\t drClamped = dr % 360;\n\t\n\t if (drClamped > 315) {\n\t angle -= 360 + angle / 360 | 0 * 360;\n\t } else if (drClamped > 135) {\n\t angle -= 180 + angle / 360 | 0 * 360;\n\t } else if (drClamped < -315) {\n\t angle += 360 + angle / 360 | 0 * 360;\n\t } else if (drClamped < -135) {\n\t angle += 180 + angle / 360 | 0 * 360;\n\t }\n\t }\n\t\n\t return angle;\n\t }\n\t\n\t function getOriginXY(interactable, element) {\n\t var origin = interactable ? interactable.options.origin : defaultOptions.origin;\n\t\n\t if (origin === 'parent') {\n\t origin = parentElement(element);\n\t } else if (origin === 'self') {\n\t origin = interactable.getRect(element);\n\t } else if (trySelector(origin)) {\n\t origin = closest(element, origin) || { x: 0, y: 0 };\n\t }\n\t\n\t if (isFunction(origin)) {\n\t origin = origin(interactable && element);\n\t }\n\t\n\t if (isElement(origin)) {\n\t origin = getElementRect(origin);\n\t }\n\t\n\t origin.x = 'x' in origin ? origin.x : origin.left;\n\t origin.y = 'y' in origin ? origin.y : origin.top;\n\t\n\t return origin;\n\t }\n\t\n\t // http://stackoverflow.com/a/5634528/2280888\n\t function _getQBezierValue(t, p1, p2, p3) {\n\t var iT = 1 - t;\n\t return iT * iT * p1 + 2 * iT * t * p2 + t * t * p3;\n\t }\n\t\n\t function getQuadraticCurvePoint(startX, startY, cpX, cpY, endX, endY, position) {\n\t return {\n\t x: _getQBezierValue(position, startX, cpX, endX),\n\t y: _getQBezierValue(position, startY, cpY, endY)\n\t };\n\t }\n\t\n\t // http://gizma.com/easing/\n\t function easeOutQuad(t, b, c, d) {\n\t t /= d;\n\t return -c * t * (t - 2) + b;\n\t }\n\t\n\t function nodeContains(parent, child) {\n\t while (child) {\n\t if (child === parent) {\n\t return true;\n\t }\n\t\n\t child = child.parentNode;\n\t }\n\t\n\t return false;\n\t }\n\t\n\t function closest(child, selector) {\n\t var parent = parentElement(child);\n\t\n\t while (isElement(parent)) {\n\t if (matchesSelector(parent, selector)) {\n\t return parent;\n\t }\n\t\n\t parent = parentElement(parent);\n\t }\n\t\n\t return null;\n\t }\n\t\n\t function parentElement(node) {\n\t var parent = node.parentNode;\n\t\n\t if (isDocFrag(parent)) {\n\t // skip past #shado-root fragments\n\t while ((parent = parent.host) && isDocFrag(parent)) {}\n\t\n\t return parent;\n\t }\n\t\n\t return parent;\n\t }\n\t\n\t function inContext(interactable, element) {\n\t return interactable._context === element.ownerDocument || nodeContains(interactable._context, element);\n\t }\n\t\n\t function testIgnore(interactable, interactableElement, element) {\n\t var ignoreFrom = interactable.options.ignoreFrom;\n\t\n\t if (!ignoreFrom || !isElement(element)) {\n\t return false;\n\t }\n\t\n\t if (isString(ignoreFrom)) {\n\t return matchesUpTo(element, ignoreFrom, interactableElement);\n\t } else if (isElement(ignoreFrom)) {\n\t return nodeContains(ignoreFrom, element);\n\t }\n\t\n\t return false;\n\t }\n\t\n\t function testAllow(interactable, interactableElement, element) {\n\t var allowFrom = interactable.options.allowFrom;\n\t\n\t if (!allowFrom) {\n\t return true;\n\t }\n\t\n\t if (!isElement(element)) {\n\t return false;\n\t }\n\t\n\t if (isString(allowFrom)) {\n\t return matchesUpTo(element, allowFrom, interactableElement);\n\t } else if (isElement(allowFrom)) {\n\t return nodeContains(allowFrom, element);\n\t }\n\t\n\t return false;\n\t }\n\t\n\t function checkAxis(axis, interactable) {\n\t if (!interactable) {\n\t return false;\n\t }\n\t\n\t var thisAxis = interactable.options.drag.axis;\n\t\n\t return axis === 'xy' || thisAxis === 'xy' || thisAxis === axis;\n\t }\n\t\n\t function checkSnap(interactable, action) {\n\t var options = interactable.options;\n\t\n\t if (/^resize/.test(action)) {\n\t action = 'resize';\n\t }\n\t\n\t return options[action].snap && options[action].snap.enabled;\n\t }\n\t\n\t function checkRestrict(interactable, action) {\n\t var options = interactable.options;\n\t\n\t if (/^resize/.test(action)) {\n\t action = 'resize';\n\t }\n\t\n\t return options[action].restrict && options[action].restrict.enabled;\n\t }\n\t\n\t function checkAutoScroll(interactable, action) {\n\t var options = interactable.options;\n\t\n\t if (/^resize/.test(action)) {\n\t action = 'resize';\n\t }\n\t\n\t return options[action].autoScroll && options[action].autoScroll.enabled;\n\t }\n\t\n\t function withinInteractionLimit(interactable, element, action) {\n\t var options = interactable.options,\n\t maxActions = options[action.name].max,\n\t maxPerElement = options[action.name].maxPerElement,\n\t activeInteractions = 0,\n\t targetCount = 0,\n\t targetElementCount = 0;\n\t\n\t for (var i = 0, len = interactions.length; i < len; i++) {\n\t var interaction = interactions[i],\n\t otherAction = interaction.prepared.name,\n\t active = interaction.interacting();\n\t\n\t if (!active) {\n\t continue;\n\t }\n\t\n\t activeInteractions++;\n\t\n\t if (activeInteractions >= maxInteractions) {\n\t return false;\n\t }\n\t\n\t if (interaction.target !== interactable) {\n\t continue;\n\t }\n\t\n\t targetCount += otherAction === action.name | 0;\n\t\n\t if (targetCount >= maxActions) {\n\t return false;\n\t }\n\t\n\t if (interaction.element === element) {\n\t targetElementCount++;\n\t\n\t if (otherAction !== action.name || targetElementCount >= maxPerElement) {\n\t return false;\n\t }\n\t }\n\t }\n\t\n\t return maxInteractions > 0;\n\t }\n\t\n\t // Test for the element that's \"above\" all other qualifiers\n\t function indexOfDeepestElement(elements) {\n\t var dropzone,\n\t deepestZone = elements[0],\n\t index = deepestZone ? 0 : -1,\n\t parent,\n\t deepestZoneParents = [],\n\t dropzoneParents = [],\n\t child,\n\t i,\n\t n;\n\t\n\t for (i = 1; i < elements.length; i++) {\n\t dropzone = elements[i];\n\t\n\t // an element might belong to multiple selector dropzones\n\t if (!dropzone || dropzone === deepestZone) {\n\t continue;\n\t }\n\t\n\t if (!deepestZone) {\n\t deepestZone = dropzone;\n\t index = i;\n\t continue;\n\t }\n\t\n\t // check if the deepest or current are document.documentElement or document.rootElement\n\t // - if the current dropzone is, do nothing and continue\n\t if (dropzone.parentNode === dropzone.ownerDocument) {\n\t continue;\n\t }\n\t // - if deepest is, update with the current dropzone and continue to next\n\t else if (deepestZone.parentNode === dropzone.ownerDocument) {\n\t deepestZone = dropzone;\n\t index = i;\n\t continue;\n\t }\n\t\n\t if (!deepestZoneParents.length) {\n\t parent = deepestZone;\n\t while (parent.parentNode && parent.parentNode !== parent.ownerDocument) {\n\t deepestZoneParents.unshift(parent);\n\t parent = parent.parentNode;\n\t }\n\t }\n\t\n\t // if this element is an svg element and the current deepest is\n\t // an HTMLElement\n\t if (deepestZone instanceof HTMLElement && dropzone instanceof SVGElement && !(dropzone instanceof SVGSVGElement)) {\n\t if (dropzone === deepestZone.parentNode) {\n\t continue;\n\t }\n\t\n\t parent = dropzone.ownerSVGElement;\n\t } else {\n\t parent = dropzone;\n\t }\n\t\n\t dropzoneParents = [];\n\t\n\t while (parent.parentNode !== parent.ownerDocument) {\n\t dropzoneParents.unshift(parent);\n\t parent = parent.parentNode;\n\t }\n\t\n\t n = 0;\n\t\n\t // get (position of last common ancestor) + 1\n\t while (dropzoneParents[n] && dropzoneParents[n] === deepestZoneParents[n]) {\n\t n++;\n\t }\n\t\n\t var parents = [dropzoneParents[n - 1], dropzoneParents[n], deepestZoneParents[n]];\n\t\n\t child = parents[0].lastChild;\n\t\n\t while (child) {\n\t if (child === parents[1]) {\n\t deepestZone = dropzone;\n\t index = i;\n\t deepestZoneParents = [];\n\t\n\t break;\n\t } else if (child === parents[2]) {\n\t break;\n\t }\n\t\n\t child = child.previousSibling;\n\t }\n\t }\n\t\n\t return index;\n\t }\n\t\n\t function Interaction() {\n\t this.target = null; // current interactable being interacted with\n\t this.element = null; // the target element of the interactable\n\t this.dropTarget = null; // the dropzone a drag target might be dropped into\n\t this.dropElement = null; // the element at the time of checking\n\t this.prevDropTarget = null; // the dropzone that was recently dragged away from\n\t this.prevDropElement = null; // the element at the time of checking\n\t\n\t this.prepared = { // action that's ready to be fired on next move event\n\t name: null,\n\t axis: null,\n\t edges: null\n\t };\n\t\n\t this.matches = []; // all selectors that are matched by target element\n\t this.matchElements = []; // corresponding elements\n\t\n\t this.inertiaStatus = {\n\t active: false,\n\t smoothEnd: false,\n\t ending: false,\n\t\n\t startEvent: null,\n\t upCoords: {},\n\t\n\t xe: 0, ye: 0,\n\t sx: 0, sy: 0,\n\t\n\t t0: 0,\n\t vx0: 0, vys: 0,\n\t duration: 0,\n\t\n\t resumeDx: 0,\n\t resumeDy: 0,\n\t\n\t lambda_v0: 0,\n\t one_ve_v0: 0,\n\t i: null\n\t };\n\t\n\t if (isFunction(Function.prototype.bind)) {\n\t this.boundInertiaFrame = this.inertiaFrame.bind(this);\n\t this.boundSmoothEndFrame = this.smoothEndFrame.bind(this);\n\t } else {\n\t var that = this;\n\t\n\t this.boundInertiaFrame = function () {\n\t return that.inertiaFrame();\n\t };\n\t this.boundSmoothEndFrame = function () {\n\t return that.smoothEndFrame();\n\t };\n\t }\n\t\n\t this.activeDrops = {\n\t dropzones: [], // the dropzones that are mentioned below\n\t elements: [], // elements of dropzones that accept the target draggable\n\t rects: [] // the rects of the elements mentioned above\n\t };\n\t\n\t // keep track of added pointers\n\t this.pointers = [];\n\t this.pointerIds = [];\n\t this.downTargets = [];\n\t this.downTimes = [];\n\t this.holdTimers = [];\n\t\n\t // Previous native pointer move event coordinates\n\t this.prevCoords = {\n\t page: { x: 0, y: 0 },\n\t client: { x: 0, y: 0 },\n\t timeStamp: 0\n\t };\n\t // current native pointer move event coordinates\n\t this.curCoords = {\n\t page: { x: 0, y: 0 },\n\t client: { x: 0, y: 0 },\n\t timeStamp: 0\n\t };\n\t\n\t // Starting InteractEvent pointer coordinates\n\t this.startCoords = {\n\t page: { x: 0, y: 0 },\n\t client: { x: 0, y: 0 },\n\t timeStamp: 0\n\t };\n\t\n\t // Change in coordinates and time of the pointer\n\t this.pointerDelta = {\n\t page: { x: 0, y: 0, vx: 0, vy: 0, speed: 0 },\n\t client: { x: 0, y: 0, vx: 0, vy: 0, speed: 0 },\n\t timeStamp: 0\n\t };\n\t\n\t this.downEvent = null; // pointerdown/mousedown/touchstart event\n\t this.downPointer = {};\n\t\n\t this._eventTarget = null;\n\t this._curEventTarget = null;\n\t\n\t this.prevEvent = null; // previous action event\n\t this.tapTime = 0; // time of the most recent tap event\n\t this.prevTap = null;\n\t\n\t this.startOffset = { left: 0, right: 0, top: 0, bottom: 0 };\n\t this.restrictOffset = { left: 0, right: 0, top: 0, bottom: 0 };\n\t this.snapOffsets = [];\n\t\n\t this.gesture = {\n\t start: { x: 0, y: 0 },\n\t\n\t startDistance: 0, // distance between two touches of touchStart\n\t prevDistance: 0,\n\t distance: 0,\n\t\n\t scale: 1, // gesture.distance / gesture.startDistance\n\t\n\t startAngle: 0, // angle of line joining two touches\n\t prevAngle: 0 // angle of the previous gesture event\n\t };\n\t\n\t this.snapStatus = {\n\t x: 0, y: 0,\n\t dx: 0, dy: 0,\n\t realX: 0, realY: 0,\n\t snappedX: 0, snappedY: 0,\n\t targets: [],\n\t locked: false,\n\t changed: false\n\t };\n\t\n\t this.restrictStatus = {\n\t dx: 0, dy: 0,\n\t restrictedX: 0, restrictedY: 0,\n\t snap: null,\n\t restricted: false,\n\t changed: false\n\t };\n\t\n\t this.restrictStatus.snap = this.snapStatus;\n\t\n\t this.pointerIsDown = false;\n\t this.pointerWasMoved = false;\n\t this.gesturing = false;\n\t this.dragging = false;\n\t this.resizing = false;\n\t this.resizeAxes = 'xy';\n\t\n\t this.mouse = false;\n\t\n\t interactions.push(this);\n\t }\n\t\n\t Interaction.prototype = {\n\t getPageXY: function getPageXY(pointer, xy) {\n\t return _getPageXY(pointer, xy, this);\n\t },\n\t getClientXY: function getClientXY(pointer, xy) {\n\t return _getClientXY(pointer, xy, this);\n\t },\n\t setEventXY: function setEventXY(target, ptr) {\n\t return _setEventXY(target, ptr, this);\n\t },\n\t\n\t pointerOver: function pointerOver(pointer, event, eventTarget) {\n\t if (this.prepared.name || !this.mouse) {\n\t return;\n\t }\n\t\n\t var curMatches = [],\n\t curMatchElements = [],\n\t prevTargetElement = this.element;\n\t\n\t this.addPointer(pointer);\n\t\n\t if (this.target && (testIgnore(this.target, this.element, eventTarget) || !testAllow(this.target, this.element, eventTarget))) {\n\t // if the eventTarget should be ignored or shouldn't be allowed\n\t // clear the previous target\n\t this.target = null;\n\t this.element = null;\n\t this.matches = [];\n\t this.matchElements = [];\n\t }\n\t\n\t var elementInteractable = interactables.get(eventTarget),\n\t elementAction = elementInteractable && !testIgnore(elementInteractable, eventTarget, eventTarget) && testAllow(elementInteractable, eventTarget, eventTarget) && validateAction(elementInteractable.getAction(pointer, event, this, eventTarget), elementInteractable);\n\t\n\t if (elementAction && !withinInteractionLimit(elementInteractable, eventTarget, elementAction)) {\n\t elementAction = null;\n\t }\n\t\n\t function pushCurMatches(interactable, selector) {\n\t if (interactable && inContext(interactable, eventTarget) && !testIgnore(interactable, eventTarget, eventTarget) && testAllow(interactable, eventTarget, eventTarget) && matchesSelector(eventTarget, selector)) {\n\t curMatches.push(interactable);\n\t curMatchElements.push(eventTarget);\n\t }\n\t }\n\t\n\t if (elementAction) {\n\t this.target = elementInteractable;\n\t this.element = eventTarget;\n\t this.matches = [];\n\t this.matchElements = [];\n\t } else {\n\t interactables.forEachSelector(pushCurMatches);\n\t\n\t if (this.validateSelector(pointer, event, curMatches, curMatchElements)) {\n\t this.matches = curMatches;\n\t this.matchElements = curMatchElements;\n\t\n\t this.pointerHover(pointer, event, this.matches, this.matchElements);\n\t events.add(eventTarget, supportsPointerEvent ? pEventTypes.move : 'mousemove', listeners.pointerHover);\n\t } else if (this.target) {\n\t if (nodeContains(prevTargetElement, eventTarget)) {\n\t this.pointerHover(pointer, event, this.matches, this.matchElements);\n\t events.add(this.element, supportsPointerEvent ? pEventTypes.move : 'mousemove', listeners.pointerHover);\n\t } else {\n\t this.target = null;\n\t this.element = null;\n\t this.matches = [];\n\t this.matchElements = [];\n\t }\n\t }\n\t }\n\t },\n\t\n\t // Check what action would be performed on pointerMove target if a mouse\n\t // button were pressed and change the cursor accordingly\n\t pointerHover: function pointerHover(pointer, event, eventTarget, curEventTarget, matches, matchElements) {\n\t var target = this.target;\n\t\n\t if (!this.prepared.name && this.mouse) {\n\t var action;\n\t\n\t // update pointer coords for defaultActionChecker to use\n\t this.setEventXY(this.curCoords, [pointer]);\n\t\n\t if (matches) {\n\t action = this.validateSelector(pointer, event, matches, matchElements);\n\t } else if (target) {\n\t action = validateAction(target.getAction(this.pointers[0], event, this, this.element), this.target);\n\t }\n\t\n\t if (target && target.options.styleCursor) {\n\t if (action) {\n\t target._doc.documentElement.style.cursor = getActionCursor(action);\n\t } else {\n\t target._doc.documentElement.style.cursor = '';\n\t }\n\t }\n\t } else if (this.prepared.name) {\n\t this.checkAndPreventDefault(event, target, this.element);\n\t }\n\t },\n\t\n\t pointerOut: function pointerOut(pointer, event, eventTarget) {\n\t if (this.prepared.name) {\n\t return;\n\t }\n\t\n\t // Remove temporary event listeners for selector Interactables\n\t if (!interactables.get(eventTarget)) {\n\t events.remove(eventTarget, supportsPointerEvent ? pEventTypes.move : 'mousemove', listeners.pointerHover);\n\t }\n\t\n\t if (this.target && this.target.options.styleCursor && !this.interacting()) {\n\t this.target._doc.documentElement.style.cursor = '';\n\t }\n\t },\n\t\n\t selectorDown: function selectorDown(pointer, event, eventTarget, curEventTarget) {\n\t var that = this,\n\t\n\t // copy event to be used in timeout for IE8\n\t eventCopy = events.useAttachEvent ? extend({}, event) : event,\n\t element = eventTarget,\n\t pointerIndex = this.addPointer(pointer),\n\t action;\n\t\n\t this.holdTimers[pointerIndex] = setTimeout(function () {\n\t that.pointerHold(events.useAttachEvent ? eventCopy : pointer, eventCopy, eventTarget, curEventTarget);\n\t }, defaultOptions._holdDuration);\n\t\n\t this.pointerIsDown = true;\n\t\n\t // Check if the down event hits the current inertia target\n\t if (this.inertiaStatus.active && this.target.selector) {\n\t // climb up the DOM tree from the event target\n\t while (isElement(element)) {\n\t // if this element is the current inertia target element\n\t if (element === this.element\n\t // and the prospective action is the same as the ongoing one\n\t && validateAction(this.target.getAction(pointer, event, this, this.element), this.target).name === this.prepared.name) {\n\t // stop inertia so that the next move will be a normal one\n\t cancelFrame(this.inertiaStatus.i);\n\t this.inertiaStatus.active = false;\n\t\n\t this.collectEventTargets(pointer, event, eventTarget, 'down');\n\t return;\n\t }\n\t element = parentElement(element);\n\t }\n\t }\n\t\n\t // do nothing if interacting\n\t if (this.interacting()) {\n\t this.collectEventTargets(pointer, event, eventTarget, 'down');\n\t return;\n\t }\n\t\n\t function pushMatches(interactable, selector, context) {\n\t var elements = ie8MatchesSelector ? context.querySelectorAll(selector) : undefined;\n\t\n\t if (inContext(interactable, element) && !testIgnore(interactable, element, eventTarget) && testAllow(interactable, element, eventTarget) && matchesSelector(element, selector, elements)) {\n\t that.matches.push(interactable);\n\t that.matchElements.push(element);\n\t }\n\t }\n\t\n\t // update pointer coords for defaultActionChecker to use\n\t this.setEventXY(this.curCoords, [pointer]);\n\t this.downEvent = event;\n\t\n\t while (isElement(element) && !action) {\n\t this.matches = [];\n\t this.matchElements = [];\n\t\n\t interactables.forEachSelector(pushMatches);\n\t\n\t action = this.validateSelector(pointer, event, this.matches, this.matchElements);\n\t element = parentElement(element);\n\t }\n\t\n\t if (action) {\n\t this.prepared.name = action.name;\n\t this.prepared.axis = action.axis;\n\t this.prepared.edges = action.edges;\n\t\n\t this.collectEventTargets(pointer, event, eventTarget, 'down');\n\t\n\t return this.pointerDown(pointer, event, eventTarget, curEventTarget, action);\n\t } else {\n\t // do these now since pointerDown isn't being called from here\n\t this.downTimes[pointerIndex] = new Date().getTime();\n\t this.downTargets[pointerIndex] = eventTarget;\n\t pointerExtend(this.downPointer, pointer);\n\t\n\t copyCoords(this.prevCoords, this.curCoords);\n\t this.pointerWasMoved = false;\n\t }\n\t\n\t this.collectEventTargets(pointer, event, eventTarget, 'down');\n\t },\n\t\n\t // Determine action to be performed on next pointerMove and add appropriate\n\t // style and event Listeners\n\t pointerDown: function pointerDown(pointer, event, eventTarget, curEventTarget, forceAction) {\n\t if (!forceAction && !this.inertiaStatus.active && this.pointerWasMoved && this.prepared.name) {\n\t this.checkAndPreventDefault(event, this.target, this.element);\n\t\n\t return;\n\t }\n\t\n\t this.pointerIsDown = true;\n\t this.downEvent = event;\n\t\n\t var pointerIndex = this.addPointer(pointer),\n\t action;\n\t\n\t // If it is the second touch of a multi-touch gesture, keep the\n\t // target the same and get a new action if a target was set by the\n\t // first touch\n\t if (this.pointerIds.length > 1 && this.target._element === this.element) {\n\t var newAction = validateAction(forceAction || this.target.getAction(pointer, event, this, this.element), this.target);\n\t\n\t if (withinInteractionLimit(this.target, this.element, newAction)) {\n\t action = newAction;\n\t }\n\t\n\t this.prepared.name = null;\n\t }\n\t // Otherwise, set the target if there is no action prepared\n\t else if (!this.prepared.name) {\n\t var interactable = interactables.get(curEventTarget);\n\t\n\t if (interactable && !testIgnore(interactable, curEventTarget, eventTarget) && testAllow(interactable, curEventTarget, eventTarget) && (action = validateAction(forceAction || interactable.getAction(pointer, event, this, curEventTarget), interactable, eventTarget)) && withinInteractionLimit(interactable, curEventTarget, action)) {\n\t this.target = interactable;\n\t this.element = curEventTarget;\n\t }\n\t }\n\t\n\t var target = this.target,\n\t options = target && target.options;\n\t\n\t if (target && (forceAction || !this.prepared.name)) {\n\t action = action || validateAction(forceAction || target.getAction(pointer, event, this, curEventTarget), target, this.element);\n\t\n\t this.setEventXY(this.startCoords, this.pointers);\n\t\n\t if (!action) {\n\t return;\n\t }\n\t\n\t if (options.styleCursor) {\n\t target._doc.documentElement.style.cursor = getActionCursor(action);\n\t }\n\t\n\t this.resizeAxes = action.name === 'resize' ? action.axis : null;\n\t\n\t if (action === 'gesture' && this.pointerIds.length < 2) {\n\t action = null;\n\t }\n\t\n\t this.prepared.name = action.name;\n\t this.prepared.axis = action.axis;\n\t this.prepared.edges = action.edges;\n\t\n\t this.snapStatus.snappedX = this.snapStatus.snappedY = this.restrictStatus.restrictedX = this.restrictStatus.restrictedY = NaN;\n\t\n\t this.downTimes[pointerIndex] = new Date().getTime();\n\t this.downTargets[pointerIndex] = eventTarget;\n\t pointerExtend(this.downPointer, pointer);\n\t\n\t copyCoords(this.prevCoords, this.startCoords);\n\t this.pointerWasMoved = false;\n\t\n\t this.checkAndPreventDefault(event, target, this.element);\n\t }\n\t // if inertia is active try to resume action\n\t else if (this.inertiaStatus.active && curEventTarget === this.element && validateAction(target.getAction(pointer, event, this, this.element), target).name === this.prepared.name) {\n\t cancelFrame(this.inertiaStatus.i);\n\t this.inertiaStatus.active = false;\n\t\n\t this.checkAndPreventDefault(event, target, this.element);\n\t }\n\t },\n\t\n\t setModifications: function setModifications(coords, preEnd) {\n\t var target = this.target,\n\t shouldMove = true,\n\t shouldSnap = checkSnap(target, this.prepared.name) && (!target.options[this.prepared.name].snap.endOnly || preEnd),\n\t shouldRestrict = checkRestrict(target, this.prepared.name) && (!target.options[this.prepared.name].restrict.endOnly || preEnd);\n\t\n\t if (shouldSnap) {\n\t this.setSnapping(coords);\n\t } else {\n\t this.snapStatus.locked = false;\n\t }\n\t if (shouldRestrict) {\n\t this.setRestriction(coords);\n\t } else {\n\t this.restrictStatus.restricted = false;\n\t }\n\t\n\t if (shouldSnap && this.snapStatus.locked && !this.snapStatus.changed) {\n\t shouldMove = shouldRestrict && this.restrictStatus.restricted && this.restrictStatus.changed;\n\t } else if (shouldRestrict && this.restrictStatus.restricted && !this.restrictStatus.changed) {\n\t shouldMove = false;\n\t }\n\t\n\t return shouldMove;\n\t },\n\t\n\t setStartOffsets: function setStartOffsets(action, interactable, element) {\n\t var rect = interactable.getRect(element),\n\t origin = getOriginXY(interactable, element),\n\t snap = interactable.options[this.prepared.name].snap,\n\t restrict = interactable.options[this.prepared.name].restrict,\n\t width,\n\t height;\n\t\n\t if (rect) {\n\t this.startOffset.left = this.startCoords.page.x - rect.left;\n\t this.startOffset.top = this.startCoords.page.y - rect.top;\n\t\n\t this.startOffset.right = rect.right - this.startCoords.page.x;\n\t this.startOffset.bottom = rect.bottom - this.startCoords.page.y;\n\t\n\t if ('width' in rect) {\n\t width = rect.width;\n\t } else {\n\t width = rect.right - rect.left;\n\t }\n\t if ('height' in rect) {\n\t height = rect.height;\n\t } else {\n\t height = rect.bottom - rect.top;\n\t }\n\t } else {\n\t this.startOffset.left = this.startOffset.top = this.startOffset.right = this.startOffset.bottom = 0;\n\t }\n\t\n\t this.snapOffsets.splice(0);\n\t\n\t var snapOffset = snap && snap.offset === 'startCoords' ? {\n\t x: this.startCoords.page.x - origin.x,\n\t y: this.startCoords.page.y - origin.y\n\t } : snap && snap.offset || { x: 0, y: 0 };\n\t\n\t if (rect && snap && snap.relativePoints && snap.relativePoints.length) {\n\t for (var i = 0; i < snap.relativePoints.length; i++) {\n\t this.snapOffsets.push({\n\t x: this.startOffset.left - width * snap.relativePoints[i].x + snapOffset.x,\n\t y: this.startOffset.top - height * snap.relativePoints[i].y + snapOffset.y\n\t });\n\t }\n\t } else {\n\t this.snapOffsets.push(snapOffset);\n\t }\n\t\n\t if (rect && restrict.elementRect) {\n\t this.restrictOffset.left = this.startOffset.left - width * restrict.elementRect.left;\n\t this.restrictOffset.top = this.startOffset.top - height * restrict.elementRect.top;\n\t\n\t this.restrictOffset.right = this.startOffset.right - width * (1 - restrict.elementRect.right);\n\t this.restrictOffset.bottom = this.startOffset.bottom - height * (1 - restrict.elementRect.bottom);\n\t } else {\n\t this.restrictOffset.left = this.restrictOffset.top = this.restrictOffset.right = this.restrictOffset.bottom = 0;\n\t }\n\t },\n\t\n\t /* \\\r\n\t * Interaction.start\r\n\t [ method ]\r\n\t *\r\n\t * Start an action with the given Interactable and Element as tartgets. The\r\n\t * action must be enabled for the target Interactable and an appropriate number\r\n\t * of pointers must be held down – 1 for drag/resize, 2 for gesture.\r\n\t *\r\n\t * Use it with `interactable.able({ manualStart: false })` to always\r\n\t * [start actions manually](https://github.com/taye/interact.js/issues/114)\r\n\t *\r\n\t - action (object) The action to be performed - drag, resize, etc.\r\n\t - interactable (Interactable) The Interactable to target\r\n\t - element (Element) The DOM Element to target\r\n\t = (object) interact\r\n\t **\r\n\t | interact(target)\r\n\t | .draggable({\r\n\t | // disable the default drag start by down->move\r\n\t | manualStart: true\r\n\t | })\r\n\t | // start dragging after the user holds the pointer down\r\n\t | .on('hold', function (event) {\r\n\t | var interaction = event.interaction;\r\n\t |\r\n\t | if (!interaction.interacting()) {\r\n\t | interaction.start({ name: 'drag' },\r\n\t | event.interactable,\r\n\t | event.currentTarget);\r\n\t | }\r\n\t | });\r\n\t \\*/\n\t start: function start(action, interactable, element) {\n\t if (this.interacting() || !this.pointerIsDown || this.pointerIds.length < (action.name === 'gesture' ? 2 : 1)) {\n\t return;\n\t }\n\t\n\t // if this interaction had been removed after stopping\n\t // add it back\n\t if (indexOf(interactions, this) === -1) {\n\t interactions.push(this);\n\t }\n\t\n\t // set the startCoords if there was no prepared action\n\t if (!this.prepared.name) {\n\t this.setEventXY(this.startCoords);\n\t }\n\t\n\t this.prepared.name = action.name;\n\t this.prepared.axis = action.axis;\n\t this.prepared.edges = action.edges;\n\t this.target = interactable;\n\t this.element = element;\n\t\n\t this.setStartOffsets(action.name, interactable, element);\n\t this.setModifications(this.startCoords.page);\n\t\n\t this.prevEvent = this[this.prepared.name + 'Start'](this.downEvent);\n\t },\n\t\n\t pointerMove: function pointerMove(pointer, event, eventTarget, curEventTarget, preEnd) {\n\t if (this.inertiaStatus.active) {\n\t var pageUp = this.inertiaStatus.upCoords.page;\n\t var clientUp = this.inertiaStatus.upCoords.client;\n\t\n\t var inertiaPosition = {\n\t pageX: pageUp.x + this.inertiaStatus.sx,\n\t pageY: pageUp.y + this.inertiaStatus.sy,\n\t clientX: clientUp.x + this.inertiaStatus.sx,\n\t clientY: clientUp.y + this.inertiaStatus.sy\n\t };\n\t\n\t this.setEventXY(this.curCoords, [inertiaPosition]);\n\t } else {\n\t this.recordPointer(pointer);\n\t this.setEventXY(this.curCoords, this.pointers);\n\t }\n\t\n\t var duplicateMove = this.curCoords.page.x === this.prevCoords.page.x && this.curCoords.page.y === this.prevCoords.page.y && this.curCoords.client.x === this.prevCoords.client.x && this.curCoords.client.y === this.prevCoords.client.y;\n\t\n\t var dx,\n\t dy,\n\t pointerIndex = this.mouse ? 0 : indexOf(this.pointerIds, getPointerId(pointer));\n\t\n\t // register movement greater than pointerMoveTolerance\n\t if (this.pointerIsDown && !this.pointerWasMoved) {\n\t dx = this.curCoords.client.x - this.startCoords.client.x;\n\t dy = this.curCoords.client.y - this.startCoords.client.y;\n\t\n\t this.pointerWasMoved = hypot(dx, dy) > pointerMoveTolerance;\n\t }\n\t\n\t if (!duplicateMove && (!this.pointerIsDown || this.pointerWasMoved)) {\n\t if (this.pointerIsDown) {\n\t clearTimeout(this.holdTimers[pointerIndex]);\n\t }\n\t\n\t this.collectEventTargets(pointer, event, eventTarget, 'move');\n\t }\n\t\n\t if (!this.pointerIsDown) {\n\t return;\n\t }\n\t\n\t if (duplicateMove && this.pointerWasMoved && !preEnd) {\n\t this.checkAndPreventDefault(event, this.target, this.element);\n\t return;\n\t }\n\t\n\t // set pointer coordinate, time changes and speeds\n\t setEventDeltas(this.pointerDelta, this.prevCoords, this.curCoords);\n\t\n\t if (!this.prepared.name) {\n\t return;\n\t }\n\t\n\t if (this.pointerWasMoved\n\t // ignore movement while inertia is active\n\t && (!this.inertiaStatus.active || pointer instanceof InteractEvent && /inertiastart/.test(pointer.type))) {\n\t // if just starting an action, calculate the pointer speed now\n\t if (!this.interacting()) {\n\t setEventDeltas(this.pointerDelta, this.prevCoords, this.curCoords);\n\t\n\t // check if a drag is in the correct axis\n\t if (this.prepared.name === 'drag') {\n\t var absX = Math.abs(dx),\n\t absY = Math.abs(dy),\n\t targetAxis = this.target.options.drag.axis,\n\t axis = absX > absY ? 'x' : absX < absY ? 'y' : 'xy';\n\t\n\t // if the movement isn't in the axis of the interactable\n\t if (axis !== 'xy' && targetAxis !== 'xy' && targetAxis !== axis) {\n\t // cancel the prepared action\n\t this.prepared.name = null;\n\t\n\t // then try to get a drag from another ineractable\n\t\n\t var element = eventTarget;\n\t\n\t // check element interactables\n\t while (isElement(element)) {\n\t var elementInteractable = interactables.get(element);\n\t\n\t if (elementInteractable && elementInteractable !== this.target && !elementInteractable.options.drag.manualStart && elementInteractable.getAction(this.downPointer, this.downEvent, this, element).name === 'drag' && checkAxis(axis, elementInteractable)) {\n\t this.prepared.name = 'drag';\n\t this.target = elementInteractable;\n\t this.element = element;\n\t break;\n\t }\n\t\n\t element = parentElement(element);\n\t }\n\t\n\t // if there's no drag from element interactables,\n\t // check the selector interactables\n\t if (!this.prepared.name) {\n\t var thisInteraction = this;\n\t\n\t var getDraggable = function getDraggable(interactable, selector, context) {\n\t var elements = ie8MatchesSelector ? context.querySelectorAll(selector) : undefined;\n\t\n\t if (interactable === thisInteraction.target) {\n\t return;\n\t }\n\t\n\t if (inContext(interactable, eventTarget) && !interactable.options.drag.manualStart && !testIgnore(interactable, element, eventTarget) && testAllow(interactable, element, eventTarget) && matchesSelector(element, selector, elements) && interactable.getAction(thisInteraction.downPointer, thisInteraction.downEvent, thisInteraction, element).name === 'drag' && checkAxis(axis, interactable) && withinInteractionLimit(interactable, element, 'drag')) {\n\t return interactable;\n\t }\n\t };\n\t\n\t element = eventTarget;\n\t\n\t while (isElement(element)) {\n\t var selectorInteractable = interactables.forEachSelector(getDraggable);\n\t\n\t if (selectorInteractable) {\n\t this.prepared.name = 'drag';\n\t this.target = selectorInteractable;\n\t this.element = element;\n\t break;\n\t }\n\t\n\t element = parentElement(element);\n\t }\n\t }\n\t }\n\t }\n\t }\n\t\n\t var starting = !!this.prepared.name && !this.interacting();\n\t\n\t if (starting && (this.target.options[this.prepared.name].manualStart || !withinInteractionLimit(this.target, this.element, this.prepared))) {\n\t this.stop(event);\n\t return;\n\t }\n\t\n\t if (this.prepared.name && this.target) {\n\t if (starting) {\n\t this.start(this.prepared, this.target, this.element);\n\t }\n\t\n\t var shouldMove = this.setModifications(this.curCoords.page, preEnd);\n\t\n\t // move if snapping or restriction doesn't prevent it\n\t if (shouldMove || starting) {\n\t this.prevEvent = this[this.prepared.name + 'Move'](event);\n\t }\n\t\n\t this.checkAndPreventDefault(event, this.target, this.element);\n\t }\n\t }\n\t\n\t copyCoords(this.prevCoords, this.curCoords);\n\t\n\t if (this.dragging || this.resizing) {\n\t this.autoScrollMove(pointer);\n\t }\n\t },\n\t\n\t dragStart: function dragStart(event) {\n\t var dragEvent = new InteractEvent(this, event, 'drag', 'start', this.element);\n\t\n\t dragEvent.originalEvent = event;\n\t this.dragging = true;\n\t this.target.fire(dragEvent);\n\t\n\t // reset active dropzones\n\t this.activeDrops.dropzones = [];\n\t this.activeDrops.elements = [];\n\t this.activeDrops.rects = [];\n\t\n\t if (!this.dynamicDrop) {\n\t this.setActiveDrops(this.element);\n\t }\n\t\n\t var dropEvents = this.getDropEvents(event, dragEvent);\n\t\n\t if (dropEvents.activate) {\n\t this.fireActiveDrops(dropEvents.activate);\n\t }\n\t\n\t return dragEvent;\n\t },\n\t\n\t dragMove: function dragMove(event) {\n\t var target = this.target,\n\t dragEvent = new InteractEvent(this, event, 'drag', 'move', this.element),\n\t draggableElement = this.element,\n\t drop = this.getDrop(dragEvent, event, draggableElement);\n\t\n\t dragEvent.originalEvent = event;\n\t\n\t this.dropTarget = drop.dropzone;\n\t this.dropElement = drop.element;\n\t\n\t var dropEvents = this.getDropEvents(event, dragEvent);\n\t\n\t target.fire(dragEvent);\n\t\n\t if (dropEvents.leave) {\n\t this.prevDropTarget.fire(dropEvents.leave);\n\t }\n\t if (dropEvents.enter) {\n\t this.dropTarget.fire(dropEvents.enter);\n\t }\n\t if (dropEvents.move) {\n\t this.dropTarget.fire(dropEvents.move);\n\t }\n\t\n\t this.prevDropTarget = this.dropTarget;\n\t this.prevDropElement = this.dropElement;\n\t\n\t return dragEvent;\n\t },\n\t\n\t resizeStart: function resizeStart(event) {\n\t var resizeEvent = new InteractEvent(this, event, 'resize', 'start', this.element);\n\t\n\t if (this.prepared.edges) {\n\t var startRect = this.target.getRect(this.element);\n\t\n\t /*\r\n\t * When using the `resizable.square` or `resizable.preserveAspectRatio` options, resizing from one edge\r\n\t * will affect another. E.g. with `resizable.square`, resizing to make the right edge larger will make\r\n\t * the bottom edge larger by the same amount. We call these 'linked' edges. Any linked edges will depend\r\n\t * on the active edges and the edge being interacted with.\r\n\t */\n\t if (this.target.options.resize.square || this.target.options.resize.preserveAspectRatio) {\n\t var linkedEdges = extend({}, this.prepared.edges);\n\t\n\t linkedEdges.top = linkedEdges.top || linkedEdges.left && !linkedEdges.bottom;\n\t linkedEdges.left = linkedEdges.left || linkedEdges.top && !linkedEdges.right;\n\t linkedEdges.bottom = linkedEdges.bottom || linkedEdges.right && !linkedEdges.top;\n\t linkedEdges.right = linkedEdges.right || linkedEdges.bottom && !linkedEdges.left;\n\t\n\t this.prepared._linkedEdges = linkedEdges;\n\t } else {\n\t this.prepared._linkedEdges = null;\n\t }\n\t\n\t // if using `resizable.preserveAspectRatio` option, record aspect ratio at the start of the resize\n\t if (this.target.options.resize.preserveAspectRatio) {\n\t this.resizeStartAspectRatio = startRect.width / startRect.height;\n\t }\n\t\n\t this.resizeRects = {\n\t start: startRect,\n\t current: extend({}, startRect),\n\t restricted: extend({}, startRect),\n\t previous: extend({}, startRect),\n\t delta: {\n\t left: 0, right: 0, width: 0,\n\t top: 0, bottom: 0, height: 0\n\t }\n\t };\n\t\n\t resizeEvent.rect = this.resizeRects.restricted;\n\t resizeEvent.deltaRect = this.resizeRects.delta;\n\t }\n\t\n\t this.target.fire(resizeEvent);\n\t\n\t this.resizing = true;\n\t\n\t return resizeEvent;\n\t },\n\t\n\t resizeMove: function resizeMove(event) {\n\t var resizeEvent = new InteractEvent(this, event, 'resize', 'move', this.element);\n\t\n\t var edges = this.prepared.edges,\n\t invert = this.target.options.resize.invert,\n\t invertible = invert === 'reposition' || invert === 'negate';\n\t\n\t if (edges) {\n\t var dx = resizeEvent.dx,\n\t dy = resizeEvent.dy,\n\t start = this.resizeRects.start,\n\t current = this.resizeRects.current,\n\t restricted = this.resizeRects.restricted,\n\t delta = this.resizeRects.delta,\n\t previous = extend(this.resizeRects.previous, restricted),\n\t originalEdges = edges;\n\t\n\t // `resize.preserveAspectRatio` takes precedence over `resize.square`\n\t if (this.target.options.resize.preserveAspectRatio) {\n\t var resizeStartAspectRatio = this.resizeStartAspectRatio;\n\t\n\t edges = this.prepared._linkedEdges;\n\t\n\t if (originalEdges.left && originalEdges.bottom || originalEdges.right && originalEdges.top) {\n\t dy = -dx / resizeStartAspectRatio;\n\t } else if (originalEdges.left || originalEdges.right) {\n\t dy = dx / resizeStartAspectRatio;\n\t } else if (originalEdges.top || originalEdges.bottom) {\n\t dx = dy * resizeStartAspectRatio;\n\t }\n\t } else if (this.target.options.resize.square) {\n\t edges = this.prepared._linkedEdges;\n\t\n\t if (originalEdges.left && originalEdges.bottom || originalEdges.right && originalEdges.top) {\n\t dy = -dx;\n\t } else if (originalEdges.left || originalEdges.right) {\n\t dy = dx;\n\t } else if (originalEdges.top || originalEdges.bottom) {\n\t dx = dy;\n\t }\n\t }\n\t\n\t // update the 'current' rect without modifications\n\t if (edges.top) {\n\t current.top += dy;\n\t }\n\t if (edges.bottom) {\n\t current.bottom += dy;\n\t }\n\t if (edges.left) {\n\t current.left += dx;\n\t }\n\t if (edges.right) {\n\t current.right += dx;\n\t }\n\t\n\t if (invertible) {\n\t // if invertible, copy the current rect\n\t extend(restricted, current);\n\t\n\t if (invert === 'reposition') {\n\t // swap edge values if necessary to keep width/height positive\n\t var swap;\n\t\n\t if (restricted.top > restricted.bottom) {\n\t swap = restricted.top;\n\t\n\t restricted.top = restricted.bottom;\n\t restricted.bottom = swap;\n\t }\n\t if (restricted.left > restricted.right) {\n\t swap = restricted.left;\n\t\n\t restricted.left = restricted.right;\n\t restricted.right = swap;\n\t }\n\t }\n\t } else {\n\t // if not invertible, restrict to minimum of 0x0 rect\n\t restricted.top = Math.min(current.top, start.bottom);\n\t restricted.bottom = Math.max(current.bottom, start.top);\n\t restricted.left = Math.min(current.left, start.right);\n\t restricted.right = Math.max(current.right, start.left);\n\t }\n\t\n\t restricted.width = restricted.right - restricted.left;\n\t restricted.height = restricted.bottom - restricted.top;\n\t\n\t for (var edge in restricted) {\n\t delta[edge] = restricted[edge] - previous[edge];\n\t }\n\t\n\t resizeEvent.edges = this.prepared.edges;\n\t resizeEvent.rect = restricted;\n\t resizeEvent.deltaRect = delta;\n\t }\n\t\n\t this.target.fire(resizeEvent);\n\t\n\t return resizeEvent;\n\t },\n\t\n\t gestureStart: function gestureStart(event) {\n\t var gestureEvent = new InteractEvent(this, event, 'gesture', 'start', this.element);\n\t\n\t gestureEvent.ds = 0;\n\t\n\t this.gesture.startDistance = this.gesture.prevDistance = gestureEvent.distance;\n\t this.gesture.startAngle = this.gesture.prevAngle = gestureEvent.angle;\n\t this.gesture.scale = 1;\n\t\n\t this.gesturing = true;\n\t\n\t this.target.fire(gestureEvent);\n\t\n\t return gestureEvent;\n\t },\n\t\n\t gestureMove: function gestureMove(event) {\n\t if (!this.pointerIds.length) {\n\t return this.prevEvent;\n\t }\n\t\n\t var gestureEvent;\n\t\n\t gestureEvent = new InteractEvent(this, event, 'gesture', 'move', this.element);\n\t gestureEvent.ds = gestureEvent.scale - this.gesture.scale;\n\t\n\t this.target.fire(gestureEvent);\n\t\n\t this.gesture.prevAngle = gestureEvent.angle;\n\t this.gesture.prevDistance = gestureEvent.distance;\n\t\n\t if (gestureEvent.scale !== Infinity && gestureEvent.scale !== null && gestureEvent.scale !== undefined && !isNaN(gestureEvent.scale)) {\n\t this.gesture.scale = gestureEvent.scale;\n\t }\n\t\n\t return gestureEvent;\n\t },\n\t\n\t pointerHold: function pointerHold(pointer, event, eventTarget) {\n\t this.collectEventTargets(pointer, event, eventTarget, 'hold');\n\t },\n\t\n\t pointerUp: function pointerUp(pointer, event, eventTarget, curEventTarget) {\n\t var pointerIndex = this.mouse ? 0 : indexOf(this.pointerIds, getPointerId(pointer));\n\t\n\t clearTimeout(this.holdTimers[pointerIndex]);\n\t\n\t this.collectEventTargets(pointer, event, eventTarget, 'up');\n\t this.collectEventTargets(pointer, event, eventTarget, 'tap');\n\t\n\t this.pointerEnd(pointer, event, eventTarget, curEventTarget);\n\t\n\t this.removePointer(pointer);\n\t },\n\t\n\t pointerCancel: function pointerCancel(pointer, event, eventTarget, curEventTarget) {\n\t var pointerIndex = this.mouse ? 0 : indexOf(this.pointerIds, getPointerId(pointer));\n\t\n\t clearTimeout(this.holdTimers[pointerIndex]);\n\t\n\t this.collectEventTargets(pointer, event, eventTarget, 'cancel');\n\t this.pointerEnd(pointer, event, eventTarget, curEventTarget);\n\t\n\t this.removePointer(pointer);\n\t },\n\t\n\t // http://www.quirksmode.org/dom/events/click.html\n\t // >Events leading to dblclick\n\t //\n\t // IE8 doesn't fire down event before dblclick.\n\t // This workaround tries to fire a tap and doubletap after dblclick\n\t ie8Dblclick: function ie8Dblclick(pointer, event, eventTarget) {\n\t if (this.prevTap && event.clientX === this.prevTap.clientX && event.clientY === this.prevTap.clientY && eventTarget === this.prevTap.target) {\n\t this.downTargets[0] = eventTarget;\n\t this.downTimes[0] = new Date().getTime();\n\t this.collectEventTargets(pointer, event, eventTarget, 'tap');\n\t }\n\t },\n\t\n\t // End interact move events and stop auto-scroll unless inertia is enabled\n\t pointerEnd: function pointerEnd(pointer, event, eventTarget, curEventTarget) {\n\t var endEvent,\n\t target = this.target,\n\t options = target && target.options,\n\t inertiaOptions = options && this.prepared.name && options[this.prepared.name].inertia,\n\t inertiaStatus = this.inertiaStatus;\n\t\n\t if (this.interacting()) {\n\t if (inertiaStatus.active && !inertiaStatus.ending) {\n\t return;\n\t }\n\t\n\t var pointerSpeed,\n\t now = new Date().getTime(),\n\t inertiaPossible = false,\n\t inertia = false,\n\t smoothEnd = false,\n\t endSnap = checkSnap(target, this.prepared.name) && options[this.prepared.name].snap.endOnly,\n\t endRestrict = checkRestrict(target, this.prepared.name) && options[this.prepared.name].restrict.endOnly,\n\t dx = 0,\n\t dy = 0,\n\t startEvent;\n\t\n\t if (this.dragging) {\n\t if (options.drag.axis === 'x') {\n\t pointerSpeed = Math.abs(this.pointerDelta.client.vx);\n\t } else if (options.drag.axis === 'y') {\n\t pointerSpeed = Math.abs(this.pointerDelta.client.vy);\n\t } else /* options.drag.axis === 'xy'*/{\n\t pointerSpeed = this.pointerDelta.client.speed;\n\t }\n\t } else {\n\t pointerSpeed = this.pointerDelta.client.speed;\n\t }\n\t\n\t // check if inertia should be started\n\t inertiaPossible = inertiaOptions && inertiaOptions.enabled && this.prepared.name !== 'gesture' && event !== inertiaStatus.startEvent;\n\t\n\t inertia = inertiaPossible && now - this.curCoords.timeStamp < 50 && pointerSpeed > inertiaOptions.minSpeed && pointerSpeed > inertiaOptions.endSpeed;\n\t\n\t if (inertiaPossible && !inertia && (endSnap || endRestrict)) {\n\t var snapRestrict = {};\n\t\n\t snapRestrict.snap = snapRestrict.restrict = snapRestrict;\n\t\n\t if (endSnap) {\n\t this.setSnapping(this.curCoords.page, snapRestrict);\n\t if (snapRestrict.locked) {\n\t dx += snapRestrict.dx;\n\t dy += snapRestrict.dy;\n\t }\n\t }\n\t\n\t if (endRestrict) {\n\t this.setRestriction(this.curCoords.page, snapRestrict);\n\t if (snapRestrict.restricted) {\n\t dx += snapRestrict.dx;\n\t dy += snapRestrict.dy;\n\t }\n\t }\n\t\n\t if (dx || dy) {\n\t smoothEnd = true;\n\t }\n\t }\n\t\n\t if (inertia || smoothEnd) {\n\t copyCoords(inertiaStatus.upCoords, this.curCoords);\n\t\n\t this.pointers[0] = inertiaStatus.startEvent = startEvent = new InteractEvent(this, event, this.prepared.name, 'inertiastart', this.element);\n\t\n\t inertiaStatus.t0 = now;\n\t\n\t target.fire(inertiaStatus.startEvent);\n\t\n\t if (inertia) {\n\t inertiaStatus.vx0 = this.pointerDelta.client.vx;\n\t inertiaStatus.vy0 = this.pointerDelta.client.vy;\n\t inertiaStatus.v0 = pointerSpeed;\n\t\n\t this.calcInertia(inertiaStatus);\n\t\n\t var page = extend({}, this.curCoords.page),\n\t origin = getOriginXY(target, this.element),\n\t statusObject;\n\t\n\t page.x = page.x + inertiaStatus.xe - origin.x;\n\t page.y = page.y + inertiaStatus.ye - origin.y;\n\t\n\t statusObject = {\n\t useStatusXY: true,\n\t x: page.x,\n\t y: page.y,\n\t dx: 0,\n\t dy: 0,\n\t snap: null\n\t };\n\t\n\t statusObject.snap = statusObject;\n\t\n\t dx = dy = 0;\n\t\n\t if (endSnap) {\n\t var snap = this.setSnapping(this.curCoords.page, statusObject);\n\t\n\t if (snap.locked) {\n\t dx += snap.dx;\n\t dy += snap.dy;\n\t }\n\t }\n\t\n\t if (endRestrict) {\n\t var restrict = this.setRestriction(this.curCoords.page, statusObject);\n\t\n\t if (restrict.restricted) {\n\t dx += restrict.dx;\n\t dy += restrict.dy;\n\t }\n\t }\n\t\n\t inertiaStatus.modifiedXe += dx;\n\t inertiaStatus.modifiedYe += dy;\n\t\n\t inertiaStatus.i = reqFrame(this.boundInertiaFrame);\n\t } else {\n\t inertiaStatus.smoothEnd = true;\n\t inertiaStatus.xe = dx;\n\t inertiaStatus.ye = dy;\n\t\n\t inertiaStatus.sx = inertiaStatus.sy = 0;\n\t\n\t inertiaStatus.i = reqFrame(this.boundSmoothEndFrame);\n\t }\n\t\n\t inertiaStatus.active = true;\n\t return;\n\t }\n\t\n\t if (endSnap || endRestrict) {\n\t // fire a move event at the snapped coordinates\n\t this.pointerMove(pointer, event, eventTarget, curEventTarget, true);\n\t }\n\t }\n\t\n\t if (this.dragging) {\n\t endEvent = new InteractEvent(this, event, 'drag', 'end', this.element);\n\t\n\t var draggableElement = this.element,\n\t drop = this.getDrop(endEvent, event, draggableElement);\n\t\n\t this.dropTarget = drop.dropzone;\n\t this.dropElement = drop.element;\n\t\n\t var dropEvents = this.getDropEvents(event, endEvent);\n\t\n\t if (dropEvents.leave) {\n\t this.prevDropTarget.fire(dropEvents.leave);\n\t }\n\t if (dropEvents.enter) {\n\t this.dropTarget.fire(dropEvents.enter);\n\t }\n\t if (dropEvents.drop) {\n\t this.dropTarget.fire(dropEvents.drop);\n\t }\n\t if (dropEvents.deactivate) {\n\t this.fireActiveDrops(dropEvents.deactivate);\n\t }\n\t\n\t target.fire(endEvent);\n\t } else if (this.resizing) {\n\t endEvent = new InteractEvent(this, event, 'resize', 'end', this.element);\n\t target.fire(endEvent);\n\t } else if (this.gesturing) {\n\t endEvent = new InteractEvent(this, event, 'gesture', 'end', this.element);\n\t target.fire(endEvent);\n\t }\n\t\n\t this.stop(event);\n\t },\n\t\n\t collectDrops: function collectDrops(element) {\n\t var drops = [],\n\t elements = [],\n\t i;\n\t\n\t element = element || this.element;\n\t\n\t // collect all dropzones and their elements which qualify for a drop\n\t for (i = 0; i < interactables.length; i++) {\n\t if (!interactables[i].options.drop.enabled) {\n\t continue;\n\t }\n\t\n\t var current = interactables[i],\n\t accept = current.options.drop.accept;\n\t\n\t // test the draggable element against the dropzone's accept setting\n\t if (isElement(accept) && accept !== element || isString(accept) && !matchesSelector(element, accept)) {\n\t continue;\n\t }\n\t\n\t // query for new elements if necessary\n\t var dropElements = current.selector ? current._context.querySelectorAll(current.selector) : [current._element];\n\t\n\t for (var j = 0, len = dropElements.length; j < len; j++) {\n\t var currentElement = dropElements[j];\n\t\n\t if (currentElement === element) {\n\t continue;\n\t }\n\t\n\t drops.push(current);\n\t elements.push(currentElement);\n\t }\n\t }\n\t\n\t return {\n\t dropzones: drops,\n\t elements: elements\n\t };\n\t },\n\t\n\t fireActiveDrops: function fireActiveDrops(event) {\n\t var i, current, currentElement, prevElement;\n\t\n\t // loop through all active dropzones and trigger event\n\t for (i = 0; i < this.activeDrops.dropzones.length; i++) {\n\t current = this.activeDrops.dropzones[i];\n\t currentElement = this.activeDrops.elements[i];\n\t\n\t // prevent trigger of duplicate events on same element\n\t if (currentElement !== prevElement) {\n\t // set current element as event target\n\t event.target = currentElement;\n\t current.fire(event);\n\t }\n\t prevElement = currentElement;\n\t }\n\t },\n\t\n\t // Collect a new set of possible drops and save them in activeDrops.\n\t // setActiveDrops should always be called when a drag has just started or a\n\t // drag event happens while dynamicDrop is true\n\t setActiveDrops: function setActiveDrops(dragElement) {\n\t // get dropzones and their elements that could receive the draggable\n\t var possibleDrops = this.collectDrops(dragElement, true);\n\t\n\t this.activeDrops.dropzones = possibleDrops.dropzones;\n\t this.activeDrops.elements = possibleDrops.elements;\n\t this.activeDrops.rects = [];\n\t\n\t for (var i = 0; i < this.activeDrops.dropzones.length; i++) {\n\t this.activeDrops.rects[i] = this.activeDrops.dropzones[i].getRect(this.activeDrops.elements[i]);\n\t }\n\t },\n\t\n\t getDrop: function getDrop(dragEvent, event, dragElement) {\n\t var validDrops = [];\n\t\n\t if (dynamicDrop) {\n\t this.setActiveDrops(dragElement);\n\t }\n\t\n\t // collect all dropzones and their elements which qualify for a drop\n\t for (var j = 0; j < this.activeDrops.dropzones.length; j++) {\n\t var current = this.activeDrops.dropzones[j],\n\t currentElement = this.activeDrops.elements[j],\n\t rect = this.activeDrops.rects[j];\n\t\n\t validDrops.push(current.dropCheck(dragEvent, event, this.target, dragElement, currentElement, rect) ? currentElement : null);\n\t }\n\t\n\t // get the most appropriate dropzone based on DOM depth and order\n\t var dropIndex = indexOfDeepestElement(validDrops),\n\t dropzone = this.activeDrops.dropzones[dropIndex] || null,\n\t element = this.activeDrops.elements[dropIndex] || null;\n\t\n\t return {\n\t dropzone: dropzone,\n\t element: element\n\t };\n\t },\n\t\n\t getDropEvents: function getDropEvents(pointerEvent, dragEvent) {\n\t var dropEvents = {\n\t enter: null,\n\t leave: null,\n\t activate: null,\n\t deactivate: null,\n\t move: null,\n\t drop: null\n\t };\n\t\n\t if (this.dropElement !== this.prevDropElement) {\n\t // if there was a prevDropTarget, create a dragleave event\n\t if (this.prevDropTarget) {\n\t dropEvents.leave = {\n\t target: this.prevDropElement,\n\t dropzone: this.prevDropTarget,\n\t relatedTarget: dragEvent.target,\n\t draggable: dragEvent.interactable,\n\t dragEvent: dragEvent,\n\t interaction: this,\n\t timeStamp: dragEvent.timeStamp,\n\t type: 'dragleave'\n\t };\n\t\n\t dragEvent.dragLeave = this.prevDropElement;\n\t dragEvent.prevDropzone = this.prevDropTarget;\n\t }\n\t // if the dropTarget is not null, create a dragenter event\n\t if (this.dropTarget) {\n\t dropEvents.enter = {\n\t target: this.dropElement,\n\t dropzone: this.dropTarget,\n\t relatedTarget: dragEvent.target,\n\t draggable: dragEvent.interactable,\n\t dragEvent: dragEvent,\n\t interaction: this,\n\t timeStamp: dragEvent.timeStamp,\n\t type: 'dragenter'\n\t };\n\t\n\t dragEvent.dragEnter = this.dropElement;\n\t dragEvent.dropzone = this.dropTarget;\n\t }\n\t }\n\t\n\t if (dragEvent.type === 'dragend' && this.dropTarget) {\n\t dropEvents.drop = {\n\t target: this.dropElement,\n\t dropzone: this.dropTarget,\n\t relatedTarget: dragEvent.target,\n\t draggable: dragEvent.interactable,\n\t dragEvent: dragEvent,\n\t interaction: this,\n\t timeStamp: dragEvent.timeStamp,\n\t type: 'drop'\n\t };\n\t\n\t dragEvent.dropzone = this.dropTarget;\n\t }\n\t if (dragEvent.type === 'dragstart') {\n\t dropEvents.activate = {\n\t target: null,\n\t dropzone: null,\n\t relatedTarget: dragEvent.target,\n\t draggable: dragEvent.interactable,\n\t dragEvent: dragEvent,\n\t interaction: this,\n\t timeStamp: dragEvent.timeStamp,\n\t type: 'dropactivate'\n\t };\n\t }\n\t if (dragEvent.type === 'dragend') {\n\t dropEvents.deactivate = {\n\t target: null,\n\t dropzone: null,\n\t relatedTarget: dragEvent.target,\n\t draggable: dragEvent.interactable,\n\t dragEvent: dragEvent,\n\t interaction: this,\n\t timeStamp: dragEvent.timeStamp,\n\t type: 'dropdeactivate'\n\t };\n\t }\n\t if (dragEvent.type === 'dragmove' && this.dropTarget) {\n\t dropEvents.move = {\n\t target: this.dropElement,\n\t dropzone: this.dropTarget,\n\t relatedTarget: dragEvent.target,\n\t draggable: dragEvent.interactable,\n\t dragEvent: dragEvent,\n\t interaction: this,\n\t dragmove: dragEvent,\n\t timeStamp: dragEvent.timeStamp,\n\t type: 'dropmove'\n\t };\n\t dragEvent.dropzone = this.dropTarget;\n\t }\n\t\n\t return dropEvents;\n\t },\n\t\n\t currentAction: function currentAction() {\n\t return this.dragging && 'drag' || this.resizing && 'resize' || this.gesturing && 'gesture' || null;\n\t },\n\t\n\t interacting: function interacting() {\n\t return this.dragging || this.resizing || this.gesturing;\n\t },\n\t\n\t clearTargets: function clearTargets() {\n\t this.target = this.element = null;\n\t\n\t this.dropTarget = this.dropElement = this.prevDropTarget = this.prevDropElement = null;\n\t },\n\t\n\t stop: function stop(event) {\n\t if (this.interacting()) {\n\t autoScroll.stop();\n\t this.matches = [];\n\t this.matchElements = [];\n\t\n\t var target = this.target;\n\t\n\t if (target.options.styleCursor) {\n\t target._doc.documentElement.style.cursor = '';\n\t }\n\t\n\t // prevent Default only if were previously interacting\n\t if (event && isFunction(event.preventDefault)) {\n\t this.checkAndPreventDefault(event, target, this.element);\n\t }\n\t\n\t if (this.dragging) {\n\t this.activeDrops.dropzones = this.activeDrops.elements = this.activeDrops.rects = null;\n\t }\n\t }\n\t\n\t this.clearTargets();\n\t\n\t this.pointerIsDown = this.snapStatus.locked = this.dragging = this.resizing = this.gesturing = false;\n\t this.prepared.name = this.prevEvent = null;\n\t this.inertiaStatus.resumeDx = this.inertiaStatus.resumeDy = 0;\n\t\n\t // remove pointers if their ID isn't in this.pointerIds\n\t for (var i = 0; i < this.pointers.length; i++) {\n\t if (indexOf(this.pointerIds, getPointerId(this.pointers[i])) === -1) {\n\t this.pointers.splice(i, 1);\n\t }\n\t }\n\t },\n\t\n\t inertiaFrame: function inertiaFrame() {\n\t var inertiaStatus = this.inertiaStatus,\n\t options = this.target.options[this.prepared.name].inertia,\n\t lambda = options.resistance,\n\t t = new Date().getTime() / 1000 - inertiaStatus.t0;\n\t\n\t if (t < inertiaStatus.te) {\n\t var progress = 1 - (Math.exp(-lambda * t) - inertiaStatus.lambda_v0) / inertiaStatus.one_ve_v0;\n\t\n\t if (inertiaStatus.modifiedXe === inertiaStatus.xe && inertiaStatus.modifiedYe === inertiaStatus.ye) {\n\t inertiaStatus.sx = inertiaStatus.xe * progress;\n\t inertiaStatus.sy = inertiaStatus.ye * progress;\n\t } else {\n\t var quadPoint = getQuadraticCurvePoint(0, 0, inertiaStatus.xe, inertiaStatus.ye, inertiaStatus.modifiedXe, inertiaStatus.modifiedYe, progress);\n\t\n\t inertiaStatus.sx = quadPoint.x;\n\t inertiaStatus.sy = quadPoint.y;\n\t }\n\t\n\t this.pointerMove(inertiaStatus.startEvent, inertiaStatus.startEvent);\n\t\n\t inertiaStatus.i = reqFrame(this.boundInertiaFrame);\n\t } else {\n\t inertiaStatus.ending = true;\n\t\n\t inertiaStatus.sx = inertiaStatus.modifiedXe;\n\t inertiaStatus.sy = inertiaStatus.modifiedYe;\n\t\n\t this.pointerMove(inertiaStatus.startEvent, inertiaStatus.startEvent);\n\t this.pointerEnd(inertiaStatus.startEvent, inertiaStatus.startEvent);\n\t\n\t inertiaStatus.active = inertiaStatus.ending = false;\n\t }\n\t },\n\t\n\t smoothEndFrame: function smoothEndFrame() {\n\t var inertiaStatus = this.inertiaStatus,\n\t t = new Date().getTime() - inertiaStatus.t0,\n\t duration = this.target.options[this.prepared.name].inertia.smoothEndDuration;\n\t\n\t if (t < duration) {\n\t inertiaStatus.sx = easeOutQuad(t, 0, inertiaStatus.xe, duration);\n\t inertiaStatus.sy = easeOutQuad(t, 0, inertiaStatus.ye, duration);\n\t\n\t this.pointerMove(inertiaStatus.startEvent, inertiaStatus.startEvent);\n\t\n\t inertiaStatus.i = reqFrame(this.boundSmoothEndFrame);\n\t } else {\n\t inertiaStatus.ending = true;\n\t\n\t inertiaStatus.sx = inertiaStatus.xe;\n\t inertiaStatus.sy = inertiaStatus.ye;\n\t\n\t this.pointerMove(inertiaStatus.startEvent, inertiaStatus.startEvent);\n\t this.pointerEnd(inertiaStatus.startEvent, inertiaStatus.startEvent);\n\t\n\t inertiaStatus.smoothEnd = inertiaStatus.active = inertiaStatus.ending = false;\n\t }\n\t },\n\t\n\t addPointer: function addPointer(pointer) {\n\t var id = getPointerId(pointer),\n\t index = this.mouse ? 0 : indexOf(this.pointerIds, id);\n\t\n\t if (index === -1) {\n\t index = this.pointerIds.length;\n\t }\n\t\n\t this.pointerIds[index] = id;\n\t this.pointers[index] = pointer;\n\t\n\t return index;\n\t },\n\t\n\t removePointer: function removePointer(pointer) {\n\t var id = getPointerId(pointer),\n\t index = this.mouse ? 0 : indexOf(this.pointerIds, id);\n\t\n\t if (index === -1) {\n\t return;\n\t }\n\t\n\t this.pointers.splice(index, 1);\n\t this.pointerIds.splice(index, 1);\n\t this.downTargets.splice(index, 1);\n\t this.downTimes.splice(index, 1);\n\t this.holdTimers.splice(index, 1);\n\t },\n\t\n\t recordPointer: function recordPointer(pointer) {\n\t var index = this.mouse ? 0 : indexOf(this.pointerIds, getPointerId(pointer));\n\t\n\t if (index === -1) {\n\t return;\n\t }\n\t\n\t this.pointers[index] = pointer;\n\t },\n\t\n\t collectEventTargets: function collectEventTargets(pointer, event, eventTarget, eventType) {\n\t var pointerIndex = this.mouse ? 0 : indexOf(this.pointerIds, getPointerId(pointer));\n\t\n\t // do not fire a tap event if the pointer was moved before being lifted\n\t if (eventType === 'tap' && (this.pointerWasMoved\n\t // or if the pointerup target is different to the pointerdown target\n\t || !(this.downTargets[pointerIndex] && this.downTargets[pointerIndex] === eventTarget))) {\n\t return;\n\t }\n\t\n\t var targets = [],\n\t elements = [],\n\t element = eventTarget;\n\t\n\t function collectSelectors(interactable, selector, context) {\n\t var els = ie8MatchesSelector ? context.querySelectorAll(selector) : undefined;\n\t\n\t if (interactable._iEvents[eventType] && isElement(element) && inContext(interactable, element) && !testIgnore(interactable, element, eventTarget) && testAllow(interactable, element, eventTarget) && matchesSelector(element, selector, els)) {\n\t targets.push(interactable);\n\t elements.push(element);\n\t }\n\t }\n\t\n\t while (element) {\n\t if (interact.isSet(element) && interact(element)._iEvents[eventType]) {\n\t targets.push(interact(element));\n\t elements.push(element);\n\t }\n\t\n\t interactables.forEachSelector(collectSelectors);\n\t\n\t element = parentElement(element);\n\t }\n\t\n\t // create the tap event even if there are no listeners so that\n\t // doubletap can still be created and fired\n\t if (targets.length || eventType === 'tap') {\n\t this.firePointers(pointer, event, eventTarget, targets, elements, eventType);\n\t }\n\t },\n\t\n\t firePointers: function firePointers(pointer, event, eventTarget, targets, elements, eventType) {\n\t var pointerIndex = this.mouse ? 0 : indexOf(this.pointerIds, getPointerId(pointer)),\n\t pointerEvent = {},\n\t i,\n\t\n\t // for tap events\n\t interval,\n\t createNewDoubleTap;\n\t\n\t // if it's a doubletap then the event properties would have been\n\t // copied from the tap event and provided as the pointer argument\n\t if (eventType === 'doubletap') {\n\t pointerEvent = pointer;\n\t } else {\n\t pointerExtend(pointerEvent, event);\n\t if (event !== pointer) {\n\t pointerExtend(pointerEvent, pointer);\n\t }\n\t\n\t pointerEvent.preventDefault = preventOriginalDefault;\n\t pointerEvent.stopPropagation = InteractEvent.prototype.stopPropagation;\n\t pointerEvent.stopImmediatePropagation = InteractEvent.prototype.stopImmediatePropagation;\n\t pointerEvent.interaction = this;\n\t\n\t pointerEvent.timeStamp = new Date().getTime();\n\t pointerEvent.originalEvent = event;\n\t pointerEvent.originalPointer = pointer;\n\t pointerEvent.type = eventType;\n\t pointerEvent.pointerId = getPointerId(pointer);\n\t pointerEvent.pointerType = this.mouse ? 'mouse' : !supportsPointerEvent ? 'touch' : isString(pointer.pointerType) ? pointer.pointerType : [,, 'touch', 'pen', 'mouse'][pointer.pointerType];\n\t }\n\t\n\t if (eventType === 'tap') {\n\t pointerEvent.dt = pointerEvent.timeStamp - this.downTimes[pointerIndex];\n\t\n\t interval = pointerEvent.timeStamp - this.tapTime;\n\t createNewDoubleTap = !!(this.prevTap && this.prevTap.type !== 'doubletap' && this.prevTap.target === pointerEvent.target && interval < 500);\n\t\n\t pointerEvent.double = createNewDoubleTap;\n\t\n\t this.tapTime = pointerEvent.timeStamp;\n\t }\n\t\n\t for (i = 0; i < targets.length; i++) {\n\t pointerEvent.currentTarget = elements[i];\n\t pointerEvent.interactable = targets[i];\n\t targets[i].fire(pointerEvent);\n\t\n\t if (pointerEvent.immediatePropagationStopped || pointerEvent.propagationStopped && elements[i + 1] !== pointerEvent.currentTarget) {\n\t break;\n\t }\n\t }\n\t\n\t if (createNewDoubleTap) {\n\t var doubleTap = {};\n\t\n\t extend(doubleTap, pointerEvent);\n\t\n\t doubleTap.dt = interval;\n\t doubleTap.type = 'doubletap';\n\t\n\t this.collectEventTargets(doubleTap, event, eventTarget, 'doubletap');\n\t\n\t this.prevTap = doubleTap;\n\t } else if (eventType === 'tap') {\n\t this.prevTap = pointerEvent;\n\t }\n\t },\n\t\n\t validateSelector: function validateSelector(pointer, event, matches, matchElements) {\n\t for (var i = 0, len = matches.length; i < len; i++) {\n\t var match = matches[i],\n\t matchElement = matchElements[i],\n\t action = validateAction(match.getAction(pointer, event, this, matchElement), match);\n\t\n\t if (action && withinInteractionLimit(match, matchElement, action)) {\n\t this.target = match;\n\t this.element = matchElement;\n\t\n\t return action;\n\t }\n\t }\n\t },\n\t\n\t setSnapping: function setSnapping(pageCoords, status) {\n\t var snap = this.target.options[this.prepared.name].snap,\n\t targets = [],\n\t target,\n\t page,\n\t i;\n\t\n\t status = status || this.snapStatus;\n\t\n\t if (status.useStatusXY) {\n\t page = { x: status.x, y: status.y };\n\t } else {\n\t var origin = getOriginXY(this.target, this.element);\n\t\n\t page = extend({}, pageCoords);\n\t\n\t page.x -= origin.x;\n\t page.y -= origin.y;\n\t }\n\t\n\t status.realX = page.x;\n\t status.realY = page.y;\n\t\n\t page.x = page.x - this.inertiaStatus.resumeDx;\n\t page.y = page.y - this.inertiaStatus.resumeDy;\n\t\n\t var len = snap.targets ? snap.targets.length : 0;\n\t\n\t for (var relIndex = 0; relIndex < this.snapOffsets.length; relIndex++) {\n\t var relative = {\n\t x: page.x - this.snapOffsets[relIndex].x,\n\t y: page.y - this.snapOffsets[relIndex].y\n\t };\n\t\n\t for (i = 0; i < len; i++) {\n\t if (isFunction(snap.targets[i])) {\n\t target = snap.targets[i](relative.x, relative.y, this);\n\t } else {\n\t target = snap.targets[i];\n\t }\n\t\n\t if (!target) {\n\t continue;\n\t }\n\t\n\t targets.push({\n\t x: isNumber(target.x) ? target.x + this.snapOffsets[relIndex].x : relative.x,\n\t y: isNumber(target.y) ? target.y + this.snapOffsets[relIndex].y : relative.y,\n\t\n\t range: isNumber(target.range) ? target.range : snap.range\n\t });\n\t }\n\t }\n\t\n\t var closest = {\n\t target: null,\n\t inRange: false,\n\t distance: 0,\n\t range: 0,\n\t dx: 0,\n\t dy: 0\n\t };\n\t\n\t for (i = 0, len = targets.length; i < len; i++) {\n\t target = targets[i];\n\t\n\t var range = target.range,\n\t dx = target.x - page.x,\n\t dy = target.y - page.y,\n\t distance = hypot(dx, dy),\n\t inRange = distance <= range;\n\t\n\t // Infinite targets count as being out of range\n\t // compared to non infinite ones that are in range\n\t if (range === Infinity && closest.inRange && closest.range !== Infinity) {\n\t inRange = false;\n\t }\n\t\n\t if (!closest.target || (inRange\n\t // is the closest target in range?\n\t ? closest.inRange && range !== Infinity\n\t // the pointer is relatively deeper in this target\n\t ? distance / range < closest.distance / closest.range\n\t // this target has Infinite range and the closest doesn't\n\t : range === Infinity && closest.range !== Infinity ||\n\t // OR this target is closer that the previous closest\n\t distance < closest.distance :\n\t // The other is not in range and the pointer is closer to this target\n\t !closest.inRange && distance < closest.distance)) {\n\t if (range === Infinity) {\n\t inRange = true;\n\t }\n\t\n\t closest.target = target;\n\t closest.distance = distance;\n\t closest.range = range;\n\t closest.inRange = inRange;\n\t closest.dx = dx;\n\t closest.dy = dy;\n\t\n\t status.range = range;\n\t }\n\t }\n\t\n\t var snapChanged;\n\t\n\t if (closest.target) {\n\t snapChanged = status.snappedX !== closest.target.x || status.snappedY !== closest.target.y;\n\t\n\t status.snappedX = closest.target.x;\n\t status.snappedY = closest.target.y;\n\t } else {\n\t snapChanged = true;\n\t\n\t status.snappedX = NaN;\n\t status.snappedY = NaN;\n\t }\n\t\n\t status.dx = closest.dx;\n\t status.dy = closest.dy;\n\t\n\t status.changed = snapChanged || closest.inRange && !status.locked;\n\t status.locked = closest.inRange;\n\t\n\t return status;\n\t },\n\t\n\t setRestriction: function setRestriction(pageCoords, status) {\n\t var target = this.target,\n\t restrict = target && target.options[this.prepared.name].restrict,\n\t restriction = restrict && restrict.restriction,\n\t page;\n\t\n\t if (!restriction) {\n\t return status;\n\t }\n\t\n\t status = status || this.restrictStatus;\n\t\n\t page = status.useStatusXY ? page = { x: status.x, y: status.y } : page = extend({}, pageCoords);\n\t\n\t if (status.snap && status.snap.locked) {\n\t page.x += status.snap.dx || 0;\n\t page.y += status.snap.dy || 0;\n\t }\n\t\n\t page.x -= this.inertiaStatus.resumeDx;\n\t page.y -= this.inertiaStatus.resumeDy;\n\t\n\t status.dx = 0;\n\t status.dy = 0;\n\t status.restricted = false;\n\t\n\t var rect, restrictedX, restrictedY;\n\t\n\t if (isString(restriction)) {\n\t if (restriction === 'parent') {\n\t restriction = parentElement(this.element);\n\t } else if (restriction === 'self') {\n\t restriction = target.getRect(this.element);\n\t } else {\n\t restriction = closest(this.element, restriction);\n\t }\n\t\n\t if (!restriction) {\n\t return status;\n\t }\n\t }\n\t\n\t if (isFunction(restriction)) {\n\t restriction = restriction(page.x, page.y, this.element);\n\t }\n\t\n\t if (isElement(restriction)) {\n\t restriction = getElementRect(restriction);\n\t }\n\t\n\t rect = restriction;\n\t\n\t if (!restriction) {\n\t restrictedX = page.x;\n\t restrictedY = page.y;\n\t }\n\t // object is assumed to have\n\t // x, y, width, height or\n\t // left, top, right, bottom\n\t else if ('x' in restriction && 'y' in restriction) {\n\t restrictedX = Math.max(Math.min(rect.x + rect.width - this.restrictOffset.right, page.x), rect.x + this.restrictOffset.left);\n\t restrictedY = Math.max(Math.min(rect.y + rect.height - this.restrictOffset.bottom, page.y), rect.y + this.restrictOffset.top);\n\t } else {\n\t restrictedX = Math.max(Math.min(rect.right - this.restrictOffset.right, page.x), rect.left + this.restrictOffset.left);\n\t restrictedY = Math.max(Math.min(rect.bottom - this.restrictOffset.bottom, page.y), rect.top + this.restrictOffset.top);\n\t }\n\t\n\t status.dx = restrictedX - page.x;\n\t status.dy = restrictedY - page.y;\n\t\n\t status.changed = status.restrictedX !== restrictedX || status.restrictedY !== restrictedY;\n\t status.restricted = !!(status.dx || status.dy);\n\t\n\t status.restrictedX = restrictedX;\n\t status.restrictedY = restrictedY;\n\t\n\t return status;\n\t },\n\t\n\t checkAndPreventDefault: function checkAndPreventDefault(event, interactable, element) {\n\t if (!(interactable = interactable || this.target)) {\n\t return;\n\t }\n\t\n\t var options = interactable.options,\n\t prevent = options.preventDefault;\n\t\n\t if (prevent === 'auto' && element && !/^(input|select|textarea)$/i.test(event.target.nodeName)) {\n\t // do not preventDefault on pointerdown if the prepared action is a drag\n\t // and dragging can only start from a certain direction - this allows\n\t // a touch to pan the viewport if a drag isn't in the right direction\n\t if (/down|start/i.test(event.type) && this.prepared.name === 'drag' && options.drag.axis !== 'xy') {\n\t return;\n\t }\n\t\n\t // with manualStart, only preventDefault while interacting\n\t if (options[this.prepared.name] && options[this.prepared.name].manualStart && !this.interacting()) {\n\t return;\n\t }\n\t\n\t event.preventDefault();\n\t return;\n\t }\n\t\n\t if (prevent === 'always') {\n\t event.preventDefault();\n\t return;\n\t }\n\t },\n\t\n\t calcInertia: function calcInertia(status) {\n\t var inertiaOptions = this.target.options[this.prepared.name].inertia,\n\t lambda = inertiaOptions.resistance,\n\t inertiaDur = -Math.log(inertiaOptions.endSpeed / status.v0) / lambda;\n\t\n\t status.x0 = this.prevEvent.pageX;\n\t status.y0 = this.prevEvent.pageY;\n\t status.t0 = status.startEvent.timeStamp / 1000;\n\t status.sx = status.sy = 0;\n\t\n\t status.modifiedXe = status.xe = (status.vx0 - inertiaDur) / lambda;\n\t status.modifiedYe = status.ye = (status.vy0 - inertiaDur) / lambda;\n\t status.te = inertiaDur;\n\t\n\t status.lambda_v0 = lambda / status.v0;\n\t status.one_ve_v0 = 1 - inertiaOptions.endSpeed / status.v0;\n\t },\n\t\n\t autoScrollMove: function autoScrollMove(pointer) {\n\t if (!(this.interacting() && checkAutoScroll(this.target, this.prepared.name))) {\n\t return;\n\t }\n\t\n\t if (this.inertiaStatus.active) {\n\t autoScroll.x = autoScroll.y = 0;\n\t return;\n\t }\n\t\n\t var top,\n\t right,\n\t bottom,\n\t left,\n\t options = this.target.options[this.prepared.name].autoScroll,\n\t container = options.container || getWindow(this.element);\n\t\n\t if (isWindow(container)) {\n\t left = pointer.clientX < autoScroll.margin;\n\t top = pointer.clientY < autoScroll.margin;\n\t right = pointer.clientX > container.innerWidth - autoScroll.margin;\n\t bottom = pointer.clientY > container.innerHeight - autoScroll.margin;\n\t } else {\n\t var rect = getElementClientRect(container);\n\t\n\t left = pointer.clientX < rect.left + autoScroll.margin;\n\t top = pointer.clientY < rect.top + autoScroll.margin;\n\t right = pointer.clientX > rect.right - autoScroll.margin;\n\t bottom = pointer.clientY > rect.bottom - autoScroll.margin;\n\t }\n\t\n\t autoScroll.x = right ? 1 : left ? -1 : 0;\n\t autoScroll.y = bottom ? 1 : top ? -1 : 0;\n\t\n\t if (!autoScroll.isScrolling) {\n\t // set the autoScroll properties to those of the target\n\t autoScroll.margin = options.margin;\n\t autoScroll.speed = options.speed;\n\t\n\t autoScroll.start(this);\n\t }\n\t },\n\t\n\t _updateEventTargets: function _updateEventTargets(target, currentTarget) {\n\t this._eventTarget = target;\n\t this._curEventTarget = currentTarget;\n\t }\n\t\n\t };\n\t\n\t function getInteractionFromPointer(pointer, eventType, eventTarget) {\n\t var i = 0,\n\t len = interactions.length,\n\t mouseEvent = /mouse/i.test(pointer.pointerType || eventType)\n\t // MSPointerEvent.MSPOINTER_TYPE_MOUSE\n\t || pointer.pointerType === 4,\n\t interaction;\n\t\n\t var id = getPointerId(pointer);\n\t\n\t // try to resume inertia with a new pointer\n\t if (/down|start/i.test(eventType)) {\n\t for (i = 0; i < len; i++) {\n\t interaction = interactions[i];\n\t\n\t var element = eventTarget;\n\t\n\t if (interaction.inertiaStatus.active && interaction.target.options[interaction.prepared.name].inertia.allowResume && interaction.mouse === mouseEvent) {\n\t while (element) {\n\t // if the element is the interaction element\n\t if (element === interaction.element) {\n\t return interaction;\n\t }\n\t element = parentElement(element);\n\t }\n\t }\n\t }\n\t }\n\t\n\t // if it's a mouse interaction\n\t if (mouseEvent || !supportsTouch || supportsPointerEvent) {\n\t // find a mouse interaction that's not in inertia phase\n\t for (i = 0; i < len; i++) {\n\t if (interactions[i].mouse && !interactions[i].inertiaStatus.active) {\n\t return interactions[i];\n\t }\n\t }\n\t\n\t // find any interaction specifically for mouse.\n\t // if the eventType is a mousedown, and inertia is active\n\t // ignore the interaction\n\t for (i = 0; i < len; i++) {\n\t if (interactions[i].mouse && !(/down/.test(eventType) && interactions[i].inertiaStatus.active)) {\n\t return interaction;\n\t }\n\t }\n\t\n\t // create a new interaction for mouse\n\t interaction = new Interaction();\n\t interaction.mouse = true;\n\t\n\t return interaction;\n\t }\n\t\n\t // get interaction that has this pointer\n\t for (i = 0; i < len; i++) {\n\t if (contains(interactions[i].pointerIds, id)) {\n\t return interactions[i];\n\t }\n\t }\n\t\n\t // at this stage, a pointerUp should not return an interaction\n\t if (/up|end|out/i.test(eventType)) {\n\t return null;\n\t }\n\t\n\t // get first idle interaction\n\t for (i = 0; i < len; i++) {\n\t interaction = interactions[i];\n\t\n\t if ((!interaction.prepared.name || interaction.target.options.gesture.enabled) && !interaction.interacting() && !(!mouseEvent && interaction.mouse)) {\n\t return interaction;\n\t }\n\t }\n\t\n\t return new Interaction();\n\t }\n\t\n\t function doOnInteractions(method) {\n\t return function (event) {\n\t var interaction,\n\t eventTarget = getActualElement(event.path ? event.path[0] : event.target),\n\t curEventTarget = getActualElement(event.currentTarget),\n\t i;\n\t\n\t if (supportsTouch && /touch/.test(event.type)) {\n\t prevTouchTime = new Date().getTime();\n\t\n\t for (i = 0; i < event.changedTouches.length; i++) {\n\t var pointer = event.changedTouches[i];\n\t\n\t interaction = getInteractionFromPointer(pointer, event.type, eventTarget);\n\t\n\t if (!interaction) {\n\t continue;\n\t }\n\t\n\t interaction._updateEventTargets(eventTarget, curEventTarget);\n\t\n\t interaction[method](pointer, event, eventTarget, curEventTarget);\n\t }\n\t } else {\n\t if (!supportsPointerEvent && /mouse/.test(event.type)) {\n\t // ignore mouse events while touch interactions are active\n\t for (i = 0; i < interactions.length; i++) {\n\t if (!interactions[i].mouse && interactions[i].pointerIsDown) {\n\t return;\n\t }\n\t }\n\t\n\t // try to ignore mouse events that are simulated by the browser\n\t // after a touch event\n\t if (new Date().getTime() - prevTouchTime < 500) {\n\t return;\n\t }\n\t }\n\t\n\t interaction = getInteractionFromPointer(event, event.type, eventTarget);\n\t\n\t if (!interaction) {\n\t return;\n\t }\n\t\n\t interaction._updateEventTargets(eventTarget, curEventTarget);\n\t\n\t interaction[method](event, event, eventTarget, curEventTarget);\n\t }\n\t };\n\t }\n\t\n\t function InteractEvent(interaction, event, action, phase, element, related) {\n\t var client,\n\t page,\n\t target = interaction.target,\n\t snapStatus = interaction.snapStatus,\n\t restrictStatus = interaction.restrictStatus,\n\t pointers = interaction.pointers,\n\t deltaSource = (target && target.options || defaultOptions).deltaSource,\n\t sourceX = deltaSource + 'X',\n\t sourceY = deltaSource + 'Y',\n\t options = target ? target.options : defaultOptions,\n\t origin = getOriginXY(target, element),\n\t starting = phase === 'start',\n\t ending = phase === 'end',\n\t coords = starting ? interaction.startCoords : interaction.curCoords;\n\t\n\t element = element || interaction.element;\n\t\n\t page = extend({}, coords.page);\n\t client = extend({}, coords.client);\n\t\n\t page.x -= origin.x;\n\t page.y -= origin.y;\n\t\n\t client.x -= origin.x;\n\t client.y -= origin.y;\n\t\n\t var relativePoints = options[action].snap && options[action].snap.relativePoints;\n\t\n\t if (checkSnap(target, action) && !(starting && relativePoints && relativePoints.length)) {\n\t this.snap = {\n\t range: snapStatus.range,\n\t locked: snapStatus.locked,\n\t x: snapStatus.snappedX,\n\t y: snapStatus.snappedY,\n\t realX: snapStatus.realX,\n\t realY: snapStatus.realY,\n\t dx: snapStatus.dx,\n\t dy: snapStatus.dy\n\t };\n\t\n\t if (snapStatus.locked) {\n\t page.x += snapStatus.dx;\n\t page.y += snapStatus.dy;\n\t client.x += snapStatus.dx;\n\t client.y += snapStatus.dy;\n\t }\n\t }\n\t\n\t if (checkRestrict(target, action) && !(starting && options[action].restrict.elementRect) && restrictStatus.restricted) {\n\t page.x += restrictStatus.dx;\n\t page.y += restrictStatus.dy;\n\t client.x += restrictStatus.dx;\n\t client.y += restrictStatus.dy;\n\t\n\t this.restrict = {\n\t dx: restrictStatus.dx,\n\t dy: restrictStatus.dy\n\t };\n\t }\n\t\n\t this.pageX = page.x;\n\t this.pageY = page.y;\n\t this.clientX = client.x;\n\t this.clientY = client.y;\n\t\n\t this.x0 = interaction.startCoords.page.x - origin.x;\n\t this.y0 = interaction.startCoords.page.y - origin.y;\n\t this.clientX0 = interaction.startCoords.client.x - origin.x;\n\t this.clientY0 = interaction.startCoords.client.y - origin.y;\n\t this.ctrlKey = event.ctrlKey;\n\t this.altKey = event.altKey;\n\t this.shiftKey = event.shiftKey;\n\t this.metaKey = event.metaKey;\n\t this.button = event.button;\n\t this.buttons = event.buttons;\n\t this.target = element;\n\t this.t0 = interaction.downTimes[0];\n\t this.type = action + (phase || '');\n\t\n\t this.interaction = interaction;\n\t this.interactable = target;\n\t\n\t var inertiaStatus = interaction.inertiaStatus;\n\t\n\t if (inertiaStatus.active) {\n\t this.detail = 'inertia';\n\t }\n\t\n\t if (related) {\n\t this.relatedTarget = related;\n\t }\n\t\n\t // end event dx, dy is difference between start and end points\n\t if (ending) {\n\t if (deltaSource === 'client') {\n\t this.dx = client.x - interaction.startCoords.client.x;\n\t this.dy = client.y - interaction.startCoords.client.y;\n\t } else {\n\t this.dx = page.x - interaction.startCoords.page.x;\n\t this.dy = page.y - interaction.startCoords.page.y;\n\t }\n\t } else if (starting) {\n\t this.dx = 0;\n\t this.dy = 0;\n\t }\n\t // copy properties from previousmove if starting inertia\n\t else if (phase === 'inertiastart') {\n\t this.dx = interaction.prevEvent.dx;\n\t this.dy = interaction.prevEvent.dy;\n\t } else {\n\t if (deltaSource === 'client') {\n\t this.dx = client.x - interaction.prevEvent.clientX;\n\t this.dy = client.y - interaction.prevEvent.clientY;\n\t } else {\n\t this.dx = page.x - interaction.prevEvent.pageX;\n\t this.dy = page.y - interaction.prevEvent.pageY;\n\t }\n\t }\n\t if (interaction.prevEvent && interaction.prevEvent.detail === 'inertia' && !inertiaStatus.active && options[action].inertia && options[action].inertia.zeroResumeDelta) {\n\t inertiaStatus.resumeDx += this.dx;\n\t inertiaStatus.resumeDy += this.dy;\n\t\n\t this.dx = this.dy = 0;\n\t }\n\t\n\t if (action === 'resize' && interaction.resizeAxes) {\n\t if (options.resize.square) {\n\t if (interaction.resizeAxes === 'y') {\n\t this.dx = this.dy;\n\t } else {\n\t this.dy = this.dx;\n\t }\n\t this.axes = 'xy';\n\t } else {\n\t this.axes = interaction.resizeAxes;\n\t\n\t if (interaction.resizeAxes === 'x') {\n\t this.dy = 0;\n\t } else if (interaction.resizeAxes === 'y') {\n\t this.dx = 0;\n\t }\n\t }\n\t } else if (action === 'gesture') {\n\t this.touches = [pointers[0], pointers[1]];\n\t\n\t if (starting) {\n\t this.distance = touchDistance(pointers, deltaSource);\n\t this.box = touchBBox(pointers);\n\t this.scale = 1;\n\t this.ds = 0;\n\t this.angle = touchAngle(pointers, undefined, deltaSource);\n\t this.da = 0;\n\t } else if (ending || event instanceof InteractEvent) {\n\t this.distance = interaction.prevEvent.distance;\n\t this.box = interaction.prevEvent.box;\n\t this.scale = interaction.prevEvent.scale;\n\t this.ds = this.scale - 1;\n\t this.angle = interaction.prevEvent.angle;\n\t this.da = this.angle - interaction.gesture.startAngle;\n\t } else {\n\t this.distance = touchDistance(pointers, deltaSource);\n\t this.box = touchBBox(pointers);\n\t this.scale = this.distance / interaction.gesture.startDistance;\n\t this.angle = touchAngle(pointers, interaction.gesture.prevAngle, deltaSource);\n\t\n\t this.ds = this.scale - interaction.gesture.prevScale;\n\t this.da = this.angle - interaction.gesture.prevAngle;\n\t }\n\t }\n\t\n\t if (starting) {\n\t this.timeStamp = interaction.downTimes[0];\n\t this.dt = 0;\n\t this.duration = 0;\n\t this.speed = 0;\n\t this.velocityX = 0;\n\t this.velocityY = 0;\n\t } else if (phase === 'inertiastart') {\n\t this.timeStamp = interaction.prevEvent.timeStamp;\n\t this.dt = interaction.prevEvent.dt;\n\t this.duration = interaction.prevEvent.duration;\n\t this.speed = interaction.prevEvent.speed;\n\t this.velocityX = interaction.prevEvent.velocityX;\n\t this.velocityY = interaction.prevEvent.velocityY;\n\t } else {\n\t this.timeStamp = new Date().getTime();\n\t this.dt = this.timeStamp - interaction.prevEvent.timeStamp;\n\t this.duration = this.timeStamp - interaction.downTimes[0];\n\t\n\t if (event instanceof InteractEvent) {\n\t var dx = this[sourceX] - interaction.prevEvent[sourceX],\n\t dy = this[sourceY] - interaction.prevEvent[sourceY],\n\t dt = this.dt / 1000;\n\t\n\t this.speed = hypot(dx, dy) / dt;\n\t this.velocityX = dx / dt;\n\t this.velocityY = dy / dt;\n\t }\n\t // if normal move or end event, use previous user event coords\n\t else {\n\t // speed and velocity in pixels per second\n\t this.speed = interaction.pointerDelta[deltaSource].speed;\n\t this.velocityX = interaction.pointerDelta[deltaSource].vx;\n\t this.velocityY = interaction.pointerDelta[deltaSource].vy;\n\t }\n\t }\n\t\n\t if ((ending || phase === 'inertiastart') && interaction.prevEvent.speed > 600 && this.timeStamp - interaction.prevEvent.timeStamp < 150) {\n\t var angle = 180 * Math.atan2(interaction.prevEvent.velocityY, interaction.prevEvent.velocityX) / Math.PI,\n\t overlap = 22.5;\n\t\n\t if (angle < 0) {\n\t angle += 360;\n\t }\n\t\n\t var left = 135 - overlap <= angle && angle < 225 + overlap,\n\t up = 225 - overlap <= angle && angle < 315 + overlap,\n\t right = !left && (315 - overlap <= angle || angle < 45 + overlap),\n\t down = !up && 45 - overlap <= angle && angle < 135 + overlap;\n\t\n\t this.swipe = {\n\t up: up,\n\t down: down,\n\t left: left,\n\t right: right,\n\t angle: angle,\n\t speed: interaction.prevEvent.speed,\n\t velocity: {\n\t x: interaction.prevEvent.velocityX,\n\t y: interaction.prevEvent.velocityY\n\t }\n\t };\n\t }\n\t }\n\t\n\t InteractEvent.prototype = {\n\t preventDefault: blank,\n\t stopImmediatePropagation: function stopImmediatePropagation() {\n\t this.immediatePropagationStopped = this.propagationStopped = true;\n\t },\n\t stopPropagation: function stopPropagation() {\n\t this.propagationStopped = true;\n\t }\n\t };\n\t\n\t function preventOriginalDefault() {\n\t this.originalEvent.preventDefault();\n\t }\n\t\n\t function getActionCursor(action) {\n\t var cursor = '';\n\t\n\t if (action.name === 'drag') {\n\t cursor = actionCursors.drag;\n\t }\n\t if (action.name === 'resize') {\n\t if (action.axis) {\n\t cursor = actionCursors[action.name + action.axis];\n\t } else if (action.edges) {\n\t var cursorKey = 'resize',\n\t edgeNames = ['top', 'bottom', 'left', 'right'];\n\t\n\t for (var i = 0; i < 4; i++) {\n\t if (action.edges[edgeNames[i]]) {\n\t cursorKey += edgeNames[i];\n\t }\n\t }\n\t\n\t cursor = actionCursors[cursorKey];\n\t }\n\t }\n\t\n\t return cursor;\n\t }\n\t\n\t function checkResizeEdge(name, value, page, element, interactableElement, rect, margin) {\n\t // false, '', undefined, null\n\t if (!value) {\n\t return false;\n\t }\n\t\n\t // true value, use pointer coords and element rect\n\t if (value === true) {\n\t // if dimensions are negative, \"switch\" edges\n\t var width = isNumber(rect.width) ? rect.width : rect.right - rect.left,\n\t height = isNumber(rect.height) ? rect.height : rect.bottom - rect.top;\n\t\n\t if (width < 0) {\n\t if (name === 'left') {\n\t name = 'right';\n\t } else if (name === 'right') {\n\t name = 'left';\n\t }\n\t }\n\t if (height < 0) {\n\t if (name === 'top') {\n\t name = 'bottom';\n\t } else if (name === 'bottom') {\n\t name = 'top';\n\t }\n\t }\n\t\n\t if (name === 'left') {\n\t return page.x < (width >= 0 ? rect.left : rect.right) + margin;\n\t }\n\t if (name === 'top') {\n\t return page.y < (height >= 0 ? rect.top : rect.bottom) + margin;\n\t }\n\t\n\t if (name === 'right') {\n\t return page.x > (width >= 0 ? rect.right : rect.left) - margin;\n\t }\n\t if (name === 'bottom') {\n\t return page.y > (height >= 0 ? rect.bottom : rect.top) - margin;\n\t }\n\t }\n\t\n\t // the remaining checks require an element\n\t if (!isElement(element)) {\n\t return false;\n\t }\n\t\n\t return isElement(value)\n\t // the value is an element to use as a resize handle\n\t ? value === element\n\t // otherwise check if element matches value as selector\n\t : matchesUpTo(element, value, interactableElement);\n\t }\n\t\n\t function defaultActionChecker(pointer, interaction, element) {\n\t var rect = this.getRect(element),\n\t shouldResize = false,\n\t action = null,\n\t resizeAxes = null,\n\t resizeEdges,\n\t page = extend({}, interaction.curCoords.page),\n\t options = this.options;\n\t\n\t if (!rect) {\n\t return null;\n\t }\n\t\n\t if (actionIsEnabled.resize && options.resize.enabled) {\n\t var resizeOptions = options.resize;\n\t\n\t resizeEdges = {\n\t left: false, right: false, top: false, bottom: false\n\t };\n\t\n\t // if using resize.edges\n\t if (isObject(resizeOptions.edges)) {\n\t for (var edge in resizeEdges) {\n\t resizeEdges[edge] = checkResizeEdge(edge, resizeOptions.edges[edge], page, interaction._eventTarget, element, rect, resizeOptions.margin || margin);\n\t }\n\t\n\t resizeEdges.left = resizeEdges.left && !resizeEdges.right;\n\t resizeEdges.top = resizeEdges.top && !resizeEdges.bottom;\n\t\n\t shouldResize = resizeEdges.left || resizeEdges.right || resizeEdges.top || resizeEdges.bottom;\n\t } else {\n\t var right = options.resize.axis !== 'y' && page.x > rect.right - margin,\n\t bottom = options.resize.axis !== 'x' && page.y > rect.bottom - margin;\n\t\n\t shouldResize = right || bottom;\n\t resizeAxes = (right ? 'x' : '') + (bottom ? 'y' : '');\n\t }\n\t }\n\t\n\t action = shouldResize ? 'resize' : actionIsEnabled.drag && options.drag.enabled ? 'drag' : null;\n\t\n\t if (actionIsEnabled.gesture && interaction.pointerIds.length >= 2 && !(interaction.dragging || interaction.resizing)) {\n\t action = 'gesture';\n\t }\n\t\n\t if (action) {\n\t return {\n\t name: action,\n\t axis: resizeAxes,\n\t edges: resizeEdges\n\t };\n\t }\n\t\n\t return null;\n\t }\n\t\n\t // Check if action is enabled globally and the current target supports it\n\t // If so, return the validated action. Otherwise, return null\n\t function validateAction(action, interactable) {\n\t if (!isObject(action)) {\n\t return null;\n\t }\n\t\n\t var actionName = action.name,\n\t options = interactable.options;\n\t\n\t if ((actionName === 'resize' && options.resize.enabled || actionName === 'drag' && options.drag.enabled || actionName === 'gesture' && options.gesture.enabled) && actionIsEnabled[actionName]) {\n\t if (actionName === 'resize' || actionName === 'resizeyx') {\n\t actionName = 'resizexy';\n\t }\n\t\n\t return action;\n\t }\n\t return null;\n\t }\n\t\n\t var listeners = {},\n\t interactionListeners = ['dragStart', 'dragMove', 'resizeStart', 'resizeMove', 'gestureStart', 'gestureMove', 'pointerOver', 'pointerOut', 'pointerHover', 'selectorDown', 'pointerDown', 'pointerMove', 'pointerUp', 'pointerCancel', 'pointerEnd', 'addPointer', 'removePointer', 'recordPointer', 'autoScrollMove'];\n\t\n\t for (var i = 0, len = interactionListeners.length; i < len; i++) {\n\t var name = interactionListeners[i];\n\t\n\t listeners[name] = doOnInteractions(name);\n\t }\n\t\n\t // bound to the interactable context when a DOM event\n\t // listener is added to a selector interactable\n\t function delegateListener(event, useCapture) {\n\t var fakeEvent = {},\n\t delegated = delegatedEvents[event.type],\n\t eventTarget = getActualElement(event.path ? event.path[0] : event.target),\n\t element = eventTarget;\n\t\n\t useCapture = useCapture ? true : false;\n\t\n\t // duplicate the event so that currentTarget can be changed\n\t for (var prop in event) {\n\t fakeEvent[prop] = event[prop];\n\t }\n\t\n\t fakeEvent.originalEvent = event;\n\t fakeEvent.preventDefault = preventOriginalDefault;\n\t\n\t // climb up document tree looking for selector matches\n\t while (isElement(element)) {\n\t for (var i = 0; i < delegated.selectors.length; i++) {\n\t var selector = delegated.selectors[i],\n\t context = delegated.contexts[i];\n\t\n\t if (matchesSelector(element, selector) && nodeContains(context, eventTarget) && nodeContains(context, element)) {\n\t var listeners = delegated.listeners[i];\n\t\n\t fakeEvent.currentTarget = element;\n\t\n\t for (var j = 0; j < listeners.length; j++) {\n\t if (listeners[j][1] === useCapture) {\n\t listeners[j][0](fakeEvent);\n\t }\n\t }\n\t }\n\t }\n\t\n\t element = parentElement(element);\n\t }\n\t }\n\t\n\t function delegateUseCapture(event) {\n\t return delegateListener.call(this, event, true);\n\t }\n\t\n\t interactables.indexOfElement = function indexOfElement(element, context) {\n\t context = context || document;\n\t\n\t for (var i = 0; i < this.length; i++) {\n\t var interactable = this[i];\n\t\n\t if (interactable.selector === element && interactable._context === context || !interactable.selector && interactable._element === element) {\n\t return i;\n\t }\n\t }\n\t return -1;\n\t };\n\t\n\t interactables.get = function interactableGet(element, options) {\n\t return this[this.indexOfElement(element, options && options.context)];\n\t };\n\t\n\t interactables.forEachSelector = function (callback) {\n\t for (var i = 0; i < this.length; i++) {\n\t var interactable = this[i];\n\t\n\t if (!interactable.selector) {\n\t continue;\n\t }\n\t\n\t var ret = callback(interactable, interactable.selector, interactable._context, i, this);\n\t\n\t if (ret !== undefined) {\n\t return ret;\n\t }\n\t }\n\t };\n\t\n\t /* \\\r\n\t * interact\r\n\t [ method ]\r\n\t *\r\n\t * The methods of this variable can be used to set elements as\r\n\t * interactables and also to change various default settings.\r\n\t *\r\n\t * Calling it as a function and passing an element or a valid CSS selector\r\n\t * string returns an Interactable object which has various methods to\r\n\t * configure it.\r\n\t *\r\n\t - element (Element | string) The HTML or SVG Element to interact with or CSS selector\r\n\t = (object) An @Interactable\r\n\t *\r\n\t > Usage\r\n\t | interact(document.getElementById('draggable')).draggable(true);\r\n\t |\r\n\t | var rectables = interact('rect');\r\n\t | rectables\r\n\t | .gesturable(true)\r\n\t | .on('gesturemove', function (event) {\r\n\t | // something cool...\r\n\t | })\r\n\t | .autoScroll(true);\r\n\t \\*/\n\t function interact(element, options) {\n\t return interactables.get(element, options) || new Interactable(element, options);\n\t }\n\t\n\t /* \\\r\n\t * Interactable\r\n\t [ property ]\r\n\t **\r\n\t * Object type returned by @interact\r\n\t \\*/\n\t function Interactable(element, options) {\n\t this._element = element;\n\t this._iEvents = this._iEvents || {};\n\t\n\t var _window;\n\t\n\t if (trySelector(element)) {\n\t this.selector = element;\n\t\n\t var context = options && options.context;\n\t\n\t _window = context ? getWindow(context) : window;\n\t\n\t if (context && (_window.Node ? context instanceof _window.Node : isElement(context) || context === _window.document)) {\n\t this._context = context;\n\t }\n\t } else {\n\t _window = getWindow(element);\n\t\n\t if (isElement(element, _window)) {\n\t if (supportsPointerEvent) {\n\t events.add(this._element, pEventTypes.down, listeners.pointerDown);\n\t events.add(this._element, pEventTypes.move, listeners.pointerHover);\n\t } else {\n\t events.add(this._element, 'mousedown', listeners.pointerDown);\n\t events.add(this._element, 'mousemove', listeners.pointerHover);\n\t events.add(this._element, 'touchstart', listeners.pointerDown);\n\t events.add(this._element, 'touchmove', listeners.pointerHover);\n\t }\n\t }\n\t }\n\t\n\t this._doc = _window.document;\n\t\n\t if (!contains(documents, this._doc)) {\n\t listenToDocument(this._doc);\n\t }\n\t\n\t interactables.push(this);\n\t\n\t this.set(options);\n\t }\n\t\n\t Interactable.prototype = {\n\t setOnEvents: function setOnEvents(action, phases) {\n\t if (action === 'drop') {\n\t if (isFunction(phases.ondrop)) {\n\t this.ondrop = phases.ondrop;\n\t }\n\t if (isFunction(phases.ondropactivate)) {\n\t this.ondropactivate = phases.ondropactivate;\n\t }\n\t if (isFunction(phases.ondropdeactivate)) {\n\t this.ondropdeactivate = phases.ondropdeactivate;\n\t }\n\t if (isFunction(phases.ondragenter)) {\n\t this.ondragenter = phases.ondragenter;\n\t }\n\t if (isFunction(phases.ondragleave)) {\n\t this.ondragleave = phases.ondragleave;\n\t }\n\t if (isFunction(phases.ondropmove)) {\n\t this.ondropmove = phases.ondropmove;\n\t }\n\t } else {\n\t action = 'on' + action;\n\t\n\t if (isFunction(phases.onstart)) {\n\t this[action + 'start'] = phases.onstart;\n\t }\n\t if (isFunction(phases.onmove)) {\n\t this[action + 'move'] = phases.onmove;\n\t }\n\t if (isFunction(phases.onend)) {\n\t this[action + 'end'] = phases.onend;\n\t }\n\t if (isFunction(phases.oninertiastart)) {\n\t this[action + 'inertiastart'] = phases.oninertiastart;\n\t }\n\t }\n\t\n\t return this;\n\t },\n\t\n\t /* \\\r\n\t * Interactable.draggable\r\n\t [ method ]\r\n\t *\r\n\t * Gets or sets whether drag actions can be performed on the\r\n\t * Interactable\r\n\t *\r\n\t = (boolean) Indicates if this can be the target of drag events\r\n\t | var isDraggable = interact('ul li').draggable();\r\n\t * or\r\n\t - options (boolean | object) #optional true/false or An object with event listeners to be fired on drag events (object makes the Interactable draggable)\r\n\t = (object) This Interactable\r\n\t | interact(element).draggable({\r\n\t | onstart: function (event) {},\r\n\t | onmove : function (event) {},\r\n\t | onend : function (event) {},\r\n\t |\r\n\t | // the axis in which the first movement must be\r\n\t | // for the drag sequence to start\r\n\t | // 'xy' by default - any direction\r\n\t | axis: 'x' || 'y' || 'xy',\r\n\t |\r\n\t | // max number of drags that can happen concurrently\r\n\t | // with elements of this Interactable. Infinity by default\r\n\t | max: Infinity,\r\n\t |\r\n\t | // max number of drags that can target the same element+Interactable\r\n\t | // 1 by default\r\n\t | maxPerElement: 2\r\n\t | });\r\n\t \\*/\n\t draggable: function draggable(options) {\n\t if (isObject(options)) {\n\t this.options.drag.enabled = options.enabled === false ? false : true;\n\t this.setPerAction('drag', options);\n\t this.setOnEvents('drag', options);\n\t\n\t if (/^x$|^y$|^xy$/.test(options.axis)) {\n\t this.options.drag.axis = options.axis;\n\t } else if (options.axis === null) {\n\t delete this.options.drag.axis;\n\t }\n\t\n\t return this;\n\t }\n\t\n\t if (isBool(options)) {\n\t this.options.drag.enabled = options;\n\t\n\t return this;\n\t }\n\t\n\t return this.options.drag;\n\t },\n\t\n\t setPerAction: function setPerAction(action, options) {\n\t // for all the default per-action options\n\t for (var option in options) {\n\t // if this option exists for this action\n\t if (option in defaultOptions[action]) {\n\t // if the option in the options arg is an object value\n\t if (isObject(options[option])) {\n\t // duplicate the object\n\t this.options[action][option] = extend(this.options[action][option] || {}, options[option]);\n\t\n\t if (isObject(defaultOptions.perAction[option]) && 'enabled' in defaultOptions.perAction[option]) {\n\t this.options[action][option].enabled = options[option].enabled === false ? false : true;\n\t }\n\t } else if (isBool(options[option]) && isObject(defaultOptions.perAction[option])) {\n\t this.options[action][option].enabled = options[option];\n\t } else if (options[option] !== undefined) {\n\t // or if it's not undefined, do a plain assignment\n\t this.options[action][option] = options[option];\n\t }\n\t }\n\t }\n\t },\n\t\n\t /* \\\r\n\t * Interactable.dropzone\r\n\t [ method ]\r\n\t *\r\n\t * Returns or sets whether elements can be dropped onto this\r\n\t * Interactable to trigger drop events\r\n\t *\r\n\t * Dropzones can receive the following events:\r\n\t * - `dropactivate` and `dropdeactivate` when an acceptable drag starts and ends\r\n\t * - `dragenter` and `dragleave` when a draggable enters and leaves the dropzone\r\n\t * - `dragmove` when a draggable that has entered the dropzone is moved\r\n\t * - `drop` when a draggable is dropped into this dropzone\r\n\t *\r\n\t * Use the `accept` option to allow only elements that match the given CSS selector or element.\r\n\t *\r\n\t * Use the `overlap` option to set how drops are checked for. The allowed values are:\r\n\t * - `'pointer'`, the pointer must be over the dropzone (default)\r\n\t * - `'center'`, the draggable element's center must be over the dropzone\r\n\t * - a number from 0-1 which is the `(intersection area) / (draggable area)`.\r\n\t * e.g. `0.5` for drop to happen when half of the area of the\r\n\t * draggable is over the dropzone\r\n\t *\r\n\t - options (boolean | object | null) #optional The new value to be set.\r\n\t | interact('.drop').dropzone({\r\n\t | accept: '.can-drop' || document.getElementById('single-drop'),\r\n\t | overlap: 'pointer' || 'center' || zeroToOne\r\n\t | }\r\n\t = (boolean | object) The current setting or this Interactable\r\n\t \\*/\n\t dropzone: function dropzone(options) {\n\t if (isObject(options)) {\n\t this.options.drop.enabled = options.enabled === false ? false : true;\n\t this.setOnEvents('drop', options);\n\t\n\t if (/^(pointer|center)$/.test(options.overlap)) {\n\t this.options.drop.overlap = options.overlap;\n\t } else if (isNumber(options.overlap)) {\n\t this.options.drop.overlap = Math.max(Math.min(1, options.overlap), 0);\n\t }\n\t if ('accept' in options) {\n\t this.options.drop.accept = options.accept;\n\t }\n\t if ('checker' in options) {\n\t this.options.drop.checker = options.checker;\n\t }\n\t\n\t return this;\n\t }\n\t\n\t if (isBool(options)) {\n\t this.options.drop.enabled = options;\n\t\n\t return this;\n\t }\n\t\n\t return this.options.drop;\n\t },\n\t\n\t dropCheck: function dropCheck(dragEvent, event, draggable, draggableElement, dropElement, rect) {\n\t var dropped = false;\n\t\n\t // if the dropzone has no rect (eg. display: none)\n\t // call the custom dropChecker or just return false\n\t if (!(rect = rect || this.getRect(dropElement))) {\n\t return this.options.drop.checker ? this.options.drop.checker(dragEvent, event, dropped, this, dropElement, draggable, draggableElement) : false;\n\t }\n\t\n\t var dropOverlap = this.options.drop.overlap;\n\t\n\t if (dropOverlap === 'pointer') {\n\t var page = _getPageXY(dragEvent),\n\t origin = getOriginXY(draggable, draggableElement),\n\t horizontal,\n\t vertical;\n\t\n\t page.x += origin.x;\n\t page.y += origin.y;\n\t\n\t horizontal = page.x > rect.left && page.x < rect.right;\n\t vertical = page.y > rect.top && page.y < rect.bottom;\n\t\n\t dropped = horizontal && vertical;\n\t }\n\t\n\t var dragRect = draggable.getRect(draggableElement);\n\t\n\t if (dropOverlap === 'center') {\n\t var cx = dragRect.left + dragRect.width / 2,\n\t cy = dragRect.top + dragRect.height / 2;\n\t\n\t dropped = cx >= rect.left && cx <= rect.right && cy >= rect.top && cy <= rect.bottom;\n\t }\n\t\n\t if (isNumber(dropOverlap)) {\n\t var overlapArea = Math.max(0, Math.min(rect.right, dragRect.right) - Math.max(rect.left, dragRect.left)) * Math.max(0, Math.min(rect.bottom, dragRect.bottom) - Math.max(rect.top, dragRect.top)),\n\t overlapRatio = overlapArea / (dragRect.width * dragRect.height);\n\t\n\t dropped = overlapRatio >= dropOverlap;\n\t }\n\t\n\t if (this.options.drop.checker) {\n\t dropped = this.options.drop.checker(dragEvent, event, dropped, this, dropElement, draggable, draggableElement);\n\t }\n\t\n\t return dropped;\n\t },\n\t\n\t /* \\\r\n\t * Interactable.dropChecker\r\n\t [ method ]\r\n\t *\r\n\t * DEPRECATED. Use interactable.dropzone({ checker: function... }) instead.\r\n\t *\r\n\t * Gets or sets the function used to check if a dragged element is\r\n\t * over this Interactable.\r\n\t *\r\n\t - checker (function) #optional The function that will be called when checking for a drop\r\n\t = (Function | Interactable) The checker function or this Interactable\r\n\t *\r\n\t * The checker function takes the following arguments:\r\n\t *\r\n\t - dragEvent (InteractEvent) The related dragmove or dragend event\r\n\t - event (TouchEvent | PointerEvent | MouseEvent) The user move/up/end Event related to the dragEvent\r\n\t - dropped (boolean) The value from the default drop checker\r\n\t - dropzone (Interactable) The dropzone interactable\r\n\t - dropElement (Element) The dropzone element\r\n\t - draggable (Interactable) The Interactable being dragged\r\n\t - draggableElement (Element) The actual element that's being dragged\r\n\t *\r\n\t > Usage:\r\n\t | interact(target)\r\n\t | .dropChecker(function(dragEvent, // related dragmove or dragend event\r\n\t | event, // TouchEvent/PointerEvent/MouseEvent\r\n\t | dropped, // bool result of the default checker\r\n\t | dropzone, // dropzone Interactable\r\n\t | dropElement, // dropzone elemnt\r\n\t | draggable, // draggable Interactable\r\n\t | draggableElement) {// draggable element\r\n\t |\r\n\t | return dropped && event.target.hasAttribute('allow-drop');\r\n\t | }\r\n\t \\*/\n\t dropChecker: function dropChecker(checker) {\n\t if (isFunction(checker)) {\n\t this.options.drop.checker = checker;\n\t\n\t return this;\n\t }\n\t if (checker === null) {\n\t delete this.options.getRect;\n\t\n\t return this;\n\t }\n\t\n\t return this.options.drop.checker;\n\t },\n\t\n\t /* \\\r\n\t * Interactable.accept\r\n\t [ method ]\r\n\t *\r\n\t * Deprecated. add an `accept` property to the options object passed to\r\n\t * @Interactable.dropzone instead.\r\n\t *\r\n\t * Gets or sets the Element or CSS selector match that this\r\n\t * Interactable accepts if it is a dropzone.\r\n\t *\r\n\t - newValue (Element | string | null) #optional\r\n\t * If it is an Element, then only that element can be dropped into this dropzone.\r\n\t * If it is a string, the element being dragged must match it as a selector.\r\n\t * If it is null, the accept options is cleared - it accepts any element.\r\n\t *\r\n\t = (string | Element | null | Interactable) The current accept option if given `undefined` or this Interactable\r\n\t \\*/\n\t accept: function accept(newValue) {\n\t if (isElement(newValue)) {\n\t this.options.drop.accept = newValue;\n\t\n\t return this;\n\t }\n\t\n\t // test if it is a valid CSS selector\n\t if (trySelector(newValue)) {\n\t this.options.drop.accept = newValue;\n\t\n\t return this;\n\t }\n\t\n\t if (newValue === null) {\n\t delete this.options.drop.accept;\n\t\n\t return this;\n\t }\n\t\n\t return this.options.drop.accept;\n\t },\n\t\n\t /* \\\r\n\t * Interactable.resizable\r\n\t [ method ]\r\n\t *\r\n\t * Gets or sets whether resize actions can be performed on the\r\n\t * Interactable\r\n\t *\r\n\t = (boolean) Indicates if this can be the target of resize elements\r\n\t | var isResizeable = interact('input[type=text]').resizable();\r\n\t * or\r\n\t - options (boolean | object) #optional true/false or An object with event listeners to be fired on resize events (object makes the Interactable resizable)\r\n\t = (object) This Interactable\r\n\t | interact(element).resizable({\r\n\t | onstart: function (event) {},\r\n\t | onmove : function (event) {},\r\n\t | onend : function (event) {},\r\n\t |\r\n\t | edges: {\r\n\t | top : true, // Use pointer coords to check for resize.\r\n\t | left : false, // Disable resizing from left edge.\r\n\t | bottom: '.resize-s',// Resize if pointer target matches selector\r\n\t | right : handleEl // Resize if pointer target is the given Element\r\n\t | },\r\n\t |\r\n\t | // Width and height can be adjusted independently. When `true`, width and\r\n\t | // height are adjusted at a 1:1 ratio.\r\n\t | square: false,\r\n\t |\r\n\t | // Width and height can be adjusted independently. When `true`, width and\r\n\t | // height maintain the aspect ratio they had when resizing started.\r\n\t | preserveAspectRatio: false,\r\n\t |\r\n\t | // a value of 'none' will limit the resize rect to a minimum of 0x0\r\n\t | // 'negate' will allow the rect to have negative width/height\r\n\t | // 'reposition' will keep the width/height positive by swapping\r\n\t | // the top and bottom edges and/or swapping the left and right edges\r\n\t | invert: 'none' || 'negate' || 'reposition'\r\n\t |\r\n\t | // limit multiple resizes.\r\n\t | // See the explanation in the @Interactable.draggable example\r\n\t | max: Infinity,\r\n\t | maxPerElement: 1,\r\n\t | });\r\n\t \\*/\n\t resizable: function resizable(options) {\n\t if (isObject(options)) {\n\t this.options.resize.enabled = options.enabled === false ? false : true;\n\t this.setPerAction('resize', options);\n\t this.setOnEvents('resize', options);\n\t\n\t if (/^x$|^y$|^xy$/.test(options.axis)) {\n\t this.options.resize.axis = options.axis;\n\t } else if (options.axis === null) {\n\t this.options.resize.axis = defaultOptions.resize.axis;\n\t }\n\t\n\t if (isBool(options.preserveAspectRatio)) {\n\t this.options.resize.preserveAspectRatio = options.preserveAspectRatio;\n\t } else if (isBool(options.square)) {\n\t this.options.resize.square = options.square;\n\t }\n\t\n\t return this;\n\t }\n\t if (isBool(options)) {\n\t this.options.resize.enabled = options;\n\t\n\t return this;\n\t }\n\t return this.options.resize;\n\t },\n\t\n\t /* \\\r\n\t * Interactable.squareResize\r\n\t [ method ]\r\n\t *\r\n\t * Deprecated. Add a `square: true || false` property to @Interactable.resizable instead\r\n\t *\r\n\t * Gets or sets whether resizing is forced 1:1 aspect\r\n\t *\r\n\t = (boolean) Current setting\r\n\t *\r\n\t * or\r\n\t *\r\n\t - newValue (boolean) #optional\r\n\t = (object) this Interactable\r\n\t \\*/\n\t squareResize: function squareResize(newValue) {\n\t if (isBool(newValue)) {\n\t this.options.resize.square = newValue;\n\t\n\t return this;\n\t }\n\t\n\t if (newValue === null) {\n\t delete this.options.resize.square;\n\t\n\t return this;\n\t }\n\t\n\t return this.options.resize.square;\n\t },\n\t\n\t /* \\\r\n\t * Interactable.gesturable\r\n\t [ method ]\r\n\t *\r\n\t * Gets or sets whether multitouch gestures can be performed on the\r\n\t * Interactable's element\r\n\t *\r\n\t = (boolean) Indicates if this can be the target of gesture events\r\n\t | var isGestureable = interact(element).gesturable();\r\n\t * or\r\n\t - options (boolean | object) #optional true/false or An object with event listeners to be fired on gesture events (makes the Interactable gesturable)\r\n\t = (object) this Interactable\r\n\t | interact(element).gesturable({\r\n\t | onstart: function (event) {},\r\n\t | onmove : function (event) {},\r\n\t | onend : function (event) {},\r\n\t |\r\n\t | // limit multiple gestures.\r\n\t | // See the explanation in @Interactable.draggable example\r\n\t | max: Infinity,\r\n\t | maxPerElement: 1,\r\n\t | });\r\n\t \\*/\n\t gesturable: function gesturable(options) {\n\t if (isObject(options)) {\n\t this.options.gesture.enabled = options.enabled === false ? false : true;\n\t this.setPerAction('gesture', options);\n\t this.setOnEvents('gesture', options);\n\t\n\t return this;\n\t }\n\t\n\t if (isBool(options)) {\n\t this.options.gesture.enabled = options;\n\t\n\t return this;\n\t }\n\t\n\t return this.options.gesture;\n\t },\n\t\n\t /* \\\r\n\t * Interactable.autoScroll\r\n\t [ method ]\r\n\t **\r\n\t * Deprecated. Add an `autoscroll` property to the options object\r\n\t * passed to @Interactable.draggable or @Interactable.resizable instead.\r\n\t *\r\n\t * Returns or sets whether dragging and resizing near the edges of the\r\n\t * window/container trigger autoScroll for this Interactable\r\n\t *\r\n\t = (object) Object with autoScroll properties\r\n\t *\r\n\t * or\r\n\t *\r\n\t - options (object | boolean) #optional\r\n\t * options can be:\r\n\t * - an object with margin, distance and interval properties,\r\n\t * - true or false to enable or disable autoScroll or\r\n\t = (Interactable) this Interactable\r\n\t \\*/\n\t autoScroll: function autoScroll(options) {\n\t if (isObject(options)) {\n\t options = extend({ actions: ['drag', 'resize'] }, options);\n\t } else if (isBool(options)) {\n\t options = { actions: ['drag', 'resize'], enabled: options };\n\t }\n\t\n\t return this.setOptions('autoScroll', options);\n\t },\n\t\n\t /* \\\r\n\t * Interactable.snap\r\n\t [ method ]\r\n\t **\r\n\t * Deprecated. Add a `snap` property to the options object passed\r\n\t * to @Interactable.draggable or @Interactable.resizable instead.\r\n\t *\r\n\t * Returns or sets if and how action coordinates are snapped. By\r\n\t * default, snapping is relative to the pointer coordinates. You can\r\n\t * change this by setting the\r\n\t * [`elementOrigin`](https://github.com/taye/interact.js/pull/72).\r\n\t **\r\n\t = (boolean | object) `false` if snap is disabled; object with snap properties if snap is enabled\r\n\t **\r\n\t * or\r\n\t **\r\n\t - options (object | boolean | null) #optional\r\n\t = (Interactable) this Interactable\r\n\t > Usage\r\n\t | interact(document.querySelector('#thing')).snap({\r\n\t | targets: [\r\n\t | // snap to this specific point\r\n\t | {\r\n\t | x: 100,\r\n\t | y: 100,\r\n\t | range: 25\r\n\t | },\r\n\t | // give this function the x and y page coords and snap to the object returned\r\n\t | function (x, y) {\r\n\t | return {\r\n\t | x: x,\r\n\t | y: (75 + 50 * Math.sin(x * 0.04)),\r\n\t | range: 40\r\n\t | };\r\n\t | },\r\n\t | // create a function that snaps to a grid\r\n\t | interact.createSnapGrid({\r\n\t | x: 50,\r\n\t | y: 50,\r\n\t | range: 10, // optional\r\n\t | offset: { x: 5, y: 10 } // optional\r\n\t | })\r\n\t | ],\r\n\t | // do not snap during normal movement.\r\n\t | // Instead, trigger only one snapped move event\r\n\t | // immediately before the end event.\r\n\t | endOnly: true,\r\n\t |\r\n\t | relativePoints: [\r\n\t | { x: 0, y: 0 }, // snap relative to the top left of the element\r\n\t | { x: 1, y: 1 }, // and also to the bottom right\r\n\t | ],\r\n\t |\r\n\t | // offset the snap target coordinates\r\n\t | // can be an object with x/y or 'startCoords'\r\n\t | offset: { x: 50, y: 50 }\r\n\t | }\r\n\t | });\r\n\t \\*/\n\t snap: function snap(options) {\n\t var ret = this.setOptions('snap', options);\n\t\n\t if (ret === this) {\n\t return this;\n\t }\n\t\n\t return ret.drag;\n\t },\n\t\n\t setOptions: function setOptions(option, options) {\n\t var actions = options && isArray(options.actions) ? options.actions : ['drag'];\n\t\n\t var i;\n\t\n\t if (isObject(options) || isBool(options)) {\n\t for (i = 0; i < actions.length; i++) {\n\t var action = /resize/.test(actions[i]) ? 'resize' : actions[i];\n\t\n\t if (!isObject(this.options[action])) {\n\t continue;\n\t }\n\t\n\t var thisOption = this.options[action][option];\n\t\n\t if (isObject(options)) {\n\t extend(thisOption, options);\n\t thisOption.enabled = options.enabled === false ? false : true;\n\t\n\t if (option === 'snap') {\n\t if (thisOption.mode === 'grid') {\n\t thisOption.targets = [interact.createSnapGrid(extend({\n\t offset: thisOption.gridOffset || { x: 0, y: 0 }\n\t }, thisOption.grid || {}))];\n\t } else if (thisOption.mode === 'anchor') {\n\t thisOption.targets = thisOption.anchors;\n\t } else if (thisOption.mode === 'path') {\n\t thisOption.targets = thisOption.paths;\n\t }\n\t\n\t if ('elementOrigin' in options) {\n\t thisOption.relativePoints = [options.elementOrigin];\n\t }\n\t }\n\t } else if (isBool(options)) {\n\t thisOption.enabled = options;\n\t }\n\t }\n\t\n\t return this;\n\t }\n\t\n\t var ret = {},\n\t allActions = ['drag', 'resize', 'gesture'];\n\t\n\t for (i = 0; i < allActions.length; i++) {\n\t if (option in defaultOptions[allActions[i]]) {\n\t ret[allActions[i]] = this.options[allActions[i]][option];\n\t }\n\t }\n\t\n\t return ret;\n\t },\n\t\n\t /* \\\r\n\t * Interactable.inertia\r\n\t [ method ]\r\n\t **\r\n\t * Deprecated. Add an `inertia` property to the options object passed\r\n\t * to @Interactable.draggable or @Interactable.resizable instead.\r\n\t *\r\n\t * Returns or sets if and how events continue to run after the pointer is released\r\n\t **\r\n\t = (boolean | object) `false` if inertia is disabled; `object` with inertia properties if inertia is enabled\r\n\t **\r\n\t * or\r\n\t **\r\n\t - options (object | boolean | null) #optional\r\n\t = (Interactable) this Interactable\r\n\t > Usage\r\n\t | // enable and use default settings\r\n\t | interact(element).inertia(true);\r\n\t |\r\n\t | // enable and use custom settings\r\n\t | interact(element).inertia({\r\n\t | // value greater than 0\r\n\t | // high values slow the object down more quickly\r\n\t | resistance : 16,\r\n\t |\r\n\t | // the minimum launch speed (pixels per second) that results in inertia start\r\n\t | minSpeed : 200,\r\n\t |\r\n\t | // inertia will stop when the object slows down to this speed\r\n\t | endSpeed : 20,\r\n\t |\r\n\t | // boolean; should actions be resumed when the pointer goes down during inertia\r\n\t | allowResume : true,\r\n\t |\r\n\t | // boolean; should the jump when resuming from inertia be ignored in event.dx/dy\r\n\t | zeroResumeDelta: false,\r\n\t |\r\n\t | // if snap/restrict are set to be endOnly and inertia is enabled, releasing\r\n\t | // the pointer without triggering inertia will animate from the release\r\n\t | // point to the snaped/restricted point in the given amount of time (ms)\r\n\t | smoothEndDuration: 300,\r\n\t |\r\n\t | // an array of action types that can have inertia (no gesture)\r\n\t | actions : ['drag', 'resize']\r\n\t | });\r\n\t |\r\n\t | // reset custom settings and use all defaults\r\n\t | interact(element).inertia(null);\r\n\t \\*/\n\t inertia: function inertia(options) {\n\t var ret = this.setOptions('inertia', options);\n\t\n\t if (ret === this) {\n\t return this;\n\t }\n\t\n\t return ret.drag;\n\t },\n\t\n\t getAction: function getAction(pointer, event, interaction, element) {\n\t var action = this.defaultActionChecker(pointer, interaction, element);\n\t\n\t if (this.options.actionChecker) {\n\t return this.options.actionChecker(pointer, event, action, this, element, interaction);\n\t }\n\t\n\t return action;\n\t },\n\t\n\t defaultActionChecker: defaultActionChecker,\n\t\n\t /* \\\r\n\t * Interactable.actionChecker\r\n\t [ method ]\r\n\t *\r\n\t * Gets or sets the function used to check action to be performed on\r\n\t * pointerDown\r\n\t *\r\n\t - checker (function | null) #optional A function which takes a pointer event, defaultAction string, interactable, element and interaction as parameters and returns an object with name property 'drag' 'resize' or 'gesture' and optionally an `edges` object with boolean 'top', 'left', 'bottom' and right props.\r\n\t = (Function | Interactable) The checker function or this Interactable\r\n\t *\r\n\t | interact('.resize-drag')\r\n\t | .resizable(true)\r\n\t | .draggable(true)\r\n\t | .actionChecker(function (pointer, event, action, interactable, element, interaction) {\r\n\t |\r\n\t | if (interact.matchesSelector(event.target, '.drag-handle') {\r\n\t | // force drag with handle target\r\n\t | action.name = drag;\r\n\t | }\r\n\t | else {\r\n\t | // resize from the top and right edges\r\n\t | action.name = 'resize';\r\n\t | action.edges = { top: true, right: true };\r\n\t | }\r\n\t |\r\n\t | return action;\r\n\t | });\r\n\t \\*/\n\t actionChecker: function actionChecker(checker) {\n\t if (isFunction(checker)) {\n\t this.options.actionChecker = checker;\n\t\n\t return this;\n\t }\n\t\n\t if (checker === null) {\n\t delete this.options.actionChecker;\n\t\n\t return this;\n\t }\n\t\n\t return this.options.actionChecker;\n\t },\n\t\n\t /* \\\r\n\t * Interactable.getRect\r\n\t [ method ]\r\n\t *\r\n\t * The default function to get an Interactables bounding rect. Can be\r\n\t * overridden using @Interactable.rectChecker.\r\n\t *\r\n\t - element (Element) #optional The element to measure.\r\n\t = (object) The object's bounding rectangle.\r\n\t o {\r\n\t o top : 0,\r\n\t o left : 0,\r\n\t o bottom: 0,\r\n\t o right : 0,\r\n\t o width : 0,\r\n\t o height: 0\r\n\t o }\r\n\t \\*/\n\t getRect: function rectCheck(element) {\n\t element = element || this._element;\n\t\n\t if (this.selector && !isElement(element)) {\n\t element = this._context.querySelector(this.selector);\n\t }\n\t\n\t return getElementRect(element);\n\t },\n\t\n\t /* \\\r\n\t * Interactable.rectChecker\r\n\t [ method ]\r\n\t *\r\n\t * Returns or sets the function used to calculate the interactable's\r\n\t * element's rectangle\r\n\t *\r\n\t - checker (function) #optional A function which returns this Interactable's bounding rectangle. See @Interactable.getRect\r\n\t = (function | object) The checker function or this Interactable\r\n\t \\*/\n\t rectChecker: function rectChecker(checker) {\n\t if (isFunction(checker)) {\n\t this.getRect = checker;\n\t\n\t return this;\n\t }\n\t\n\t if (checker === null) {\n\t delete this.options.getRect;\n\t\n\t return this;\n\t }\n\t\n\t return this.getRect;\n\t },\n\t\n\t /* \\\r\n\t * Interactable.styleCursor\r\n\t [ method ]\r\n\t *\r\n\t * Returns or sets whether the action that would be performed when the\r\n\t * mouse on the element are checked on `mousemove` so that the cursor\r\n\t * may be styled appropriately\r\n\t *\r\n\t - newValue (boolean) #optional\r\n\t = (boolean | Interactable) The current setting or this Interactable\r\n\t \\*/\n\t styleCursor: function styleCursor(newValue) {\n\t if (isBool(newValue)) {\n\t this.options.styleCursor = newValue;\n\t\n\t return this;\n\t }\n\t\n\t if (newValue === null) {\n\t delete this.options.styleCursor;\n\t\n\t return this;\n\t }\n\t\n\t return this.options.styleCursor;\n\t },\n\t\n\t /* \\\r\n\t * Interactable.preventDefault\r\n\t [ method ]\r\n\t *\r\n\t * Returns or sets whether to prevent the browser's default behaviour\r\n\t * in response to pointer events. Can be set to:\r\n\t * - `'always'` to always prevent\r\n\t * - `'never'` to never prevent\r\n\t * - `'auto'` to let interact.js try to determine what would be best\r\n\t *\r\n\t - newValue (string) #optional `true`, `false` or `'auto'`\r\n\t = (string | Interactable) The current setting or this Interactable\r\n\t \\*/\n\t preventDefault: function preventDefault(newValue) {\n\t if (/^(always|never|auto)$/.test(newValue)) {\n\t this.options.preventDefault = newValue;\n\t return this;\n\t }\n\t\n\t if (isBool(newValue)) {\n\t this.options.preventDefault = newValue ? 'always' : 'never';\n\t return this;\n\t }\n\t\n\t return this.options.preventDefault;\n\t },\n\t\n\t /* \\\r\n\t * Interactable.origin\r\n\t [ method ]\r\n\t *\r\n\t * Gets or sets the origin of the Interactable's element. The x and y\r\n\t * of the origin will be subtracted from action event coordinates.\r\n\t *\r\n\t - origin (object | string) #optional An object eg. { x: 0, y: 0 } or string 'parent', 'self' or any CSS selector\r\n\t * OR\r\n\t - origin (Element) #optional An HTML or SVG Element whose rect will be used\r\n\t **\r\n\t = (object) The current origin or this Interactable\r\n\t \\*/\n\t origin: function origin(newValue) {\n\t if (trySelector(newValue)) {\n\t this.options.origin = newValue;\n\t return this;\n\t } else if (isObject(newValue)) {\n\t this.options.origin = newValue;\n\t return this;\n\t }\n\t\n\t return this.options.origin;\n\t },\n\t\n\t /* \\\r\n\t * Interactable.deltaSource\r\n\t [ method ]\r\n\t *\r\n\t * Returns or sets the mouse coordinate types used to calculate the\r\n\t * movement of the pointer.\r\n\t *\r\n\t - newValue (string) #optional Use 'client' if you will be scrolling while interacting; Use 'page' if you want autoScroll to work\r\n\t = (string | object) The current deltaSource or this Interactable\r\n\t \\*/\n\t deltaSource: function deltaSource(newValue) {\n\t if (newValue === 'page' || newValue === 'client') {\n\t this.options.deltaSource = newValue;\n\t\n\t return this;\n\t }\n\t\n\t return this.options.deltaSource;\n\t },\n\t\n\t /* \\\r\n\t * Interactable.restrict\r\n\t [ method ]\r\n\t **\r\n\t * Deprecated. Add a `restrict` property to the options object passed to\r\n\t * @Interactable.draggable, @Interactable.resizable or @Interactable.gesturable instead.\r\n\t *\r\n\t * Returns or sets the rectangles within which actions on this\r\n\t * interactable (after snap calculations) are restricted. By default,\r\n\t * restricting is relative to the pointer coordinates. You can change\r\n\t * this by setting the\r\n\t * [`elementRect`](https://github.com/taye/interact.js/pull/72).\r\n\t **\r\n\t - options (object) #optional an object with keys drag, resize, and/or gesture whose values are rects, Elements, CSS selectors, or 'parent' or 'self'\r\n\t = (object) The current restrictions object or this Interactable\r\n\t **\r\n\t | interact(element).restrict({\r\n\t | // the rect will be `interact.getElementRect(element.parentNode)`\r\n\t | drag: element.parentNode,\r\n\t |\r\n\t | // x and y are relative to the the interactable's origin\r\n\t | resize: { x: 100, y: 100, width: 200, height: 200 }\r\n\t | })\r\n\t |\r\n\t | interact('.draggable').restrict({\r\n\t | // the rect will be the selected element's parent\r\n\t | drag: 'parent',\r\n\t |\r\n\t | // do not restrict during normal movement.\r\n\t | // Instead, trigger only one restricted move event\r\n\t | // immediately before the end event.\r\n\t | endOnly: true,\r\n\t |\r\n\t | // https://github.com/taye/interact.js/pull/72#issue-41813493\r\n\t | elementRect: { top: 0, left: 0, bottom: 1, right: 1 }\r\n\t | });\r\n\t \\*/\n\t restrict: function restrict(options) {\n\t if (!isObject(options)) {\n\t return this.setOptions('restrict', options);\n\t }\n\t\n\t var actions = ['drag', 'resize', 'gesture'],\n\t ret;\n\t\n\t for (var i = 0; i < actions.length; i++) {\n\t var action = actions[i];\n\t\n\t if (action in options) {\n\t var perAction = extend({\n\t actions: [action],\n\t restriction: options[action]\n\t }, options);\n\t\n\t ret = this.setOptions('restrict', perAction);\n\t }\n\t }\n\t\n\t return ret;\n\t },\n\t\n\t /* \\\r\n\t * Interactable.context\r\n\t [ method ]\r\n\t *\r\n\t * Gets the selector context Node of the Interactable. The default is `window.document`.\r\n\t *\r\n\t = (Node) The context Node of this Interactable\r\n\t **\r\n\t \\*/\n\t context: function context() {\n\t return this._context;\n\t },\n\t\n\t _context: document,\n\t\n\t /* \\\r\n\t * Interactable.ignoreFrom\r\n\t [ method ]\r\n\t *\r\n\t * If the target of the `mousedown`, `pointerdown` or `touchstart`\r\n\t * event or any of it's parents match the given CSS selector or\r\n\t * Element, no drag/resize/gesture is started.\r\n\t *\r\n\t - newValue (string | Element | null) #optional a CSS selector string, an Element or `null` to not ignore any elements\r\n\t = (string | Element | object) The current ignoreFrom value or this Interactable\r\n\t **\r\n\t | interact(element, { ignoreFrom: document.getElementById('no-action') });\r\n\t | // or\r\n\t | interact(element).ignoreFrom('input, textarea, a');\r\n\t \\*/\n\t ignoreFrom: function ignoreFrom(newValue) {\n\t if (trySelector(newValue)) {\n\t // CSS selector to match event.target\n\t this.options.ignoreFrom = newValue;\n\t return this;\n\t }\n\t\n\t if (isElement(newValue)) {\n\t // specific element\n\t this.options.ignoreFrom = newValue;\n\t return this;\n\t }\n\t\n\t return this.options.ignoreFrom;\n\t },\n\t\n\t /* \\\r\n\t * Interactable.allowFrom\r\n\t [ method ]\r\n\t *\r\n\t * A drag/resize/gesture is started only If the target of the\r\n\t * `mousedown`, `pointerdown` or `touchstart` event or any of it's\r\n\t * parents match the given CSS selector or Element.\r\n\t *\r\n\t - newValue (string | Element | null) #optional a CSS selector string, an Element or `null` to allow from any element\r\n\t = (string | Element | object) The current allowFrom value or this Interactable\r\n\t **\r\n\t | interact(element, { allowFrom: document.getElementById('drag-handle') });\r\n\t | // or\r\n\t | interact(element).allowFrom('.handle');\r\n\t \\*/\n\t allowFrom: function allowFrom(newValue) {\n\t if (trySelector(newValue)) {\n\t // CSS selector to match event.target\n\t this.options.allowFrom = newValue;\n\t return this;\n\t }\n\t\n\t if (isElement(newValue)) {\n\t // specific element\n\t this.options.allowFrom = newValue;\n\t return this;\n\t }\n\t\n\t return this.options.allowFrom;\n\t },\n\t\n\t /* \\\r\n\t * Interactable.element\r\n\t [ method ]\r\n\t *\r\n\t * If this is not a selector Interactable, it returns the element this\r\n\t * interactable represents\r\n\t *\r\n\t = (Element) HTML / SVG Element\r\n\t \\*/\n\t element: function element() {\n\t return this._element;\n\t },\n\t\n\t /* \\\r\n\t * Interactable.fire\r\n\t [ method ]\r\n\t *\r\n\t * Calls listeners for the given InteractEvent type bound globally\r\n\t * and directly to this Interactable\r\n\t *\r\n\t - iEvent (InteractEvent) The InteractEvent object to be fired on this Interactable\r\n\t = (Interactable) this Interactable\r\n\t \\*/\n\t fire: function fire(iEvent) {\n\t if (!(iEvent && iEvent.type) || !contains(eventTypes, iEvent.type)) {\n\t return this;\n\t }\n\t\n\t var listeners,\n\t i,\n\t len,\n\t onEvent = 'on' + iEvent.type,\n\t funcName = '';\n\t\n\t // Interactable#on() listeners\n\t if (iEvent.type in this._iEvents) {\n\t listeners = this._iEvents[iEvent.type];\n\t\n\t for (i = 0, len = listeners.length; i < len && !iEvent.immediatePropagationStopped; i++) {\n\t funcName = listeners[i].name;\n\t listeners[i](iEvent);\n\t }\n\t }\n\t\n\t // interactable.onevent listener\n\t if (isFunction(this[onEvent])) {\n\t funcName = this[onEvent].name;\n\t this[onEvent](iEvent);\n\t }\n\t\n\t // interact.on() listeners\n\t if (iEvent.type in globalEvents && (listeners = globalEvents[iEvent.type])) {\n\t for (i = 0, len = listeners.length; i < len && !iEvent.immediatePropagationStopped; i++) {\n\t funcName = listeners[i].name;\n\t listeners[i](iEvent);\n\t }\n\t }\n\t\n\t return this;\n\t },\n\t\n\t /* \\\r\n\t * Interactable.on\r\n\t [ method ]\r\n\t *\r\n\t * Binds a listener for an InteractEvent or DOM event.\r\n\t *\r\n\t - eventType (string | array | object) The types of events to listen for\r\n\t - listener (function) The function to be called on the given event(s)\r\n\t - useCapture (boolean) #optional useCapture flag for addEventListener\r\n\t = (object) This Interactable\r\n\t \\*/\n\t on: function on(eventType, listener, useCapture) {\n\t var i;\n\t\n\t if (isString(eventType) && eventType.search(' ') !== -1) {\n\t eventType = eventType.trim().split(/ +/);\n\t }\n\t\n\t if (isArray(eventType)) {\n\t for (i = 0; i < eventType.length; i++) {\n\t this.on(eventType[i], listener, useCapture);\n\t }\n\t\n\t return this;\n\t }\n\t\n\t if (isObject(eventType)) {\n\t for (var prop in eventType) {\n\t this.on(prop, eventType[prop], listener);\n\t }\n\t\n\t return this;\n\t }\n\t\n\t if (eventType === 'wheel') {\n\t eventType = wheelEvent;\n\t }\n\t\n\t // convert to boolean\n\t useCapture = useCapture ? true : false;\n\t\n\t if (contains(eventTypes, eventType)) {\n\t // if this type of event was never bound to this Interactable\n\t if (!(eventType in this._iEvents)) {\n\t this._iEvents[eventType] = [listener];\n\t } else {\n\t this._iEvents[eventType].push(listener);\n\t }\n\t }\n\t // delegated event for selector\n\t else if (this.selector) {\n\t if (!delegatedEvents[eventType]) {\n\t delegatedEvents[eventType] = {\n\t selectors: [],\n\t contexts: [],\n\t listeners: []\n\t };\n\t\n\t // add delegate listener functions\n\t for (i = 0; i < documents.length; i++) {\n\t events.add(documents[i], eventType, delegateListener);\n\t events.add(documents[i], eventType, delegateUseCapture, true);\n\t }\n\t }\n\t\n\t var delegated = delegatedEvents[eventType],\n\t index;\n\t\n\t for (index = delegated.selectors.length - 1; index >= 0; index--) {\n\t if (delegated.selectors[index] === this.selector && delegated.contexts[index] === this._context) {\n\t break;\n\t }\n\t }\n\t\n\t if (index === -1) {\n\t index = delegated.selectors.length;\n\t\n\t delegated.selectors.push(this.selector);\n\t delegated.contexts.push(this._context);\n\t delegated.listeners.push([]);\n\t }\n\t\n\t // keep listener and useCapture flag\n\t delegated.listeners[index].push([listener, useCapture]);\n\t } else {\n\t events.add(this._element, eventType, listener, useCapture);\n\t }\n\t\n\t return this;\n\t },\n\t\n\t /* \\\r\n\t * Interactable.off\r\n\t [ method ]\r\n\t *\r\n\t * Removes an InteractEvent or DOM event listener\r\n\t *\r\n\t - eventType (string | array | object) The types of events that were listened for\r\n\t - listener (function) The listener function to be removed\r\n\t - useCapture (boolean) #optional useCapture flag for removeEventListener\r\n\t = (object) This Interactable\r\n\t \\*/\n\t off: function off(eventType, listener, useCapture) {\n\t var i;\n\t\n\t if (isString(eventType) && eventType.search(' ') !== -1) {\n\t eventType = eventType.trim().split(/ +/);\n\t }\n\t\n\t if (isArray(eventType)) {\n\t for (i = 0; i < eventType.length; i++) {\n\t this.off(eventType[i], listener, useCapture);\n\t }\n\t\n\t return this;\n\t }\n\t\n\t if (isObject(eventType)) {\n\t for (var prop in eventType) {\n\t this.off(prop, eventType[prop], listener);\n\t }\n\t\n\t return this;\n\t }\n\t\n\t var eventList,\n\t index = -1;\n\t\n\t // convert to boolean\n\t useCapture = useCapture ? true : false;\n\t\n\t if (eventType === 'wheel') {\n\t eventType = wheelEvent;\n\t }\n\t\n\t // if it is an action event type\n\t if (contains(eventTypes, eventType)) {\n\t eventList = this._iEvents[eventType];\n\t\n\t if (eventList && (index = indexOf(eventList, listener)) !== -1) {\n\t this._iEvents[eventType].splice(index, 1);\n\t }\n\t }\n\t // delegated event\n\t else if (this.selector) {\n\t var delegated = delegatedEvents[eventType],\n\t matchFound = false;\n\t\n\t if (!delegated) {\n\t return this;\n\t }\n\t\n\t // count from last index of delegated to 0\n\t for (index = delegated.selectors.length - 1; index >= 0; index--) {\n\t // look for matching selector and context Node\n\t if (delegated.selectors[index] === this.selector && delegated.contexts[index] === this._context) {\n\t var listeners = delegated.listeners[index];\n\t\n\t // each item of the listeners array is an array: [function, useCaptureFlag]\n\t for (i = listeners.length - 1; i >= 0; i--) {\n\t var fn = listeners[i][0],\n\t useCap = listeners[i][1];\n\t\n\t // check if the listener functions and useCapture flags match\n\t if (fn === listener && useCap === useCapture) {\n\t // remove the listener from the array of listeners\n\t listeners.splice(i, 1);\n\t\n\t // if all listeners for this interactable have been removed\n\t // remove the interactable from the delegated arrays\n\t if (!listeners.length) {\n\t delegated.selectors.splice(index, 1);\n\t delegated.contexts.splice(index, 1);\n\t delegated.listeners.splice(index, 1);\n\t\n\t // remove delegate function from context\n\t events.remove(this._context, eventType, delegateListener);\n\t events.remove(this._context, eventType, delegateUseCapture, true);\n\t\n\t // remove the arrays if they are empty\n\t if (!delegated.selectors.length) {\n\t delegatedEvents[eventType] = null;\n\t }\n\t }\n\t\n\t // only remove one listener\n\t matchFound = true;\n\t break;\n\t }\n\t }\n\t\n\t if (matchFound) {\n\t break;\n\t }\n\t }\n\t }\n\t }\n\t // remove listener from this Interatable's element\n\t else {\n\t events.remove(this._element, eventType, listener, useCapture);\n\t }\n\t\n\t return this;\n\t },\n\t\n\t /* \\\r\n\t * Interactable.set\r\n\t [ method ]\r\n\t *\r\n\t * Reset the options of this Interactable\r\n\t - options (object) The new settings to apply\r\n\t = (object) This Interactable\r\n\t \\*/\n\t set: function set(options) {\n\t if (!isObject(options)) {\n\t options = {};\n\t }\n\t\n\t this.options = extend({}, defaultOptions.base);\n\t\n\t var i,\n\t actions = ['drag', 'drop', 'resize', 'gesture'],\n\t methods = ['draggable', 'dropzone', 'resizable', 'gesturable'],\n\t perActions = extend(extend({}, defaultOptions.perAction), options[action] || {});\n\t\n\t for (i = 0; i < actions.length; i++) {\n\t var action = actions[i];\n\t\n\t this.options[action] = extend({}, defaultOptions[action]);\n\t\n\t this.setPerAction(action, perActions);\n\t\n\t this[methods[i]](options[action]);\n\t }\n\t\n\t var settings = ['accept', 'actionChecker', 'allowFrom', 'deltaSource', 'dropChecker', 'ignoreFrom', 'origin', 'preventDefault', 'rectChecker', 'styleCursor'];\n\t\n\t for (i = 0, len = settings.length; i < len; i++) {\n\t var setting = settings[i];\n\t\n\t this.options[setting] = defaultOptions.base[setting];\n\t\n\t if (setting in options) {\n\t this[setting](options[setting]);\n\t }\n\t }\n\t\n\t return this;\n\t },\n\t\n\t /* \\\r\n\t * Interactable.unset\r\n\t [ method ]\r\n\t *\r\n\t * Remove this interactable from the list of interactables and remove\r\n\t * it's drag, drop, resize and gesture capabilities\r\n\t *\r\n\t = (object) @interact\r\n\t \\*/\n\t unset: function unset() {\n\t events.remove(this._element, 'all');\n\t\n\t if (!isString(this.selector)) {\n\t events.remove(this, 'all');\n\t if (this.options.styleCursor) {\n\t this._element.style.cursor = '';\n\t }\n\t } else {\n\t // remove delegated events\n\t for (var type in delegatedEvents) {\n\t var delegated = delegatedEvents[type];\n\t\n\t for (var i = 0; i < delegated.selectors.length; i++) {\n\t if (delegated.selectors[i] === this.selector && delegated.contexts[i] === this._context) {\n\t delegated.selectors.splice(i, 1);\n\t delegated.contexts.splice(i, 1);\n\t delegated.listeners.splice(i, 1);\n\t\n\t // remove the arrays if they are empty\n\t if (!delegated.selectors.length) {\n\t delegatedEvents[type] = null;\n\t }\n\t }\n\t\n\t events.remove(this._context, type, delegateListener);\n\t events.remove(this._context, type, delegateUseCapture, true);\n\t\n\t break;\n\t }\n\t }\n\t }\n\t\n\t this.dropzone(false);\n\t\n\t interactables.splice(indexOf(interactables, this), 1);\n\t\n\t return interact;\n\t }\n\t };\n\t\n\t function warnOnce(method, message) {\n\t var warned = false;\n\t\n\t return function () {\n\t if (!warned) {\n\t window.console.warn(message);\n\t warned = true;\n\t }\n\t\n\t return method.apply(this, arguments);\n\t };\n\t }\n\t\n\t Interactable.prototype.snap = warnOnce(Interactable.prototype.snap, 'Interactable#snap is deprecated. See the new documentation for snapping at http://interactjs.io/docs/snapping');\n\t Interactable.prototype.restrict = warnOnce(Interactable.prototype.restrict, 'Interactable#restrict is deprecated. See the new documentation for resticting at http://interactjs.io/docs/restriction');\n\t Interactable.prototype.inertia = warnOnce(Interactable.prototype.inertia, 'Interactable#inertia is deprecated. See the new documentation for inertia at http://interactjs.io/docs/inertia');\n\t Interactable.prototype.autoScroll = warnOnce(Interactable.prototype.autoScroll, 'Interactable#autoScroll is deprecated. See the new documentation for autoScroll at http://interactjs.io/docs/#autoscroll');\n\t Interactable.prototype.squareResize = warnOnce(Interactable.prototype.squareResize, 'Interactable#squareResize is deprecated. See http://interactjs.io/docs/#resize-square');\n\t\n\t Interactable.prototype.accept = warnOnce(Interactable.prototype.accept, 'Interactable#accept is deprecated. use Interactable#dropzone({ accept: target }) instead');\n\t Interactable.prototype.dropChecker = warnOnce(Interactable.prototype.dropChecker, 'Interactable#dropChecker is deprecated. use Interactable#dropzone({ dropChecker: checkerFunction }) instead');\n\t Interactable.prototype.context = warnOnce(Interactable.prototype.context, 'Interactable#context as a method is deprecated. It will soon be a DOM Node instead');\n\t\n\t /* \\\r\n\t * interact.isSet\r\n\t [ method ]\r\n\t *\r\n\t * Check if an element has been set\r\n\t - element (Element) The Element being searched for\r\n\t = (boolean) Indicates if the element or CSS selector was previously passed to interact\r\n\t \\*/\n\t interact.isSet = function (element, options) {\n\t return interactables.indexOfElement(element, options && options.context) !== -1;\n\t };\n\t\n\t /* \\\r\n\t * interact.on\r\n\t [ method ]\r\n\t *\r\n\t * Adds a global listener for an InteractEvent or adds a DOM event to\r\n\t * `document`\r\n\t *\r\n\t - type (string | array | object) The types of events to listen for\r\n\t - listener (function) The function to be called on the given event(s)\r\n\t - useCapture (boolean) #optional useCapture flag for addEventListener\r\n\t = (object) interact\r\n\t \\*/\n\t interact.on = function (type, listener, useCapture) {\n\t if (isString(type) && type.search(' ') !== -1) {\n\t type = type.trim().split(/ +/);\n\t }\n\t\n\t if (isArray(type)) {\n\t for (var i = 0; i < type.length; i++) {\n\t interact.on(type[i], listener, useCapture);\n\t }\n\t\n\t return interact;\n\t }\n\t\n\t if (isObject(type)) {\n\t for (var prop in type) {\n\t interact.on(prop, type[prop], listener);\n\t }\n\t\n\t return interact;\n\t }\n\t\n\t // if it is an InteractEvent type, add listener to globalEvents\n\t if (contains(eventTypes, type)) {\n\t // if this type of event was never bound\n\t if (!globalEvents[type]) {\n\t globalEvents[type] = [listener];\n\t } else {\n\t globalEvents[type].push(listener);\n\t }\n\t }\n\t // If non InteractEvent type, addEventListener to document\n\t else {\n\t events.add(document, type, listener, useCapture);\n\t }\n\t\n\t return interact;\n\t };\n\t\n\t /* \\\r\n\t * interact.off\r\n\t [ method ]\r\n\t *\r\n\t * Removes a global InteractEvent listener or DOM event from `document`\r\n\t *\r\n\t - type (string | array | object) The types of events that were listened for\r\n\t - listener (function) The listener function to be removed\r\n\t - useCapture (boolean) #optional useCapture flag for removeEventListener\r\n\t = (object) interact\r\n\t \\*/\n\t interact.off = function (type, listener, useCapture) {\n\t if (isString(type) && type.search(' ') !== -1) {\n\t type = type.trim().split(/ +/);\n\t }\n\t\n\t if (isArray(type)) {\n\t for (var i = 0; i < type.length; i++) {\n\t interact.off(type[i], listener, useCapture);\n\t }\n\t\n\t return interact;\n\t }\n\t\n\t if (isObject(type)) {\n\t for (var prop in type) {\n\t interact.off(prop, type[prop], listener);\n\t }\n\t\n\t return interact;\n\t }\n\t\n\t if (!contains(eventTypes, type)) {\n\t events.remove(document, type, listener, useCapture);\n\t } else {\n\t var index;\n\t\n\t if (type in globalEvents && (index = indexOf(globalEvents[type], listener)) !== -1) {\n\t globalEvents[type].splice(index, 1);\n\t }\n\t }\n\t\n\t return interact;\n\t };\n\t\n\t /* \\\r\n\t * interact.enableDragging\r\n\t [ method ]\r\n\t *\r\n\t * Deprecated.\r\n\t *\r\n\t * Returns or sets whether dragging is enabled for any Interactables\r\n\t *\r\n\t - newValue (boolean) #optional `true` to allow the action; `false` to disable action for all Interactables\r\n\t = (boolean | object) The current setting or interact\r\n\t \\*/\n\t interact.enableDragging = warnOnce(function (newValue) {\n\t if (newValue !== null && newValue !== undefined) {\n\t actionIsEnabled.drag = newValue;\n\t\n\t return interact;\n\t }\n\t return actionIsEnabled.drag;\n\t }, 'interact.enableDragging is deprecated and will soon be removed.');\n\t\n\t /* \\\r\n\t * interact.enableResizing\r\n\t [ method ]\r\n\t *\r\n\t * Deprecated.\r\n\t *\r\n\t * Returns or sets whether resizing is enabled for any Interactables\r\n\t *\r\n\t - newValue (boolean) #optional `true` to allow the action; `false` to disable action for all Interactables\r\n\t = (boolean | object) The current setting or interact\r\n\t \\*/\n\t interact.enableResizing = warnOnce(function (newValue) {\n\t if (newValue !== null && newValue !== undefined) {\n\t actionIsEnabled.resize = newValue;\n\t\n\t return interact;\n\t }\n\t return actionIsEnabled.resize;\n\t }, 'interact.enableResizing is deprecated and will soon be removed.');\n\t\n\t /* \\\r\n\t * interact.enableGesturing\r\n\t [ method ]\r\n\t *\r\n\t * Deprecated.\r\n\t *\r\n\t * Returns or sets whether gesturing is enabled for any Interactables\r\n\t *\r\n\t - newValue (boolean) #optional `true` to allow the action; `false` to disable action for all Interactables\r\n\t = (boolean | object) The current setting or interact\r\n\t \\*/\n\t interact.enableGesturing = warnOnce(function (newValue) {\n\t if (newValue !== null && newValue !== undefined) {\n\t actionIsEnabled.gesture = newValue;\n\t\n\t return interact;\n\t }\n\t return actionIsEnabled.gesture;\n\t }, 'interact.enableGesturing is deprecated and will soon be removed.');\n\t\n\t interact.eventTypes = eventTypes;\n\t\n\t /* \\\r\n\t * interact.debug\r\n\t [ method ]\r\n\t *\r\n\t * Returns debugging data\r\n\t = (object) An object with properties that outline the current state and expose internal functions and variables\r\n\t \\*/\n\t interact.debug = function () {\n\t var interaction = interactions[0] || new Interaction();\n\t\n\t return {\n\t interactions: interactions,\n\t target: interaction.target,\n\t dragging: interaction.dragging,\n\t resizing: interaction.resizing,\n\t gesturing: interaction.gesturing,\n\t prepared: interaction.prepared,\n\t matches: interaction.matches,\n\t matchElements: interaction.matchElements,\n\t\n\t prevCoords: interaction.prevCoords,\n\t startCoords: interaction.startCoords,\n\t\n\t pointerIds: interaction.pointerIds,\n\t pointers: interaction.pointers,\n\t addPointer: listeners.addPointer,\n\t removePointer: listeners.removePointer,\n\t recordPointer: listeners.recordPointer,\n\t\n\t snap: interaction.snapStatus,\n\t restrict: interaction.restrictStatus,\n\t inertia: interaction.inertiaStatus,\n\t\n\t downTime: interaction.downTimes[0],\n\t downEvent: interaction.downEvent,\n\t downPointer: interaction.downPointer,\n\t prevEvent: interaction.prevEvent,\n\t\n\t Interactable: Interactable,\n\t interactables: interactables,\n\t pointerIsDown: interaction.pointerIsDown,\n\t defaultOptions: defaultOptions,\n\t defaultActionChecker: defaultActionChecker,\n\t\n\t actionCursors: actionCursors,\n\t dragMove: listeners.dragMove,\n\t resizeMove: listeners.resizeMove,\n\t gestureMove: listeners.gestureMove,\n\t pointerUp: listeners.pointerUp,\n\t pointerDown: listeners.pointerDown,\n\t pointerMove: listeners.pointerMove,\n\t pointerHover: listeners.pointerHover,\n\t\n\t eventTypes: eventTypes,\n\t\n\t events: events,\n\t globalEvents: globalEvents,\n\t delegatedEvents: delegatedEvents,\n\t\n\t prefixedPropREs: prefixedPropREs\n\t };\n\t };\n\t\n\t // expose the functions used to calculate multi-touch properties\n\t interact.getPointerAverage = pointerAverage;\n\t interact.getTouchBBox = touchBBox;\n\t interact.getTouchDistance = touchDistance;\n\t interact.getTouchAngle = touchAngle;\n\t\n\t interact.getElementRect = getElementRect;\n\t interact.getElementClientRect = getElementClientRect;\n\t interact.matchesSelector = matchesSelector;\n\t interact.closest = closest;\n\t\n\t /* \\\r\n\t * interact.margin\r\n\t [ method ]\r\n\t *\r\n\t * Deprecated. Use `interact(target).resizable({ margin: number });` instead.\r\n\t * Returns or sets the margin for autocheck resizing used in\r\n\t * @Interactable.getAction. That is the distance from the bottom and right\r\n\t * edges of an element clicking in which will start resizing\r\n\t *\r\n\t - newValue (number) #optional\r\n\t = (number | interact) The current margin value or interact\r\n\t \\*/\n\t interact.margin = warnOnce(function (newvalue) {\n\t if (isNumber(newvalue)) {\n\t margin = newvalue;\n\t\n\t return interact;\n\t }\n\t return margin;\n\t }, 'interact.margin is deprecated. Use interact(target).resizable({ margin: number }); instead.');\n\t\n\t /* \\\r\n\t * interact.supportsTouch\r\n\t [ method ]\r\n\t *\r\n\t = (boolean) Whether or not the browser supports touch input\r\n\t \\*/\n\t interact.supportsTouch = function () {\n\t return supportsTouch;\n\t };\n\t\n\t /* \\\r\n\t * interact.supportsPointerEvent\r\n\t [ method ]\r\n\t *\r\n\t = (boolean) Whether or not the browser supports PointerEvents\r\n\t \\*/\n\t interact.supportsPointerEvent = function () {\n\t return supportsPointerEvent;\n\t };\n\t\n\t /* \\\r\n\t * interact.stop\r\n\t [ method ]\r\n\t *\r\n\t * Cancels all interactions (end events are not fired)\r\n\t *\r\n\t - event (Event) An event on which to call preventDefault()\r\n\t = (object) interact\r\n\t \\*/\n\t interact.stop = function (event) {\n\t for (var i = interactions.length - 1; i >= 0; i--) {\n\t interactions[i].stop(event);\n\t }\n\t\n\t return interact;\n\t };\n\t\n\t /* \\\r\n\t * interact.dynamicDrop\r\n\t [ method ]\r\n\t *\r\n\t * Returns or sets whether the dimensions of dropzone elements are\r\n\t * calculated on every dragmove or only on dragstart for the default\r\n\t * dropChecker\r\n\t *\r\n\t - newValue (boolean) #optional True to check on each move. False to check only before start\r\n\t = (boolean | interact) The current setting or interact\r\n\t \\*/\n\t interact.dynamicDrop = function (newValue) {\n\t if (isBool(newValue)) {\n\t // if (dragging && dynamicDrop !== newValue && !newValue) {\n\t // calcRects(dropzones);\n\t // }\n\t\n\t dynamicDrop = newValue;\n\t\n\t return interact;\n\t }\n\t return dynamicDrop;\n\t };\n\t\n\t /* \\\r\n\t * interact.pointerMoveTolerance\r\n\t [ method ]\r\n\t * Returns or sets the distance the pointer must be moved before an action\r\n\t * sequence occurs. This also affects tolerance for tap events.\r\n\t *\r\n\t - newValue (number) #optional The movement from the start position must be greater than this value\r\n\t = (number | Interactable) The current setting or interact\r\n\t \\*/\n\t interact.pointerMoveTolerance = function (newValue) {\n\t if (isNumber(newValue)) {\n\t pointerMoveTolerance = newValue;\n\t\n\t return this;\n\t }\n\t\n\t return pointerMoveTolerance;\n\t };\n\t\n\t /* \\\r\n\t * interact.maxInteractions\r\n\t [ method ]\r\n\t **\r\n\t * Returns or sets the maximum number of concurrent interactions allowed.\r\n\t * By default only 1 interaction is allowed at a time (for backwards\r\n\t * compatibility). To allow multiple interactions on the same Interactables\r\n\t * and elements, you need to enable it in the draggable, resizable and\r\n\t * gesturable `'max'` and `'maxPerElement'` options.\r\n\t **\r\n\t - newValue (number) #optional Any number. newValue <= 0 means no interactions.\r\n\t \\*/\n\t interact.maxInteractions = function (newValue) {\n\t if (isNumber(newValue)) {\n\t maxInteractions = newValue;\n\t\n\t return this;\n\t }\n\t\n\t return maxInteractions;\n\t };\n\t\n\t interact.createSnapGrid = function (grid) {\n\t return function (x, y) {\n\t var offsetX = 0,\n\t offsetY = 0;\n\t\n\t if (isObject(grid.offset)) {\n\t offsetX = grid.offset.x;\n\t offsetY = grid.offset.y;\n\t }\n\t\n\t var gridx = Math.round((x - offsetX) / grid.x),\n\t gridy = Math.round((y - offsetY) / grid.y),\n\t newX = gridx * grid.x + offsetX,\n\t newY = gridy * grid.y + offsetY;\n\t\n\t return {\n\t x: newX,\n\t y: newY,\n\t range: grid.range\n\t };\n\t };\n\t };\n\t\n\t function endAllInteractions(event) {\n\t for (var i = 0; i < interactions.length; i++) {\n\t interactions[i].pointerEnd(event, event);\n\t }\n\t }\n\t\n\t function listenToDocument(doc) {\n\t if (contains(documents, doc)) {\n\t return;\n\t }\n\t\n\t var win = doc.defaultView || doc.parentWindow;\n\t\n\t // add delegate event listener\n\t for (var eventType in delegatedEvents) {\n\t events.add(doc, eventType, delegateListener);\n\t events.add(doc, eventType, delegateUseCapture, true);\n\t }\n\t\n\t if (supportsPointerEvent) {\n\t if (PointerEvent === win.MSPointerEvent) {\n\t pEventTypes = {\n\t up: 'MSPointerUp', down: 'MSPointerDown', over: 'mouseover',\n\t out: 'mouseout', move: 'MSPointerMove', cancel: 'MSPointerCancel' };\n\t } else {\n\t pEventTypes = {\n\t up: 'pointerup', down: 'pointerdown', over: 'pointerover',\n\t out: 'pointerout', move: 'pointermove', cancel: 'pointercancel' };\n\t }\n\t\n\t events.add(doc, pEventTypes.down, listeners.selectorDown);\n\t events.add(doc, pEventTypes.move, listeners.pointerMove);\n\t events.add(doc, pEventTypes.over, listeners.pointerOver);\n\t events.add(doc, pEventTypes.out, listeners.pointerOut);\n\t events.add(doc, pEventTypes.up, listeners.pointerUp);\n\t events.add(doc, pEventTypes.cancel, listeners.pointerCancel);\n\t\n\t // autoscroll\n\t events.add(doc, pEventTypes.move, listeners.autoScrollMove);\n\t } else {\n\t events.add(doc, 'mousedown', listeners.selectorDown);\n\t events.add(doc, 'mousemove', listeners.pointerMove);\n\t events.add(doc, 'mouseup', listeners.pointerUp);\n\t events.add(doc, 'mouseover', listeners.pointerOver);\n\t events.add(doc, 'mouseout', listeners.pointerOut);\n\t\n\t events.add(doc, 'touchstart', listeners.selectorDown);\n\t events.add(doc, 'touchmove', listeners.pointerMove);\n\t events.add(doc, 'touchend', listeners.pointerUp);\n\t events.add(doc, 'touchcancel', listeners.pointerCancel);\n\t\n\t // autoscroll\n\t events.add(doc, 'mousemove', listeners.autoScrollMove);\n\t events.add(doc, 'touchmove', listeners.autoScrollMove);\n\t }\n\t\n\t events.add(win, 'blur', endAllInteractions);\n\t\n\t try {\n\t if (win.frameElement) {\n\t var parentDoc = win.frameElement.ownerDocument,\n\t parentWindow = parentDoc.defaultView;\n\t\n\t events.add(parentDoc, 'mouseup', listeners.pointerEnd);\n\t events.add(parentDoc, 'touchend', listeners.pointerEnd);\n\t events.add(parentDoc, 'touchcancel', listeners.pointerEnd);\n\t events.add(parentDoc, 'pointerup', listeners.pointerEnd);\n\t events.add(parentDoc, 'MSPointerUp', listeners.pointerEnd);\n\t events.add(parentWindow, 'blur', endAllInteractions);\n\t }\n\t } catch (error) {\n\t interact.windowParentError = error;\n\t }\n\t\n\t // prevent native HTML5 drag on interact.js target elements\n\t events.add(doc, 'dragstart', function (event) {\n\t for (var i = 0; i < interactions.length; i++) {\n\t var interaction = interactions[i];\n\t\n\t if (interaction.element && (interaction.element === event.target || nodeContains(interaction.element, event.target))) {\n\t interaction.checkAndPreventDefault(event, interaction.target, interaction.element);\n\t return;\n\t }\n\t }\n\t });\n\t\n\t if (events.useAttachEvent) {\n\t // For IE's lack of Event#preventDefault\n\t events.add(doc, 'selectstart', function (event) {\n\t var interaction = interactions[0];\n\t\n\t if (interaction.currentAction()) {\n\t interaction.checkAndPreventDefault(event);\n\t }\n\t });\n\t\n\t // For IE's bad dblclick event sequence\n\t events.add(doc, 'dblclick', doOnInteractions('ie8Dblclick'));\n\t }\n\t\n\t documents.push(doc);\n\t }\n\t\n\t listenToDocument(document);\n\t\n\t function indexOf(array, target) {\n\t for (var i = 0, len = array.length; i < len; i++) {\n\t if (array[i] === target) {\n\t return i;\n\t }\n\t }\n\t\n\t return -1;\n\t }\n\t\n\t function contains(array, target) {\n\t return indexOf(array, target) !== -1;\n\t }\n\t\n\t function matchesSelector(element, selector, nodeList) {\n\t if (ie8MatchesSelector) {\n\t return ie8MatchesSelector(element, selector, nodeList);\n\t }\n\t\n\t // remove /deep/ from selectors if shadowDOM polyfill is used\n\t if (window !== realWindow) {\n\t selector = selector.replace(/\\/deep\\//g, ' ');\n\t }\n\t\n\t return element[prefixedMatchesSelector](selector);\n\t }\n\t\n\t function matchesUpTo(element, selector, limit) {\n\t while (isElement(element)) {\n\t if (matchesSelector(element, selector)) {\n\t return true;\n\t }\n\t\n\t element = parentElement(element);\n\t\n\t if (element === limit) {\n\t return matchesSelector(element, selector);\n\t }\n\t }\n\t\n\t return false;\n\t }\n\t\n\t // For IE8's lack of an Element#matchesSelector\n\t // taken from http://tanalin.com/en/blog/2012/12/matches-selector-ie8/ and modified\n\t if (!(prefixedMatchesSelector in Element.prototype) || !isFunction(Element.prototype[prefixedMatchesSelector])) {\n\t ie8MatchesSelector = function ie8MatchesSelector(element, selector, elems) {\n\t elems = elems || element.parentNode.querySelectorAll(selector);\n\t\n\t for (var i = 0, len = elems.length; i < len; i++) {\n\t if (elems[i] === element) {\n\t return true;\n\t }\n\t }\n\t\n\t return false;\n\t };\n\t }\n\t\n\t // requestAnimationFrame polyfill\n\t (function () {\n\t var lastTime = 0,\n\t vendors = ['ms', 'moz', 'webkit', 'o'];\n\t\n\t for (var x = 0; x < vendors.length && !realWindow.requestAnimationFrame; ++x) {\n\t reqFrame = realWindow[vendors[x] + 'RequestAnimationFrame'];\n\t cancelFrame = realWindow[vendors[x] + 'CancelAnimationFrame'] || realWindow[vendors[x] + 'CancelRequestAnimationFrame'];\n\t }\n\t\n\t if (!reqFrame) {\n\t reqFrame = function reqFrame(callback) {\n\t var currTime = new Date().getTime(),\n\t timeToCall = Math.max(0, 16 - (currTime - lastTime)),\n\t id = setTimeout(function () {\n\t callback(currTime + timeToCall);\n\t }, timeToCall);\n\t lastTime = currTime + timeToCall;\n\t return id;\n\t };\n\t }\n\t\n\t if (!cancelFrame) {\n\t cancelFrame = function cancelFrame(id) {\n\t clearTimeout(id);\n\t };\n\t }\n\t })();\n\t\n\t /* global exports: true, module, define */\n\t\n\t // http://documentcloud.github.io/underscore/docs/underscore.html#section-11\n\t if (true) {\n\t if (typeof module !== 'undefined' && module.exports) {\n\t exports = module.exports = interact;\n\t }\n\t exports.interact = interact;\n\t }\n\t // AMD\n\t else if (typeof define === 'function' && define.amd) {\n\t define('interact', function () {\n\t return interact;\n\t });\n\t } else {\n\t realWindow.interact = interact;\n\t }\n\t})(typeof window === 'undefined' ? undefined : window);\n\n/***/ }),\n/* 6 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\texports.RowSelectionModel = exports.RowMoveManager = exports.HeaderMenu = exports.HeaderButtons = exports.CheckboxSelectColumn = exports.CellSelectionModel = exports.CellRangeSelector = exports.CellRangeDecorator = exports.CellCopyManager = exports.AutoTooltips = undefined;\n\t\n\tvar _slick = __webpack_require__(7);\n\t\n\tvar _slick2 = _interopRequireDefault(_slick);\n\t\n\tvar _slick3 = __webpack_require__(9);\n\t\n\tvar _slick4 = _interopRequireDefault(_slick3);\n\t\n\tvar _slick5 = __webpack_require__(11);\n\t\n\tvar _slick6 = _interopRequireDefault(_slick5);\n\t\n\tvar _slick7 = __webpack_require__(12);\n\t\n\tvar _slick8 = _interopRequireDefault(_slick7);\n\t\n\tvar _slick9 = __webpack_require__(13);\n\t\n\tvar _slick10 = _interopRequireDefault(_slick9);\n\t\n\tvar _slick11 = __webpack_require__(15);\n\t\n\tvar _slick12 = _interopRequireDefault(_slick11);\n\t\n\tvar _slick13 = __webpack_require__(17);\n\t\n\tvar _slick14 = _interopRequireDefault(_slick13);\n\t\n\tvar _slick15 = __webpack_require__(19);\n\t\n\tvar _slick16 = _interopRequireDefault(_slick15);\n\t\n\tvar _slick17 = __webpack_require__(21);\n\t\n\tvar _slick18 = _interopRequireDefault(_slick17);\n\t\n\tvar _slick19 = __webpack_require__(23);\n\t\n\tvar _slick20 = _interopRequireDefault(_slick19);\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\t\n\texports.AutoTooltips = _slick2.default;\n\texports.CellCopyManager = _slick4.default;\n\texports.CellRangeDecorator = _slick6.default;\n\texports.CellRangeSelector = _slick8.default;\n\texports.CellSelectionModel = _slick10.default;\n\texports.CheckboxSelectColumn = _slick12.default;\n\texports.HeaderButtons = _slick14.default;\n\texports.HeaderMenu = _slick16.default;\n\texports.RowMoveManager = _slick18.default;\n\texports.RowSelectionModel = _slick20.default;\n\n/***/ }),\n/* 7 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _slick = __webpack_require__(8);\n\t\n\tvar _slick2 = _interopRequireDefault(_slick);\n\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n\texports.default = _slick2.default;\n\n/***/ }),\n/* 8 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _jquery = __webpack_require__(2);\n\t\n\tvar _jquery2 = _interopRequireDefault(_jquery);\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\t\n\texports.default = AutoTooltips;\n\t\n\t/**\r\n\t * AutoTooltips plugin to show/hide tooltips when columns are too narrow to fit content.\r\n\t * @constructor\r\n\t * @param {boolean} [options.enableForCells=true] - Enable tooltip for grid cells\r\n\t * @param {boolean} [options.enableForHeaderCells=false] - Enable tooltip for header cells\r\n\t * @param {number} [options.maxToolTipLength=null] - The maximum length for a tooltip\r\n\t */\n\t\n\tfunction AutoTooltips(options) {\n\t var _grid = void 0;\n\t var _self = this;\n\t var _defaults = {\n\t enableForCells: true,\n\t enableForHeaderCells: false,\n\t maxToolTipLength: null\n\t };\n\t\n\t /**\r\n\t * Initialize plugin.\r\n\t */\n\t function init(grid) {\n\t options = Object.assign({}, _defaults, options);\n\t _grid = grid;\n\t if (options.enableForCells) _grid.onMouseEnter.subscribe(handleMouseEnter);\n\t if (options.enableForHeaderCells) _grid.onHeaderMouseEnter.subscribe(handleHeaderMouseEnter);\n\t }\n\t\n\t /**\r\n\t * Destroy plugin.\r\n\t */\n\t function destroy() {\n\t if (options.enableForCells) _grid.onMouseEnter.unsubscribe(handleMouseEnter);\n\t if (options.enableForHeaderCells) _grid.onHeaderMouseEnter.unsubscribe(handleHeaderMouseEnter);\n\t }\n\t\n\t /**\r\n\t * Handle mouse entering grid cell to add/remove tooltip.\r\n\t * @param {jQuery.Event} e - The event\r\n\t */\n\t function handleMouseEnter(e) {\n\t var cell = _grid.getCellFromEvent(e);\n\t if (cell) {\n\t var $node = (0, _jquery2.default)(_grid.getCellNode(cell.row, cell.cell));\n\t var text = void 0;\n\t if ($node.innerWidth() < $node[0].scrollWidth) {\n\t text = _jquery2.default.trim($node.text());\n\t if (options.maxToolTipLength && text.length > options.maxToolTipLength) {\n\t text = text.substr(0, options.maxToolTipLength - 3) + '...';\n\t }\n\t } else {\n\t text = '';\n\t }\n\t $node.attr('title', text);\n\t }\n\t }\n\t\n\t /**\r\n\t * Handle mouse entering header cell to add/remove tooltip.\r\n\t * @param {jQuery.Event} e - The event\r\n\t * @param {object} args.column - The column definition\r\n\t */\n\t function handleHeaderMouseEnter(e, args) {\n\t var column = args.column,\n\t $node = (0, _jquery2.default)(e.target).closest('.slick-header-column');\n\t if (column && !column.toolTip) {\n\t $node.attr('title', $node.innerWidth() < $node[0].scrollWidth ? column.name : '');\n\t }\n\t }\n\t\n\t // Public API\n\t Object.assign(this, {\n\t init: init,\n\t destroy: destroy\n\t });\n\t}\n\n/***/ }),\n/* 9 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _slick = __webpack_require__(10);\n\t\n\tvar _slick2 = _interopRequireDefault(_slick);\n\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n\texports.default = _slick2.default;\n\n/***/ }),\n/* 10 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _slick = __webpack_require__(1);\n\t\n\tvar _slick2 = _interopRequireDefault(_slick);\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\t\n\tvar keyCode = _slick2.default.keyCode;\n\texports.default = CellCopyManager;\n\t\n\t\n\tfunction CellCopyManager() {\n\t var _grid;\n\t var _self = this;\n\t var _copiedRanges;\n\t\n\t function init(grid) {\n\t _grid = grid;\n\t _grid.onKeyDown.subscribe(handleKeyDown);\n\t }\n\t\n\t function destroy() {\n\t _grid.onKeyDown.unsubscribe(handleKeyDown);\n\t }\n\t\n\t function handleKeyDown(e, args) {\n\t var ranges;\n\t if (!_grid.getEditorLock().isActive()) {\n\t if (e.which == keyCode.ESCAPE) {\n\t if (_copiedRanges) {\n\t e.preventDefault();\n\t clearCopySelection();\n\t _self.onCopyCancelled.notify({ ranges: _copiedRanges });\n\t _copiedRanges = null;\n\t }\n\t }\n\t\n\t if (e.which == 67 && (e.ctrlKey || e.metaKey)) {\n\t ranges = _grid.getSelectionModel().getSelectedRanges();\n\t if (ranges.length != 0) {\n\t e.preventDefault();\n\t _copiedRanges = ranges;\n\t markCopySelection(ranges);\n\t _self.onCopyCells.notify({ ranges: ranges });\n\t }\n\t }\n\t\n\t if (e.which == 86 && (e.ctrlKey || e.metaKey)) {\n\t if (_copiedRanges) {\n\t e.preventDefault();\n\t clearCopySelection();\n\t ranges = _grid.getSelectionModel().getSelectedRanges();\n\t _self.onPasteCells.notify({ from: _copiedRanges, to: ranges });\n\t _copiedRanges = null;\n\t }\n\t }\n\t }\n\t }\n\t\n\t function markCopySelection(ranges) {\n\t var columns = _grid.getColumns();\n\t var hash = {};\n\t for (var i = 0; i < ranges.length; i++) {\n\t for (var j = ranges[i].fromRow; j <= ranges[i].toRow; j++) {\n\t hash[j] = {};\n\t for (var k = ranges[i].fromCell; k <= ranges[i].toCell; k++) {\n\t hash[j][columns[k].id] = 'copied';\n\t }\n\t }\n\t }\n\t _grid.setCellCssStyles('copy-manager', hash);\n\t }\n\t\n\t function clearCopySelection() {\n\t _grid.removeCellCssStyles('copy-manager');\n\t }\n\t\n\t Object.assign(this, {\n\t init: init,\n\t destroy: destroy,\n\t clearCopySelection: clearCopySelection,\n\t\n\t onCopyCells: new _slick2.default.Event(),\n\t onCopyCancelled: new _slick2.default.Event(),\n\t onPasteCells: new _slick2.default.Event()\n\t });\n\t}\n\n/***/ }),\n/* 11 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _slick = __webpack_require__(3);\n\t\n\tvar _slick2 = _interopRequireDefault(_slick);\n\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n\texports.default = _slick2.default;\n\n/***/ }),\n/* 12 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _slick = __webpack_require__(4);\n\t\n\tvar _slick2 = _interopRequireDefault(_slick);\n\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n\texports.default = _slick2.default;\n\n/***/ }),\n/* 13 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _slick = __webpack_require__(14);\n\t\n\tvar _slick2 = _interopRequireDefault(_slick);\n\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n\texports.default = _slick2.default;\n\n/***/ }),\n/* 14 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _slick = __webpack_require__(1);\n\t\n\tvar _slick2 = _interopRequireDefault(_slick);\n\t\n\tvar _slick3 = __webpack_require__(4);\n\t\n\tvar _slick4 = _interopRequireDefault(_slick3);\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\t\n\texports.default = CellSelectionModel;\n\t\n\t\n\tfunction CellSelectionModel() {\n\t var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {\n\t selectActiveCell: true\n\t };\n\t\n\t var _grid = void 0;\n\t var _canvas = void 0;\n\t var _ranges = [];\n\t var _self = this;\n\t var _selector = new _slick4.default({\n\t selectionCss: {\n\t border: '2px solid black'\n\t }\n\t });\n\t var _options = void 0;\n\t var _defaults = {\n\t selectActiveCell: true\n\t };\n\t\n\t function init(grid) {\n\t _options = Object.assign({}, options);\n\t _grid = grid;\n\t _canvas = _grid.getCanvasNode();\n\t _grid.onActiveCellChanged.subscribe(handleActiveCellChange);\n\t _grid.onKeyDown.subscribe(handleKeyDown);\n\t grid.registerPlugin(_selector);\n\t _selector.onCellRangeSelected.subscribe(handleCellRangeSelected);\n\t _selector.onBeforeCellRangeSelected.subscribe(handleBeforeCellRangeSelected);\n\t }\n\t\n\t function destroy() {\n\t _grid.onActiveCellChanged.unsubscribe(handleActiveCellChange);\n\t _grid.onKeyDown.unsubscribe(handleKeyDown);\n\t _selector.onCellRangeSelected.unsubscribe(handleCellRangeSelected);\n\t _selector.onBeforeCellRangeSelected.unsubscribe(handleBeforeCellRangeSelected);\n\t _grid.unregisterPlugin(_selector);\n\t }\n\t\n\t function removeInvalidRanges(ranges) {\n\t var result = [];\n\t\n\t for (var i = 0; i < ranges.length; i++) {\n\t var r = ranges[i];\n\t if (_grid.canCellBeSelected(r.fromRow, r.fromCell) && _grid.canCellBeSelected(r.toRow, r.toCell)) {\n\t result.push(r);\n\t }\n\t }\n\t\n\t return result;\n\t }\n\t\n\t function setSelectedRanges(ranges) {\n\t // simle check for: empty selection didn't change, prevent firing onSelectedRangesChanged\n\t if ((!_ranges || _ranges.length === 0) && (!ranges || ranges.length === 0)) {\n\t return;\n\t }\n\t\n\t _ranges = removeInvalidRanges(ranges);\n\t _self.onSelectedRangesChanged.notify(_ranges);\n\t }\n\t\n\t function getSelectedRanges() {\n\t return _ranges;\n\t }\n\t\n\t function handleBeforeCellRangeSelected(e, args) {\n\t if (_grid.getEditorLock().isActive()) {\n\t e.stopPropagation();\n\t return false;\n\t }\n\t }\n\t\n\t function handleCellRangeSelected(e, args) {\n\t setSelectedRanges([args.range]);\n\t }\n\t\n\t function handleActiveCellChange(e, args) {\n\t if (_options.selectActiveCell && args.row != null && args.cell != null) {\n\t setSelectedRanges([new _slick2.default.Range(args.row, args.cell)]);\n\t }\n\t }\n\t\n\t function handleKeyDown(e) {\n\t /** *\r\n\t * Кey codes\r\n\t * 37 left\r\n\t * 38 up\r\n\t * 39 right\r\n\t * 40 down\r\n\t */\n\t var ranges = void 0,\n\t last = void 0;\n\t var active = _grid.getActiveCell();\n\t\n\t if (active && e.shiftKey && !e.ctrlKey && !e.altKey && (e.which == 37 || e.which == 39 || e.which == 38 || e.which == 40)) {\n\t ranges = getSelectedRanges();\n\t if (!ranges.length) ranges.push(new _slick2.default.Range(active.row, active.cell));\n\t\n\t // keyboard can work with last range only\n\t last = ranges.pop();\n\t\n\t // can't handle selection out of active cell\n\t if (!last.contains(active.row, active.cell)) last = new _slick2.default.Range(active.row, active.cell);\n\t\n\t var dRow = last.toRow - last.fromRow,\n\t dCell = last.toCell - last.fromCell,\n\t\n\t // walking direction\n\t dirRow = active.row == last.fromRow ? 1 : -1,\n\t dirCell = active.cell == last.fromCell ? 1 : -1;\n\t\n\t if (e.which == 37) {\n\t dCell -= dirCell;\n\t } else if (e.which == 39) {\n\t dCell += dirCell;\n\t } else if (e.which == 38) {\n\t dRow -= dirRow;\n\t } else if (e.which == 40) {\n\t dRow += dirRow;\n\t }\n\t\n\t // define new selection range\n\t var new_last = new _slick2.default.Range(active.row, active.cell, active.row + dirRow * dRow, active.cell + dirCell * dCell);\n\t if (removeInvalidRanges([new_last]).length) {\n\t ranges.push(new_last);\n\t var viewRow = dirRow > 0 ? new_last.toRow : new_last.fromRow;\n\t var viewCell = dirCell > 0 ? new_last.toCell : new_last.fromCell;\n\t _grid.scrollRowIntoView(viewRow);\n\t _grid.scrollCellIntoView(viewRow, viewCell);\n\t } else ranges.push(last);\n\t\n\t setSelectedRanges(ranges);\n\t\n\t e.preventDefault();\n\t e.stopPropagation();\n\t }\n\t }\n\t\n\t Object.assign(this, {\n\t getSelectedRanges: getSelectedRanges,\n\t setSelectedRanges: setSelectedRanges,\n\t\n\t init: init,\n\t destroy: destroy,\n\t\n\t onSelectedRangesChanged: new _slick2.default.Event()\n\t });\n\t}\n\n/***/ }),\n/* 15 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _slick = __webpack_require__(16);\n\t\n\tvar _slick2 = _interopRequireDefault(_slick);\n\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n\texports.default = _slick2.default;\n\n/***/ }),\n/* 16 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _jquery = __webpack_require__(2);\n\t\n\tvar _jquery2 = _interopRequireDefault(_jquery);\n\t\n\tvar _slick = __webpack_require__(1);\n\t\n\tvar _slick2 = _interopRequireDefault(_slick);\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\t\n\texports.default = CheckboxSelectColumn;\n\t\n\t\n\tfunction CheckboxSelectColumn(options) {\n\t var _grid = void 0;\n\t var _self = this;\n\t var _handler = new _slick2.default.EventHandler();\n\t var _selectedRowsLookup = {};\n\t var _defaults = {\n\t columnId: '_checkbox_selector',\n\t cssClass: null,\n\t toolTip: 'Select/Deselect All',\n\t width: 30\n\t };\n\t\n\t var _options = _jquery2.default.extend(true, {}, _defaults, options);\n\t\n\t function init(grid) {\n\t _grid = grid;\n\t _handler.subscribe(_grid.onSelectedRowsChanged, handleSelectedRowsChanged).subscribe(_grid.onClick, handleClick).subscribe(_grid.onHeaderClick, handleHeaderClick).subscribe(_grid.onKeyDown, handleKeyDown);\n\t }\n\t\n\t function destroy() {\n\t _handler.unsubscribeAll();\n\t }\n\t\n\t function handleSelectedRowsChanged(e, args) {\n\t var selectedRows = _grid.getSelectedRows();\n\t var lookup = {},\n\t row = void 0,\n\t i = void 0;\n\t for (i = 0; i < selectedRows.length; i++) {\n\t row = selectedRows[i];\n\t lookup[row] = true;\n\t if (lookup[row] !== _selectedRowsLookup[row]) {\n\t _grid.invalidateRow(row);\n\t delete _selectedRowsLookup[row];\n\t }\n\t }\n\t for (i in _selectedRowsLookup) {\n\t _grid.invalidateRow(i);\n\t }\n\t _selectedRowsLookup = lookup;\n\t _grid.render();\n\t\n\t if (selectedRows.length && selectedRows.length == _grid.getDataLength()) {\n\t _grid.updateColumnHeader(_options.columnId, \"\", _options.toolTip);\n\t } else {\n\t _grid.updateColumnHeader(_options.columnId, \"\", _options.toolTip);\n\t }\n\t }\n\t\n\t function handleKeyDown(e, args) {\n\t if (e.which == 32) {\n\t if (_grid.getColumns()[args.cell].id === _options.columnId) {\n\t // if editing, try to commit\n\t if (!_grid.getEditorLock().isActive() || _grid.getEditorLock().commitCurrentEdit()) {\n\t toggleRowSelection(args.row);\n\t }\n\t e.preventDefault();\n\t e.stopImmediatePropagation();\n\t }\n\t }\n\t }\n\t\n\t function handleClick(e, args) {\n\t // clicking on a row select checkbox\n\t if (_grid.getColumns()[args.cell].id === _options.columnId && (0, _jquery2.default)(e.target).is(':checkbox')) {\n\t // if editing, try to commit\n\t if (_grid.getEditorLock().isActive() && !_grid.getEditorLock().commitCurrentEdit()) {\n\t e.preventDefault();\n\t e.stopImmediatePropagation();\n\t return;\n\t }\n\t\n\t toggleRowSelection(args.row);\n\t e.stopPropagation();\n\t e.stopImmediatePropagation();\n\t }\n\t }\n\t\n\t function toggleRowSelection(row) {\n\t if (_selectedRowsLookup[row]) {\n\t _grid.setSelectedRows(_jquery2.default.grep(_grid.getSelectedRows(), function (n) {\n\t return n != row;\n\t }));\n\t } else {\n\t _grid.setSelectedRows(_grid.getSelectedRows().concat(row));\n\t }\n\t }\n\t\n\t function handleHeaderClick(e, args) {\n\t if (args.column.id == _options.columnId && (0, _jquery2.default)(e.target).is(':checkbox')) {\n\t // if editing, try to commit\n\t if (_grid.getEditorLock().isActive() && !_grid.getEditorLock().commitCurrentEdit()) {\n\t e.preventDefault();\n\t e.stopImmediatePropagation();\n\t return;\n\t }\n\t\n\t if ((0, _jquery2.default)(e.target).is(':checked')) {\n\t var rows = [];\n\t for (var i = 0; i < _grid.getDataLength(); i++) {\n\t rows.push(i);\n\t }\n\t _grid.setSelectedRows(rows);\n\t } else {\n\t _grid.setSelectedRows([]);\n\t }\n\t e.stopPropagation();\n\t e.stopImmediatePropagation();\n\t }\n\t }\n\t\n\t function getColumnDefinition() {\n\t return {\n\t id: _options.columnId,\n\t name: \"\",\n\t toolTip: _options.toolTip,\n\t field: 'sel',\n\t width: _options.width,\n\t resizable: false,\n\t sortable: false,\n\t cssClass: _options.cssClass,\n\t formatter: checkboxSelectionFormatter\n\t };\n\t }\n\t\n\t function checkboxSelectionFormatter(row, cell, value, columnDef, dataContext) {\n\t if (dataContext) {\n\t return _selectedRowsLookup[row] ? \"\" : \"\";\n\t }\n\t return null;\n\t }\n\t\n\t Object.assign(this, {\n\t init: init,\n\t destroy: destroy,\n\t\n\t getColumnDefinition: getColumnDefinition\n\t });\n\t}\n\n/***/ }),\n/* 17 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _slick = __webpack_require__(18);\n\t\n\tvar _slick2 = _interopRequireDefault(_slick);\n\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n\texports.default = _slick2.default;\n\n/***/ }),\n/* 18 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _jquery = __webpack_require__(2);\n\t\n\tvar _jquery2 = _interopRequireDefault(_jquery);\n\t\n\tvar _slick = __webpack_require__(1);\n\t\n\tvar _slick2 = _interopRequireDefault(_slick);\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\t\n\texports.default = HeaderButtons;\n\t/** *\r\n\t * A plugin to add custom buttons to column headers.\r\n\t *\r\n\t * USAGE:\r\n\t *\r\n\t * Add the plugin .js & .css files and register it with the grid.\r\n\t *\r\n\t * To specify a custom button in a column header, extend the column definition like so:\r\n\t *\r\n\t * var columns = [\r\n\t * {\r\n\t * id: 'myColumn',\r\n\t * name: 'My column',\r\n\t *\r\n\t * // This is the relevant part\r\n\t * header: {\r\n\t * buttons: [\r\n\t * {\r\n\t * // button options\r\n\t * },\r\n\t * {\r\n\t * // button options\r\n\t * }\r\n\t * ]\r\n\t * }\r\n\t * }\r\n\t * ];\r\n\t *\r\n\t * Available button options:\r\n\t * cssClass: CSS class to add to the button.\r\n\t * image: Relative button image path.\r\n\t * tooltip: Button tooltip.\r\n\t * showOnHover: Only show the button on hover.\r\n\t * handler: Button click handler.\r\n\t * command: A command identifier to be passed to the onCommand event handlers.\r\n\t *\r\n\t * The plugin exposes the following events:\r\n\t * onCommand: Fired on button click for buttons with 'command' specified.\r\n\t * Event args:\r\n\t * grid: Reference to the grid.\r\n\t * column: Column definition.\r\n\t * command: Button command identified.\r\n\t * button: Button options. Note that you can change the button options in your\r\n\t * event handler, and the column header will be automatically updated to\r\n\t * reflect them. This is useful if you want to implement something like a\r\n\t * toggle button.\r\n\t *\r\n\t *\r\n\t * @param options {Object} Options:\r\n\t * buttonCssClass: a CSS class to use for buttons (default 'slick-header-button')\r\n\t * @class Slick.Plugins.HeaderButtons\r\n\t * @constructor\r\n\t */\n\t\n\tfunction HeaderButtons(options) {\n\t var _grid;\n\t var _self = this;\n\t var _handler = new _slick2.default.EventHandler();\n\t var _defaults = {\n\t buttonCssClass: 'slick-header-button'\n\t };\n\t\n\t function init(grid) {\n\t options = Object.assign({}, _defaults, options);\n\t _grid = grid;\n\t _handler.subscribe(_grid.onHeaderCellRendered, handleHeaderCellRendered).subscribe(_grid.onBeforeHeaderCellDestroy, handleBeforeHeaderCellDestroy);\n\t\n\t // Force the grid to re-render the header now that the events are hooked up.\n\t _grid.setColumns(_grid.getColumns());\n\t }\n\t\n\t function destroy() {\n\t _handler.unsubscribeAll();\n\t }\n\t\n\t function handleHeaderCellRendered(e, args) {\n\t var column = args.column;\n\t\n\t if (column.header && column.header.buttons) {\n\t // Append buttons in reverse order since they are floated to the right.\n\t var i = column.header.buttons.length;\n\t while (i--) {\n\t var button = column.header.buttons[i];\n\t var btn = (0, _jquery2.default)('').addClass(options.buttonCssClass).data('column', column).data('button', button);\n\t\n\t if (button.showOnHover) {\n\t btn.addClass('slick-header-button-hidden');\n\t }\n\t\n\t if (button.image) {\n\t btn.css('backgroundImage', 'url(' + button.image + ')');\n\t }\n\t\n\t if (button.cssClass) {\n\t btn.addClass(button.cssClass);\n\t }\n\t\n\t if (button.tooltip) {\n\t btn.attr('title', button.tooltip);\n\t }\n\t\n\t if (button.command) {\n\t btn.data('command', button.command);\n\t }\n\t\n\t if (button.handler) {\n\t btn.bind('click', button.handler);\n\t }\n\t\n\t btn.bind('click', handleButtonClick).appendTo(args.node);\n\t args.node.classList.add('has-buttons');\n\t }\n\t }\n\t }\n\t\n\t function handleBeforeHeaderCellDestroy(e, args) {\n\t var column = args.column;\n\t\n\t if (column.header && column.header.buttons) {\n\t // Removing buttons via jQuery will also clean up any event handlers and data.\n\t // NOTE: If you attach event handlers directly or using a different framework,\n\t // you must also clean them up here to avoid memory leaks.\n\t (0, _jquery2.default)(args.node).find('.' + options.buttonCssClass).remove();\n\t }\n\t }\n\t\n\t function handleButtonClick(e) {\n\t var command = (0, _jquery2.default)(this).data('command');\n\t var columnDef = (0, _jquery2.default)(this).data('column');\n\t var button = (0, _jquery2.default)(this).data('button');\n\t\n\t if (command != null) {\n\t _self.onCommand.notify({\n\t 'grid': _grid,\n\t 'column': columnDef,\n\t 'command': command,\n\t 'button': button\n\t }, e, _self);\n\t\n\t // Update the header in case the user updated the button definition in the handler.\n\t _grid.updateColumnHeader(columnDef.id);\n\t }\n\t\n\t // Stop propagation so that it doesn't register as a header click event.\n\t e.preventDefault();\n\t e.stopPropagation();\n\t }\n\t\n\t Object.assign(this, {\n\t init: init,\n\t destroy: destroy,\n\t\n\t 'onCommand': new _slick2.default.Event()\n\t });\n\t}\n\n/***/ }),\n/* 19 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _slick = __webpack_require__(20);\n\t\n\tvar _slick2 = _interopRequireDefault(_slick);\n\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n\texports.default = _slick2.default;\n\n/***/ }),\n/* 20 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _jquery = __webpack_require__(2);\n\t\n\tvar _jquery2 = _interopRequireDefault(_jquery);\n\t\n\tvar _slick = __webpack_require__(1);\n\t\n\tvar _slick2 = _interopRequireDefault(_slick);\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\t\n\t// import './slick.headermenu.css';\n\t\n\texports.default = HeaderMenu;\n\t\n\t/** *\r\n\t * A plugin to add drop-down menus to column headers.\r\n\t *\r\n\t * USAGE:\r\n\t *\r\n\t * Add the plugin .js & .css files and register it with the grid.\r\n\t *\r\n\t * To specify a menu in a column header, extend the column definition like so:\r\n\t *\r\n\t * const columns = [\r\n\t * {\r\n\t * id: 'myColumn',\r\n\t * name: 'My column',\r\n\t *\r\n\t * // This is the relevant part\r\n\t * header: {\r\n\t * menu: {\r\n\t * items: [\r\n\t * {\r\n\t * // menu item options\r\n\t * },\r\n\t * {\r\n\t * // menu item options\r\n\t * }\r\n\t * ]\r\n\t * }\r\n\t * }\r\n\t * }\r\n\t * ];\r\n\t *\r\n\t *\r\n\t * Available menu options:\r\n\t * tooltip: Menu button tooltip.\r\n\t *\r\n\t *\r\n\t * Available menu item options:\r\n\t * title: Menu item text.\r\n\t * disabled: Whether the item is disabled.\r\n\t * tooltip: Item tooltip.\r\n\t * command: A command identifier to be passed to the onCommand event handlers.\r\n\t * iconCssClass: A CSS class to be added to the menu item icon.\r\n\t * iconImage: A url to the icon image.\r\n\t *\r\n\t *\r\n\t * The plugin exposes the following events:\r\n\t * onBeforeMenuShow: Fired before the menu is shown. You can customize the menu or dismiss it by returning false.\r\n\t * Event args:\r\n\t * grid: Reference to the grid.\r\n\t * column: Column definition.\r\n\t * menu: Menu options. Note that you can change the menu items here.\r\n\t *\r\n\t * onCommand: Fired on menu item click for buttons with 'command' specified.\r\n\t * Event args:\r\n\t * grid: Reference to the grid.\r\n\t * column: Column definition.\r\n\t * command: Button command identified.\r\n\t * button: Button options. Note that you can change the button options in your\r\n\t * event handler, and the column header will be automatically updated to\r\n\t * reflect them. This is useful if you want to implement something like a\r\n\t * toggle button.\r\n\t *\r\n\t *\r\n\t * @param options {Object} Options:\r\n\t * buttonCssClass: an extra CSS class to add to the menu button\r\n\t * buttonImage: a url to the menu button image (default '../images/down.gif')\r\n\t * @class Slick.Plugins.HeaderButtons\r\n\t * @constructor\r\n\t */\n\t\n\tfunction HeaderMenu(options) {\n\t var _grid = void 0;\n\t var _self = this;\n\t var _handler = new _slick2.default.EventHandler();\n\t var _defaults = {\n\t buttonCssClass: null,\n\t buttonImage: null\n\t };\n\t\n\t var $menu = void 0;\n\t var $activeHeaderColumn = void 0;\n\t\n\t function init(grid) {\n\t options = Object.assign({}, _defaults, options);\n\t _grid = grid;\n\t _handler.subscribe(_grid.onHeaderCellRendered, handleHeaderCellRendered).subscribe(_grid.onBeforeHeaderCellDestroy, handleBeforeHeaderCellDestroy);\n\t\n\t // Force the grid to re-render the header now that the events are hooked up.\n\t _grid.setColumns(_grid.getColumns());\n\t\n\t // Hide the menu on outside click.\n\t (0, _jquery2.default)(document.body).bind('mousedown', handleBodyMouseDown);\n\t }\n\t\n\t function destroy() {\n\t _handler.unsubscribeAll();\n\t (0, _jquery2.default)(document.body).unbind('mousedown', handleBodyMouseDown);\n\t }\n\t\n\t function handleBodyMouseDown(e) {\n\t if ($menu && $menu[0] != e.target && !_jquery2.default.contains($menu[0], e.target)) {\n\t hideMenu();\n\t }\n\t }\n\t\n\t function hideMenu() {\n\t if ($menu) {\n\t $menu.remove();\n\t $menu = null;\n\t $activeHeaderColumn.removeClass('slick-header-column-active');\n\t }\n\t }\n\t\n\t function handleHeaderCellRendered(e, args) {\n\t var column = args.column;\n\t var menu = column.header && column.header.menu;\n\t\n\t if (menu) {\n\t var $el = (0, _jquery2.default)('').addClass('slick-header-menubutton').data('column', column).data('menu', menu);\n\t\n\t if (options.buttonCssClass) {\n\t $el.addClass(options.buttonCssClass);\n\t }\n\t\n\t if (options.buttonImage) {\n\t $el.css('background-image', 'url(' + options.buttonImage + ')');\n\t }\n\t\n\t if (menu.tooltip) {\n\t $el.attr('title', menu.tooltip);\n\t }\n\t\n\t $el.bind('click', showMenu).appendTo(args.node);\n\t }\n\t }\n\t\n\t function handleBeforeHeaderCellDestroy(e, args) {\n\t var column = args.column;\n\t\n\t if (column.header && column.header.menu) {\n\t (0, _jquery2.default)(args.node).find('.slick-header-menubutton').remove();\n\t }\n\t }\n\t\n\t function showMenu(e) {\n\t var $menuButton = (0, _jquery2.default)(this);\n\t var menu = $menuButton.data('menu');\n\t var columnDef = $menuButton.data('column');\n\t\n\t // Let the user modify the menu or cancel altogether,\n\t // or provide alternative menu implementation.\n\t if (_self.onBeforeMenuShow.notify({\n\t 'grid': _grid,\n\t 'column': columnDef,\n\t 'menu': menu\n\t }, e, _self) == false) {\n\t return;\n\t }\n\t\n\t if (!$menu) {\n\t $menu = (0, _jquery2.default)(\"\").appendTo(_grid.getContainerNode());\n\t }\n\t $menu.empty();\n\t\n\t // Construct the menu items.\n\t for (var i = 0; i < menu.items.length; i++) {\n\t var item = menu.items[i];\n\t\n\t var $li = (0, _jquery2.default)(\"\").data('command', item.command || '').data('column', columnDef).data('item', item).bind('click', handleMenuItemClick).appendTo($menu);\n\t\n\t if (item.disabled) {\n\t $li.addClass('slick-header-menuitem-disabled');\n\t }\n\t\n\t if (item.tooltip) {\n\t $li.attr('title', item.tooltip);\n\t }\n\t\n\t var $icon = (0, _jquery2.default)(\"\").appendTo($li);\n\t\n\t if (item.iconCssClass) {\n\t $icon.addClass(item.iconCssClass);\n\t }\n\t\n\t if (item.iconImage) {\n\t $icon.css('background-image', 'url(' + item.iconImage + ')');\n\t }\n\t\n\t (0, _jquery2.default)(\"\").text(item.title).appendTo($li);\n\t }\n\t\n\t // Position the menu.\n\t $menu.offset({ top: (0, _jquery2.default)(this).offset().top + (0, _jquery2.default)(this).height(), left: (0, _jquery2.default)(this).offset().left });\n\t\n\t // Mark the header as active to keep the highlighting.\n\t $activeHeaderColumn = $menuButton.closest('.slick-header-column');\n\t $activeHeaderColumn.addClass('slick-header-column-active');\n\t\n\t // Stop propagation so that it doesn't register as a header click event.\n\t e.preventDefault();\n\t e.stopPropagation();\n\t }\n\t\n\t function handleMenuItemClick(e) {\n\t var command = (0, _jquery2.default)(this).data('command');\n\t var columnDef = (0, _jquery2.default)(this).data('column');\n\t var item = (0, _jquery2.default)(this).data('item');\n\t\n\t if (item.disabled) {\n\t return;\n\t }\n\t\n\t hideMenu();\n\t\n\t if (command != null && command != '') {\n\t _self.onCommand.notify({\n\t 'grid': _grid,\n\t 'column': columnDef,\n\t 'command': command,\n\t 'item': item\n\t }, e, _self);\n\t }\n\t\n\t // Stop propagation so that it doesn't register as a header click event.\n\t e.preventDefault();\n\t e.stopPropagation();\n\t }\n\t\n\t Object.assign(this, {\n\t init: init,\n\t destroy: destroy,\n\t\n\t 'onBeforeMenuShow': new _slick2.default.Event(),\n\t 'onCommand': new _slick2.default.Event()\n\t });\n\t}\n\n/***/ }),\n/* 21 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _slick = __webpack_require__(22);\n\t\n\tvar _slick2 = _interopRequireDefault(_slick);\n\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n\texports.default = _slick2.default;\n\n/***/ }),\n/* 22 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _slick = __webpack_require__(1);\n\t\n\tvar _slick2 = _interopRequireDefault(_slick);\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\t\n\texports.default = RowMoveManager;\n\t\n\t\n\tfunction RowMoveManager(options) {\n\t var _grid = void 0;\n\t var _canvas = void 0;\n\t var _dragging = void 0;\n\t var _self = this;\n\t var _handler = new _slick2.default.EventHandler();\n\t var _defaults = {\n\t cancelEditOnDrag: false\n\t };\n\t\n\t function init(grid) {\n\t options = Object.assign({}, _defaults, options);\n\t _grid = grid;\n\t _canvas = _grid.getCanvasNode();\n\t _handler.subscribe(_grid.onDragInit, handleDragInit).subscribe(_grid.onDragStart, handleDragStart).subscribe(_grid.onDrag, handleDrag).subscribe(_grid.onDragEnd, handleDragEnd);\n\t }\n\t\n\t function destroy() {\n\t _handler.unsubscribeAll();\n\t }\n\t\n\t function handleDragInit(e, dd) {\n\t // prevent the grid from cancelling drag'n'drop by default\n\t e.stopImmediatePropagation();\n\t }\n\t\n\t function handleDragStart(e, dd) {\n\t var cell = _grid.getCellFromEvent(e);\n\t\n\t if (options.cancelEditOnDrag && _grid.getEditorLock().isActive()) {\n\t _grid.getEditorLock().cancelCurrentEdit();\n\t }\n\t\n\t if (_grid.getEditorLock().isActive() || !/move|selectAndMove/.test(_grid.getColumns()[cell.cell].behavior)) {\n\t return false;\n\t }\n\t\n\t _dragging = true;\n\t e.stopImmediatePropagation();\n\t\n\t var selectedRows = _grid.getSelectedRows();\n\t\n\t if (selectedRows.length == 0 || $.inArray(cell.row, selectedRows) == -1) {\n\t selectedRows = [cell.row];\n\t _grid.setSelectedRows(selectedRows);\n\t }\n\t\n\t var rowHeight = _grid.getOptions().rowHeight;\n\t\n\t dd.selectedRows = selectedRows;\n\t\n\t dd.selectionProxy = $(\"\").css('position', 'absolute').css('zIndex', '99999').css('width', $(_canvas).innerWidth()).css('height', rowHeight * selectedRows.length).appendTo(_canvas);\n\t\n\t dd.guide = $(\"\").css('position', 'absolute').css('zIndex', '99998').css('width', $(_canvas).innerWidth()).css('top', -1000).appendTo(_canvas);\n\t\n\t dd.insertBefore = -1;\n\t }\n\t\n\t function handleDrag(e, dd) {\n\t if (!_dragging) {\n\t return;\n\t }\n\t\n\t e.stopImmediatePropagation();\n\t\n\t var top = e.pageY - $(_canvas).offset().top;\n\t dd.selectionProxy.css('top', top - 5);\n\t\n\t var insertBefore = Math.max(0, Math.min(Math.round(top / _grid.getOptions().rowHeight), _grid.getDataLength()));\n\t if (insertBefore !== dd.insertBefore) {\n\t var eventData = {\n\t 'rows': dd.selectedRows,\n\t 'insertBefore': insertBefore\n\t };\n\t\n\t if (_self.onBeforeMoveRows.notify(eventData) === false) {\n\t dd.guide.css('top', -1000);\n\t dd.canMove = false;\n\t } else {\n\t dd.guide.css('top', insertBefore * _grid.getOptions().rowHeight);\n\t dd.canMove = true;\n\t }\n\t\n\t dd.insertBefore = insertBefore;\n\t }\n\t }\n\t\n\t function handleDragEnd(e, dd) {\n\t if (!_dragging) {\n\t return;\n\t }\n\t _dragging = false;\n\t e.stopImmediatePropagation();\n\t\n\t dd.guide.remove();\n\t dd.selectionProxy.remove();\n\t\n\t if (dd.canMove) {\n\t var eventData = {\n\t 'rows': dd.selectedRows,\n\t 'insertBefore': dd.insertBefore\n\t };\n\t // TODO: _grid.remapCellCssClasses ?\n\t _self.onMoveRows.notify(eventData);\n\t }\n\t }\n\t\n\t Object.assign(this, {\n\t 'onBeforeMoveRows': new _slick2.default.Event(),\n\t 'onMoveRows': new _slick2.default.Event(),\n\t init: init,\n\t destroy: destroy\n\t });\n\t}\n\n/***/ }),\n/* 23 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _slick = __webpack_require__(24);\n\t\n\tvar _slick2 = _interopRequireDefault(_slick);\n\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n\texports.default = _slick2.default;\n\n/***/ }),\n/* 24 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _jquery = __webpack_require__(2);\n\t\n\tvar _jquery2 = _interopRequireDefault(_jquery);\n\t\n\tvar _slick = __webpack_require__(1);\n\t\n\tvar _slick2 = _interopRequireDefault(_slick);\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\t\n\texports.default = RowSelectionModel;\n\t\n\t\n\tfunction RowSelectionModel(options) {\n\t var _grid = void 0;\n\t var _ranges = [];\n\t var _self = this;\n\t var _handler = new _slick2.default.EventHandler();\n\t var _inHandler = void 0;\n\t var _options = void 0;\n\t var _defaults = {\n\t selectActiveRow: true\n\t };\n\t\n\t function init(grid) {\n\t _options = Object.assign({}, _defaults, options);\n\t _grid = grid;\n\t _handler.subscribe(_grid.onActiveCellChanged, wrapHandler(handleActiveCellChange));\n\t _handler.subscribe(_grid.onKeyDown, wrapHandler(handleKeyDown));\n\t _handler.subscribe(_grid.onClick, wrapHandler(handleClick));\n\t }\n\t\n\t function destroy() {\n\t _handler.unsubscribeAll();\n\t }\n\t\n\t function wrapHandler(handler) {\n\t return function () {\n\t if (!_inHandler) {\n\t _inHandler = true;\n\t handler.apply(this, arguments);\n\t _inHandler = false;\n\t }\n\t };\n\t }\n\t\n\t function rangesToRows(ranges) {\n\t var rows = [];\n\t for (var i = 0; i < ranges.length; i++) {\n\t for (var j = ranges[i].fromRow; j <= ranges[i].toRow; j++) {\n\t rows.push(j);\n\t }\n\t }\n\t return rows;\n\t }\n\t\n\t function rowsToRanges(rows) {\n\t var ranges = [];\n\t var lastCell = _grid.getColumns().length - 1;\n\t for (var i = 0; i < rows.length; i++) {\n\t ranges.push(new _slick2.default.Range(rows[i], 0, rows[i], lastCell));\n\t }\n\t return ranges;\n\t }\n\t\n\t function getRowsRange(from, to) {\n\t var i = void 0;\n\t var rows = [];\n\t for (i = from; i <= to; i++) {\n\t rows.push(i);\n\t }\n\t for (i = to; i < from; i++) {\n\t rows.push(i);\n\t }\n\t return rows;\n\t }\n\t\n\t function getSelectedRows() {\n\t return rangesToRows(_ranges);\n\t }\n\t\n\t function setSelectedRows(rows) {\n\t setSelectedRanges(rowsToRanges(rows));\n\t }\n\t\n\t function setSelectedRanges(ranges) {\n\t // simle check for: empty selection didn't change, prevent firing onSelectedRangesChanged\n\t if ((!_ranges || _ranges.length === 0) && (!ranges || ranges.length === 0)) {\n\t return;\n\t }\n\t _ranges = ranges;\n\t _self.onSelectedRangesChanged.notify(_ranges);\n\t }\n\t\n\t function getSelectedRanges() {\n\t return _ranges;\n\t }\n\t\n\t function handleActiveCellChange(e, data) {\n\t if (_options.selectActiveRow && data.row != null) {\n\t setSelectedRanges([new _slick2.default.Range(data.row, 0, data.row, _grid.getColumns().length - 1)]);\n\t }\n\t }\n\t\n\t function handleKeyDown(e) {\n\t var activeRow = _grid.getActiveCell();\n\t if (activeRow && e.shiftKey && !e.ctrlKey && !e.altKey && !e.metaKey && (e.which == 38 || e.which == 40)) {\n\t var selectedRows = getSelectedRows();\n\t selectedRows.sort(function (x, y) {\n\t return x - y;\n\t });\n\t\n\t if (!selectedRows.length) {\n\t selectedRows = [activeRow.row];\n\t }\n\t\n\t var top = selectedRows[0];\n\t var bottom = selectedRows[selectedRows.length - 1];\n\t var active = void 0;\n\t\n\t if (e.which == 40) {\n\t active = activeRow.row < bottom || top == bottom ? ++bottom : ++top;\n\t } else {\n\t active = activeRow.row < bottom ? --bottom : --top;\n\t }\n\t\n\t if (active >= 0 && active < _grid.getDataLength()) {\n\t _grid.scrollRowIntoView(active);\n\t _ranges = rowsToRanges(getRowsRange(top, bottom));\n\t setSelectedRanges(_ranges);\n\t }\n\t\n\t e.preventDefault();\n\t e.stopPropagation();\n\t }\n\t }\n\t\n\t function handleClick(e) {\n\t var cell = _grid.getCellFromEvent(e);\n\t if (!cell || !_grid.canCellBeActive(cell.row, cell.cell)) {\n\t return false;\n\t }\n\t\n\t if (!_grid.getOptions().multiSelect || !e.ctrlKey && !e.shiftKey && !e.metaKey) {\n\t return false;\n\t }\n\t\n\t var selection = rangesToRows(_ranges);\n\t var idx = _jquery2.default.inArray(cell.row, selection);\n\t\n\t if (idx === -1 && (e.ctrlKey || e.metaKey)) {\n\t selection.push(cell.row);\n\t _grid.setActiveCell(cell.row, cell.cell);\n\t } else if (idx !== -1 && (e.ctrlKey || e.metaKey)) {\n\t selection = _jquery2.default.grep(selection, function (o, i) {\n\t return o !== cell.row;\n\t });\n\t _grid.setActiveCell(cell.row, cell.cell);\n\t } else if (selection.length && e.shiftKey) {\n\t var last = selection.pop();\n\t var from = Math.min(cell.row, last);\n\t var to = Math.max(cell.row, last);\n\t selection = [];\n\t for (var i = from; i <= to; i++) {\n\t if (i !== last) {\n\t selection.push(i);\n\t }\n\t }\n\t selection.push(last);\n\t _grid.setActiveCell(cell.row, cell.cell);\n\t }\n\t\n\t _ranges = rowsToRanges(selection);\n\t setSelectedRanges(_ranges);\n\t e.stopImmediatePropagation();\n\t\n\t return true;\n\t }\n\t\n\t Object.assign(this, {\n\t getSelectedRows: getSelectedRows,\n\t setSelectedRows: setSelectedRows,\n\t\n\t getSelectedRanges: getSelectedRanges,\n\t setSelectedRanges: setSelectedRanges,\n\t\n\t init: init,\n\t destroy: destroy,\n\t\n\t 'onSelectedRangesChanged': new _slick2.default.Event()\n\t });\n\t}\n\n/***/ }),\n/* 25 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\texports.Plugins = exports.FrozenGrid = exports.Grid = exports.Data = exports.Formatters = exports.Editors = exports.Slick = undefined;\n\t\n\tvar _slick = __webpack_require__(1);\n\t\n\tvar _slick2 = _interopRequireDefault(_slick);\n\t\n\tvar _slick3 = __webpack_require__(28);\n\t\n\tvar _slick4 = _interopRequireDefault(_slick3);\n\t\n\tvar _slick5 = __webpack_require__(27);\n\t\n\tvar _slick6 = _interopRequireDefault(_slick5);\n\t\n\tvar _slick7 = __webpack_require__(30);\n\t\n\tvar _slick8 = _interopRequireDefault(_slick7);\n\t\n\tvar _slickFrozen = __webpack_require__(26);\n\t\n\tvar _slickFrozen2 = _interopRequireDefault(_slickFrozen);\n\t\n\tvar _slick9 = __webpack_require__(29);\n\t\n\tvar _slick10 = _interopRequireDefault(_slick9);\n\t\n\tvar _plugins = __webpack_require__(6);\n\t\n\tvar Plugins = _interopRequireWildcard(_plugins);\n\t\n\tfunction _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\t\n\texports.Slick = _slick2.default;\n\texports.Editors = _slick4.default;\n\texports.Formatters = _slick10.default;\n\texports.Data = _slick6.default;\n\texports.Grid = _slick8.default;\n\texports.FrozenGrid = _slickFrozen2.default;\n\texports.Plugins = Plugins;\n\n/***/ }),\n/* 26 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _jquery = __webpack_require__(2);\n\t\n\tvar _jquery2 = _interopRequireDefault(_jquery);\n\t\n\tvar _interact = __webpack_require__(5);\n\t\n\tvar _interact2 = _interopRequireDefault(_interact);\n\t\n\tvar _slick = __webpack_require__(1);\n\t\n\tvar _slick2 = _interopRequireDefault(_slick);\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\t\n\t// Slick.Grid globals pretense\n\t_slick2.default.FrozenGrid = SlickGrid; /**\r\n\t * @license\r\n\t * (c) 2009-2013 Michael Leibman\r\n\t * michael{dot}leibman{at}gmail{dot}com\r\n\t * http://github.com/mleibman/slickgrid\r\n\t *\r\n\t * Distributed under MIT license.\r\n\t * All rights reserved.\r\n\t *\r\n\t * SlickGrid v2.2\r\n\t *\r\n\t * NOTES:\r\n\t * Cell/row DOM manipulations are done directly bypassing jQuery's DOM manipulation methods.\r\n\t * This increases the speed dramatically, but can only be done safely because there are no event handlers\r\n\t * or data associated with any cell/row DOM nodes. Cell editors must make sure they implement .destroy()\r\n\t * and do proper cleanup.\r\n\t */\n\t\n\texports.default = SlickGrid;\n\t\n\t// shared across all grids on the page\n\t\n\tvar scrollbarDimensions;\n\tvar maxSupportedCssHeight; // browser's breaking point\n\t\n\t//////////////////////////////////////////////////////////////////////////////////////////////\n\t// SlickGrid class implementation (available as Slick.Grid)\n\t\n\t/**\r\n\t * Creates a new instance of the grid.\r\n\t * @class SlickGrid\r\n\t * @constructor\r\n\t * @param {Node} container Container node to create the grid in.\r\n\t * @param {Array,Object} data An array of objects for databinding.\r\n\t * @param {Array} columns An array of column definitions.\r\n\t * @param {Object} options Grid options.\r\n\t **/\n\tfunction SlickGrid(container, data, columns, options) {\n\t // settings\n\t var defaults = {\n\t explicitInitialization: false,\n\t rowHeight: 25,\n\t defaultColumnWidth: 80,\n\t enableAddRow: false,\n\t leaveSpaceForNewRows: false,\n\t editable: false,\n\t autoEdit: true,\n\t enableCellNavigation: true,\n\t enableColumnReorder: true,\n\t asyncEditorLoading: false,\n\t asyncEditorLoadDelay: 100,\n\t forceFitColumns: false,\n\t enableAsyncPostRender: false,\n\t asyncPostRenderDelay: 50,\n\t autoHeight: false,\n\t editorLock: _slick2.default.GlobalEditorLock,\n\t showHeaderRow: false,\n\t headerRowHeight: 25,\n\t showFooterRow: false,\n\t footerRowHeight: 25,\n\t showTopPanel: false,\n\t topPanelHeight: 25,\n\t formatterFactory: null,\n\t editorFactory: null,\n\t cellFlashingCssClass: \"flashing\",\n\t selectedCellCssClass: \"selected\",\n\t multiSelect: true,\n\t enableTextSelectionOnCells: false,\n\t dataItemColumnValueExtractor: null,\n\t frozenBottom: false,\n\t frozenColumn: -1,\n\t frozenRow: -1,\n\t fullWidthRows: false,\n\t multiColumnSort: false,\n\t defaultFormatter: defaultFormatter,\n\t forceSyncScrolling: false,\n\t addNewRowCssClass: \"new-row\"\n\t };\n\t\n\t var columnDefaults = {\n\t name: \"\",\n\t resizable: true,\n\t sortable: false,\n\t minWidth: 30,\n\t rerenderOnResize: false,\n\t headerCssClass: null,\n\t defaultSortAsc: true,\n\t focusable: true,\n\t selectable: true\n\t };\n\t\n\t // scroller\n\t var th; // virtual height\n\t var h; // real scrollable height\n\t var ph; // page height\n\t var n; // number of pages\n\t var cj; // \"jumpiness\" coefficient\n\t\n\t var page = 0; // current page\n\t var offset = 0; // current page offset\n\t var vScrollDir = 1;\n\t\n\t // private\n\t var initialized = false;\n\t var $container;\n\t var uid = \"slickgrid_\" + Math.round(1000000 * Math.random());\n\t var self = this;\n\t var $focusSink, $focusSink2;\n\t var $groupHeaders = (0, _jquery2.default)();\n\t var $headerScroller;\n\t var $headers;\n\t var $headerRow, $headerRowScroller, $headerRowSpacerL, $headerRowSpacerR;\n\t var $footerRow, $footerRowScroller, $footerRowSpacerL, $footerRowSpacerR;\n\t var $topPanelScroller;\n\t var $topPanel;\n\t var $viewport;\n\t var $canvas;\n\t var $style;\n\t var $boundAncestors;\n\t var treeColumns;\n\t var stylesheet, columnCssRulesL, columnCssRulesR;\n\t var viewportH, viewportW;\n\t var canvasWidth, canvasWidthL, canvasWidthR;\n\t var headersWidth, headersWidthL, headersWidthR;\n\t var viewportHasHScroll, viewportHasVScroll;\n\t var headerColumnWidthDiff = 0,\n\t headerColumnHeightDiff = 0,\n\t // border+padding\n\t cellWidthDiff = 0,\n\t cellHeightDiff = 0;\n\t var absoluteColumnMinWidth;\n\t var hasFrozenRows = false;\n\t var frozenRowsHeight = 0;\n\t var actualFrozenRow = -1;\n\t var paneTopH = 0;\n\t var paneBottomH = 0;\n\t var viewportTopH = 0;\n\t var viewportBottomH = 0;\n\t var topPanelH = 0;\n\t var headerRowH = 0;\n\t var footerRowH = 0;\n\t\n\t var tabbingDirection = 1;\n\t var $activeCanvasNode;\n\t var $activeViewportNode;\n\t var activePosX;\n\t var activeRow, activeCell;\n\t var activeCellNode = null;\n\t var currentEditor = null;\n\t var serializedEditorValue;\n\t var editController;\n\t\n\t var rowsCache = {};\n\t var renderedRows = 0;\n\t var numVisibleRows = 0;\n\t var prevScrollTop = 0;\n\t var scrollTop = 0;\n\t var lastRenderedScrollTop = 0;\n\t var lastRenderedScrollLeft = 0;\n\t var prevScrollLeft = 0;\n\t var scrollLeft = 0;\n\t\n\t var selectionModel;\n\t var selectedRows = [];\n\t\n\t var plugins = [];\n\t var cellCssClasses = {};\n\t\n\t var columnsById = {};\n\t var sortColumns = [];\n\t var columnPosLeft = [];\n\t var columnPosRight = [];\n\t\n\t // async call handles\n\t var h_editorLoader = null;\n\t var h_render = null;\n\t var h_postrender = null;\n\t var postProcessedRows = {};\n\t var postProcessToRow = null;\n\t var postProcessFromRow = null;\n\t\n\t // perf counters\n\t var counter_rows_rendered = 0;\n\t var counter_rows_removed = 0;\n\t\n\t // These two variables work around a bug with inertial scrolling in Webkit/Blink on Mac.\n\t // See http://crbug.com/312427.\n\t var rowNodeFromLastMouseWheelEvent; // this node must not be deleted while inertial scrolling\n\t var zombieRowNodeFromLastMouseWheelEvent; // node that was hidden instead of getting deleted\n\t\n\t var $paneHeaderL;\n\t var $paneHeaderR;\n\t var $paneTopL;\n\t var $paneTopR;\n\t var $paneBottomL;\n\t var $paneBottomR;\n\t\n\t var $headerScrollerL;\n\t var $headerScrollerR;\n\t\n\t var $headerL;\n\t var $headerR;\n\t\n\t var $groupHeadersL;\n\t var $groupHeadersR;\n\t\n\t var $headerRowScrollerL;\n\t var $headerRowScrollerR;\n\t\n\t var $footerRowScrollerL;\n\t var $footerRowScrollerR;\n\t\n\t var $headerRowL;\n\t var $headerRowR;\n\t\n\t var $footerRowL;\n\t var $footerRowR;\n\t\n\t var $topPanelScrollerL;\n\t var $topPanelScrollerR;\n\t\n\t var $topPanelL;\n\t var $topPanelR;\n\t\n\t var $viewportTopL;\n\t var $viewportTopR;\n\t var $viewportBottomL;\n\t var $viewportBottomR;\n\t\n\t var $canvasTopL;\n\t var $canvasTopR;\n\t var $canvasBottomL;\n\t var $canvasBottomR;\n\t\n\t var $viewportScrollContainerX;\n\t var $viewportScrollContainerY;\n\t var $headerScrollContainer;\n\t var $headerRowScrollContainer;\n\t var $footerRowScrollContainer;\n\t\n\t //////////////////////////////////////////////////////////////////////////////////////////////\n\t // Initialization\n\t\n\t function init() {\n\t $container = (0, _jquery2.default)(container);\n\t if ($container.length < 1) {\n\t throw new Error(\"SlickGrid requires a valid container, \" + container + \" does not exist in the DOM.\");\n\t }\n\t\n\t // calculate these only once and share between grid instances\n\t maxSupportedCssHeight = maxSupportedCssHeight || getMaxSupportedCssHeight();\n\t scrollbarDimensions = scrollbarDimensions || measureScrollbar();\n\t\n\t options = _jquery2.default.extend({}, defaults, options);\n\t validateAndEnforceOptions();\n\t columnDefaults.width = options.defaultColumnWidth;\n\t\n\t treeColumns = new _slick2.default.TreeColumns(columns);\n\t columns = treeColumns.extractColumns();\n\t\n\t columnsById = {};\n\t for (var i = 0; i < columns.length; i++) {\n\t var m = columns[i] = _jquery2.default.extend({}, columnDefaults, columns[i]);\n\t columnsById[m.id] = i;\n\t if (m.minWidth && m.width < m.minWidth) {\n\t m.width = m.minWidth;\n\t }\n\t if (m.maxWidth && m.width > m.maxWidth) {\n\t m.width = m.maxWidth;\n\t }\n\t }\n\t\n\t editController = {\n\t \"commitCurrentEdit\": commitCurrentEdit,\n\t \"cancelCurrentEdit\": cancelCurrentEdit\n\t };\n\t\n\t $container.empty().css(\"overflow\", \"hidden\").css(\"outline\", 0).addClass(uid).addClass(\"ui-widget\");\n\t\n\t // set up a positioning container if needed\n\t if (!/relative|absolute|fixed/.test($container.css(\"position\"))) {\n\t $container.css(\"position\", \"relative\");\n\t }\n\t\n\t $focusSink = (0, _jquery2.default)(\"\").appendTo($container);\n\t\n\t // Containers used for scrolling frozen columns and rows\n\t $paneHeaderL = (0, _jquery2.default)(\"\").appendTo($container);\n\t $paneHeaderR = (0, _jquery2.default)(\"\").appendTo($container);\n\t $paneTopL = (0, _jquery2.default)(\"\").appendTo($container);\n\t $paneTopR = (0, _jquery2.default)(\"\").appendTo($container);\n\t $paneBottomL = (0, _jquery2.default)(\"\").appendTo($container);\n\t $paneBottomR = (0, _jquery2.default)(\"\").appendTo($container);\n\t\n\t // Append the header scroller containers\n\t $headerScrollerL = (0, _jquery2.default)(\"\").appendTo($paneHeaderL);\n\t $headerScrollerR = (0, _jquery2.default)(\"\").appendTo($paneHeaderR);\n\t\n\t // Cache the header scroller containers\n\t $headerScroller = (0, _jquery2.default)().add($headerScrollerL).add($headerScrollerR);\n\t\n\t if (treeColumns.hasDepth()) {\n\t $groupHeadersL = [], $groupHeadersR = [];\n\t for (var index = 0; index < treeColumns.getDepth() - 1; index++) {\n\t $groupHeadersL[index] = (0, _jquery2.default)(\"\").appendTo($headerScrollerL);\n\t $groupHeadersR[index] = (0, _jquery2.default)(\"\").appendTo($headerScrollerR);\n\t }\n\t\n\t $groupHeaders = (0, _jquery2.default)().add($groupHeadersL).add($groupHeadersR);\n\t }\n\t\n\t // Append the columnn containers to the headers\n\t $headerL = (0, _jquery2.default)(\"\").appendTo($headerScrollerL);\n\t $headerR = (0, _jquery2.default)(\"\").appendTo($headerScrollerR);\n\t\n\t // Cache the header columns\n\t $headers = (0, _jquery2.default)().add($headerL).add($headerR);\n\t\n\t $headerRowScrollerL = (0, _jquery2.default)(\"\").appendTo($paneTopL);\n\t $headerRowScrollerR = (0, _jquery2.default)(\"\").appendTo($paneTopR);\n\t\n\t $headerRowScroller = (0, _jquery2.default)().add($headerRowScrollerL).add($headerRowScrollerR);\n\t\n\t $headerRowSpacerL = (0, _jquery2.default)(\"\").css(\"width\", getCanvasWidth() + scrollbarDimensions.width + \"px\").appendTo($headerRowScrollerL);\n\t $headerRowSpacerR = (0, _jquery2.default)(\"\").css(\"width\", getCanvasWidth() + scrollbarDimensions.width + \"px\").appendTo($headerRowScrollerR);\n\t\n\t $headerRowL = (0, _jquery2.default)(\"\").appendTo($headerRowScrollerL);\n\t $headerRowR = (0, _jquery2.default)(\"\").appendTo($headerRowScrollerR);\n\t\n\t $headerRow = (0, _jquery2.default)().add($headerRowL).add($headerRowR);\n\t\n\t // Append the top panel scroller\n\t $topPanelScrollerL = (0, _jquery2.default)(\"\").appendTo($paneTopL);\n\t $topPanelScrollerR = (0, _jquery2.default)(\"\").appendTo($paneTopR);\n\t\n\t $topPanelScroller = (0, _jquery2.default)().add($topPanelScrollerL).add($topPanelScrollerR);\n\t\n\t // Append the top panel\n\t $topPanelL = (0, _jquery2.default)(\"\").appendTo($topPanelScrollerL);\n\t $topPanelR = (0, _jquery2.default)(\"\").appendTo($topPanelScrollerR);\n\t\n\t $topPanel = (0, _jquery2.default)().add($topPanelL).add($topPanelR);\n\t\n\t if (!options.showTopPanel) {\n\t $topPanelScroller.hide();\n\t }\n\t\n\t if (!options.showHeaderRow) {\n\t $headerRowScroller.hide();\n\t }\n\t\n\t // Append the viewport containers\n\t $viewportTopL = (0, _jquery2.default)(\"\").appendTo($paneTopL);\n\t $viewportTopR = (0, _jquery2.default)(\"\").appendTo($paneTopR);\n\t $viewportBottomL = (0, _jquery2.default)(\"\").appendTo($paneBottomL);\n\t $viewportBottomR = (0, _jquery2.default)(\"\").appendTo($paneBottomR);\n\t\n\t // Cache the viewports\n\t $viewport = (0, _jquery2.default)().add($viewportTopL).add($viewportTopR).add($viewportBottomL).add($viewportBottomR);\n\t\n\t // Default the active viewport to the top left\n\t $activeViewportNode = $viewportTopL;\n\t\n\t // Append the canvas containers\n\t $canvasTopL = (0, _jquery2.default)(\"\").appendTo($viewportTopL);\n\t $canvasTopR = (0, _jquery2.default)(\"\").appendTo($viewportTopR);\n\t $canvasBottomL = (0, _jquery2.default)(\"\").appendTo($viewportBottomL);\n\t $canvasBottomR = (0, _jquery2.default)(\"\").appendTo($viewportBottomR);\n\t\n\t // Cache the canvases\n\t $canvas = (0, _jquery2.default)().add($canvasTopL).add($canvasTopR).add($canvasBottomL).add($canvasBottomR);\n\t\n\t // Default the active canvas to the top left\n\t $activeCanvasNode = $canvasTopL;\n\t\n\t // footer Row\n\t $footerRowScrollerR = (0, _jquery2.default)(\"\").appendTo($paneTopR);\n\t $footerRowScrollerL = (0, _jquery2.default)(\"\").appendTo($paneTopL);\n\t\n\t $footerRowScroller = (0, _jquery2.default)().add($footerRowScrollerL).add($footerRowScrollerR);\n\t\n\t $footerRowSpacerL = (0, _jquery2.default)(\"\").css(\"width\", getCanvasWidth() + scrollbarDimensions.width + \"px\").appendTo($footerRowScrollerL);\n\t $footerRowSpacerR = (0, _jquery2.default)(\"\").css(\"width\", getCanvasWidth() + scrollbarDimensions.width + \"px\").appendTo($footerRowScrollerR);\n\t\n\t $footerRowL = (0, _jquery2.default)(\"\").appendTo($footerRowScrollerL);\n\t $footerRowR = (0, _jquery2.default)(\"\").appendTo($footerRowScrollerR);\n\t\n\t $footerRow = (0, _jquery2.default)().add($footerRowL).add($footerRowR);\n\t\n\t if (!options.showFooterRow) {\n\t $footerRowScroller.hide();\n\t }\n\t\n\t $focusSink2 = $focusSink.clone().appendTo($container);\n\t\n\t if (!options.explicitInitialization) {\n\t finishInitialization();\n\t }\n\t }\n\t\n\t function finishInitialization() {\n\t if (!initialized) {\n\t initialized = true;\n\t\n\t getViewportWidth();\n\t getViewportHeight();\n\t\n\t // header columns and cells may have different padding/border skewing width calculations (box-sizing, hello?)\n\t // calculate the diff so we can set consistent sizes\n\t measureCellPaddingAndBorder();\n\t\n\t // for usability reasons, all text selection in SlickGrid is disabled\n\t // with the exception of input and textarea elements (selection must\n\t // be enabled there so that editors work as expected); note that\n\t // selection in grid cells (grid body) is already unavailable in\n\t // all browsers except IE\n\t disableSelection($headers); // disable all text selection in header (including input and textarea)\n\t\n\t if (!options.enableTextSelectionOnCells) {\n\t // disable text selection in grid cells except in input and textarea elements\n\t // (this is IE-specific, because selectstart event will only fire in IE)\n\t $viewport.bind(\"selectstart.ui\", function (event) {\n\t return (0, _jquery2.default)(event.target).is(\"input,textarea\");\n\t });\n\t }\n\t\n\t setFrozenOptions();\n\t setPaneVisibility();\n\t setScroller();\n\t setOverflow();\n\t\n\t updateColumnCaches();\n\t createColumnHeaders();\n\t createColumnGroupHeaders();\n\t createColumnFooter();\n\t setupColumnSort();\n\t createCssRules();\n\t resizeCanvas();\n\t bindAncestorScrollEvents();\n\t\n\t $container.bind(\"resize.slickgrid\", resizeCanvas);\n\t $viewport.on(\"scroll\", handleScroll);\n\t\n\t if (_jquery2.default.fn.mousewheel && (options.frozenColumn > -1 || hasFrozenRows)) {\n\t $viewport.on(\"mousewheel\", handleMouseWheel);\n\t }\n\t\n\t $headerScroller.bind(\"contextmenu\", handleHeaderContextMenu).bind(\"click\", handleHeaderClick).delegate(\".slick-header-column\", \"mouseenter\", handleHeaderMouseEnter).delegate(\".slick-header-column\", \"mouseleave\", handleHeaderMouseLeave);\n\t $headerRowScroller.bind(\"scroll\", handleHeaderRowScroll);\n\t\n\t $footerRowScroller.bind(\"scroll\", handleFooterRowScroll);\n\t\n\t $focusSink.add($focusSink2).bind(\"keydown\", handleKeyDown);\n\t $canvas.bind(\"keydown\", handleKeyDown).bind(\"click\", handleClick).bind(\"dblclick\", handleDblClick).bind(\"contextmenu\", handleContextMenu).delegate(\".slick-cell\", \"mouseenter\", handleMouseEnter).delegate(\".slick-cell\", \"mouseleave\", handleMouseLeave);\n\t\n\t // legacy support for drag events\n\t (0, _interact2.default)($canvas[0]).allowFrom('div.slick-cell').draggable({\n\t onmove: handleDrag,\n\t onstart: handleDragStart,\n\t onend: handleDragEnd\n\t }).styleCursor(false);\n\t\n\t // Work around http://crbug.com/312427.\n\t if (navigator.userAgent.toLowerCase().match(/webkit/) && navigator.userAgent.toLowerCase().match(/macintosh/)) {\n\t $canvas.on(\"mousewheel\", handleMouseWheel);\n\t }\n\t }\n\t }\n\t\n\t function hasFrozenColumns() {\n\t return options.frozenColumn > -1;\n\t }\n\t\n\t function registerPlugin(plugin) {\n\t plugins.unshift(plugin);\n\t plugin.init(self);\n\t }\n\t\n\t function unregisterPlugin(plugin) {\n\t for (var i = plugins.length; i >= 0; i--) {\n\t if (plugins[i] === plugin) {\n\t if (plugins[i].destroy) {\n\t plugins[i].destroy();\n\t }\n\t plugins.splice(i, 1);\n\t break;\n\t }\n\t }\n\t }\n\t\n\t function setSelectionModel(model) {\n\t if (selectionModel) {\n\t selectionModel.onSelectedRangesChanged.unsubscribe(handleSelectedRangesChanged);\n\t if (selectionModel.destroy) {\n\t selectionModel.destroy();\n\t }\n\t }\n\t\n\t selectionModel = model;\n\t if (selectionModel) {\n\t selectionModel.init(self);\n\t selectionModel.onSelectedRangesChanged.subscribe(handleSelectedRangesChanged);\n\t }\n\t }\n\t\n\t function getSelectionModel() {\n\t return selectionModel;\n\t }\n\t\n\t function getCanvasNode() {\n\t return $canvas[0];\n\t }\n\t\n\t function getActiveCanvasNode(element) {\n\t setActiveCanvasNode(element);\n\t\n\t return $activeCanvasNode[0];\n\t }\n\t\n\t function getCanvases() {\n\t return $canvas;\n\t }\n\t\n\t function setActiveCanvasNode(element) {\n\t if (element) {\n\t $activeCanvasNode = (0, _jquery2.default)(element.target).closest('.grid-canvas');\n\t }\n\t }\n\t\n\t function getViewportNode() {\n\t return $viewport[0];\n\t }\n\t\n\t function getActiveViewportNode(element) {\n\t setActiveViewPortNode(element);\n\t\n\t return $activeViewportNode[0];\n\t }\n\t\n\t function setActiveViewportNode(element) {\n\t if (element) {\n\t $activeViewportNode = (0, _jquery2.default)(element.target).closest('.slick-viewport');\n\t }\n\t }\n\t\n\t function measureScrollbar() {\n\t var $c = (0, _jquery2.default)(\"\").appendTo(document.body);\n\t var dim = {\n\t width: $c.width() - $c[0].clientWidth,\n\t height: $c.height() - $c[0].clientHeight\n\t };\n\t $c.remove();\n\t return dim;\n\t }\n\t\n\t function getHeadersWidth() {\n\t headersWidth = headersWidthL = headersWidthR = 0;\n\t\n\t for (var i = 0, ii = columns.length; i < ii; i++) {\n\t var width = columns[i].width;\n\t\n\t if (options.frozenColumn > -1 && i > options.frozenColumn) {\n\t headersWidthR += width;\n\t } else {\n\t headersWidthL += width;\n\t }\n\t }\n\t\n\t if (hasFrozenColumns()) {\n\t headersWidthL = headersWidthL + 1000;\n\t\n\t headersWidthR = Math.max(headersWidthR, viewportW) + headersWidthL;\n\t headersWidthR += scrollbarDimensions.width;\n\t } else {\n\t headersWidthL += scrollbarDimensions.width;\n\t headersWidthL = Math.max(headersWidthL, viewportW) + 1000;\n\t }\n\t\n\t headersWidth = headersWidthL + headersWidthR;\n\t }\n\t\n\t function getHeadersWidthL() {\n\t headersWidthL = 0;\n\t\n\t columns.forEach(function (column, i) {\n\t if (!(options.frozenColumn > -1 && i > options.frozenColumn)) headersWidthL += column.width;\n\t });\n\t\n\t if (hasFrozenColumns()) {\n\t headersWidthL += 1000;\n\t } else {\n\t headersWidthL += scrollbarDimensions.width;\n\t headersWidthL = Math.max(headersWidthL, viewportW) + 1000;\n\t }\n\t\n\t return headersWidthL;\n\t }\n\t\n\t function getHeadersWidthR() {\n\t headersWidthR = 0;\n\t\n\t columns.forEach(function (column, i) {\n\t if (options.frozenColumn > -1 && i > options.frozenColumn) headersWidthR += column.width;\n\t });\n\t\n\t if (hasFrozenColumns()) {\n\t headersWidthR = Math.max(headersWidthR, viewportW) + getHeadersWidthL();\n\t headersWidthR += scrollbarDimensions.width;\n\t }\n\t\n\t return headersWidthR;\n\t }\n\t\n\t function getCanvasWidth() {\n\t var availableWidth = viewportHasVScroll ? viewportW - scrollbarDimensions.width : viewportW;\n\t\n\t var i = columns.length;\n\t\n\t canvasWidthL = canvasWidthR = 0;\n\t\n\t while (i--) {\n\t if (hasFrozenColumns() && i > options.frozenColumn) {\n\t canvasWidthR += columns[i].width;\n\t } else {\n\t canvasWidthL += columns[i].width;\n\t }\n\t }\n\t\n\t var totalRowWidth = canvasWidthL + canvasWidthR;\n\t\n\t return options.fullWidthRows ? Math.max(totalRowWidth, availableWidth) : totalRowWidth;\n\t }\n\t\n\t function updateCanvasWidth(forceColumnWidthsUpdate) {\n\t var oldCanvasWidth = canvasWidth;\n\t var oldCanvasWidthL = canvasWidthL;\n\t var oldCanvasWidthR = canvasWidthR;\n\t var widthChanged;\n\t canvasWidth = getCanvasWidth();\n\t\n\t widthChanged = canvasWidth !== oldCanvasWidth || canvasWidthL !== oldCanvasWidthL || canvasWidthR !== oldCanvasWidthR;\n\t\n\t if (widthChanged || hasFrozenColumns() || hasFrozenRows) {\n\t $canvasTopL.width(canvasWidthL);\n\t\n\t getHeadersWidth();\n\t\n\t $headerL.width(headersWidthL);\n\t $headerR.width(headersWidthR);\n\t\n\t if (hasFrozenColumns()) {\n\t $canvasTopR.width(canvasWidthR);\n\t\n\t $paneHeaderL.width(canvasWidthL);\n\t $paneHeaderR.css('left', canvasWidthL);\n\t $paneHeaderR.css('width', viewportW - canvasWidthL);\n\t\n\t $paneTopL.width(canvasWidthL);\n\t $paneTopR.css('left', canvasWidthL);\n\t $paneTopR.css('width', viewportW - canvasWidthL);\n\t\n\t $headerRowScrollerL.width(canvasWidthL);\n\t $headerRowScrollerR.width(viewportW - canvasWidthL);\n\t\n\t $headerRowL.width(canvasWidthL);\n\t $headerRowR.width(canvasWidthR);\n\t\n\t $footerRowScrollerL.width(canvasWidthL);\n\t $footerRowScrollerR.width(viewportW - canvasWidthL);\n\t\n\t $footerRowL.width(canvasWidthL);\n\t $footerRowR.width(canvasWidthR);\n\t\n\t $viewportTopL.width(canvasWidthL);\n\t $viewportTopR.width(viewportW - canvasWidthL);\n\t\n\t if (hasFrozenRows) {\n\t $paneBottomL.width(canvasWidthL);\n\t $paneBottomR.css('left', canvasWidthL);\n\t\n\t $viewportBottomL.width(canvasWidthL);\n\t $viewportBottomR.width(viewportW - canvasWidthL);\n\t\n\t $canvasBottomL.width(canvasWidthL);\n\t $canvasBottomR.width(canvasWidthR);\n\t }\n\t } else {\n\t $paneHeaderL.width('100%');\n\t\n\t $paneTopL.width('100%');\n\t\n\t $headerRowScrollerL.width('100%');\n\t\n\t $headerRowL.width(canvasWidth);\n\t\n\t $footerRowScrollerL.width('100%');\n\t\n\t $footerRowL.width(canvasWidth);\n\t\n\t $viewportTopL.width('100%');\n\t\n\t if (hasFrozenRows) {\n\t $viewportBottomL.width('100%');\n\t $canvasBottomL.width(canvasWidthL);\n\t }\n\t }\n\t\n\t viewportHasHScroll = canvasWidth > viewportW - scrollbarDimensions.width;\n\t }\n\t\n\t $headerRowSpacerL.width(canvasWidth + (viewportHasVScroll ? scrollbarDimensions.width : 0));\n\t $headerRowSpacerR.width(canvasWidth + (viewportHasVScroll ? scrollbarDimensions.width : 0));\n\t\n\t $footerRowSpacerL.width(canvasWidth + (viewportHasVScroll ? scrollbarDimensions.width : 0));\n\t $footerRowSpacerR.width(canvasWidth + (viewportHasVScroll ? scrollbarDimensions.width : 0));\n\t\n\t if (widthChanged || forceColumnWidthsUpdate) {\n\t applyColumnWidths();\n\t }\n\t }\n\t\n\t function disableSelection($target) {\n\t if ($target && $target.jquery) {\n\t $target.attr(\"unselectable\", \"on\").css(\"MozUserSelect\", \"none\").bind(\"selectstart.ui\", function () {\n\t return false;\n\t }); // from jquery:ui.core.js 1.7.2\n\t }\n\t }\n\t\n\t function getMaxSupportedCssHeight() {\n\t var supportedHeight = 1000000;\n\t // FF reports the height back but still renders blank after ~6M px\n\t var testUpTo = navigator.userAgent.toLowerCase().match(/firefox/) ? 6000000 : 1000000000;\n\t var div = (0, _jquery2.default)(\"\").appendTo(document.body);\n\t\n\t while (true) {\n\t var test = supportedHeight * 2;\n\t div.css(\"height\", test);\n\t if (test > testUpTo || div.height() !== test) {\n\t break;\n\t } else {\n\t supportedHeight = test;\n\t }\n\t }\n\t\n\t div.remove();\n\t return supportedHeight;\n\t }\n\t\n\t // TODO: this is static. need to handle page mutation.\n\t function bindAncestorScrollEvents() {\n\t var elem = hasFrozenRows && !options.frozenBottom ? $canvasBottomL[0] : $canvasTopL[0];\n\t while ((elem = elem.parentNode) != document.body && elem != null) {\n\t // bind to scroll containers only\n\t if (elem == $viewportTopL[0] || elem.scrollWidth != elem.clientWidth || elem.scrollHeight != elem.clientHeight) {\n\t var $elem = (0, _jquery2.default)(elem);\n\t if (!$boundAncestors) {\n\t $boundAncestors = $elem;\n\t } else {\n\t $boundAncestors = $boundAncestors.add($elem);\n\t }\n\t $elem.bind(\"scroll.\" + uid, handleActiveCellPositionChange);\n\t }\n\t }\n\t }\n\t\n\t function unbindAncestorScrollEvents() {\n\t if (!$boundAncestors) {\n\t return;\n\t }\n\t $boundAncestors.unbind(\"scroll.\" + uid);\n\t $boundAncestors = null;\n\t }\n\t\n\t function updateColumnHeader(columnId, title, toolTip) {\n\t if (!initialized) {\n\t return;\n\t }\n\t var idx = getColumnIndex(columnId);\n\t if (idx == null) {\n\t return;\n\t }\n\t\n\t var columnDef = columns[idx];\n\t var $header = $headers.children().eq(idx);\n\t if ($header) {\n\t if (title !== undefined) {\n\t columns[idx].name = title;\n\t }\n\t if (toolTip !== undefined) {\n\t columns[idx].toolTip = toolTip;\n\t }\n\t\n\t trigger(self.onBeforeHeaderCellDestroy, {\n\t \"node\": $header[0],\n\t \"column\": columnDef\n\t });\n\t\n\t $header.attr(\"title\", toolTip || \"\").children().eq(0).html(title);\n\t\n\t trigger(self.onHeaderCellRendered, {\n\t \"node\": $header[0],\n\t \"column\": columnDef\n\t });\n\t }\n\t }\n\t\n\t function getHeaderRow() {\n\t return hasFrozenColumns() ? $headerRow : $headerRow[0];\n\t }\n\t\n\t function getHeaderRowColumn(columnId) {\n\t var idx = getColumnIndex(columnId);\n\t\n\t var $headerRowTarget;\n\t\n\t if (hasFrozenColumns()) {\n\t if (idx <= options.frozenColumn) {\n\t $headerRowTarget = $headerRowL;\n\t } else {\n\t $headerRowTarget = $headerRowR;\n\t\n\t idx -= options.frozenColumn + 1;\n\t }\n\t } else {\n\t $headerRowTarget = $headerRowL;\n\t }\n\t\n\t var $header = $headerRowTarget.children().eq(idx);\n\t return $header && $header[0];\n\t }\n\t\n\t function getFooterRow() {\n\t return hasFrozenColumns() ? $footerRow : $footerRow[0];\n\t }\n\t\n\t function getFooterRowColumn(columnId) {\n\t var idx = getColumnIndex(columnId);\n\t\n\t var $footerRowTarget;\n\t\n\t if (hasFrozenColumns()) {\n\t if (idx <= options.frozenColumn) {\n\t $footerRowTarget = $footerRowL;\n\t } else {\n\t $footerRowTarget = $footerRowR;\n\t\n\t idx -= options.frozenColumn + 1;\n\t }\n\t } else {\n\t $footerRowTarget = $footerRowL;\n\t }\n\t\n\t var $footer = $footerRowTarget.children().eq(idx);\n\t return $footer && $footer[0];\n\t }\n\t\n\t function createColumnFooter() {\n\t $footerRow.find(\".slick-footerrow-column\").each(function () {\n\t var columnDef = (0, _jquery2.default)(this).data(\"column\");\n\t if (columnDef) {\n\t trigger(self.onBeforeFooterRowCellDestroy, {\n\t \"node\": this,\n\t \"column\": columnDef\n\t });\n\t }\n\t });\n\t\n\t $footerRowL.empty();\n\t $footerRowR.empty();\n\t\n\t for (var i = 0; i < columns.length; i++) {\n\t var m = columns[i];\n\t\n\t var footerRowCell = (0, _jquery2.default)(\"\").data(\"column\", m).addClass(hasFrozenColumns() && i <= options.frozenColumn ? 'frozen' : '').appendTo(hasFrozenColumns() && i > options.frozenColumn ? $footerRowR : $footerRowL);\n\t\n\t trigger(self.onFooterRowCellRendered, {\n\t \"node\": footerRowCell[0],\n\t \"column\": m\n\t });\n\t }\n\t }\n\t\n\t function createColumnGroupHeaders() {\n\t var columnsLength = 0;\n\t var frozenColumnsValid = false;\n\t\n\t if (!treeColumns.hasDepth()) return;\n\t\n\t for (var index = 0; index < $groupHeadersL.length; index++) {\n\t\n\t $groupHeadersL[index].empty();\n\t $groupHeadersR[index].empty();\n\t\n\t var groupColumns = treeColumns.getColumnsInDepth(index);\n\t\n\t for (var indexGroup in groupColumns) {\n\t var m = groupColumns[indexGroup];\n\t\n\t columnsLength += m.extractColumns().length;\n\t\n\t if (hasFrozenColumns() && index == 0 && columnsLength - 1 === options.frozenColumn) frozenColumnsValid = true;\n\t\n\t (0, _jquery2.default)(\"\").html(\"\" + m.name + \"\").attr(\"id\", \"\" + uid + m.id).attr(\"title\", m.toolTip || \"\").data(\"column\", m).addClass(m.headerCssClass || \"\").addClass(hasFrozenColumns() && columnsLength - 1 <= options.frozenColumn ? 'frozen' : '').appendTo(hasFrozenColumns() && columnsLength - 1 > options.frozenColumn ? $groupHeadersR[index] : $groupHeadersL[index]);\n\t }\n\t\n\t if (hasFrozenColumns() && index == 0 && !frozenColumnsValid) {\n\t $groupHeadersL[index].empty();\n\t $groupHeadersR[index].empty();\n\t alert(\"All columns of group should to be grouped!\");\n\t break;\n\t }\n\t }\n\t\n\t applyColumnGroupHeaderWidths();\n\t }\n\t\n\t function createColumnHeaders() {\n\t function onMouseEnter() {\n\t (0, _jquery2.default)(this).addClass(\"ui-state-hover\");\n\t }\n\t\n\t function onMouseLeave() {\n\t (0, _jquery2.default)(this).removeClass(\"ui-state-hover\");\n\t }\n\t\n\t $headers.find(\".slick-header-column\").each(function () {\n\t var columnDef = (0, _jquery2.default)(this).data(\"column\");\n\t if (columnDef) {\n\t trigger(self.onBeforeHeaderCellDestroy, {\n\t \"node\": this,\n\t \"column\": columnDef\n\t });\n\t }\n\t });\n\t\n\t $headerL.empty();\n\t $headerR.empty();\n\t\n\t getHeadersWidth();\n\t\n\t $headerL.width(headersWidthL);\n\t $headerR.width(headersWidthR);\n\t\n\t $headerRow.find(\".slick-headerrow-column\").each(function () {\n\t var columnDef = (0, _jquery2.default)(this).data(\"column\");\n\t if (columnDef) {\n\t trigger(self.onBeforeHeaderRowCellDestroy, {\n\t \"node\": this,\n\t \"column\": columnDef\n\t });\n\t }\n\t });\n\t\n\t $headerRowL.empty();\n\t $headerRowR.empty();\n\t\n\t for (var i = 0; i < columns.length; i++) {\n\t var m = columns[i];\n\t\n\t var $headerTarget = hasFrozenColumns() ? i <= options.frozenColumn ? $headerL : $headerR : $headerL;\n\t var $headerRowTarget = hasFrozenColumns() ? i <= options.frozenColumn ? $headerRowL : $headerRowR : $headerRowL;\n\t\n\t var header = (0, _jquery2.default)(\"\").html(\"\" + m.name + \"\").width(m.width - headerColumnWidthDiff).attr(\"id\", \"\" + uid + m.id).attr(\"title\", m.toolTip || \"\").data(\"column\", m).addClass(m.headerCssClass || \"\").addClass(hasFrozenColumns() && i <= options.frozenColumn ? 'frozen' : '').appendTo($headerTarget);\n\t\n\t if (options.enableColumnReorder || m.sortable) {\n\t header.on('mouseenter', onMouseEnter).on('mouseleave', onMouseLeave);\n\t }\n\t\n\t if (m.sortable) {\n\t header.addClass(\"slick-header-sortable\");\n\t header.append(\"\");\n\t }\n\t\n\t trigger(self.onHeaderCellRendered, {\n\t \"node\": header[0],\n\t \"column\": m\n\t });\n\t\n\t if (options.showHeaderRow) {\n\t var headerRowCell = (0, _jquery2.default)(\"\").data(\"column\", m).appendTo($headerRowTarget);\n\t\n\t trigger(self.onHeaderRowCellRendered, {\n\t \"node\": headerRowCell[0],\n\t \"column\": m\n\t });\n\t }\n\t }\n\t\n\t setSortColumns(sortColumns);\n\t setupColumnResize();\n\t if (options.enableColumnReorder) {\n\t setupColumnReorder();\n\t }\n\t }\n\t\n\t function setupColumnSort() {\n\t $headers.click(function (e) {\n\t // temporary workaround for a bug in jQuery 1.7.1 (http://bugs.jquery.com/ticket/11328)\n\t e.metaKey = e.metaKey || e.ctrlKey;\n\t\n\t if ((0, _jquery2.default)(e.target).hasClass(\"slick-resizable-handle\")) {\n\t return;\n\t }\n\t\n\t var $col = (0, _jquery2.default)(e.target).closest(\".slick-header-column\");\n\t if (!$col.length) {\n\t return;\n\t }\n\t\n\t var column = $col.data(\"column\");\n\t if (column.sortable) {\n\t if (!getEditorLock().commitCurrentEdit()) {\n\t return;\n\t }\n\t\n\t var sortOpts = null;\n\t var i = 0;\n\t for (; i < sortColumns.length; i++) {\n\t if (sortColumns[i].columnId == column.id) {\n\t sortOpts = sortColumns[i];\n\t sortOpts.sortAsc = !sortOpts.sortAsc;\n\t break;\n\t }\n\t }\n\t\n\t if (e.metaKey && options.multiColumnSort) {\n\t if (sortOpts) {\n\t sortColumns.splice(i, 1);\n\t }\n\t } else {\n\t if (!e.shiftKey && !e.metaKey || !options.multiColumnSort) {\n\t sortColumns = [];\n\t }\n\t\n\t if (!sortOpts) {\n\t sortOpts = {\n\t columnId: column.id,\n\t sortAsc: column.defaultSortAsc\n\t };\n\t sortColumns.push(sortOpts);\n\t } else if (sortColumns.length == 0) {\n\t sortColumns.push(sortOpts);\n\t }\n\t }\n\t\n\t setSortColumns(sortColumns);\n\t\n\t if (!options.multiColumnSort) {\n\t trigger(self.onSort, {\n\t multiColumnSort: false,\n\t sortCol: column,\n\t sortAsc: sortOpts.sortAsc\n\t }, e);\n\t } else {\n\t trigger(self.onSort, {\n\t multiColumnSort: true,\n\t sortCols: _jquery2.default.map(sortColumns, function (col) {\n\t return {\n\t sortCol: columns[getColumnIndex(col.columnId)],\n\t sortAsc: col.sortAsc\n\t };\n\t })\n\t }, e);\n\t }\n\t }\n\t });\n\t }\n\t\n\t function currentPositionInHeader(id) {\n\t var currentPosition = 0;\n\t $headers.find('.slick-header-column').each(function (i) {\n\t if (this.id == id) {\n\t currentPosition = i;\n\t return false;\n\t }\n\t });\n\t\n\t return currentPosition;\n\t }\n\t\n\t function limitPositionInGroup(idColumn) {\n\t var groupColumnOfPreviousPosition,\n\t startLimit = 0,\n\t endLimit = 0;\n\t\n\t treeColumns.getColumnsInDepth($groupHeadersL.length - 1).some(function (groupColumn) {\n\t startLimit = endLimit;\n\t endLimit += groupColumn.columns.length;\n\t\n\t groupColumn.columns.some(function (column) {\n\t\n\t if (column.id === idColumn) groupColumnOfPreviousPosition = groupColumn;\n\t\n\t return groupColumnOfPreviousPosition;\n\t });\n\t\n\t return groupColumnOfPreviousPosition;\n\t });\n\t\n\t endLimit--;\n\t\n\t return {\n\t start: startLimit,\n\t end: endLimit,\n\t group: groupColumnOfPreviousPosition\n\t };\n\t }\n\t\n\t function remove(arr, elem) {\n\t var index = arr.lastIndexOf(elem);\n\t if (index > -1) {\n\t arr.splice(index, 1);\n\t remove(arr, elem);\n\t }\n\t }\n\t\n\t function columnPositionValidInGroup($item) {\n\t var currentPosition = currentPositionInHeader($item[0].id);\n\t var limit = limitPositionInGroup($item.data('column').id);\n\t var positionValid = limit.start <= currentPosition && currentPosition <= limit.end;\n\t\n\t return {\n\t limit: limit,\n\t valid: positionValid,\n\t message: positionValid ? '' : 'Column \"'.concat($item.text(), '\" can be reordered only within the \"', limit.group.name, '\" group!')\n\t };\n\t }\n\t\n\t function setupColumnReorder() {\n\t var x = 0;\n\t var delta = 0;\n\t var placeholder = document.createElement('div');\n\t\n\t placeholder.className = 'interact-placeholder';\n\t\n\t (0, _interact2.default)('.slick-header-column').ignoreFrom('.slick-resizable-handle').draggable({\n\t inertia: true,\n\t // keep the element within the area of it's parent\n\t restrict: {\n\t restriction: 'parent',\n\t endOnly: true,\n\t elementRect: { top: 0, left: 0, bottom: 0, right: 0 }\n\t },\n\t // enable autoScroll\n\t autoScroll: true,\n\t axis: 'x',\n\t onstart: function onstart(event) {\n\t x = 0;\n\t delta = event.target.offsetWidth;\n\t\n\t // get old order\n\t $headers.find('.slick-header-column').each(function (index) {\n\t (0, _jquery2.default)(this).data('index', index);\n\t });\n\t\n\t placeholder.style.height = event.target.offsetHeight + 'px';\n\t placeholder.style.width = delta + 'px';\n\t\n\t (0, _jquery2.default)(event.target).after(placeholder).css({\n\t position: 'absolute',\n\t zIndex: 1000,\n\t marginLeft: (0, _jquery2.default)(event.target).position().left - 1000\n\t });\n\t },\n\t\n\t onmove: function onmove(event) {\n\t x += event.dx;\n\t event.target.style.transform = 'translate3d(' + x + 'px, -3px, 100px)';\n\t // event.target.style.marginLeft = x + 'px';\n\t },\n\t\n\t onend: function onend(event) {\n\t x = 0;\n\t delta = 0;\n\t\n\t if (treeColumns.hasDepth()) {\n\t var validPositionInGroup = columnPositionValidInGroup((0, _jquery2.default)(event.target));\n\t var limit = validPositionInGroup.limit;\n\t\n\t var cancel = !validPositionInGroup.valid;\n\t\n\t if (cancel) alert(validPositionInGroup.message);\n\t }\n\t\n\t placeholder.parentNode.removeChild(placeholder);\n\t\n\t if (cancel) {\n\t event.target.style.transform = 'none';\n\t setColumns(getColumns());\n\t return;\n\t }\n\t\n\t (0, _jquery2.default)(event.target).css({\n\t position: 'relative',\n\t zIndex: '',\n\t marginLeft: 0,\n\t transform: 'none'\n\t });\n\t\n\t var newColumns = [];\n\t $headers.find('.slick-header-column').each(function (index) {\n\t newColumns.push(columns[(0, _jquery2.default)(this).data('index')]);\n\t (0, _jquery2.default)(this).removeData('index');\n\t });\n\t\n\t setColumns(newColumns);\n\t\n\t trigger(self.onColumnsReordered, { impactedColumns: getImpactedColumns(limit), grid: self });\n\t setupColumnResize();\n\t }\n\t }).dropzone({\n\t accept: '.slick-header-column',\n\t\n\t ondragenter: function ondragenter(event) {\n\t event.target.classList.add('interact-drop-active');\n\t event.relatedTarget.classList.add('interact-can-drop');\n\t },\n\t\n\t ondragleave: function ondragleave(event) {\n\t event.target.classList.remove('interact-drop-active');\n\t event.relatedTarget.classList.remove('interact-can-drop');\n\t },\n\t\n\t ondrop: function ondrop(event) {\n\t event.target.classList.remove('interact-drop-active');\n\t event.relatedTarget.classList.remove('interact-can-drop');\n\t (0, _jquery2.default)(event.target)[x > 0 ? 'after' : 'before'](event.relatedTarget);\n\t }\n\t }).styleCursor(false);\n\t }\n\t\n\t function getImpactedColumns(limit) {\n\t var impactedColumns = [];\n\t\n\t if (limit != undefined) {\n\t\n\t for (var i = limit.start; i <= limit.end; i++) {\n\t impactedColumns.push(columns[i]);\n\t }\n\t } else {\n\t\n\t impactedColumns = columns;\n\t }\n\t\n\t return impactedColumns;\n\t }\n\t\n\t function setupColumnResize() {\n\t var $col, j, c, pageX, columnElements, minPageX, maxPageX, firstResizable, lastResizable;\n\t columnElements = $headers.children();\n\t columnElements.find('.slick-resizable-handle').remove();\n\t columnElements.each(function (i, e) {\n\t if (columns[i].resizable) {\n\t if (firstResizable === undefined) {\n\t firstResizable = i;\n\t }\n\t lastResizable = i;\n\t }\n\t });\n\t if (firstResizable === undefined) {\n\t return;\n\t }\n\t columnElements.each(function (i, element) {\n\t if (i < firstResizable || options.forceFitColumns && i >= lastResizable) {\n\t return;\n\t }\n\t $col = (0, _jquery2.default)(element);\n\t\n\t var $handle = (0, _jquery2.default)(\"\");\n\t $handle.appendTo(element);\n\t\n\t if ($col.data('resizable')) return;\n\t\n\t var activeColumn = columns[i];\n\t if (activeColumn.resizable) {\n\t $col.data('resizable', true);\n\t (0, _interact2.default)(element).resizable({\n\t preserveAspectRatio: false,\n\t edges: { left: true, right: true, bottom: false, top: false }\n\t }).on('resizestart', function (event) {\n\t if (!getEditorLock().commitCurrentEdit()) {\n\t return false;\n\t }\n\t activeColumn.previousWidth = event.rect.width;\n\t event.target.classList.add('slick-header-column-active');\n\t }).on('resizemove', function (event) {\n\t var x = event.dx;\n\t var width = activeColumn.width += x;\n\t\n\t if (activeColumn.minWidth > 0 && activeColumn.minWidth > width) width = activeColumn.minWidth;else if (activeColumn.maxWidth > 0 && activeColumn.maxWidth < width) width = activeColumn.maxWidth;\n\t\n\t activeColumn.width = width;\n\t\n\t if (options.forceFitColumns) {\n\t autosizeColumns();\n\t }\n\t applyColumnHeaderWidths();\n\t if (options.syncColumnCellResize) {\n\t applyColumnWidths();\n\t }\n\t }).on('resizeend', function (event) {\n\t event.target.classList.remove('slick-header-column-active');\n\t if (treeColumns.hasDepth()) createColumnGroupHeaders();\n\t\n\t invalidateAllRows();\n\t updateCanvasWidth(true);\n\t render();\n\t trigger(self.onColumnsResized, { grid: self });\n\t });\n\t }\n\t });\n\t }\n\t\n\t function getVBoxDelta($el) {\n\t var p = [\"borderTopWidth\", \"borderBottomWidth\", \"paddingTop\", \"paddingBottom\"];\n\t var delta = 0;\n\t _jquery2.default.each(p, function (n, val) {\n\t delta += parseFloat($el.css(val)) || 0;\n\t });\n\t return delta;\n\t }\n\t\n\t function setFrozenOptions() {\n\t options.frozenColumn = options.frozenColumn >= 0 && options.frozenColumn < columns.length ? parseInt(options.frozenColumn) : -1;\n\t\n\t options.frozenRow = options.frozenRow >= 0 && options.frozenRow < numVisibleRows ? parseInt(options.frozenRow) : -1;\n\t\n\t if (options.frozenRow > -1) {\n\t hasFrozenRows = true;\n\t frozenRowsHeight = options.frozenRow * options.rowHeight;\n\t\n\t var dataLength = getDataLength() || this.data.length;\n\t\n\t actualFrozenRow = options.frozenBottom ? dataLength - options.frozenRow : options.frozenRow;\n\t } else {\n\t hasFrozenRows = false;\n\t }\n\t }\n\t\n\t function setPaneVisibility() {\n\t if (hasFrozenColumns()) {\n\t $paneHeaderR.show();\n\t $paneTopR.show();\n\t\n\t if (hasFrozenRows) {\n\t $paneBottomL.show();\n\t $paneBottomR.show();\n\t } else {\n\t $paneBottomR.hide();\n\t $paneBottomL.hide();\n\t }\n\t } else {\n\t $paneHeaderR.hide();\n\t $paneTopR.hide();\n\t $paneBottomR.hide();\n\t\n\t if (hasFrozenRows) {\n\t $paneBottomL.show();\n\t } else {\n\t $paneBottomR.hide();\n\t $paneBottomL.hide();\n\t }\n\t }\n\t }\n\t\n\t function setOverflow() {\n\t $viewportTopL.css({\n\t 'overflow-x': hasFrozenColumns() ? hasFrozenRows ? 'hidden' : 'scroll' : hasFrozenRows ? 'hidden' : 'auto',\n\t 'overflow-y': hasFrozenColumns() ? hasFrozenRows ? 'hidden' : 'hidden' : hasFrozenRows ? 'scroll' : 'auto'\n\t });\n\t\n\t $viewportTopR.css({\n\t 'overflow-x': hasFrozenColumns() ? hasFrozenRows ? 'hidden' : 'scroll' : hasFrozenRows ? 'hidden' : 'auto',\n\t 'overflow-y': hasFrozenColumns() ? hasFrozenRows ? 'scroll' : 'auto' : hasFrozenRows ? 'scroll' : 'auto'\n\t });\n\t\n\t $viewportBottomL.css({\n\t 'overflow-x': hasFrozenColumns() ? hasFrozenRows ? 'scroll' : 'auto' : hasFrozenRows ? 'auto' : 'auto',\n\t 'overflow-y': hasFrozenColumns() ? hasFrozenRows ? 'hidden' : 'hidden' : hasFrozenRows ? 'scroll' : 'auto'\n\t });\n\t\n\t $viewportBottomR.css({\n\t 'overflow-x': hasFrozenColumns() ? hasFrozenRows ? 'scroll' : 'auto' : hasFrozenRows ? 'auto' : 'auto',\n\t 'overflow-y': hasFrozenColumns() ? hasFrozenRows ? 'auto' : 'auto' : hasFrozenRows ? 'auto' : 'auto'\n\t });\n\t }\n\t\n\t function setScroller() {\n\t if (hasFrozenColumns()) {\n\t $headerScrollContainer = $headerScrollerR;\n\t $headerRowScrollContainer = $headerRowScrollerR;\n\t $footerRowScrollContainer = $footerRowScrollerR;\n\t\n\t if (hasFrozenRows) {\n\t if (options.frozenBottom) {\n\t $viewportScrollContainerX = $viewportBottomR;\n\t $viewportScrollContainerY = $viewportTopR;\n\t } else {\n\t $viewportScrollContainerX = $viewportScrollContainerY = $viewportBottomR;\n\t }\n\t } else {\n\t $viewportScrollContainerX = $viewportScrollContainerY = $viewportTopR;\n\t }\n\t } else {\n\t $headerScrollContainer = $headerScrollerL;\n\t $headerRowScrollContainer = $headerRowScrollerL;\n\t $footerRowScrollContainer = $footerRowScrollerL;\n\t\n\t if (hasFrozenRows) {\n\t if (options.frozenBottom) {\n\t $viewportScrollContainerX = $viewportBottomL;\n\t $viewportScrollContainerY = $viewportTopL;\n\t } else {\n\t $viewportScrollContainerX = $viewportScrollContainerY = $viewportBottomL;\n\t }\n\t } else {\n\t $viewportScrollContainerX = $viewportScrollContainerY = $viewportTopL;\n\t }\n\t }\n\t }\n\t\n\t function measureCellPaddingAndBorder() {\n\t var el;\n\t var h = [\"borderLeftWidth\", \"borderRightWidth\", \"paddingLeft\", \"paddingRight\"];\n\t var v = [\"borderTopWidth\", \"borderBottomWidth\", \"paddingTop\", \"paddingBottom\"];\n\t\n\t el = (0, _jquery2.default)(\"
-
\").appendTo($headers);\n\t headerColumnWidthDiff = headerColumnHeightDiff = 0;\n\t if (el.css(\"box-sizing\") != \"border-box\" && el.css(\"-moz-box-sizing\") != \"border-box\" && el.css(\"-webkit-box-sizing\") != \"border-box\") {\n\t _jquery2.default.each(h, function (n, val) {\n\t headerColumnWidthDiff += parseFloat(el.css(val)) || 0;\n\t });\n\t _jquery2.default.each(v, function (n, val) {\n\t headerColumnHeightDiff += parseFloat(el.css(val)) || 0;\n\t });\n\t }\n\t el.remove();\n\t\n\t var r = (0, _jquery2.default)(\"\").appendTo($canvas);\n\t el = (0, _jquery2.default)(\"
-
\").appendTo(r);\n\t cellWidthDiff = cellHeightDiff = 0;\n\t if (el.css(\"box-sizing\") != \"border-box\" && el.css(\"-moz-box-sizing\") != \"border-box\" && el.css(\"-webkit-box-sizing\") != \"border-box\") {\n\t _jquery2.default.each(h, function (n, val) {\n\t cellWidthDiff += parseFloat(el.css(val)) || 0;\n\t });\n\t _jquery2.default.each(v, function (n, val) {\n\t cellHeightDiff += parseFloat(el.css(val)) || 0;\n\t });\n\t }\n\t r.remove();\n\t\n\t absoluteColumnMinWidth = Math.max(headerColumnWidthDiff, cellWidthDiff);\n\t }\n\t\n\t function createCssRules() {\n\t $style = (0, _jquery2.default)(\"\").appendTo((0, _jquery2.default)(\"head\"));\n\t var rowHeight = options.rowHeight - cellHeightDiff;\n\t var rules = [\".\" + uid + \" .slick-group-header-column { left: 1000px; }\", \".\" + uid + \" .slick-header-column { left: 1000px; }\", \".\" + uid + \" .slick-top-panel { height:\" + options.topPanelHeight + \"px; }\", \".\" + uid + \" .slick-headerrow-columns { height:\" + options.headerRowHeight + \"px; }\", \".\" + uid + \" .slick-cell { height:\" + rowHeight + \"px; }\", \".\" + uid + \" .slick-row { height:\" + options.rowHeight + \"px; }\", \".\" + uid + \" .slick-footerrow-columns { height:\" + options.footerRowHeight + \"px; }\"];\n\t\n\t for (var i = 0; i < columns.length; i++) {\n\t rules.push(\".\" + uid + \" .l\" + i + \" { }\");\n\t rules.push(\".\" + uid + \" .r\" + i + \" { }\");\n\t }\n\t\n\t if ($style[0].styleSheet) {\n\t // IE\n\t $style[0].styleSheet.cssText = rules.join(\" \");\n\t } else {\n\t $style[0].appendChild(document.createTextNode(rules.join(\" \")));\n\t }\n\t }\n\t\n\t function getColumnCssRules(idx) {\n\t if (!stylesheet) {\n\t var sheets = document.styleSheets;\n\t for (var i = 0; i < sheets.length; i++) {\n\t if ((sheets[i].ownerNode || sheets[i].owningElement) == $style[0]) {\n\t stylesheet = sheets[i];\n\t break;\n\t }\n\t }\n\t\n\t if (!stylesheet) {\n\t throw new Error(\"Cannot find stylesheet.\");\n\t }\n\t\n\t // find and cache column CSS rules\n\t columnCssRulesL = [];\n\t columnCssRulesR = [];\n\t var cssRules = stylesheet.cssRules || stylesheet.rules;\n\t var matches, columnIdx;\n\t for (var i = 0; i < cssRules.length; i++) {\n\t var selector = cssRules[i].selectorText;\n\t if (matches = /\\.l\\d+/.exec(selector)) {\n\t columnIdx = parseInt(matches[0].substr(2, matches[0].length - 2), 10);\n\t columnCssRulesL[columnIdx] = cssRules[i];\n\t } else if (matches = /\\.r\\d+/.exec(selector)) {\n\t columnIdx = parseInt(matches[0].substr(2, matches[0].length - 2), 10);\n\t columnCssRulesR[columnIdx] = cssRules[i];\n\t }\n\t }\n\t }\n\t\n\t return {\n\t \"left\": columnCssRulesL[idx],\n\t \"right\": columnCssRulesR[idx]\n\t };\n\t }\n\t\n\t function removeCssRules() {\n\t $style.remove();\n\t stylesheet = null;\n\t }\n\t\n\t function destroy() {\n\t getEditorLock().cancelCurrentEdit();\n\t\n\t trigger(self.onBeforeDestroy, {});\n\t\n\t var i = plugins.length;\n\t while (i--) {\n\t unregisterPlugin(plugins[i]);\n\t }\n\t\n\t unbindAncestorScrollEvents();\n\t $container.unbind(\".slickgrid\");\n\t removeCssRules();\n\t\n\t $container.empty().removeClass(uid);\n\t }\n\t\n\t //////////////////////////////////////////////////////////////////////////////////////////////\n\t // General\n\t\n\t function trigger(evt, args, e) {\n\t e = e || new _slick2.default.EventData();\n\t args = args || {};\n\t args.grid = self;\n\t return evt.notify(args, e, self);\n\t }\n\t\n\t function getEditorLock() {\n\t return options.editorLock;\n\t }\n\t\n\t function getEditController() {\n\t return editController;\n\t }\n\t\n\t function getColumnIndex(id) {\n\t return columnsById[id];\n\t }\n\t\n\t function autosizeColumns() {\n\t var i,\n\t c,\n\t widths = [],\n\t shrinkLeeway = 0,\n\t total = 0,\n\t prevTotal,\n\t availWidth = viewportHasVScroll ? viewportW - scrollbarDimensions.width : viewportW;\n\t\n\t for (i = 0; i < columns.length; i++) {\n\t c = columns[i];\n\t widths.push(c.width);\n\t total += c.width;\n\t if (c.resizable) {\n\t shrinkLeeway += c.width - Math.max(c.minWidth, absoluteColumnMinWidth);\n\t }\n\t }\n\t\n\t // shrink\n\t prevTotal = total;\n\t while (total > availWidth && shrinkLeeway) {\n\t var shrinkProportion = (total - availWidth) / shrinkLeeway;\n\t for (i = 0; i < columns.length && total > availWidth; i++) {\n\t c = columns[i];\n\t var width = widths[i];\n\t if (!c.resizable || width <= c.minWidth || width <= absoluteColumnMinWidth) {\n\t continue;\n\t }\n\t var absMinWidth = Math.max(c.minWidth, absoluteColumnMinWidth);\n\t var shrinkSize = Math.floor(shrinkProportion * (width - absMinWidth)) || 1;\n\t shrinkSize = Math.min(shrinkSize, width - absMinWidth);\n\t total -= shrinkSize;\n\t shrinkLeeway -= shrinkSize;\n\t widths[i] -= shrinkSize;\n\t }\n\t if (prevTotal <= total) {\n\t // avoid infinite loop\n\t break;\n\t }\n\t prevTotal = total;\n\t }\n\t\n\t // grow\n\t prevTotal = total;\n\t while (total < availWidth) {\n\t var growProportion = availWidth / total;\n\t for (i = 0; i < columns.length && total < availWidth; i++) {\n\t c = columns[i];\n\t var currentWidth = widths[i];\n\t var growSize;\n\t\n\t if (!c.resizable || c.maxWidth <= currentWidth) {\n\t growSize = 0;\n\t } else {\n\t growSize = Math.min(Math.floor(growProportion * currentWidth) - currentWidth, c.maxWidth - currentWidth || 1000000) || 1;\n\t }\n\t total += growSize;\n\t widths[i] += growSize;\n\t }\n\t if (prevTotal >= total) {\n\t // avoid infinite loop\n\t break;\n\t }\n\t prevTotal = total;\n\t }\n\t\n\t var reRender = false;\n\t for (i = 0; i < columns.length; i++) {\n\t if (columns[i].rerenderOnResize && columns[i].width != widths[i]) {\n\t reRender = true;\n\t }\n\t columns[i].width = widths[i];\n\t }\n\t\n\t applyColumnHeaderWidths();\n\t applyColumnGroupHeaderWidths();\n\t updateCanvasWidth(true);\n\t if (reRender) {\n\t invalidateAllRows();\n\t render();\n\t }\n\t }\n\t\n\t function applyColumnGroupHeaderWidths() {\n\t if (!treeColumns.hasDepth()) return;\n\t\n\t for (var depth = $groupHeadersL.length - 1; depth >= 0; depth--) {\n\t\n\t var groupColumns = treeColumns.getColumnsInDepth(depth);\n\t\n\t (0, _jquery2.default)().add($groupHeadersL[depth]).add($groupHeadersR[depth]).each(function (i) {\n\t var $groupHeader = (0, _jquery2.default)(this),\n\t currentColumnIndex = 0;\n\t\n\t $groupHeader.width(i == 0 ? getHeadersWidthL() : getHeadersWidthR());\n\t\n\t $groupHeader.children().each(function () {\n\t var $groupHeaderColumn = (0, _jquery2.default)(this);\n\t\n\t var m = (0, _jquery2.default)(this).data('column');\n\t\n\t m.width = 0;\n\t\n\t m.columns.forEach(function () {\n\t var $headerColumn = $groupHeader.next().children(':eq(' + currentColumnIndex++ + ')');\n\t m.width += $headerColumn.outerWidth();\n\t });\n\t\n\t $groupHeaderColumn.width(m.width - headerColumnWidthDiff);\n\t });\n\t });\n\t }\n\t }\n\t\n\t function applyColumnHeaderWidths() {\n\t if (!initialized) {\n\t return;\n\t }\n\t var h;\n\t for (var i = 0, headers = $headers.children(), ii = headers.length; i < ii; i++) {\n\t h = (0, _jquery2.default)(headers[i]);\n\t if (h.width() !== columns[i].width - headerColumnWidthDiff) {\n\t h.width(columns[i].width - headerColumnWidthDiff);\n\t }\n\t }\n\t\n\t updateColumnCaches();\n\t }\n\t\n\t function applyColumnWidths() {\n\t var x = 0,\n\t w,\n\t rule;\n\t for (var i = 0; i < columns.length; i++) {\n\t w = columns[i].width;\n\t\n\t rule = getColumnCssRules(i);\n\t rule.left.style.left = x + \"px\";\n\t rule.right.style.right = (options.frozenColumn != -1 && i > options.frozenColumn ? canvasWidthR : canvasWidthL) - x - w + \"px\";\n\t\n\t // If this column is frozen, reset the css left value since the\n\t // column starts in a new viewport.\n\t if (options.frozenColumn == i) {\n\t x = 0;\n\t } else {\n\t x += columns[i].width;\n\t }\n\t }\n\t }\n\t\n\t function setSortColumn(columnId, ascending) {\n\t setSortColumns([{\n\t columnId: columnId,\n\t sortAsc: ascending\n\t }]);\n\t }\n\t\n\t function setSortColumns(cols) {\n\t sortColumns = cols;\n\t\n\t var headerColumnEls = $headers.children();\n\t headerColumnEls.removeClass(\"slick-header-column-sorted\").find(\".slick-sort-indicator\").removeClass(\"slick-sort-indicator-asc slick-sort-indicator-desc\");\n\t\n\t _jquery2.default.each(sortColumns, function (i, col) {\n\t if (col.sortAsc == null) {\n\t col.sortAsc = true;\n\t }\n\t var columnIndex = getColumnIndex(col.columnId);\n\t if (columnIndex != null) {\n\t headerColumnEls.eq(columnIndex).addClass(\"slick-header-column-sorted\").find(\".slick-sort-indicator\").addClass(col.sortAsc ? \"slick-sort-indicator-asc\" : \"slick-sort-indicator-desc\");\n\t }\n\t });\n\t }\n\t\n\t function getSortColumns() {\n\t return sortColumns;\n\t }\n\t\n\t function handleSelectedRangesChanged(e, ranges) {\n\t selectedRows = [];\n\t var hash = {};\n\t for (var i = 0; i < ranges.length; i++) {\n\t for (var j = ranges[i].fromRow; j <= ranges[i].toRow; j++) {\n\t if (!hash[j]) {\n\t // prevent duplicates\n\t selectedRows.push(j);\n\t hash[j] = {};\n\t }\n\t for (var k = ranges[i].fromCell; k <= ranges[i].toCell; k++) {\n\t if (canCellBeSelected(j, k)) {\n\t hash[j][columns[k].id] = options.selectedCellCssClass;\n\t }\n\t }\n\t }\n\t }\n\t\n\t setCellCssStyles(options.selectedCellCssClass, hash);\n\t\n\t trigger(self.onSelectedRowsChanged, {\n\t rows: getSelectedRows()\n\t }, e);\n\t }\n\t\n\t function getColumns() {\n\t return columns;\n\t }\n\t\n\t function updateColumnCaches() {\n\t // Pre-calculate cell boundaries.\n\t columnPosLeft = [];\n\t columnPosRight = [];\n\t var x = 0;\n\t for (var i = 0, ii = columns.length; i < ii; i++) {\n\t columnPosLeft[i] = x;\n\t columnPosRight[i] = x + columns[i].width;\n\t\n\t if (options.frozenColumn == i) {\n\t x = 0;\n\t } else {\n\t x += columns[i].width;\n\t }\n\t }\n\t }\n\t\n\t function setColumns(columnDefinitions) {\n\t var _treeColumns = new _slick2.default.TreeColumns(columnDefinitions);\n\t if (_treeColumns.hasDepth()) {\n\t treeColumns = _treeColumns;\n\t columns = treeColumns.extractColumns();\n\t } else {\n\t columns = columnDefinitions;\n\t }\n\t\n\t columnsById = {};\n\t for (var i = 0; i < columns.length; i++) {\n\t var m = columns[i] = _jquery2.default.extend({}, columnDefaults, columns[i]);\n\t columnsById[m.id] = i;\n\t if (m.minWidth && m.width < m.minWidth) {\n\t m.width = m.minWidth;\n\t }\n\t if (m.maxWidth && m.width > m.maxWidth) {\n\t m.width = m.maxWidth;\n\t }\n\t }\n\t\n\t updateColumnCaches();\n\t\n\t if (initialized) {\n\t setPaneVisibility();\n\t setOverflow();\n\t\n\t invalidateAllRows();\n\t createColumnHeaders();\n\t createColumnGroupHeaders();\n\t createColumnFooter();\n\t removeCssRules();\n\t createCssRules();\n\t resizeCanvas();\n\t updateCanvasWidth();\n\t applyColumnWidths();\n\t handleScroll();\n\t }\n\t }\n\t\n\t function getOptions() {\n\t return options;\n\t }\n\t\n\t function setOptions(args) {\n\t if (!getEditorLock().commitCurrentEdit()) {\n\t return;\n\t }\n\t\n\t makeActiveCellNormal();\n\t\n\t if (options.enableAddRow !== args.enableAddRow) {\n\t invalidateRow(getDataLength());\n\t }\n\t\n\t options = _jquery2.default.extend(options, args);\n\t validateAndEnforceOptions();\n\t\n\t setFrozenOptions();\n\t setScroller();\n\t zombieRowNodeFromLastMouseWheelEvent = null;\n\t\n\t setColumns(treeColumns.extractColumns());\n\t render();\n\t }\n\t\n\t function validateAndEnforceOptions() {\n\t if (options.autoHeight) {\n\t options.leaveSpaceForNewRows = false;\n\t }\n\t }\n\t\n\t function setData(newData, scrollToTop) {\n\t data = newData;\n\t invalidateAllRows();\n\t updateRowCount();\n\t if (scrollToTop) {\n\t scrollTo(0);\n\t }\n\t }\n\t\n\t function getData() {\n\t return data;\n\t }\n\t\n\t function getDataLength() {\n\t if (data.getLength) {\n\t return data.getLength();\n\t } else {\n\t return data.length;\n\t }\n\t }\n\t\n\t function getDataLengthIncludingAddNew() {\n\t return getDataLength() + (options.enableAddRow ? 1 : 0);\n\t }\n\t\n\t function getDataItem(i) {\n\t if (data.getItem) {\n\t return data.getItem(i);\n\t } else {\n\t return data[i];\n\t }\n\t }\n\t\n\t function getTopPanel() {\n\t return $topPanel[0];\n\t }\n\t\n\t function setTopPanelVisibility(visible) {\n\t if (options.showTopPanel != visible) {\n\t options.showTopPanel = visible;\n\t if (visible) {\n\t $topPanelScroller.slideDown(\"fast\", resizeCanvas);\n\t } else {\n\t $topPanelScroller.slideUp(\"fast\", resizeCanvas);\n\t }\n\t }\n\t }\n\t\n\t function setHeaderRowVisibility(visible) {\n\t if (options.showHeaderRow != visible) {\n\t options.showHeaderRow = visible;\n\t if (visible) {\n\t $headerRowScroller.slideDown(\"fast\", resizeCanvas);\n\t } else {\n\t $headerRowScroller.slideUp(\"fast\", resizeCanvas);\n\t }\n\t }\n\t }\n\t\n\t function setFooterRowVisibility(visible) {\n\t if (options.showFooterRow != visible) {\n\t options.showFooterRow = visible;\n\t if (visible) {\n\t $footerRowScroller.fadeIn(\"fast\", resizeCanvas);\n\t } else {\n\t $footerRowScroller.slideDown(\"fast\", resizeCanvas);\n\t }\n\t }\n\t }\n\t\n\t function getContainerNode() {\n\t return $container.get(0);\n\t }\n\t\n\t //////////////////////////////////////////////////////////////////////////////////////////////\n\t // Rendering / Scrolling\n\t\n\t function getRowTop(row) {\n\t return options.rowHeight * row - offset;\n\t }\n\t\n\t function getRowFromPosition(y) {\n\t return Math.floor((y + offset) / options.rowHeight);\n\t }\n\t\n\t function scrollTo(y) {\n\t y = Math.max(y, 0);\n\t y = Math.min(y, th - $viewportScrollContainerY.height() + (viewportHasHScroll || hasFrozenColumns() ? scrollbarDimensions.height : 0));\n\t\n\t var oldOffset = offset;\n\t\n\t page = Math.min(n - 1, Math.floor(y / ph));\n\t offset = Math.round(page * cj);\n\t var newScrollTop = y - offset;\n\t\n\t if (offset != oldOffset) {\n\t var range = getVisibleRange(newScrollTop);\n\t cleanupRows(range);\n\t updateRowPositions();\n\t }\n\t\n\t if (prevScrollTop != newScrollTop) {\n\t vScrollDir = prevScrollTop + oldOffset < newScrollTop + offset ? 1 : -1;\n\t\n\t lastRenderedScrollTop = scrollTop = prevScrollTop = newScrollTop;\n\t\n\t if (hasFrozenColumns()) {\n\t $viewportTopL[0].scrollTop = newScrollTop;\n\t }\n\t\n\t if (hasFrozenRows) {\n\t $viewportBottomL[0].scrollTop = $viewportBottomR[0].scrollTop = newScrollTop;\n\t }\n\t\n\t $viewportScrollContainerY[0].scrollTop = newScrollTop;\n\t\n\t trigger(self.onViewportChanged, {});\n\t }\n\t }\n\t\n\t function defaultFormatter(row, cell, value, columnDef, dataContext) {\n\t if (value == null) {\n\t return \"\";\n\t } else {\n\t return (value + \"\").replace(/&/g, \"&\").replace(//g, \">\");\n\t }\n\t }\n\t\n\t function getFormatter(row, column) {\n\t var rowMetadata = data.getItemMetadata && data.getItemMetadata(row);\n\t\n\t // look up by id, then index\n\t var columnOverrides = rowMetadata && rowMetadata.columns && (rowMetadata.columns[column.id] || rowMetadata.columns[getColumnIndex(column.id)]);\n\t\n\t return columnOverrides && columnOverrides.formatter || rowMetadata && rowMetadata.formatter || column.formatter || options.formatterFactory && options.formatterFactory.getFormatter(column) || options.defaultFormatter;\n\t }\n\t\n\t function callFormatter(row, cell, value, m, item) {\n\t\n\t var result;\n\t\n\t // pass metadata to formatter\n\t var metadata = data.getItemMetadata && data.getItemMetadata(row);\n\t metadata = metadata && metadata.columns;\n\t\n\t if (metadata) {\n\t var columnData = metadata[m.id] || metadata[cell];\n\t result = getFormatter(row, m)(row, cell, value, m, item, columnData);\n\t } else {\n\t result = getFormatter(row, m)(row, cell, value, m, item);\n\t }\n\t\n\t return result;\n\t }\n\t\n\t function getEditor(row, cell) {\n\t var column = columns[cell];\n\t var rowMetadata = data.getItemMetadata && data.getItemMetadata(row);\n\t var columnMetadata = rowMetadata && rowMetadata.columns;\n\t\n\t if (columnMetadata && columnMetadata[column.id] && columnMetadata[column.id].editor !== undefined) {\n\t return columnMetadata[column.id].editor;\n\t }\n\t if (columnMetadata && columnMetadata[cell] && columnMetadata[cell].editor !== undefined) {\n\t return columnMetadata[cell].editor;\n\t }\n\t\n\t return column.editor || options.editorFactory && options.editorFactory.getEditor(column);\n\t }\n\t\n\t function getDataItemValueForColumn(item, columnDef) {\n\t if (options.dataItemColumnValueExtractor) {\n\t return options.dataItemColumnValueExtractor(item, columnDef);\n\t }\n\t return item[columnDef.field];\n\t }\n\t\n\t function appendRowHtml(stringArrayL, stringArrayR, row, range, dataLength) {\n\t var d = getDataItem(row);\n\t var dataLoading = row < dataLength && !d;\n\t var rowCss = \"slick-row\" + (hasFrozenRows && row < options.frozenRow ? ' frozen' : '') + (dataLoading ? \" loading\" : \"\") + (row === activeRow ? \" active\" : \"\") + (row % 2 == 1 ? \" odd\" : \" even\");\n\t\n\t if (!d) {\n\t rowCss += \" \" + options.addNewRowCssClass;\n\t }\n\t\n\t var metadata = data.getItemMetadata && data.getItemMetadata(row);\n\t\n\t if (metadata && metadata.cssClasses) {\n\t rowCss += \" \" + metadata.cssClasses;\n\t }\n\t\n\t var frozenRowOffset = getFrozenRowOffset(row);\n\t\n\t var rowHtml = \"
\";\n\t\n\t stringArrayL.push(rowHtml);\n\t\n\t if (hasFrozenColumns()) {\n\t stringArrayR.push(rowHtml);\n\t }\n\t\n\t var colspan, m;\n\t for (var i = 0, ii = columns.length; i < ii; i++) {\n\t m = columns[i];\n\t colspan = 1;\n\t if (metadata && metadata.columns) {\n\t var columnData = metadata.columns[m.id] || metadata.columns[i];\n\t colspan = columnData && columnData.colspan || 1;\n\t if (colspan === \"*\") {\n\t colspan = ii - i;\n\t }\n\t }\n\t\n\t // Do not render cells outside of the viewport.\n\t if (columnPosRight[Math.min(ii - 1, i + colspan - 1)] > range.leftPx) {\n\t if (columnPosLeft[i] > range.rightPx) {\n\t // All columns to the right are outside the range.\n\t break;\n\t }\n\t\n\t if (hasFrozenColumns() && i > options.frozenColumn) {\n\t appendCellHtml(stringArrayR, row, i, colspan, d);\n\t } else {\n\t appendCellHtml(stringArrayL, row, i, colspan, d);\n\t }\n\t } else if (hasFrozenColumns() && i <= options.frozenColumn) {\n\t appendCellHtml(stringArrayL, row, i, colspan, d);\n\t }\n\t\n\t if (colspan > 1) {\n\t i += colspan - 1;\n\t }\n\t }\n\t\n\t stringArrayL.push(\"
\");\n\t\n\t if (hasFrozenColumns()) {\n\t stringArrayR.push(\"
\");\n\t }\n\t }\n\t\n\t function appendCellHtml(stringArray, row, cell, colspan, item) {\n\t var m = columns[cell];\n\t var cellCss = \"slick-cell l\" + cell + \" r\" + Math.min(columns.length - 1, cell + colspan - 1) + (m.cssClass ? \" \" + m.cssClass : \"\");\n\t\n\t if (hasFrozenColumns() && cell <= options.frozenColumn) cellCss += ' frozen';\n\t\n\t if (row === activeRow && cell === activeCell) cellCss += \" active\";\n\t\n\t // TODO: merge them together in the setter\n\t for (var key in cellCssClasses) {\n\t if (cellCssClasses[key][row] && cellCssClasses[key][row][m.id]) {\n\t cellCss += \" \" + cellCssClasses[key][row][m.id];\n\t }\n\t }\n\t\n\t stringArray.push(\"
\");\n\t\n\t // if there is a corresponding row (if not, this is the Add New row or this data hasn't been loaded yet)\n\t if (item) {\n\t var value = getDataItemValueForColumn(item, m);\n\t stringArray.push(callFormatter(row, cell, value, m, item));\n\t }\n\t\n\t stringArray.push(\"
\");\n\t\n\t rowsCache[row].cellRenderQueue.push(cell);\n\t rowsCache[row].cellColSpans[cell] = colspan;\n\t }\n\t\n\t function cleanupRows(rangeToKeep) {\n\t for (var i in rowsCache) {\n\t var removeFrozenRow = true;\n\t\n\t if (hasFrozenRows && (options.frozenBottom && i >= actualFrozenRow || // Frozen bottom rows\n\t !options.frozenBottom && i <= actualFrozenRow // Frozen top rows\n\t )) {\n\t removeFrozenRow = false;\n\t }\n\t\n\t if ((i = parseInt(i, 10)) !== activeRow && (i < rangeToKeep.top || i > rangeToKeep.bottom) && removeFrozenRow) {\n\t removeRowFromCache(i);\n\t }\n\t }\n\t }\n\t\n\t function invalidate() {\n\t updateRowCount();\n\t invalidateAllRows();\n\t render();\n\t }\n\t\n\t function invalidateAllRows() {\n\t if (currentEditor) {\n\t makeActiveCellNormal();\n\t }\n\t for (var row in rowsCache) {\n\t removeRowFromCache(row);\n\t }\n\t }\n\t\n\t function removeRowFromCache(row) {\n\t var cacheEntry = rowsCache[row];\n\t if (!cacheEntry) {\n\t return;\n\t }\n\t\n\t if (rowNodeFromLastMouseWheelEvent == cacheEntry.rowNode[0] || hasFrozenColumns() && rowNodeFromLastMouseWheelEvent == cacheEntry.rowNode[1]) {\n\t\n\t cacheEntry.rowNode.hide();\n\t\n\t zombieRowNodeFromLastMouseWheelEvent = cacheEntry.rowNode;\n\t } else {\n\t\n\t cacheEntry.rowNode.each(function () {\n\t this.parentElement.removeChild(this);\n\t });\n\t }\n\t\n\t delete rowsCache[row];\n\t delete postProcessedRows[row];\n\t renderedRows--;\n\t counter_rows_removed++;\n\t }\n\t\n\t function invalidateRows(rows) {\n\t var i, rl;\n\t if (!rows || !rows.length) {\n\t return;\n\t }\n\t vScrollDir = 0;\n\t for (i = 0, rl = rows.length; i < rl; i++) {\n\t if (currentEditor && activeRow === rows[i]) {\n\t makeActiveCellNormal();\n\t }\n\t if (rowsCache[rows[i]]) {\n\t removeRowFromCache(rows[i]);\n\t }\n\t }\n\t }\n\t\n\t function invalidateRow(row) {\n\t invalidateRows([row]);\n\t }\n\t\n\t function updateCell(row, cell) {\n\t var cellNode = getCellNode(row, cell);\n\t if (!cellNode) {\n\t return;\n\t }\n\t\n\t var m = columns[cell],\n\t d = getDataItem(row);\n\t if (currentEditor && activeRow === row && activeCell === cell) {\n\t currentEditor.loadValue(d);\n\t } else {\n\t cellNode.innerHTML = d ? callFormatter(row, cell, getDataItemValueForColumn(d, m), m, d) : \"\";\n\t invalidatePostProcessingResults(row);\n\t }\n\t }\n\t\n\t function updateRow(row) {\n\t var cacheEntry = rowsCache[row];\n\t if (!cacheEntry) {\n\t return;\n\t }\n\t\n\t ensureCellNodesInRowsCache(row);\n\t\n\t var d = getDataItem(row);\n\t\n\t for (var columnIdx in cacheEntry.cellNodesByColumnIdx) {\n\t if (!cacheEntry.cellNodesByColumnIdx.hasOwnProperty(columnIdx)) {\n\t continue;\n\t }\n\t\n\t columnIdx = columnIdx | 0;\n\t var m = columns[columnIdx],\n\t node = cacheEntry.cellNodesByColumnIdx[columnIdx][0];\n\t\n\t if (row === activeRow && columnIdx === activeCell && currentEditor) {\n\t currentEditor.loadValue(d);\n\t } else if (d) {\n\t node.innerHTML = callFormatter(row, columnIdx, getDataItemValueForColumn(d, m), m, d);\n\t } else {\n\t node.innerHTML = \"\";\n\t }\n\t }\n\t\n\t invalidatePostProcessingResults(row);\n\t }\n\t\n\t function getViewportHeight() {\n\t if (options.autoHeight) {\n\t viewportH = options.rowHeight * getDataLengthIncludingAddNew() + (options.frozenColumn == -1 ? $headers.outerHeight() : 0);\n\t } else {\n\t topPanelH = options.showTopPanel ? options.topPanelHeight + getVBoxDelta($topPanelScroller) : 0;\n\t\n\t headerRowH = options.showHeaderRow ? options.headerRowHeight + getVBoxDelta($headerRowScroller) : 0;\n\t\n\t footerRowH = options.showFooterRow ? options.footerRowHeight + getVBoxDelta($footerRowScroller) : 0;\n\t\n\t viewportH = parseFloat(_jquery2.default.css($container[0], \"height\", true)) - parseFloat(_jquery2.default.css($container[0], \"paddingTop\", true)) - parseFloat(_jquery2.default.css($container[0], \"paddingBottom\", true)) - parseFloat(_jquery2.default.css($headerScroller[0], \"height\")) - getVBoxDelta($headerScroller) - topPanelH - headerRowH - footerRowH;\n\t }\n\t\n\t numVisibleRows = Math.ceil(viewportH / options.rowHeight);\n\t }\n\t\n\t function getViewportWidth() {\n\t viewportW = parseFloat(_jquery2.default.css($container[0], \"width\", true));\n\t }\n\t\n\t function resizeCanvas() {\n\t if (!initialized) {\n\t return;\n\t }\n\t\n\t paneTopH = 0;\n\t paneBottomH = 0;\n\t viewportTopH = 0;\n\t viewportBottomH = 0;\n\t\n\t getViewportWidth();\n\t getViewportHeight();\n\t\n\t // Account for Frozen Rows\n\t if (hasFrozenRows) {\n\t if (options.frozenBottom) {\n\t paneTopH = viewportH - frozenRowsHeight - scrollbarDimensions.height;\n\t\n\t paneBottomH = frozenRowsHeight + scrollbarDimensions.height;\n\t } else {\n\t paneTopH = frozenRowsHeight;\n\t paneBottomH = viewportH - frozenRowsHeight;\n\t }\n\t } else {\n\t paneTopH = viewportH;\n\t }\n\t\n\t // The top pane includes the top panel and the header row\n\t paneTopH += topPanelH + headerRowH + footerRowH;\n\t\n\t if (hasFrozenColumns() && options.autoHeight) {\n\t paneTopH += scrollbarDimensions.height;\n\t }\n\t\n\t // The top viewport does not contain the top panel or header row\n\t viewportTopH = paneTopH - topPanelH - headerRowH - footerRowH;\n\t\n\t if (options.autoHeight) {\n\t if (hasFrozenColumns()) {\n\t $container.height(paneTopH + parseFloat(_jquery2.default.css($headerScrollerL[0], \"height\")));\n\t }\n\t\n\t $paneTopL.css('position', 'relative');\n\t }\n\t\n\t $paneTopL.css({\n\t 'top': $paneHeaderL.height(),\n\t 'height': paneTopH\n\t });\n\t\n\t var paneBottomTop = $paneTopL.position().top + paneTopH;\n\t\n\t $viewportTopL.height(viewportTopH);\n\t\n\t if (hasFrozenColumns()) {\n\t $paneTopR.css({\n\t 'top': $paneHeaderL.height(),\n\t 'height': paneTopH\n\t });\n\t\n\t $viewportTopR.height(viewportTopH);\n\t\n\t if (hasFrozenRows) {\n\t $paneBottomL.css({\n\t 'top': paneBottomTop,\n\t 'height': paneBottomH\n\t });\n\t\n\t $paneBottomR.css({\n\t 'top': paneBottomTop,\n\t 'height': paneBottomH\n\t });\n\t\n\t $viewportBottomR.height(paneBottomH);\n\t }\n\t } else {\n\t if (hasFrozenRows) {\n\t $paneBottomL.css({\n\t 'width': '100%',\n\t 'height': paneBottomH\n\t });\n\t\n\t $paneBottomL.css('top', paneBottomTop);\n\t }\n\t }\n\t\n\t if (hasFrozenRows) {\n\t $viewportBottomL.height(paneBottomH);\n\t\n\t if (options.frozenBottom) {\n\t $canvasBottomL.height(frozenRowsHeight);\n\t\n\t if (hasFrozenColumns()) {\n\t $canvasBottomR.height(frozenRowsHeight);\n\t }\n\t } else {\n\t $canvasTopL.height(frozenRowsHeight);\n\t\n\t if (hasFrozenColumns()) {\n\t $canvasTopR.height(frozenRowsHeight);\n\t }\n\t }\n\t } else {\n\t $viewportTopR.height(viewportTopH);\n\t }\n\t\n\t if (options.forceFitColumns) {\n\t autosizeColumns();\n\t }\n\t\n\t updateRowCount();\n\t handleScroll();\n\t // Since the width has changed, force the render() to reevaluate virtually rendered cells.\n\t lastRenderedScrollLeft = -1;\n\t render();\n\t }\n\t\n\t function updateRowCount() {\n\t if (!initialized) {\n\t return;\n\t }\n\t\n\t var dataLengthIncludingAddNew = getDataLengthIncludingAddNew();\n\t var numberOfRows = 0;\n\t var oldH = hasFrozenRows && !options.frozenBottom ? $canvasBottomL.height() : $canvasTopL.height();\n\t\n\t if (hasFrozenRows) {\n\t var numberOfRows = getDataLength() - options.frozenRow;\n\t } else {\n\t var numberOfRows = dataLengthIncludingAddNew + (options.leaveSpaceForNewRows ? numVisibleRows - 1 : 0);\n\t }\n\t\n\t var tempViewportH = $viewportScrollContainerY.height();\n\t var oldViewportHasVScroll = viewportHasVScroll;\n\t // with autoHeight, we do not need to accommodate the vertical scroll bar\n\t viewportHasVScroll = !options.autoHeight && numberOfRows * options.rowHeight > tempViewportH;\n\t\n\t makeActiveCellNormal();\n\t\n\t // remove the rows that are now outside of the data range\n\t // this helps avoid redundant calls to .removeRow() when the size of the data decreased by thousands of rows\n\t var l = dataLengthIncludingAddNew - 1;\n\t for (var i in rowsCache) {\n\t if (i >= l) {\n\t removeRowFromCache(i);\n\t }\n\t }\n\t\n\t th = Math.max(options.rowHeight * numberOfRows, tempViewportH - scrollbarDimensions.height);\n\t\n\t if (activeCellNode && activeRow > l) {\n\t resetActiveCell();\n\t }\n\t\n\t if (th < maxSupportedCssHeight) {\n\t // just one page\n\t h = ph = th;\n\t n = 1;\n\t cj = 0;\n\t } else {\n\t // break into pages\n\t h = maxSupportedCssHeight;\n\t ph = h / 100;\n\t n = Math.floor(th / ph);\n\t cj = (th - h) / (n - 1);\n\t }\n\t\n\t if (h !== oldH) {\n\t if (hasFrozenRows && !options.frozenBottom) {\n\t $canvasBottomL.css(\"height\", h);\n\t\n\t if (hasFrozenColumns()) {\n\t $canvasBottomR.css(\"height\", h);\n\t }\n\t } else {\n\t $canvasTopL.css(\"height\", h);\n\t $canvasTopR.css(\"height\", h);\n\t }\n\t\n\t scrollTop = $viewportScrollContainerY[0].scrollTop;\n\t }\n\t\n\t var oldScrollTopInRange = scrollTop + offset <= th - tempViewportH;\n\t\n\t if (th == 0 || scrollTop == 0) {\n\t page = offset = 0;\n\t } else if (oldScrollTopInRange) {\n\t // maintain virtual position\n\t scrollTo(scrollTop + offset);\n\t } else {\n\t // scroll to bottom\n\t scrollTo(th - tempViewportH);\n\t }\n\t\n\t if (h != oldH && options.autoHeight) {\n\t resizeCanvas();\n\t }\n\t\n\t if (options.forceFitColumns && oldViewportHasVScroll != viewportHasVScroll) {\n\t autosizeColumns();\n\t }\n\t updateCanvasWidth(false);\n\t }\n\t\n\t function getVisibleRange(viewportTop, viewportLeft) {\n\t if (viewportTop == null) {\n\t viewportTop = scrollTop;\n\t }\n\t if (viewportLeft == null) {\n\t viewportLeft = scrollLeft;\n\t }\n\t\n\t return {\n\t top: getRowFromPosition(viewportTop),\n\t bottom: getRowFromPosition(viewportTop + viewportH) + 1,\n\t leftPx: viewportLeft,\n\t rightPx: viewportLeft + viewportW\n\t };\n\t }\n\t\n\t function getRenderedRange(viewportTop, viewportLeft) {\n\t var range = getVisibleRange(viewportTop, viewportLeft);\n\t var buffer = Math.round(viewportH / options.rowHeight);\n\t var minBuffer = 3;\n\t\n\t if (vScrollDir == -1) {\n\t range.top -= buffer;\n\t range.bottom += minBuffer;\n\t } else if (vScrollDir == 1) {\n\t range.top -= minBuffer;\n\t range.bottom += buffer;\n\t } else {\n\t range.top -= minBuffer;\n\t range.bottom += minBuffer;\n\t }\n\t\n\t range.top = Math.max(0, range.top);\n\t range.bottom = Math.min(getDataLengthIncludingAddNew() - 1, range.bottom);\n\t\n\t range.leftPx -= viewportW;\n\t range.rightPx += viewportW;\n\t\n\t range.leftPx = Math.max(0, range.leftPx);\n\t range.rightPx = Math.min(canvasWidth, range.rightPx);\n\t\n\t return range;\n\t }\n\t\n\t function ensureCellNodesInRowsCache(row) {\n\t var cacheEntry = rowsCache[row];\n\t if (cacheEntry) {\n\t if (cacheEntry.cellRenderQueue.length) {\n\t var $lastNode = cacheEntry.rowNode.children().last();\n\t while (cacheEntry.cellRenderQueue.length) {\n\t var columnIdx = cacheEntry.cellRenderQueue.pop();\n\t\n\t cacheEntry.cellNodesByColumnIdx[columnIdx] = $lastNode;\n\t $lastNode = $lastNode.prev();\n\t\n\t // Hack to retrieve the frozen columns because\n\t if ($lastNode.length == 0) {\n\t $lastNode = (0, _jquery2.default)(cacheEntry.rowNode[0]).children().last();\n\t }\n\t }\n\t }\n\t }\n\t }\n\t\n\t function cleanUpCells(range, row) {\n\t // Ignore frozen rows\n\t if (hasFrozenRows && (options.frozenBottom && row > actualFrozenRow || // Frozen bottom rows\n\t row <= actualFrozenRow // Frozen top rows\n\t )) {\n\t return;\n\t }\n\t\n\t var totalCellsRemoved = 0;\n\t var cacheEntry = rowsCache[row];\n\t\n\t // Remove cells outside the range.\n\t var cellsToRemove = [];\n\t for (var i in cacheEntry.cellNodesByColumnIdx) {\n\t // I really hate it when people mess with Array.prototype.\n\t if (!cacheEntry.cellNodesByColumnIdx.hasOwnProperty(i)) {\n\t continue;\n\t }\n\t\n\t // This is a string, so it needs to be cast back to a number.\n\t i = i | 0;\n\t\n\t // Ignore frozen columns\n\t if (i <= options.frozenColumn) {\n\t continue;\n\t }\n\t\n\t var colspan = cacheEntry.cellColSpans[i];\n\t if (columnPosLeft[i] > range.rightPx || columnPosRight[Math.min(columns.length - 1, i + colspan - 1)] < range.leftPx) {\n\t if (!(row == activeRow && i == activeCell)) {\n\t cellsToRemove.push(i);\n\t }\n\t }\n\t }\n\t\n\t var cellToRemove;\n\t while ((cellToRemove = cellsToRemove.pop()) != null) {\n\t cacheEntry.cellNodesByColumnIdx[cellToRemove][0].parentElement.removeChild(cacheEntry.cellNodesByColumnIdx[cellToRemove][0]);\n\t delete cacheEntry.cellColSpans[cellToRemove];\n\t delete cacheEntry.cellNodesByColumnIdx[cellToRemove];\n\t if (postProcessedRows[row]) {\n\t delete postProcessedRows[row][cellToRemove];\n\t }\n\t totalCellsRemoved++;\n\t }\n\t }\n\t\n\t function cleanUpAndRenderCells(range) {\n\t var cacheEntry;\n\t var stringArray = [];\n\t var processedRows = [];\n\t var cellsAdded;\n\t var totalCellsAdded = 0;\n\t var colspan;\n\t\n\t for (var row = range.top, btm = range.bottom; row <= btm; row++) {\n\t cacheEntry = rowsCache[row];\n\t if (!cacheEntry) {\n\t continue;\n\t }\n\t\n\t // cellRenderQueue populated in renderRows() needs to be cleared first\n\t ensureCellNodesInRowsCache(row);\n\t\n\t cleanUpCells(range, row);\n\t\n\t // Render missing cells.\n\t cellsAdded = 0;\n\t\n\t var metadata = data.getItemMetadata && data.getItemMetadata(row);\n\t metadata = metadata && metadata.columns;\n\t\n\t var d = getDataItem(row);\n\t\n\t // TODO: shorten this loop (index? heuristics? binary search?)\n\t for (var i = 0, ii = columns.length; i < ii; i++) {\n\t // Cells to the right are outside the range.\n\t if (columnPosLeft[i] > range.rightPx) {\n\t break;\n\t }\n\t\n\t // Already rendered.\n\t if ((colspan = cacheEntry.cellColSpans[i]) != null) {\n\t i += colspan > 1 ? colspan - 1 : 0;\n\t continue;\n\t }\n\t\n\t colspan = 1;\n\t if (metadata) {\n\t var columnData = metadata[columns[i].id] || metadata[i];\n\t colspan = columnData && columnData.colspan || 1;\n\t if (colspan === \"*\") {\n\t colspan = ii - i;\n\t }\n\t }\n\t\n\t if (columnPosRight[Math.min(ii - 1, i + colspan - 1)] > range.leftPx) {\n\t appendCellHtml(stringArray, row, i, colspan, d);\n\t cellsAdded++;\n\t }\n\t\n\t i += colspan > 1 ? colspan - 1 : 0;\n\t }\n\t\n\t if (cellsAdded) {\n\t totalCellsAdded += cellsAdded;\n\t processedRows.push(row);\n\t }\n\t }\n\t\n\t if (!stringArray.length) {\n\t return;\n\t }\n\t\n\t var x = document.createElement(\"div\");\n\t x.innerHTML = stringArray.join(\"\");\n\t\n\t var processedRow;\n\t var $node;\n\t while ((processedRow = processedRows.pop()) != null) {\n\t cacheEntry = rowsCache[processedRow];\n\t var columnIdx;\n\t while ((columnIdx = cacheEntry.cellRenderQueue.pop()) != null) {\n\t $node = (0, _jquery2.default)(x).children().last();\n\t\n\t if (hasFrozenColumns() && columnIdx > options.frozenColumn) {\n\t (0, _jquery2.default)(cacheEntry.rowNode[1]).append($node);\n\t } else {\n\t (0, _jquery2.default)(cacheEntry.rowNode[0]).append($node);\n\t }\n\t\n\t cacheEntry.cellNodesByColumnIdx[columnIdx] = $node;\n\t }\n\t }\n\t }\n\t\n\t function renderRows(range) {\n\t var stringArrayL = [],\n\t stringArrayR = [],\n\t rows = [],\n\t needToReselectCell = false,\n\t dataLength = getDataLength();\n\t\n\t for (var i = range.top, ii = range.bottom; i <= ii; i++) {\n\t if (rowsCache[i] || hasFrozenRows && options.frozenBottom && i == getDataLength()) {\n\t continue;\n\t }\n\t renderedRows++;\n\t rows.push(i);\n\t\n\t // Create an entry right away so that appendRowHtml() can\n\t // start populatating it.\n\t rowsCache[i] = {\n\t \"rowNode\": null,\n\t\n\t // ColSpans of rendered cells (by column idx).\n\t // Can also be used for checking whether a cell has been rendered.\n\t \"cellColSpans\": [],\n\t\n\t // Cell nodes (by column idx). Lazy-populated by ensureCellNodesInRowsCache().\n\t \"cellNodesByColumnIdx\": [],\n\t\n\t // Column indices of cell nodes that have been rendered, but not yet indexed in\n\t // cellNodesByColumnIdx. These are in the same order as cell nodes added at the\n\t // end of the row.\n\t \"cellRenderQueue\": []\n\t };\n\t\n\t appendRowHtml(stringArrayL, stringArrayR, i, range, dataLength);\n\t if (activeCellNode && activeRow === i) {\n\t needToReselectCell = true;\n\t }\n\t counter_rows_rendered++;\n\t }\n\t\n\t if (!rows.length) {\n\t return;\n\t }\n\t\n\t var x = document.createElement(\"div\"),\n\t xRight = document.createElement(\"div\");\n\t\n\t x.innerHTML = stringArrayL.join(\"\");\n\t xRight.innerHTML = stringArrayR.join(\"\");\n\t\n\t for (var i = 0, ii = rows.length; i < ii; i++) {\n\t if (hasFrozenRows && rows[i] >= actualFrozenRow) {\n\t if (hasFrozenColumns()) {\n\t rowsCache[rows[i]].rowNode = (0, _jquery2.default)().add((0, _jquery2.default)(x.firstChild).appendTo($canvasBottomL)).add((0, _jquery2.default)(xRight.firstChild).appendTo($canvasBottomR));\n\t } else {\n\t rowsCache[rows[i]].rowNode = (0, _jquery2.default)().add((0, _jquery2.default)(x.firstChild).appendTo($canvasBottomL));\n\t }\n\t } else if (hasFrozenColumns()) {\n\t rowsCache[rows[i]].rowNode = (0, _jquery2.default)().add((0, _jquery2.default)(x.firstChild).appendTo($canvasTopL)).add((0, _jquery2.default)(xRight.firstChild).appendTo($canvasTopR));\n\t } else {\n\t rowsCache[rows[i]].rowNode = (0, _jquery2.default)().add((0, _jquery2.default)(x.firstChild).appendTo($canvasTopL));\n\t }\n\t }\n\t\n\t if (needToReselectCell) {\n\t activeCellNode = getCellNode(activeRow, activeCell);\n\t }\n\t }\n\t\n\t function startPostProcessing() {\n\t if (!options.enableAsyncPostRender) {\n\t return;\n\t }\n\t clearTimeout(h_postrender);\n\t h_postrender = setTimeout(asyncPostProcessRows, options.asyncPostRenderDelay);\n\t }\n\t\n\t function invalidatePostProcessingResults(row) {\n\t delete postProcessedRows[row];\n\t postProcessFromRow = Math.min(postProcessFromRow, row);\n\t postProcessToRow = Math.max(postProcessToRow, row);\n\t startPostProcessing();\n\t }\n\t\n\t function updateRowPositions() {\n\t for (var row in rowsCache) {\n\t rowsCache[row].rowNode.css('top', getRowTop(row) + \"px\");\n\t }\n\t }\n\t\n\t function render() {\n\t if (!initialized) {\n\t return;\n\t }\n\t var visible = getVisibleRange();\n\t var rendered = getRenderedRange();\n\t\n\t // remove rows no longer in the viewport\n\t cleanupRows(rendered);\n\t\n\t // add new rows & missing cells in existing rows\n\t if (lastRenderedScrollLeft != scrollLeft) {\n\t\n\t if (hasFrozenRows) {\n\t\n\t var renderedFrozenRows = _jquery2.default.extend(true, {}, rendered);\n\t\n\t if (options.frozenBottom) {\n\t\n\t renderedFrozenRows.top = actualFrozenRow;\n\t renderedFrozenRows.bottom = getDataLength();\n\t } else {\n\t\n\t renderedFrozenRows.top = 0;\n\t renderedFrozenRows.bottom = options.frozenRow;\n\t }\n\t\n\t cleanUpAndRenderCells(renderedFrozenRows);\n\t }\n\t\n\t cleanUpAndRenderCells(rendered);\n\t }\n\t\n\t // render missing rows\n\t renderRows(rendered);\n\t\n\t // Render frozen rows\n\t if (hasFrozenRows) {\n\t if (options.frozenBottom) {\n\t renderRows({\n\t top: actualFrozenRow,\n\t bottom: getDataLength() - 1,\n\t leftPx: rendered.leftPx,\n\t rightPx: rendered.rightPx\n\t });\n\t } else {\n\t renderRows({\n\t top: 0,\n\t bottom: options.frozenRow - 1,\n\t leftPx: rendered.leftPx,\n\t rightPx: rendered.rightPx\n\t });\n\t }\n\t }\n\t\n\t postProcessFromRow = visible.top;\n\t postProcessToRow = Math.min(getDataLengthIncludingAddNew() - 1, visible.bottom);\n\t startPostProcessing();\n\t\n\t lastRenderedScrollTop = scrollTop;\n\t lastRenderedScrollLeft = scrollLeft;\n\t h_render = null;\n\t }\n\t\n\t function handleHeaderRowScroll() {\n\t var scrollLeft = $headerRowScrollContainer[0].scrollLeft;\n\t if (scrollLeft != $viewportScrollContainerX[0].scrollLeft) {\n\t $viewportScrollContainerX[0].scrollLeft = scrollLeft;\n\t }\n\t }\n\t\n\t function handleFooterRowScroll() {\n\t var scrollLeft = $footerRowScrollContainer[0].scrollLeft;\n\t if (scrollLeft != $viewportScrollContainerX[0].scrollLeft) {\n\t $viewportScrollContainerX[0].scrollLeft = scrollLeft;\n\t }\n\t }\n\t\n\t function handleMouseWheel(e, delta, deltaX, deltaY) {\n\t var $rowNode = (0, _jquery2.default)(e.target).closest(\".slick-row\");\n\t var rowNode = $rowNode[0];\n\t\n\t if (rowNode != rowNodeFromLastMouseWheelEvent) {\n\t\n\t var $gridCanvas = $rowNode.parents('.grid-canvas');\n\t var left = $gridCanvas.hasClass('grid-canvas-left');\n\t\n\t if (zombieRowNodeFromLastMouseWheelEvent && zombieRowNodeFromLastMouseWheelEvent[left ? 0 : 1] != rowNode) {\n\t var zombieRow = zombieRowNodeFromLastMouseWheelEvent[left || zombieRowNodeFromLastMouseWheelEvent.length == 1 ? 0 : 1];\n\t zombieRow.parentElement.removeChild(zombieRow);\n\t\n\t zombieRowNodeFromLastMouseWheelEvent = null;\n\t }\n\t\n\t rowNodeFromLastMouseWheelEvent = rowNode;\n\t }\n\t\n\t scrollTop = Math.max(0, $viewportScrollContainerY[0].scrollTop - deltaY * options.rowHeight);\n\t scrollLeft = $viewportScrollContainerX[0].scrollLeft + deltaX * 10;\n\t var handled = _handleScroll(true);\n\t if (handled) e.preventDefault();\n\t }\n\t\n\t function handleScroll() {\n\t scrollTop = $viewportScrollContainerY[0].scrollTop;\n\t scrollLeft = $viewportScrollContainerX[0].scrollLeft;\n\t return _handleScroll(false);\n\t }\n\t\n\t function _handleScroll(isMouseWheel) {\n\t var maxScrollDistanceY = $viewportScrollContainerY[0].scrollHeight - $viewportScrollContainerY[0].clientHeight;\n\t var maxScrollDistanceX = $viewportScrollContainerY[0].scrollWidth - $viewportScrollContainerY[0].clientWidth;\n\t var hasFrozenCols = hasFrozenColumns();\n\t\n\t // Ceiling the max scroll values\n\t if (scrollTop > maxScrollDistanceY) {\n\t scrollTop = maxScrollDistanceY;\n\t }\n\t if (scrollLeft > maxScrollDistanceX) {\n\t scrollLeft = maxScrollDistanceX;\n\t }\n\t\n\t var vScrollDist = Math.abs(scrollTop - prevScrollTop);\n\t var hScrollDist = Math.abs(scrollLeft - prevScrollLeft);\n\t\n\t if (hScrollDist) {\n\t prevScrollLeft = scrollLeft;\n\t\n\t $viewportScrollContainerX[0].scrollLeft = scrollLeft;\n\t $headerScrollContainer[0].scrollLeft = scrollLeft;\n\t $topPanelScroller[0].scrollLeft = scrollLeft;\n\t $headerRowScrollContainer[0].scrollLeft = scrollLeft;\n\t $footerRowScrollContainer[0].scrollLeft = scrollLeft;\n\t\n\t if (hasFrozenCols) {\n\t if (hasFrozenRows) {\n\t $viewportTopR[0].scrollLeft = scrollLeft;\n\t }\n\t } else {\n\t if (hasFrozenRows) {\n\t $viewportTopL[0].scrollLeft = scrollLeft;\n\t }\n\t }\n\t }\n\t\n\t if (vScrollDist) {\n\t vScrollDir = prevScrollTop < scrollTop ? 1 : -1;\n\t prevScrollTop = scrollTop;\n\t\n\t if (isMouseWheel) {\n\t $viewportScrollContainerY[0].scrollTop = scrollTop;\n\t }\n\t\n\t if (hasFrozenCols) {\n\t if (hasFrozenRows && !options.frozenBottom) {\n\t $viewportBottomL[0].scrollTop = scrollTop;\n\t } else {\n\t $viewportTopL[0].scrollTop = scrollTop;\n\t }\n\t }\n\t\n\t // switch virtual pages if needed\n\t if (vScrollDist < viewportH) {\n\t scrollTo(scrollTop + offset);\n\t } else {\n\t var oldOffset = offset;\n\t if (h == viewportH) {\n\t page = 0;\n\t } else {\n\t page = Math.min(n - 1, Math.floor(scrollTop * ((th - viewportH) / (h - viewportH)) * (1 / ph)));\n\t }\n\t offset = Math.round(page * cj);\n\t if (oldOffset != offset) {\n\t invalidateAllRows();\n\t }\n\t }\n\t }\n\t\n\t if (hScrollDist || vScrollDist) {\n\t if (h_render) {\n\t clearTimeout(h_render);\n\t }\n\t\n\t if (Math.abs(lastRenderedScrollTop - scrollTop) > 20 || Math.abs(lastRenderedScrollLeft - scrollLeft) > 20) {\n\t if (options.forceSyncScrolling || Math.abs(lastRenderedScrollTop - scrollTop) < viewportH && Math.abs(lastRenderedScrollLeft - scrollLeft) < viewportW) {\n\t render();\n\t } else {\n\t h_render = setTimeout(render, 50);\n\t }\n\t\n\t trigger(self.onViewportChanged, {});\n\t }\n\t }\n\t\n\t trigger(self.onScroll, {\n\t scrollLeft: scrollLeft,\n\t scrollTop: scrollTop\n\t });\n\t\n\t if (hScrollDist || vScrollDist) return true;\n\t return false;\n\t }\n\t\n\t function asyncPostProcessRows() {\n\t var dataLength = getDataLength();\n\t while (postProcessFromRow <= postProcessToRow) {\n\t var row = vScrollDir >= 0 ? postProcessFromRow++ : postProcessToRow--;\n\t var cacheEntry = rowsCache[row];\n\t if (!cacheEntry || row >= dataLength) {\n\t continue;\n\t }\n\t\n\t if (!postProcessedRows[row]) {\n\t postProcessedRows[row] = {};\n\t }\n\t\n\t ensureCellNodesInRowsCache(row);\n\t for (var columnIdx in cacheEntry.cellNodesByColumnIdx) {\n\t if (!cacheEntry.cellNodesByColumnIdx.hasOwnProperty(columnIdx)) {\n\t continue;\n\t }\n\t\n\t columnIdx = columnIdx | 0;\n\t\n\t var m = columns[columnIdx];\n\t if (m.asyncPostRender && !postProcessedRows[row][columnIdx]) {\n\t var node = cacheEntry.cellNodesByColumnIdx[columnIdx];\n\t if (node) {\n\t m.asyncPostRender(node, row, getDataItem(row), m);\n\t }\n\t postProcessedRows[row][columnIdx] = true;\n\t }\n\t }\n\t\n\t h_postrender = setTimeout(asyncPostProcessRows, options.asyncPostRenderDelay);\n\t return;\n\t }\n\t }\n\t\n\t function updateCellCssStylesOnRenderedRows(addedHash, removedHash) {\n\t var node, columnId, addedRowHash, removedRowHash;\n\t for (var row in rowsCache) {\n\t removedRowHash = removedHash && removedHash[row];\n\t addedRowHash = addedHash && addedHash[row];\n\t\n\t if (removedRowHash) {\n\t for (columnId in removedRowHash) {\n\t if (!addedRowHash || removedRowHash[columnId] != addedRowHash[columnId]) {\n\t node = getCellNode(row, getColumnIndex(columnId));\n\t if (node) {\n\t (0, _jquery2.default)(node).removeClass(removedRowHash[columnId]);\n\t }\n\t }\n\t }\n\t }\n\t\n\t if (addedRowHash) {\n\t for (columnId in addedRowHash) {\n\t if (!removedRowHash || removedRowHash[columnId] != addedRowHash[columnId]) {\n\t node = getCellNode(row, getColumnIndex(columnId));\n\t if (node) {\n\t (0, _jquery2.default)(node).addClass(addedRowHash[columnId]);\n\t }\n\t }\n\t }\n\t }\n\t }\n\t }\n\t\n\t function addCellCssStyles(key, hash) {\n\t if (cellCssClasses[key]) {\n\t throw \"addCellCssStyles: cell CSS hash with key '\" + key + \"' already exists.\";\n\t }\n\t\n\t cellCssClasses[key] = hash;\n\t updateCellCssStylesOnRenderedRows(hash, null);\n\t\n\t trigger(self.onCellCssStylesChanged, {\n\t \"key\": key,\n\t \"hash\": hash\n\t });\n\t }\n\t\n\t function removeCellCssStyles(key) {\n\t if (!cellCssClasses[key]) {\n\t return;\n\t }\n\t\n\t updateCellCssStylesOnRenderedRows(null, cellCssClasses[key]);\n\t delete cellCssClasses[key];\n\t\n\t trigger(self.onCellCssStylesChanged, {\n\t \"key\": key,\n\t \"hash\": null\n\t });\n\t }\n\t\n\t function setCellCssStyles(key, hash) {\n\t var prevHash = cellCssClasses[key];\n\t\n\t cellCssClasses[key] = hash;\n\t updateCellCssStylesOnRenderedRows(hash, prevHash);\n\t\n\t trigger(self.onCellCssStylesChanged, {\n\t \"key\": key,\n\t \"hash\": hash\n\t });\n\t }\n\t\n\t function getCellCssStyles(key) {\n\t return cellCssClasses[key];\n\t }\n\t\n\t function flashCell(row, cell, speed) {\n\t speed = speed || 100;\n\t if (rowsCache[row]) {\n\t var toggleCellClass = function toggleCellClass(times) {\n\t if (!times) {\n\t return;\n\t }\n\t setTimeout(function () {\n\t $cell.queue(function () {\n\t $cell.toggleClass(options.cellFlashingCssClass).dequeue();\n\t toggleCellClass(times - 1);\n\t });\n\t }, speed);\n\t };\n\t\n\t var $cell = (0, _jquery2.default)(getCellNode(row, cell));\n\t\n\t toggleCellClass(4);\n\t }\n\t }\n\t\n\t //////////////////////////////////////////////////////////////////////////////////////////////\n\t // Interactivity\n\t\n\t function handleDragInit(e, dd) {\n\t var cell = getCellFromEvent(e);\n\t if (!cell || !cellExists(cell.row, cell.cell)) {\n\t return false;\n\t }\n\t\n\t var retval = trigger(self.onDragInit, dd, e);\n\t if (e.isImmediatePropagationStopped()) {\n\t return retval;\n\t }\n\t\n\t // if nobody claims to be handling drag'n'drop by stopping immediate propagation,\n\t // cancel out of it\n\t return false;\n\t }\n\t\n\t function handleDragStart(interactEvent) {\n\t var event = _jquery2.default.Event(interactEvent.originalEvent.type, interactEvent.originalEvent);\n\t var cell = getCellFromEvent(event);\n\t if (!cell || !cellExists(cell.row, cell.cell)) {\n\t return false;\n\t }\n\t\n\t var retval = trigger(self.onDragStart, interactEvent, event);\n\t if (event.isImmediatePropagationStopped()) {\n\t return retval;\n\t }\n\t\n\t return false;\n\t }\n\t\n\t function handleDrag(interactEvent) {\n\t var event = _jquery2.default.Event(interactEvent.originalEvent.type, interactEvent.originalEvent);\n\t return trigger(self.onDrag, interactEvent, event);\n\t }\n\t\n\t function handleDragEnd(interactEvent) {\n\t trigger(self.onDragEnd, interactEvent, _jquery2.default.Event('mousedown'));\n\t }\n\t\n\t function handleKeyDown(e) {\n\t trigger(self.onKeyDown, {\n\t row: activeRow,\n\t cell: activeCell\n\t }, e);\n\t var handled = e.isImmediatePropagationStopped();\n\t\n\t if (!handled) {\n\t if (!e.shiftKey && !e.altKey && !e.ctrlKey) {\n\t if (e.which == 27) {\n\t if (!getEditorLock().isActive()) {\n\t return; // no editing mode to cancel, allow bubbling and default processing (exit without cancelling the event)\n\t }\n\t cancelEditAndSetFocus();\n\t } else if (e.which == 34) {\n\t navigatePageDown();\n\t handled = true;\n\t } else if (e.which == 33) {\n\t navigatePageUp();\n\t handled = true;\n\t } else if (e.which == 37) {\n\t handled = navigateLeft();\n\t } else if (e.which == 39) {\n\t handled = navigateRight();\n\t } else if (e.which == 38) {\n\t handled = navigateUp();\n\t } else if (e.which == 40) {\n\t handled = navigateDown();\n\t } else if (e.which == 9) {\n\t handled = navigateNext();\n\t } else if (e.which == 13) {\n\t if (options.editable) {\n\t if (currentEditor) {\n\t // adding new row\n\t if (activeRow === getDataLength()) {\n\t navigateDown();\n\t } else {\n\t commitEditAndSetFocus();\n\t }\n\t } else {\n\t if (getEditorLock().commitCurrentEdit()) {\n\t makeActiveCellEditable();\n\t }\n\t }\n\t }\n\t handled = true;\n\t }\n\t } else if (e.which == 9 && e.shiftKey && !e.ctrlKey && !e.altKey) {\n\t handled = navigatePrev();\n\t }\n\t }\n\t\n\t if (handled) {\n\t // the event has been handled so don't let parent element (bubbling/propagation) or browser (default) handle it\n\t e.stopPropagation();\n\t e.preventDefault();\n\t try {\n\t e.originalEvent.keyCode = 0; // prevent default behaviour for special keys in IE browsers (F3, F5, etc.)\n\t }\n\t // ignore exceptions - setting the original event's keycode throws access denied exception for \"Ctrl\"\n\t // (hitting control key only, nothing else), \"Shift\" (maybe others)\n\t catch (error) {}\n\t }\n\t }\n\t\n\t function handleClick(e) {\n\t if (!currentEditor) {\n\t // if this click resulted in some cell child node getting focus,\n\t // don't steal it back - keyboard events will still bubble up\n\t // IE9+ seems to default DIVs to tabIndex=0 instead of -1, so check for cell clicks directly.\n\t if (e.target != document.activeElement || (0, _jquery2.default)(e.target).hasClass(\"slick-cell\")) {\n\t setFocus();\n\t }\n\t }\n\t\n\t var cell = getCellFromEvent(e);\n\t if (!cell || currentEditor !== null && activeRow == cell.row && activeCell == cell.cell) {\n\t return;\n\t }\n\t\n\t trigger(self.onClick, {\n\t row: cell.row,\n\t cell: cell.cell\n\t }, e);\n\t if (e.isImmediatePropagationStopped()) {\n\t return;\n\t }\n\t\n\t if ((activeCell != cell.cell || activeRow != cell.row) && canCellBeActive(cell.row, cell.cell)) {\n\t if (!getEditorLock().isActive() || getEditorLock().commitCurrentEdit()) {\n\t\n\t scrollRowIntoView(cell.row, false);\n\t setActiveCellInternal(getCellNode(cell.row, cell.cell));\n\t }\n\t }\n\t }\n\t\n\t function handleContextMenu(e) {\n\t var $cell = (0, _jquery2.default)(e.target).closest(\".slick-cell\", $canvas);\n\t if ($cell.length === 0) {\n\t return;\n\t }\n\t\n\t // are we editing this cell?\n\t if (activeCellNode === $cell[0] && currentEditor !== null) {\n\t return;\n\t }\n\t\n\t trigger(self.onContextMenu, {}, e);\n\t }\n\t\n\t function handleDblClick(e) {\n\t var cell = getCellFromEvent(e);\n\t if (!cell || currentEditor !== null && activeRow == cell.row && activeCell == cell.cell) {\n\t return;\n\t }\n\t\n\t trigger(self.onDblClick, {\n\t row: cell.row,\n\t cell: cell.cell\n\t }, e);\n\t if (e.isImmediatePropagationStopped()) {\n\t return;\n\t }\n\t\n\t if (options.editable) {\n\t gotoCell(cell.row, cell.cell, true);\n\t }\n\t }\n\t\n\t function handleHeaderMouseEnter(e) {\n\t trigger(self.onHeaderMouseEnter, {\n\t \"column\": (0, _jquery2.default)(this).data(\"column\")\n\t }, e);\n\t }\n\t\n\t function handleHeaderMouseLeave(e) {\n\t trigger(self.onHeaderMouseLeave, {\n\t \"column\": (0, _jquery2.default)(this).data(\"column\")\n\t }, e);\n\t }\n\t\n\t function handleHeaderContextMenu(e) {\n\t var $header = (0, _jquery2.default)(e.target).closest(\".slick-header-column\", \".slick-header-columns\");\n\t var column = $header && $header.data(\"column\");\n\t trigger(self.onHeaderContextMenu, {\n\t column: column\n\t }, e);\n\t }\n\t\n\t function handleHeaderClick(e) {\n\t var $header = (0, _jquery2.default)(e.target).closest(\".slick-header-column\", \".slick-header-columns\");\n\t var column = $header && $header.data(\"column\");\n\t if (column) {\n\t trigger(self.onHeaderClick, {\n\t column: column\n\t }, e);\n\t }\n\t }\n\t\n\t function handleMouseEnter(e) {\n\t trigger(self.onMouseEnter, {}, e);\n\t }\n\t\n\t function handleMouseLeave(e) {\n\t trigger(self.onMouseLeave, {}, e);\n\t }\n\t\n\t function cellExists(row, cell) {\n\t return !(row < 0 || row >= getDataLength() || cell < 0 || cell >= columns.length);\n\t }\n\t\n\t function getCellFromPoint(x, y) {\n\t var row = getRowFromPosition(y);\n\t var cell = 0;\n\t\n\t var w = 0;\n\t for (var i = 0; i < columns.length && w < x; i++) {\n\t w += columns[i].width;\n\t cell++;\n\t }\n\t\n\t if (cell < 0) {\n\t cell = 0;\n\t }\n\t\n\t return {\n\t row: row,\n\t cell: cell - 1\n\t };\n\t }\n\t\n\t function getCellFromNode(cellNode) {\n\t // read column number from .l CSS class\n\t var cls = /l\\d+/.exec(cellNode.className);\n\t if (!cls) {\n\t throw \"getCellFromNode: cannot get cell - \" + cellNode.className;\n\t }\n\t return parseInt(cls[0].substr(1, cls[0].length - 1), 10);\n\t }\n\t\n\t function getRowFromNode(rowNode) {\n\t for (var row in rowsCache) {\n\t for (var i in rowsCache[row].rowNode) {\n\t if (rowsCache[row].rowNode[i] === rowNode) return row | 0;\n\t }\n\t }return null;\n\t }\n\t\n\t function getFrozenRowOffset(row) {\n\t var offset = hasFrozenRows ? options.frozenBottom ? row >= actualFrozenRow ? h < viewportTopH ? actualFrozenRow * options.rowHeight : h : 0 : row >= actualFrozenRow ? frozenRowsHeight : 0 : 0;\n\t\n\t return offset;\n\t }\n\t\n\t function getCellFromEvent(e) {\n\t var row, cell;\n\t var $cell = (0, _jquery2.default)(e.target).closest(\".slick-cell\", $canvas);\n\t if (!$cell.length) {\n\t return null;\n\t }\n\t\n\t row = getRowFromNode($cell[0].parentNode);\n\t\n\t if (hasFrozenRows) {\n\t\n\t var c = $cell.parents('.grid-canvas').offset();\n\t\n\t var rowOffset = 0;\n\t var isBottom = $cell.parents('.grid-canvas-bottom').length;\n\t\n\t if (isBottom) {\n\t rowOffset = options.frozenBottom ? $canvasTopL.height() : frozenRowsHeight;\n\t }\n\t\n\t row = getCellFromPoint(e.clientX - c.left, e.clientY - c.top + rowOffset + (0, _jquery2.default)(document).scrollTop()).row;\n\t }\n\t\n\t cell = getCellFromNode($cell[0]);\n\t\n\t if (row == null || cell == null) {\n\t return null;\n\t } else {\n\t return {\n\t \"row\": row,\n\t \"cell\": cell\n\t };\n\t }\n\t }\n\t\n\t function getCellNodeBox(row, cell) {\n\t if (!cellExists(row, cell)) {\n\t return null;\n\t }\n\t\n\t var frozenRowOffset = getFrozenRowOffset(row);\n\t\n\t var y1 = getRowTop(row) - frozenRowOffset;\n\t var y2 = y1 + options.rowHeight - 1;\n\t var x1 = 0;\n\t for (var i = 0; i < cell; i++) {\n\t x1 += columns[i].width;\n\t\n\t if (options.frozenColumn == i) {\n\t x1 = 0;\n\t }\n\t }\n\t var x2 = x1 + columns[cell].width;\n\t\n\t return {\n\t top: y1,\n\t left: x1,\n\t bottom: y2,\n\t right: x2\n\t };\n\t }\n\t\n\t //////////////////////////////////////////////////////////////////////////////////////////////\n\t // Cell switching\n\t\n\t function resetActiveCell() {\n\t setActiveCellInternal(null, false);\n\t }\n\t\n\t function setFocus() {\n\t if (tabbingDirection == -1) {\n\t $focusSink[0].focus();\n\t } else {\n\t $focusSink2[0].focus();\n\t }\n\t }\n\t\n\t function scrollCellIntoView(row, cell, doPaging) {\n\t // Don't scroll to frozen cells\n\t if (cell <= options.frozenColumn) {\n\t return;\n\t }\n\t\n\t if (row < actualFrozenRow) {\n\t scrollRowIntoView(row, doPaging);\n\t }\n\t\n\t var colspan = getColspan(row, cell);\n\t var left = columnPosLeft[cell],\n\t right = columnPosRight[cell + (colspan > 1 ? colspan - 1 : 0)],\n\t scrollRight = scrollLeft + $viewportScrollContainerX.width();\n\t\n\t if (left < scrollLeft) {\n\t $viewportScrollContainerX.scrollLeft(left);\n\t handleScroll();\n\t render();\n\t } else if (right > scrollRight) {\n\t $viewportScrollContainerX.scrollLeft(Math.min(left, right - $viewportScrollContainerX[0].clientWidth));\n\t handleScroll();\n\t render();\n\t }\n\t }\n\t\n\t function setActiveCellInternal(newCell, opt_editMode) {\n\t if (activeCellNode !== null) {\n\t makeActiveCellNormal();\n\t (0, _jquery2.default)(activeCellNode).removeClass(\"active\");\n\t if (rowsCache[activeRow]) {\n\t (0, _jquery2.default)(rowsCache[activeRow].rowNode).removeClass(\"active\");\n\t }\n\t }\n\t\n\t var activeCellChanged = activeCellNode !== newCell;\n\t activeCellNode = newCell;\n\t\n\t if (activeCellNode != null) {\n\t var $activeCellNode = (0, _jquery2.default)(activeCellNode);\n\t var $activeCellOffset = $activeCellNode.offset();\n\t\n\t var rowOffset = Math.floor($activeCellNode.parents('.grid-canvas').offset().top);\n\t var isBottom = $activeCellNode.parents('.grid-canvas-bottom').length;\n\t\n\t if (hasFrozenRows && isBottom) {\n\t rowOffset -= options.frozenBottom ? $canvasTopL.height() : frozenRowsHeight;\n\t }\n\t\n\t var cell = getCellFromPoint($activeCellOffset.left, Math.ceil($activeCellOffset.top) - rowOffset);\n\t\n\t activeRow = cell.row;\n\t activeCell = activePosX = activeCell = activePosX = getCellFromNode(activeCellNode[0]);\n\t\n\t $activeCellNode.addClass(\"active\");\n\t if (rowsCache[activeRow]) {\n\t (0, _jquery2.default)(rowsCache[activeRow].rowNode).addClass('active');\n\t }\n\t\n\t if (opt_editMode == null) {\n\t opt_editMode = activeRow == getDataLength() || options.autoEdit;\n\t }\n\t\n\t if (options.editable && opt_editMode && isCellPotentiallyEditable(activeRow, activeCell)) {\n\t clearTimeout(h_editorLoader);\n\t\n\t if (options.asyncEditorLoading) {\n\t h_editorLoader = setTimeout(function () {\n\t makeActiveCellEditable();\n\t }, options.asyncEditorLoadDelay);\n\t } else {\n\t makeActiveCellEditable();\n\t }\n\t }\n\t } else {\n\t activeRow = activeCell = null;\n\t }\n\t\n\t if (activeCellChanged) {\n\t setTimeout(scrollActiveCellIntoView, 50);\n\t trigger(self.onActiveCellChanged, getActiveCell());\n\t }\n\t }\n\t\n\t function clearTextSelection() {\n\t if (document.selection && document.selection.empty) {\n\t try {\n\t //IE fails here if selected element is not in dom\n\t document.selection.empty();\n\t } catch (e) {}\n\t } else if (window.getSelection) {\n\t var sel = window.getSelection();\n\t if (sel && sel.removeAllRanges) {\n\t sel.removeAllRanges();\n\t }\n\t }\n\t }\n\t\n\t function isCellPotentiallyEditable(row, cell) {\n\t var dataLength = getDataLength();\n\t // is the data for this row loaded?\n\t if (row < dataLength && !getDataItem(row)) {\n\t return false;\n\t }\n\t\n\t // are we in the Add New row? can we create new from this cell?\n\t if (columns[cell].cannotTriggerInsert && row >= dataLength) {\n\t return false;\n\t }\n\t\n\t // does this cell have an editor?\n\t if (!getEditor(row, cell)) {\n\t return false;\n\t }\n\t\n\t return true;\n\t }\n\t\n\t function makeActiveCellNormal() {\n\t if (!currentEditor) {\n\t return;\n\t }\n\t trigger(self.onBeforeCellEditorDestroy, {\n\t editor: currentEditor\n\t });\n\t currentEditor.destroy();\n\t currentEditor = null;\n\t\n\t if (activeCellNode) {\n\t var d = getDataItem(activeRow);\n\t (0, _jquery2.default)(activeCellNode).removeClass(\"editable invalid\");\n\t if (d) {\n\t var column = columns[activeCell];\n\t activeCellNode[0].innerHTML = callFormatter(activeRow, activeCell, getDataItemValueForColumn(d, column), column, d);\n\t invalidatePostProcessingResults(activeRow);\n\t }\n\t }\n\t\n\t // if there previously was text selected on a page (such as selected text in the edit cell just removed),\n\t // IE can't set focus to anything else correctly\n\t if (navigator.userAgent.toLowerCase().match(/msie/)) {\n\t clearTextSelection();\n\t }\n\t\n\t getEditorLock().deactivate(editController);\n\t }\n\t\n\t function makeActiveCellEditable(editor) {\n\t if (!activeCellNode) {\n\t return;\n\t }\n\t if (!options.editable) {\n\t throw \"Grid : makeActiveCellEditable : should never get called when options.editable is false\";\n\t }\n\t\n\t // cancel pending async call if there is one\n\t clearTimeout(h_editorLoader);\n\t\n\t if (!isCellPotentiallyEditable(activeRow, activeCell)) {\n\t return;\n\t }\n\t\n\t var columnDef = columns[activeCell];\n\t var item = getDataItem(activeRow);\n\t\n\t if (trigger(self.onBeforeEditCell, {\n\t row: activeRow,\n\t cell: activeCell,\n\t item: item,\n\t column: columnDef\n\t }) === false) {\n\t setFocus();\n\t return;\n\t }\n\t\n\t getEditorLock().activate(editController);\n\t (0, _jquery2.default)(activeCellNode).addClass(\"editable\");\n\t\n\t // don't clear the cell if a custom editor is passed through\n\t if (!editor) {\n\t activeCellNode[0].innerHTML = \"\";\n\t }\n\t\n\t currentEditor = new (editor || getEditor(activeRow, activeCell))({\n\t grid: self,\n\t gridPosition: absBox($container[0]),\n\t position: absBox(activeCellNode[0]),\n\t container: activeCellNode,\n\t column: columnDef,\n\t item: item || {},\n\t commitChanges: commitEditAndSetFocus,\n\t cancelChanges: cancelEditAndSetFocus\n\t });\n\t\n\t if (item) {\n\t currentEditor.loadValue(item);\n\t }\n\t\n\t serializedEditorValue = currentEditor.serializeValue();\n\t\n\t if (currentEditor.position) {\n\t handleActiveCellPositionChange();\n\t }\n\t }\n\t\n\t function commitEditAndSetFocus() {\n\t // if the commit fails, it would do so due to a validation error\n\t // if so, do not steal the focus from the editor\n\t if (getEditorLock().commitCurrentEdit()) {\n\t setFocus();\n\t if (options.autoEdit) {\n\t navigateDown();\n\t }\n\t }\n\t }\n\t\n\t function cancelEditAndSetFocus() {\n\t if (getEditorLock().cancelCurrentEdit()) {\n\t setFocus();\n\t }\n\t }\n\t\n\t function absBox(elem) {\n\t var box = {\n\t top: elem.offsetTop,\n\t left: elem.offsetLeft,\n\t bottom: 0,\n\t right: 0,\n\t width: (0, _jquery2.default)(elem).outerWidth(),\n\t height: (0, _jquery2.default)(elem).outerHeight(),\n\t visible: true\n\t };\n\t box.bottom = box.top + box.height;\n\t box.right = box.left + box.width;\n\t\n\t // walk up the tree\n\t var offsetParent = elem.offsetParent;\n\t while ((elem = elem.parentNode) != document.body) {\n\t if (box.visible && elem.scrollHeight != elem.offsetHeight && (0, _jquery2.default)(elem).css(\"overflowY\") != \"visible\") {\n\t box.visible = box.bottom > elem.scrollTop && box.top < elem.scrollTop + elem.clientHeight;\n\t }\n\t\n\t if (box.visible && elem.scrollWidth != elem.offsetWidth && (0, _jquery2.default)(elem).css(\"overflowX\") != \"visible\") {\n\t box.visible = box.right > elem.scrollLeft && box.left < elem.scrollLeft + elem.clientWidth;\n\t }\n\t\n\t box.left -= elem.scrollLeft;\n\t box.top -= elem.scrollTop;\n\t\n\t if (elem === offsetParent) {\n\t box.left += elem.offsetLeft;\n\t box.top += elem.offsetTop;\n\t offsetParent = elem.offsetParent;\n\t }\n\t\n\t box.bottom = box.top + box.height;\n\t box.right = box.left + box.width;\n\t }\n\t\n\t return box;\n\t }\n\t\n\t function getActiveCellPosition() {\n\t return absBox(activeCellNode[0]);\n\t }\n\t\n\t function getGridPosition() {\n\t return absBox($container[0]);\n\t }\n\t\n\t function handleActiveCellPositionChange() {\n\t if (!activeCellNode) {\n\t return;\n\t }\n\t\n\t trigger(self.onActiveCellPositionChanged, {});\n\t\n\t if (currentEditor) {\n\t var cellBox = getActiveCellPosition();\n\t if (currentEditor.show && currentEditor.hide) {\n\t if (!cellBox.visible) {\n\t currentEditor.hide();\n\t } else {\n\t currentEditor.show();\n\t }\n\t }\n\t\n\t if (currentEditor.position) {\n\t currentEditor.position(cellBox);\n\t }\n\t }\n\t }\n\t\n\t function getCellEditor() {\n\t return currentEditor;\n\t }\n\t\n\t function getActiveCell() {\n\t if (!activeCellNode) {\n\t return null;\n\t } else {\n\t return {\n\t row: activeRow,\n\t cell: activeCell\n\t };\n\t }\n\t }\n\t\n\t function getActiveCellNode() {\n\t return activeCellNode;\n\t }\n\t\n\t function scrollActiveCellIntoView() {\n\t if (activeRow != null && activeCell != null) {\n\t scrollCellIntoView(activeRow, activeCell);\n\t }\n\t }\n\t\n\t function scrollRowIntoView(row, doPaging) {\n\t\n\t if (!hasFrozenRows || !options.frozenBottom && row > actualFrozenRow - 1 || options.frozenBottom && row < actualFrozenRow - 1) {\n\t\n\t var viewportScrollH = $viewportScrollContainerY.height();\n\t\n\t var rowAtTop = row * options.rowHeight;\n\t var rowAtBottom = (row + 1) * options.rowHeight - viewportScrollH + (viewportHasHScroll ? scrollbarDimensions.height : 0);\n\t\n\t // need to page down?\n\t if ((row + 1) * options.rowHeight > scrollTop + viewportScrollH + offset) {\n\t scrollTo(doPaging ? rowAtTop : rowAtBottom);\n\t render();\n\t }\n\t // or page up?\n\t else if (row * options.rowHeight < scrollTop + offset) {\n\t scrollTo(doPaging ? rowAtBottom : rowAtTop);\n\t render();\n\t }\n\t }\n\t }\n\t\n\t function scrollRowToTop(row) {\n\t scrollTo(row * options.rowHeight);\n\t render();\n\t }\n\t\n\t function scrollPage(dir) {\n\t var deltaRows = dir * numVisibleRows;\n\t scrollTo((getRowFromPosition(scrollTop) + deltaRows) * options.rowHeight);\n\t render();\n\t\n\t if (options.enableCellNavigation && activeRow != null) {\n\t var row = activeRow + deltaRows;\n\t var dataLengthIncludingAddNew = getDataLengthIncludingAddNew();\n\t if (row >= dataLengthIncludingAddNew) {\n\t row = dataLengthIncludingAddNew - 1;\n\t }\n\t if (row < 0) {\n\t row = 0;\n\t }\n\t\n\t var cell = 0,\n\t prevCell = null;\n\t var prevActivePosX = activePosX;\n\t while (cell <= activePosX) {\n\t if (canCellBeActive(row, cell)) {\n\t prevCell = cell;\n\t }\n\t cell += getColspan(row, cell);\n\t }\n\t\n\t if (prevCell !== null) {\n\t setActiveCellInternal(getCellNode(row, prevCell));\n\t activePosX = prevActivePosX;\n\t } else {\n\t resetActiveCell();\n\t }\n\t }\n\t }\n\t\n\t function navigatePageDown() {\n\t scrollPage(1);\n\t }\n\t\n\t function navigatePageUp() {\n\t scrollPage(-1);\n\t }\n\t\n\t function getColspan(row, cell) {\n\t var metadata = data.getItemMetadata && data.getItemMetadata(row);\n\t if (!metadata || !metadata.columns) {\n\t return 1;\n\t }\n\t\n\t var columnData = columns[cell] && (metadata.columns[columns[cell].id] || metadata.columns[cell]);\n\t var colspan = columnData && columnData.colspan;\n\t if (colspan === \"*\") {\n\t colspan = columns.length - cell;\n\t } else {\n\t colspan = colspan || 1;\n\t }\n\t\n\t return colspan;\n\t }\n\t\n\t function findFirstFocusableCell(row) {\n\t var cell = 0;\n\t while (cell < columns.length) {\n\t if (canCellBeActive(row, cell)) {\n\t return cell;\n\t }\n\t cell += getColspan(row, cell);\n\t }\n\t return null;\n\t }\n\t\n\t function findLastFocusableCell(row) {\n\t var cell = 0;\n\t var lastFocusableCell = null;\n\t while (cell < columns.length) {\n\t if (canCellBeActive(row, cell)) {\n\t lastFocusableCell = cell;\n\t }\n\t cell += getColspan(row, cell);\n\t }\n\t return lastFocusableCell;\n\t }\n\t\n\t function gotoRight(row, cell, posX) {\n\t if (cell >= columns.length) {\n\t return null;\n\t }\n\t\n\t do {\n\t cell += getColspan(row, cell);\n\t } while (cell < columns.length && !canCellBeActive(row, cell));\n\t\n\t if (cell < columns.length) {\n\t return {\n\t \"row\": row,\n\t \"cell\": cell,\n\t \"posX\": cell\n\t };\n\t }\n\t return null;\n\t }\n\t\n\t function gotoLeft(row, cell, posX) {\n\t if (cell <= 0) {\n\t return null;\n\t }\n\t\n\t var firstFocusableCell = findFirstFocusableCell(row);\n\t if (firstFocusableCell === null || firstFocusableCell >= cell) {\n\t return null;\n\t }\n\t\n\t var prev = {\n\t \"row\": row,\n\t \"cell\": firstFocusableCell,\n\t \"posX\": firstFocusableCell\n\t };\n\t var pos;\n\t while (true) {\n\t pos = gotoRight(prev.row, prev.cell, prev.posX);\n\t if (!pos) {\n\t return null;\n\t }\n\t if (pos.cell >= cell) {\n\t return prev;\n\t }\n\t prev = pos;\n\t }\n\t }\n\t\n\t function gotoDown(row, cell, posX) {\n\t var prevCell;\n\t var dataLengthIncludingAddNew = getDataLengthIncludingAddNew();\n\t while (true) {\n\t if (++row >= dataLengthIncludingAddNew) {\n\t return null;\n\t }\n\t\n\t prevCell = cell = 0;\n\t while (cell <= posX) {\n\t prevCell = cell;\n\t cell += getColspan(row, cell);\n\t }\n\t\n\t if (canCellBeActive(row, prevCell)) {\n\t return {\n\t \"row\": row,\n\t \"cell\": prevCell,\n\t \"posX\": posX\n\t };\n\t }\n\t }\n\t }\n\t\n\t function gotoUp(row, cell, posX) {\n\t var prevCell;\n\t while (true) {\n\t if (--row < 0) {\n\t return null;\n\t }\n\t\n\t prevCell = cell = 0;\n\t while (cell <= posX) {\n\t prevCell = cell;\n\t cell += getColspan(row, cell);\n\t }\n\t\n\t if (canCellBeActive(row, prevCell)) {\n\t return {\n\t \"row\": row,\n\t \"cell\": prevCell,\n\t \"posX\": posX\n\t };\n\t }\n\t }\n\t }\n\t\n\t function gotoNext(row, cell, posX) {\n\t if (row == null && cell == null) {\n\t row = cell = posX = 0;\n\t if (canCellBeActive(row, cell)) {\n\t return {\n\t \"row\": row,\n\t \"cell\": cell,\n\t \"posX\": cell\n\t };\n\t }\n\t }\n\t\n\t var pos = gotoRight(row, cell, posX);\n\t if (pos) {\n\t return pos;\n\t }\n\t\n\t var firstFocusableCell = null;\n\t var dataLengthIncludingAddNew = getDataLengthIncludingAddNew();\n\t while (++row < dataLengthIncludingAddNew) {\n\t firstFocusableCell = findFirstFocusableCell(row);\n\t if (firstFocusableCell !== null) {\n\t return {\n\t \"row\": row,\n\t \"cell\": firstFocusableCell,\n\t \"posX\": firstFocusableCell\n\t };\n\t }\n\t }\n\t return null;\n\t }\n\t\n\t function gotoPrev(row, cell, posX) {\n\t if (row == null && cell == null) {\n\t row = getDataLengthIncludingAddNew() - 1;\n\t cell = posX = columns.length - 1;\n\t if (canCellBeActive(row, cell)) {\n\t return {\n\t \"row\": row,\n\t \"cell\": cell,\n\t \"posX\": cell\n\t };\n\t }\n\t }\n\t\n\t var pos;\n\t var lastSelectableCell;\n\t while (!pos) {\n\t pos = gotoLeft(row, cell, posX);\n\t if (pos) {\n\t break;\n\t }\n\t if (--row < 0) {\n\t return null;\n\t }\n\t\n\t cell = 0;\n\t lastSelectableCell = findLastFocusableCell(row);\n\t if (lastSelectableCell !== null) {\n\t pos = {\n\t \"row\": row,\n\t \"cell\": lastSelectableCell,\n\t \"posX\": lastSelectableCell\n\t };\n\t }\n\t }\n\t return pos;\n\t }\n\t\n\t function navigateRight() {\n\t return navigate(\"right\");\n\t }\n\t\n\t function navigateLeft() {\n\t return navigate(\"left\");\n\t }\n\t\n\t function navigateDown() {\n\t return navigate(\"down\");\n\t }\n\t\n\t function navigateUp() {\n\t return navigate(\"up\");\n\t }\n\t\n\t function navigateNext() {\n\t return navigate(\"next\");\n\t }\n\t\n\t function navigatePrev() {\n\t return navigate(\"prev\");\n\t }\n\t\n\t /**\r\n\t * @param {string} dir Navigation direction.\r\n\t * @return {boolean} Whether navigation resulted in a change of active cell.\r\n\t */\n\t function navigate(dir) {\n\t if (!options.enableCellNavigation) {\n\t return false;\n\t }\n\t\n\t if (!activeCellNode && dir != \"prev\" && dir != \"next\") {\n\t return false;\n\t }\n\t\n\t if (!getEditorLock().commitCurrentEdit()) {\n\t return true;\n\t }\n\t setFocus();\n\t\n\t var tabbingDirections = {\n\t \"up\": -1,\n\t \"down\": 1,\n\t \"left\": -1,\n\t \"right\": 1,\n\t \"prev\": -1,\n\t \"next\": 1\n\t };\n\t tabbingDirection = tabbingDirections[dir];\n\t\n\t var stepFunctions = {\n\t \"up\": gotoUp,\n\t \"down\": gotoDown,\n\t \"left\": gotoLeft,\n\t \"right\": gotoRight,\n\t \"prev\": gotoPrev,\n\t \"next\": gotoNext\n\t };\n\t var stepFn = stepFunctions[dir];\n\t var pos = stepFn(activeRow, activeCell, activePosX);\n\t if (pos) {\n\t if (hasFrozenRows && options.frozenBottom & pos.row == getDataLength()) {\n\t return;\n\t }\n\t\n\t var isAddNewRow = pos.row == getDataLength();\n\t\n\t if (!options.frozenBottom && pos.row >= actualFrozenRow || options.frozenBottom && pos.row < actualFrozenRow) {\n\t scrollCellIntoView(pos.row, pos.cell, !isAddNewRow);\n\t }\n\t\n\t setActiveCellInternal(getCellNode(pos.row, pos.cell));\n\t activePosX = pos.posX;\n\t return true;\n\t } else {\n\t setActiveCellInternal(getCellNode(activeRow, activeCell));\n\t return false;\n\t }\n\t }\n\t\n\t function getCellNode(row, cell) {\n\t if (rowsCache[row]) {\n\t ensureCellNodesInRowsCache(row);\n\t return rowsCache[row].cellNodesByColumnIdx[cell];\n\t }\n\t return null;\n\t }\n\t\n\t function setActiveCell(row, cell) {\n\t if (!initialized) {\n\t return;\n\t }\n\t if (row > getDataLength() || row < 0 || cell >= columns.length || cell < 0) {\n\t return;\n\t }\n\t\n\t if (!options.enableCellNavigation) {\n\t return;\n\t }\n\t\n\t scrollCellIntoView(row, cell, false);\n\t setActiveCellInternal(getCellNode(row, cell), false);\n\t }\n\t\n\t function canCellBeActive(row, cell) {\n\t if (!options.enableCellNavigation || row >= getDataLengthIncludingAddNew() || row < 0 || cell >= columns.length || cell < 0) {\n\t return false;\n\t }\n\t\n\t var rowMetadata = data.getItemMetadata && data.getItemMetadata(row);\n\t if (rowMetadata && typeof rowMetadata.focusable === \"boolean\") {\n\t return rowMetadata.focusable;\n\t }\n\t\n\t var columnMetadata = rowMetadata && rowMetadata.columns;\n\t if (columnMetadata && columns[cell] && columnMetadata[columns[cell].id] && typeof columnMetadata[columns[cell].id].focusable === \"boolean\") {\n\t return columnMetadata[columns[cell].id].focusable;\n\t }\n\t if (columnMetadata && columnMetadata[cell] && typeof columnMetadata[cell].focusable === \"boolean\") {\n\t return columnMetadata[cell].focusable;\n\t }\n\t\n\t return columns[cell] && columns[cell].focusable;\n\t }\n\t\n\t function canCellBeSelected(row, cell) {\n\t if (row >= getDataLength() || row < 0 || cell >= columns.length || cell < 0) {\n\t return false;\n\t }\n\t\n\t var rowMetadata = data.getItemMetadata && data.getItemMetadata(row);\n\t if (rowMetadata && typeof rowMetadata.selectable === \"boolean\") {\n\t return rowMetadata.selectable;\n\t }\n\t\n\t var columnMetadata = rowMetadata && rowMetadata.columns && (rowMetadata.columns[columns[cell].id] || rowMetadata.columns[cell]);\n\t if (columnMetadata && typeof columnMetadata.selectable === \"boolean\") {\n\t return columnMetadata.selectable;\n\t }\n\t\n\t return columns[cell].selectable;\n\t }\n\t\n\t function gotoCell(row, cell, forceEdit) {\n\t if (!initialized) {\n\t return;\n\t }\n\t if (!canCellBeActive(row, cell)) {\n\t return;\n\t }\n\t\n\t if (!getEditorLock().commitCurrentEdit()) {\n\t return;\n\t }\n\t\n\t scrollCellIntoView(row, cell, false);\n\t\n\t var newCell = getCellNode(row, cell);\n\t\n\t // if selecting the 'add new' row, start editing right away\n\t setActiveCellInternal(newCell, forceEdit || row === getDataLength() || options.autoEdit);\n\t\n\t // if no editor was created, set the focus back on the grid\n\t if (!currentEditor) {\n\t setFocus();\n\t }\n\t }\n\t\n\t //////////////////////////////////////////////////////////////////////////////////////////////\n\t // IEditor implementation for the editor lock\n\t\n\t function commitCurrentEdit() {\n\t var item = getDataItem(activeRow);\n\t var column = columns[activeCell];\n\t\n\t if (currentEditor) {\n\t if (currentEditor.isValueChanged()) {\n\t var validationResults = currentEditor.validate();\n\t\n\t if (validationResults.valid) {\n\t if (activeRow < getDataLength()) {\n\t var editCommand = {\n\t row: activeRow,\n\t cell: activeCell,\n\t editor: currentEditor,\n\t serializedValue: currentEditor.serializeValue(),\n\t prevSerializedValue: serializedEditorValue,\n\t execute: function execute() {\n\t this.editor.applyValue(item, this.serializedValue);\n\t updateRow(this.row);\n\t trigger(self.onCellChange, {\n\t row: activeRow,\n\t cell: activeCell,\n\t item: item\n\t });\n\t },\n\t undo: function undo() {\n\t this.editor.applyValue(item, this.prevSerializedValue);\n\t updateRow(this.row);\n\t trigger(self.onCellChange, {\n\t row: activeRow,\n\t cell: activeCell,\n\t item: item\n\t });\n\t }\n\t };\n\t\n\t if (options.editCommandHandler) {\n\t makeActiveCellNormal();\n\t options.editCommandHandler(item, column, editCommand);\n\t } else {\n\t editCommand.execute();\n\t makeActiveCellNormal();\n\t }\n\t } else {\n\t var newItem = {};\n\t currentEditor.applyValue(newItem, currentEditor.serializeValue());\n\t makeActiveCellNormal();\n\t trigger(self.onAddNewRow, {\n\t item: newItem,\n\t column: column\n\t });\n\t }\n\t\n\t // check whether the lock has been re-acquired by event handlers\n\t return !getEditorLock().isActive();\n\t } else {\n\t // Re-add the CSS class to trigger transitions, if any.\n\t (0, _jquery2.default)(activeCellNode).removeClass(\"invalid\");\n\t (0, _jquery2.default)(activeCellNode).width(); // force layout\n\t (0, _jquery2.default)(activeCellNode).addClass(\"invalid\");\n\t\n\t trigger(self.onValidationError, {\n\t editor: currentEditor,\n\t cellNode: activeCellNode,\n\t validationResults: validationResults,\n\t row: activeRow,\n\t cell: activeCell,\n\t column: column\n\t });\n\t\n\t currentEditor.focus();\n\t return false;\n\t }\n\t }\n\t\n\t makeActiveCellNormal();\n\t }\n\t return true;\n\t }\n\t\n\t function cancelCurrentEdit() {\n\t makeActiveCellNormal();\n\t return true;\n\t }\n\t\n\t function rowsToRanges(rows) {\n\t var ranges = [];\n\t var lastCell = columns.length - 1;\n\t for (var i = 0; i < rows.length; i++) {\n\t ranges.push(new _slick2.default.Range(rows[i], 0, rows[i], lastCell));\n\t }\n\t return ranges;\n\t }\n\t\n\t function getSelectedRows() {\n\t if (!selectionModel) {\n\t throw \"Selection model is not set\";\n\t }\n\t return selectedRows;\n\t }\n\t\n\t function setSelectedRows(rows) {\n\t if (!selectionModel) {\n\t throw \"Selection model is not set\";\n\t }\n\t selectionModel.setSelectedRanges(rowsToRanges(rows));\n\t }\n\t\n\t //////////////////////////////////////////////////////////////////////////////////////////////\n\t // Debug\n\t\n\t this.debug = function () {\n\t var s = \"\";\n\t\n\t s += \"\\n\" + \"counter_rows_rendered: \" + counter_rows_rendered;\n\t s += \"\\n\" + \"counter_rows_removed: \" + counter_rows_removed;\n\t s += \"\\n\" + \"renderedRows: \" + renderedRows;\n\t s += \"\\n\" + \"numVisibleRows: \" + numVisibleRows;\n\t s += \"\\n\" + \"maxSupportedCssHeight: \" + maxSupportedCssHeight;\n\t s += \"\\n\" + \"n(umber of pages): \" + n;\n\t s += \"\\n\" + \"(current) page: \" + page;\n\t s += \"\\n\" + \"page height (ph): \" + ph;\n\t s += \"\\n\" + \"vScrollDir: \" + vScrollDir;\n\t\n\t alert(s);\n\t };\n\t\n\t // a debug helper to be able to access private members\n\t this.eval = function (expr) {\n\t return eval(expr);\n\t };\n\t\n\t //////////////////////////////////////////////////////////////////////////////////////////////\n\t // Public API\n\t\n\t _jquery2.default.extend(this, {\n\t \"slickGridVersion\": \"2.1\",\n\t\n\t // Events\n\t \"onScroll\": new _slick2.default.Event(),\n\t \"onSort\": new _slick2.default.Event(),\n\t \"onHeaderMouseEnter\": new _slick2.default.Event(),\n\t \"onHeaderMouseLeave\": new _slick2.default.Event(),\n\t \"onHeaderContextMenu\": new _slick2.default.Event(),\n\t \"onHeaderClick\": new _slick2.default.Event(),\n\t \"onHeaderCellRendered\": new _slick2.default.Event(),\n\t \"onBeforeHeaderCellDestroy\": new _slick2.default.Event(),\n\t \"onHeaderRowCellRendered\": new _slick2.default.Event(),\n\t \"onFooterRowCellRendered\": new _slick2.default.Event(),\n\t \"onBeforeHeaderRowCellDestroy\": new _slick2.default.Event(),\n\t \"onBeforeFooterRowCellDestroy\": new _slick2.default.Event(),\n\t \"onMouseEnter\": new _slick2.default.Event(),\n\t \"onMouseLeave\": new _slick2.default.Event(),\n\t \"onClick\": new _slick2.default.Event(),\n\t \"onDblClick\": new _slick2.default.Event(),\n\t \"onContextMenu\": new _slick2.default.Event(),\n\t \"onKeyDown\": new _slick2.default.Event(),\n\t \"onAddNewRow\": new _slick2.default.Event(),\n\t \"onValidationError\": new _slick2.default.Event(),\n\t \"onViewportChanged\": new _slick2.default.Event(),\n\t \"onColumnsReordered\": new _slick2.default.Event(),\n\t \"onColumnsResized\": new _slick2.default.Event(),\n\t \"onCellChange\": new _slick2.default.Event(),\n\t \"onBeforeEditCell\": new _slick2.default.Event(),\n\t \"onBeforeCellEditorDestroy\": new _slick2.default.Event(),\n\t \"onBeforeDestroy\": new _slick2.default.Event(),\n\t \"onActiveCellChanged\": new _slick2.default.Event(),\n\t \"onActiveCellPositionChanged\": new _slick2.default.Event(),\n\t \"onDragInit\": new _slick2.default.Event(),\n\t \"onDragStart\": new _slick2.default.Event(),\n\t \"onDrag\": new _slick2.default.Event(),\n\t \"onDragEnd\": new _slick2.default.Event(),\n\t \"onSelectedRowsChanged\": new _slick2.default.Event(),\n\t \"onCellCssStylesChanged\": new _slick2.default.Event(),\n\t\n\t // Methods\n\t \"registerPlugin\": registerPlugin,\n\t \"unregisterPlugin\": unregisterPlugin,\n\t \"getColumns\": getColumns,\n\t \"setColumns\": setColumns,\n\t \"getColumnIndex\": getColumnIndex,\n\t \"updateColumnHeader\": updateColumnHeader,\n\t \"setSortColumn\": setSortColumn,\n\t \"setSortColumns\": setSortColumns,\n\t \"getSortColumns\": getSortColumns,\n\t \"autosizeColumns\": autosizeColumns,\n\t \"getOptions\": getOptions,\n\t \"setOptions\": setOptions,\n\t \"getData\": getData,\n\t \"getDataLength\": getDataLength,\n\t \"getDataItem\": getDataItem,\n\t \"setData\": setData,\n\t \"getSelectionModel\": getSelectionModel,\n\t \"setSelectionModel\": setSelectionModel,\n\t \"getSelectedRows\": getSelectedRows,\n\t \"setSelectedRows\": setSelectedRows,\n\t \"getContainerNode\": getContainerNode,\n\t\n\t \"render\": render,\n\t \"invalidate\": invalidate,\n\t \"invalidateRow\": invalidateRow,\n\t \"invalidateRows\": invalidateRows,\n\t \"invalidateAllRows\": invalidateAllRows,\n\t \"updateCell\": updateCell,\n\t \"updateRow\": updateRow,\n\t \"getViewport\": getVisibleRange,\n\t \"getRenderedRange\": getRenderedRange,\n\t \"resizeCanvas\": resizeCanvas,\n\t \"updateRowCount\": updateRowCount,\n\t \"scrollRowIntoView\": scrollRowIntoView,\n\t \"scrollRowToTop\": scrollRowToTop,\n\t \"scrollCellIntoView\": scrollCellIntoView,\n\t \"getCanvasNode\": getCanvasNode,\n\t \"getCanvases\": getCanvases,\n\t \"getActiveCanvasNode\": getActiveCanvasNode,\n\t \"setActiveCanvasNode\": setActiveCanvasNode,\n\t \"getViewportNode\": getViewportNode,\n\t \"getActiveViewportNode\": getActiveViewportNode,\n\t \"setActiveViewportNode\": setActiveViewportNode,\n\t \"focus\": setFocus,\n\t\n\t \"getCellFromPoint\": getCellFromPoint,\n\t \"getCellFromEvent\": getCellFromEvent,\n\t \"getActiveCell\": getActiveCell,\n\t \"setActiveCell\": setActiveCell,\n\t \"getActiveCellNode\": getActiveCellNode,\n\t \"getActiveCellPosition\": getActiveCellPosition,\n\t \"resetActiveCell\": resetActiveCell,\n\t \"editActiveCell\": makeActiveCellEditable,\n\t \"getCellEditor\": getCellEditor,\n\t \"getCellNode\": getCellNode,\n\t \"getCellNodeBox\": getCellNodeBox,\n\t \"canCellBeSelected\": canCellBeSelected,\n\t \"canCellBeActive\": canCellBeActive,\n\t \"navigatePrev\": navigatePrev,\n\t \"navigateNext\": navigateNext,\n\t \"navigateUp\": navigateUp,\n\t \"navigateDown\": navigateDown,\n\t \"navigateLeft\": navigateLeft,\n\t \"navigateRight\": navigateRight,\n\t \"navigatePageUp\": navigatePageUp,\n\t \"navigatePageDown\": navigatePageDown,\n\t \"gotoCell\": gotoCell,\n\t \"getTopPanel\": getTopPanel,\n\t \"setTopPanelVisibility\": setTopPanelVisibility,\n\t \"setHeaderRowVisibility\": setHeaderRowVisibility,\n\t \"getHeaderRow\": getHeaderRow,\n\t \"getHeaderRowColumn\": getHeaderRowColumn,\n\t \"setFooterRowVisibility\": setFooterRowVisibility,\n\t \"getFooterRow\": getFooterRow,\n\t \"getFooterRowColumn\": getFooterRowColumn,\n\t \"getGridPosition\": getGridPosition,\n\t \"flashCell\": flashCell,\n\t \"addCellCssStyles\": addCellCssStyles,\n\t \"setCellCssStyles\": setCellCssStyles,\n\t \"removeCellCssStyles\": removeCellCssStyles,\n\t \"getCellCssStyles\": getCellCssStyles,\n\t \"getFrozenRowOffset\": getFrozenRowOffset,\n\t\n\t \"init\": finishInitialization,\n\t \"destroy\": destroy,\n\t\n\t // IEditor implementation\n\t \"getEditorLock\": getEditorLock,\n\t \"getEditController\": getEditController\n\t });\n\t\n\t init();\n\t}\n\n/***/ }),\n/* 27 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _slick = __webpack_require__(1);\n\t\n\tvar _slick2 = _interopRequireDefault(_slick);\n\t\n\tvar _jquery = __webpack_require__(2);\n\t\n\tvar _jquery2 = _interopRequireDefault(_jquery);\n\t\n\tvar _slick3 = __webpack_require__(31);\n\t\n\tvar _slick4 = _interopRequireDefault(_slick3);\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\t\n\tvar Aggregators = {\n\t Avg: AvgAggregator,\n\t Min: MinAggregator,\n\t Max: MaxAggregator,\n\t Sum: SumAggregator\n\t};\n\t\n\tvar Data = {\n\t DataView: DataView,\n\t GroupMetaDataProvider: _slick4.default,\n\t Aggregators: Aggregators\n\t};\n\t\n\texports.default = Data;\n\t\n\t/** *\r\n\t * A sample Model implementation.\r\n\t * Provides a filtered view of the underlying data.\r\n\t *\r\n\t * Relies on the data item having an \"id\" property uniquely identifying it.\r\n\t */\n\t\n\tfunction DataView(options) {\n\t var self = this;\n\t\n\t var defaults = {\n\t groupItemMetadataProvider: null,\n\t inlineFilters: false\n\t };\n\t\n\t // private\n\t var idProperty = 'id'; // property holding a unique row id\n\t var items = []; // data by index\n\t var rows = []; // data by row\n\t var idxById = {}; // indexes by id\n\t var rowsById = null; // rows by id; lazy-calculated\n\t var filter = null; // filter function\n\t var updated = null; // updated item ids\n\t var suspend = false; // suspends the recalculation\n\t var sortAsc = true;\n\t var fastSortField = void 0;\n\t var sortComparer = void 0;\n\t var refreshHints = {};\n\t var prevRefreshHints = {};\n\t var filterArgs = void 0;\n\t var filteredItems = [];\n\t var compiledFilter = void 0;\n\t var compiledFilterWithCaching = void 0;\n\t var filterCache = [];\n\t\n\t // grouping\n\t var groupingInfoDefaults = {\n\t getter: null,\n\t formatter: null,\n\t comparer: function comparer(a, b) {\n\t return a.value === b.value ? 0 : a.value > b.value ? 1 : -1;\n\t },\n\t predefinedValues: [],\n\t aggregators: [],\n\t aggregateEmpty: false,\n\t aggregateCollapsed: false,\n\t aggregateChildGroups: false,\n\t collapsed: false,\n\t displayTotalsRow: true,\n\t lazyTotalsCalculation: false\n\t };\n\t var groupingInfos = [];\n\t var groups = [];\n\t var toggledGroupsByLevel = [];\n\t var groupingDelimiter = ':|:';\n\t\n\t var pagesize = 0;\n\t var pagenum = 0;\n\t var totalRows = 0;\n\t\n\t // events\n\t var onRowCountChanged = new _slick2.default.Event();\n\t var onRowsChanged = new _slick2.default.Event();\n\t var onPagingInfoChanged = new _slick2.default.Event();\n\t\n\t options = _jquery2.default.extend(true, {}, defaults, options);\n\t\n\t function beginUpdate() {\n\t suspend = true;\n\t }\n\t\n\t function endUpdate() {\n\t suspend = false;\n\t refresh();\n\t }\n\t\n\t function setRefreshHints(hints) {\n\t refreshHints = hints;\n\t }\n\t\n\t function setFilterArgs(args) {\n\t filterArgs = args;\n\t }\n\t\n\t function updateIdxById(startingIndex) {\n\t startingIndex = startingIndex || 0;\n\t var id = void 0;\n\t for (var i = startingIndex, l = items.length; i < l; i++) {\n\t id = items[i][idProperty];\n\t if (id === undefined) {\n\t throw \"Each data element must implement a unique 'id' property\";\n\t }\n\t idxById[id] = i;\n\t }\n\t }\n\t\n\t function ensureIdUniqueness() {\n\t var id = void 0;\n\t for (var i = 0, l = items.length; i < l; i++) {\n\t id = items[i][idProperty];\n\t if (id === undefined || idxById[id] !== i) {\n\t throw \"Each data element must implement a unique 'id' property\";\n\t }\n\t }\n\t }\n\t\n\t function getItems() {\n\t return items;\n\t }\n\t\n\t function setItems(data, objectIdProperty) {\n\t if (objectIdProperty !== undefined) {\n\t idProperty = objectIdProperty;\n\t }\n\t items = filteredItems = data;\n\t idxById = {};\n\t updateIdxById();\n\t ensureIdUniqueness();\n\t refresh();\n\t }\n\t\n\t function setPagingOptions(args) {\n\t if (args.pageSize != undefined) {\n\t pagesize = args.pageSize;\n\t pagenum = pagesize ? Math.min(pagenum, Math.max(0, Math.ceil(totalRows / pagesize) - 1)) : 0;\n\t }\n\t\n\t if (args.pageNum != undefined) {\n\t pagenum = Math.min(args.pageNum, Math.max(0, Math.ceil(totalRows / pagesize) - 1));\n\t }\n\t\n\t onPagingInfoChanged.notify(getPagingInfo(), null, self);\n\t\n\t refresh();\n\t }\n\t\n\t function getPagingInfo() {\n\t var totalPages = pagesize ? Math.max(1, Math.ceil(totalRows / pagesize)) : 1;\n\t return { pageSize: pagesize, pageNum: pagenum, totalRows: totalRows, totalPages: totalPages, dataView: self };\n\t }\n\t\n\t function sort(comparer, ascending) {\n\t sortAsc = ascending;\n\t sortComparer = comparer;\n\t fastSortField = null;\n\t if (ascending === false) {\n\t items.reverse();\n\t }\n\t items.sort(comparer);\n\t if (ascending === false) {\n\t items.reverse();\n\t }\n\t idxById = {};\n\t updateIdxById();\n\t refresh();\n\t }\n\t\n\t /** *\r\n\t * Provides a workaround for the extremely slow sorting in IE.\r\n\t * Does a [lexicographic] sort on a give column by temporarily overriding Object.prototype.toString\r\n\t * to return the value of that field and then doing a native Array.sort().\r\n\t */\n\t function fastSort(field, ascending) {\n\t sortAsc = ascending;\n\t fastSortField = field;\n\t sortComparer = null;\n\t var oldToString = Object.prototype.toString;\n\t Object.prototype.toString = typeof field == 'function' ? field : function () {\n\t return this[field];\n\t };\n\t // an extra reversal for descending sort keeps the sort stable\n\t // (assuming a stable native sort implementation, which isn't true in some cases)\n\t if (ascending === false) {\n\t items.reverse();\n\t }\n\t items.sort();\n\t Object.prototype.toString = oldToString;\n\t if (ascending === false) {\n\t items.reverse();\n\t }\n\t idxById = {};\n\t updateIdxById();\n\t refresh();\n\t }\n\t\n\t function reSort() {\n\t if (sortComparer) {\n\t sort(sortComparer, sortAsc);\n\t } else if (fastSortField) {\n\t fastSort(fastSortField, sortAsc);\n\t }\n\t }\n\t\n\t function setFilter(filterFn) {\n\t filter = filterFn;\n\t if (options.inlineFilters) {\n\t compiledFilter = compileFilter();\n\t compiledFilterWithCaching = compileFilterWithCaching();\n\t }\n\t refresh();\n\t }\n\t\n\t function getGrouping() {\n\t return groupingInfos;\n\t }\n\t\n\t function setGrouping(groupingInfo) {\n\t if (!options.groupItemMetadataProvider) {\n\t options.groupItemMetadataProvider = new Data.GroupItemMetadataProvider();\n\t }\n\t\n\t groups = [];\n\t toggledGroupsByLevel = [];\n\t groupingInfo = groupingInfo || [];\n\t groupingInfos = groupingInfo instanceof Array ? groupingInfo : [groupingInfo];\n\t\n\t for (var i = 0; i < groupingInfos.length; i++) {\n\t var gi = groupingInfos[i] = _jquery2.default.extend(true, {}, groupingInfoDefaults, groupingInfos[i]);\n\t gi.getterIsAFn = typeof gi.getter === 'function';\n\t\n\t // pre-compile accumulator loops\n\t gi.compiledAccumulators = [];\n\t var idx = gi.aggregators.length;\n\t while (idx--) {\n\t gi.compiledAccumulators[idx] = compileAccumulatorLoop(gi.aggregators[idx]);\n\t }\n\t\n\t toggledGroupsByLevel[i] = {};\n\t }\n\t\n\t refresh();\n\t }\n\t\n\t /**\r\n\t * @deprecated Please use {@link setGrouping}.\r\n\t */\n\t function groupBy(valueGetter, valueFormatter, sortComparer) {\n\t if (valueGetter == null) {\n\t setGrouping([]);\n\t return;\n\t }\n\t\n\t setGrouping({\n\t getter: valueGetter,\n\t formatter: valueFormatter,\n\t comparer: sortComparer\n\t });\n\t }\n\t\n\t /**\r\n\t * @deprecated Please use {@link setGrouping}.\r\n\t */\n\t function setAggregators(groupAggregators, includeCollapsed) {\n\t if (!groupingInfos.length) {\n\t throw new Error('At least one grouping must be specified before calling setAggregators().');\n\t }\n\t\n\t groupingInfos[0].aggregators = groupAggregators;\n\t groupingInfos[0].aggregateCollapsed = includeCollapsed;\n\t\n\t setGrouping(groupingInfos);\n\t }\n\t\n\t function getItemByIdx(i) {\n\t return items[i];\n\t }\n\t\n\t function getIdxById(id) {\n\t return idxById[id];\n\t }\n\t\n\t function ensureRowsByIdCache() {\n\t if (!rowsById) {\n\t rowsById = {};\n\t for (var i = 0, l = rows.length; i < l; i++) {\n\t rowsById[rows[i][idProperty]] = i;\n\t }\n\t }\n\t }\n\t\n\t function getRowById(id) {\n\t ensureRowsByIdCache();\n\t return rowsById[id];\n\t }\n\t\n\t function getItemById(id) {\n\t return items[idxById[id]];\n\t }\n\t\n\t function mapIdsToRows(idArray) {\n\t var rows = [];\n\t ensureRowsByIdCache();\n\t for (var i = 0, l = idArray.length; i < l; i++) {\n\t var row = rowsById[idArray[i]];\n\t if (row != null) {\n\t rows[rows.length] = row;\n\t }\n\t }\n\t return rows;\n\t }\n\t\n\t function mapRowsToIds(rowArray) {\n\t var ids = [];\n\t for (var i = 0, l = rowArray.length; i < l; i++) {\n\t if (rowArray[i] < rows.length) {\n\t ids[ids.length] = rows[rowArray[i]][idProperty];\n\t }\n\t }\n\t return ids;\n\t }\n\t\n\t function updateItem(id, item) {\n\t if (idxById[id] === undefined || id !== item[idProperty]) {\n\t throw 'Invalid or non-matching id';\n\t }\n\t items[idxById[id]] = item;\n\t if (!updated) {\n\t updated = {};\n\t }\n\t updated[id] = true;\n\t refresh();\n\t }\n\t\n\t function insertItem(insertBefore, item) {\n\t items.splice(insertBefore, 0, item);\n\t updateIdxById(insertBefore);\n\t refresh();\n\t }\n\t\n\t function addItem(item) {\n\t items.push(item);\n\t updateIdxById(items.length - 1);\n\t refresh();\n\t }\n\t\n\t function deleteItem(id) {\n\t var idx = idxById[id];\n\t if (idx === undefined) {\n\t throw 'Invalid id';\n\t }\n\t delete idxById[id];\n\t items.splice(idx, 1);\n\t updateIdxById(idx);\n\t refresh();\n\t }\n\t\n\t function getLength() {\n\t return rows.length;\n\t }\n\t\n\t function getItem(i) {\n\t var item = rows[i];\n\t\n\t // if this is a group row, make sure totals are calculated and update the title\n\t if (item && item.__group && item.totals && !item.totals.initialized) {\n\t var gi = groupingInfos[item.level];\n\t if (!gi.displayTotalsRow) {\n\t calculateTotals(item.totals);\n\t item.title = gi.formatter ? gi.formatter(item) : item.value;\n\t }\n\t }\n\t // if this is a totals row, make sure it's calculated\n\t else if (item && item.__groupTotals && !item.initialized) {\n\t calculateTotals(item);\n\t }\n\t\n\t return item;\n\t }\n\t\n\t function getItemMetadata(i) {\n\t var item = rows[i];\n\t if (item === undefined) {\n\t return null;\n\t }\n\t\n\t // overrides for grouping rows\n\t if (item.__group) {\n\t return options.groupItemMetadataProvider.getGroupRowMetadata(item);\n\t }\n\t\n\t // overrides for totals rows\n\t if (item.__groupTotals) {\n\t return options.groupItemMetadataProvider.getTotalsRowMetadata(item);\n\t }\n\t\n\t return null;\n\t }\n\t\n\t function expandCollapseAllGroups(level, collapse) {\n\t if (level == null) {\n\t for (var i = 0; i < groupingInfos.length; i++) {\n\t toggledGroupsByLevel[i] = {};\n\t groupingInfos[i].collapsed = collapse;\n\t }\n\t } else {\n\t toggledGroupsByLevel[level] = {};\n\t groupingInfos[level].collapsed = collapse;\n\t }\n\t refresh();\n\t }\n\t\n\t /**\r\n\t * @param level {Number} Optional level to collapse. If not specified, applies to all levels.\r\n\t */\n\t function collapseAllGroups(level) {\n\t expandCollapseAllGroups(level, true);\n\t }\n\t\n\t /**\r\n\t * @param level {Number} Optional level to expand. If not specified, applies to all levels.\r\n\t */\n\t function expandAllGroups(level) {\n\t expandCollapseAllGroups(level, false);\n\t }\n\t\n\t function expandCollapseGroup(level, groupingKey, collapse) {\n\t toggledGroupsByLevel[level][groupingKey] = groupingInfos[level].collapsed ^ collapse;\n\t refresh();\n\t }\n\t\n\t /**\r\n\t * @param letArgs Either a Slick.Group's \"groupingKey\" property, or a\r\n\t * letiable argument list of grouping values denoting a unique path to the row. For\r\n\t * example, calling collapseGroup('high', '10%') will collapse the '10%' subgroup of\r\n\t * the 'high' group.\r\n\t */\n\t function collapseGroup(letArgs) {\n\t var args = Array.prototype.slice.call(arguments);\n\t var arg0 = args[0];\n\t if (args.length == 1 && arg0.indexOf(groupingDelimiter) != -1) {\n\t expandCollapseGroup(arg0.split(groupingDelimiter).length - 1, arg0, true);\n\t } else {\n\t expandCollapseGroup(args.length - 1, args.join(groupingDelimiter), true);\n\t }\n\t }\n\t\n\t /**\r\n\t * @param letArgs Either a Slick.Group's \"groupingKey\" property, or a\r\n\t * letiable argument list of grouping values denoting a unique path to the row. For\r\n\t * example, calling expandGroup('high', '10%') will expand the '10%' subgroup of\r\n\t * the 'high' group.\r\n\t */\n\t function expandGroup(letArgs) {\n\t var args = Array.prototype.slice.call(arguments);\n\t var arg0 = args[0];\n\t if (args.length == 1 && arg0.indexOf(groupingDelimiter) != -1) {\n\t expandCollapseGroup(arg0.split(groupingDelimiter).length - 1, arg0, false);\n\t } else {\n\t expandCollapseGroup(args.length - 1, args.join(groupingDelimiter), false);\n\t }\n\t }\n\t\n\t function getGroups() {\n\t return groups;\n\t }\n\t\n\t function extractGroups(rows, parentGroup) {\n\t var group = void 0;\n\t var val = void 0;\n\t var groups = [];\n\t var groupsByVal = {};\n\t var r = void 0;\n\t var level = parentGroup ? parentGroup.level + 1 : 0;\n\t var gi = groupingInfos[level];\n\t\n\t for (var i = 0, l = gi.predefinedValues.length; i < l; i++) {\n\t val = gi.predefinedValues[i];\n\t group = groupsByVal[val];\n\t if (!group) {\n\t group = new _slick2.default.Group();\n\t group.value = val;\n\t group.level = level;\n\t group.groupingKey = (parentGroup ? parentGroup.groupingKey + groupingDelimiter : '') + val;\n\t groups[groups.length] = group;\n\t groupsByVal[val] = group;\n\t }\n\t }\n\t\n\t for (var _i = 0, _l = rows.length; _i < _l; _i++) {\n\t r = rows[_i];\n\t val = gi.getterIsAFn ? gi.getter(r) : r[gi.getter];\n\t group = groupsByVal[val];\n\t if (!group) {\n\t group = new _slick2.default.Group();\n\t group.value = val;\n\t group.level = level;\n\t group.groupingKey = (parentGroup ? parentGroup.groupingKey + groupingDelimiter : '') + val;\n\t groups[groups.length] = group;\n\t groupsByVal[val] = group;\n\t }\n\t\n\t group.rows[group.count++] = r;\n\t }\n\t\n\t if (level < groupingInfos.length - 1) {\n\t for (var _i2 = 0; _i2 < groups.length; _i2++) {\n\t group = groups[_i2];\n\t group.groups = extractGroups(group.rows, group);\n\t }\n\t }\n\t\n\t groups.sort(groupingInfos[level].comparer);\n\t\n\t return groups;\n\t }\n\t\n\t function calculateTotals(totals) {\n\t var group = totals.group;\n\t var gi = groupingInfos[group.level];\n\t var isLeafLevel = group.level == groupingInfos.length;\n\t var agg = void 0,\n\t idx = gi.aggregators.length;\n\t\n\t if (!isLeafLevel && gi.aggregateChildGroups) {\n\t // make sure all the subgroups are calculated\n\t var i = group.groups.length;\n\t while (i--) {\n\t if (!group.groups[i].totals.initialized) {\n\t calculateTotals(group.groups[i].totals);\n\t }\n\t }\n\t }\n\t\n\t while (idx--) {\n\t agg = gi.aggregators[idx];\n\t agg.init();\n\t if (!isLeafLevel && gi.aggregateChildGroups) {\n\t gi.compiledAccumulators[idx].call(agg, group.groups);\n\t } else {\n\t gi.compiledAccumulators[idx].call(agg, group.rows);\n\t }\n\t agg.storeResult(totals);\n\t }\n\t totals.initialized = true;\n\t }\n\t\n\t function addGroupTotals(group) {\n\t var gi = groupingInfos[group.level];\n\t var totals = new _slick2.default.GroupTotals();\n\t totals.group = group;\n\t group.totals = totals;\n\t if (!gi.lazyTotalsCalculation) {\n\t calculateTotals(totals);\n\t }\n\t }\n\t\n\t function addTotals(groups, level) {\n\t level = level || 0;\n\t var gi = groupingInfos[level];\n\t var groupCollapsed = gi.collapsed;\n\t var toggledGroups = toggledGroupsByLevel[level];\n\t var idx = groups.length,\n\t g = void 0;\n\t while (idx--) {\n\t g = groups[idx];\n\t\n\t if (g.collapsed && !gi.aggregateCollapsed) {\n\t continue;\n\t }\n\t\n\t // Do a depth-first aggregation so that parent group aggregators can access subgroup totals.\n\t if (g.groups) {\n\t addTotals(g.groups, level + 1);\n\t }\n\t\n\t if (gi.aggregators.length && (gi.aggregateEmpty || g.rows.length || g.groups && g.groups.length)) {\n\t addGroupTotals(g);\n\t }\n\t\n\t g.collapsed = groupCollapsed ^ toggledGroups[g.groupingKey];\n\t g.title = gi.formatter ? gi.formatter(g) : g.value;\n\t }\n\t }\n\t\n\t function flattenGroupedRows(groups, level) {\n\t level = level || 0;\n\t var gi = groupingInfos[level];\n\t var groupedRows = [],\n\t rows = void 0,\n\t gl = 0,\n\t g = void 0;\n\t for (var i = 0, l = groups.length; i < l; i++) {\n\t g = groups[i];\n\t groupedRows[gl++] = g;\n\t\n\t if (!g.collapsed) {\n\t rows = g.groups ? flattenGroupedRows(g.groups, level + 1) : g.rows;\n\t for (var j = 0, jj = rows.length; j < jj; j++) {\n\t groupedRows[gl++] = rows[j];\n\t }\n\t }\n\t\n\t if (g.totals && gi.displayTotalsRow && (!g.collapsed || gi.aggregateCollapsed)) {\n\t groupedRows[gl++] = g.totals;\n\t }\n\t }\n\t return groupedRows;\n\t }\n\t\n\t function getFunctionInfo(fn) {\n\t var fnRegex = /^function[^(]*\\(([^)]*)\\)\\s*{([\\s\\S]*)}$/;\n\t var matches = fn.toString().match(fnRegex);\n\t return {\n\t params: matches[1].split(','),\n\t body: matches[2]\n\t };\n\t }\n\t\n\t function compileAccumulatorLoop(aggregator) {\n\t var accumulatorInfo = getFunctionInfo(aggregator.accumulate);\n\t var fn = new Function('_items', 'for (let ' + accumulatorInfo.params[0] + ', _i=0, _il=_items.length; _i<_il; _i++) {' + accumulatorInfo.params[0] + ' = _items[_i]; ' + accumulatorInfo.body + '}');\n\t fn.displayName = 'compiledAccumulatorLoop';\n\t return fn;\n\t }\n\t\n\t function compileFilter() {\n\t var filterInfo = getFunctionInfo(filter);\n\t\n\t var filterPath1 = '{ continue _coreloop; }$1';\n\t var filterPath2 = '{ _retval[_idx++] = $item$; continue _coreloop; }$1';\n\t // make some allowances for minification - there's only so far we can go with RegEx\n\t var filterBody = filterInfo.body.replace(/return false\\s*([;}]|\\}|$)/gi, filterPath1).replace(/return!1([;}]|\\}|$)/gi, filterPath1).replace(/return true\\s*([;}]|\\}|$)/gi, filterPath2).replace(/return!0([;}]|\\}|$)/gi, filterPath2).replace(/return ([^;}]+?)\\s*([;}]|$)/gi, '{ if ($1) { _retval[_idx++] = $item$; }; continue _coreloop; }$2');\n\t\n\t // This preserves the function template code after JS compression,\n\t // so that replace() commands still work as expected.\n\t var tpl = [\n\t // \"function(_items, _args) { \",\n\t 'let _retval = [], _idx = 0; ', 'let $item$, $args$ = _args; ', '_coreloop: ', 'for (let _i = 0, _il = _items.length; _i < _il; _i++) { ', '$item$ = _items[_i]; ', '$filter$; ', '} ', 'return _retval; '\n\t // \"}\"\n\t ].join('');\n\t tpl = tpl.replace(/\\$filter\\$/gi, filterBody);\n\t tpl = tpl.replace(/\\$item\\$/gi, filterInfo.params[0]);\n\t tpl = tpl.replace(/\\$args\\$/gi, filterInfo.params[1]);\n\t\n\t var fn = new Function('_items,_args', tpl);\n\t fn.displayName = 'compiledFilter';\n\t\n\t return fn;\n\t }\n\t\n\t function compileFilterWithCaching() {\n\t var filterInfo = getFunctionInfo(filter);\n\t\n\t var filterPath1 = '{ continue _coreloop; }$1';\n\t var filterPath2 = '{ _cache[_i] = true;_retval[_idx++] = $item$; continue _coreloop; }$1';\n\t // make some allowances for minification - there's only so far we can go with RegEx\n\t var filterBody = filterInfo.body.replace(/return false\\s*([;}]|\\}|$)/gi, filterPath1).replace(/return!1([;}]|\\}|$)/gi, filterPath1).replace(/return true\\s*([;}]|\\}|$)/gi, filterPath2).replace(/return!0([;}]|\\}|$)/gi, filterPath2).replace(/return ([^;}]+?)\\s*([;}]|$)/gi, '{ if ((_cache[_i] = $1)) { _retval[_idx++] = $item$; }; continue _coreloop; }$2');\n\t\n\t // This preserves the function template code after JS compression,\n\t // so that replace() commands still work as expected.\n\t var tpl = [\n\t // \"function(_items, _args, _cache) { \",\n\t 'let _retval = [], _idx = 0; ', 'let $item$, $args$ = _args; ', '_coreloop: ', 'for (let _i = 0, _il = _items.length; _i < _il; _i++) { ', '$item$ = _items[_i]; ', 'if (_cache[_i]) { ', '_retval[_idx++] = $item$; ', 'continue _coreloop; ', '} ', '$filter$; ', '} ', 'return _retval; '\n\t // \"}\"\n\t ].join('');\n\t tpl = tpl.replace(/\\$filter\\$/gi, filterBody);\n\t tpl = tpl.replace(/\\$item\\$/gi, filterInfo.params[0]);\n\t tpl = tpl.replace(/\\$args\\$/gi, filterInfo.params[1]);\n\t\n\t var fn = new Function('_items,_args,_cache', tpl);\n\t fn.displayName = 'compiledFilterWithCaching';\n\t return fn;\n\t }\n\t\n\t function uncompiledFilter(items, args) {\n\t var retval = [],\n\t idx = 0;\n\t\n\t for (var i = 0, ii = items.length; i < ii; i++) {\n\t if (filter(items[i], args)) {\n\t retval[idx++] = items[i];\n\t }\n\t }\n\t\n\t return retval;\n\t }\n\t\n\t function uncompiledFilterWithCaching(items, args, cache) {\n\t var retval = [],\n\t idx = 0,\n\t item = void 0;\n\t\n\t for (var i = 0, ii = items.length; i < ii; i++) {\n\t item = items[i];\n\t if (cache[i]) {\n\t retval[idx++] = item;\n\t } else if (filter(item, args)) {\n\t retval[idx++] = item;\n\t cache[i] = true;\n\t }\n\t }\n\t\n\t return retval;\n\t }\n\t\n\t function getFilteredAndPagedItems(items) {\n\t if (filter) {\n\t var batchFilter = options.inlineFilters ? compiledFilter : uncompiledFilter;\n\t var batchFilterWithCaching = options.inlineFilters ? compiledFilterWithCaching : uncompiledFilterWithCaching;\n\t\n\t if (refreshHints.isFilterNarrowing) {\n\t filteredItems = batchFilter(filteredItems, filterArgs);\n\t } else if (refreshHints.isFilterExpanding) {\n\t filteredItems = batchFilterWithCaching(items, filterArgs, filterCache);\n\t } else if (!refreshHints.isFilterUnchanged) {\n\t filteredItems = batchFilter(items, filterArgs);\n\t }\n\t } else {\n\t // special case: if not filtering and not paging, the resulting\n\t // rows collection needs to be a copy so that changes due to sort\n\t // can be caught\n\t filteredItems = pagesize ? items : items.concat();\n\t }\n\t\n\t // get the current page\n\t var paged = void 0;\n\t if (pagesize) {\n\t if (filteredItems.length < pagenum * pagesize) {\n\t pagenum = Math.floor(filteredItems.length / pagesize);\n\t }\n\t paged = filteredItems.slice(pagesize * pagenum, pagesize * pagenum + pagesize);\n\t } else {\n\t paged = filteredItems;\n\t }\n\t\n\t return { totalRows: filteredItems.length, rows: paged };\n\t }\n\t\n\t function getRowDiffs(rows, newRows) {\n\t var item = void 0,\n\t r = void 0,\n\t eitherIsNonData = void 0,\n\t diff = [];\n\t var from = 0,\n\t to = newRows.length;\n\t\n\t if (refreshHints && refreshHints.ignoreDiffsBefore) {\n\t from = Math.max(0, Math.min(newRows.length, refreshHints.ignoreDiffsBefore));\n\t }\n\t\n\t if (refreshHints && refreshHints.ignoreDiffsAfter) {\n\t to = Math.min(newRows.length, Math.max(0, refreshHints.ignoreDiffsAfter));\n\t }\n\t\n\t for (var i = from, rl = rows.length; i < to; i++) {\n\t if (i >= rl) {\n\t diff[diff.length] = i;\n\t } else {\n\t item = newRows[i];\n\t r = rows[i];\n\t\n\t if (groupingInfos.length && (eitherIsNonData = item.__nonDataRow || r.__nonDataRow) && item.__group !== r.__group || item.__group && !item.equals(r) || eitherIsNonData && (\n\t // no good way to compare totals since they are arbitrary DTOs\n\t // deep object comparison is pretty expensive\n\t // always considering them 'dirty' seems easier for the time being\n\t item.__groupTotals || r.__groupTotals) || item[idProperty] != r[idProperty] || updated && updated[item[idProperty]]) {\n\t diff[diff.length] = i;\n\t }\n\t }\n\t }\n\t return diff;\n\t }\n\t\n\t function recalc(_items) {\n\t rowsById = null;\n\t\n\t if (refreshHints.isFilterNarrowing != prevRefreshHints.isFilterNarrowing || refreshHints.isFilterExpanding != prevRefreshHints.isFilterExpanding) {\n\t filterCache = [];\n\t }\n\t\n\t var filteredItems = getFilteredAndPagedItems(_items);\n\t totalRows = filteredItems.totalRows;\n\t var newRows = filteredItems.rows;\n\t\n\t groups = [];\n\t if (groupingInfos.length) {\n\t groups = extractGroups(newRows);\n\t if (groups.length) {\n\t addTotals(groups);\n\t newRows = flattenGroupedRows(groups);\n\t }\n\t }\n\t\n\t var diff = getRowDiffs(rows, newRows);\n\t\n\t rows = newRows;\n\t\n\t return diff;\n\t }\n\t\n\t function refresh() {\n\t if (suspend) {\n\t return;\n\t }\n\t\n\t var countBefore = rows.length;\n\t var totalRowsBefore = totalRows;\n\t\n\t var diff = recalc(items, filter); // pass as direct refs to avoid closure perf hit\n\t\n\t // if the current page is no longer valid, go to last page and recalc\n\t // we suffer a performance penalty here, but the main loop (recalc) remains highly optimized\n\t if (pagesize && totalRows < pagenum * pagesize) {\n\t pagenum = Math.max(0, Math.ceil(totalRows / pagesize) - 1);\n\t diff = recalc(items, filter);\n\t }\n\t\n\t updated = null;\n\t prevRefreshHints = refreshHints;\n\t refreshHints = {};\n\t\n\t if (totalRowsBefore !== totalRows) {\n\t onPagingInfoChanged.notify(getPagingInfo(), null, self);\n\t }\n\t if (countBefore !== rows.length) {\n\t onRowCountChanged.notify({ previous: countBefore, current: rows.length, dataView: self }, null, self);\n\t }\n\t if (diff.length > 0) {\n\t onRowsChanged.notify({ rows: diff, dataView: self }, null, self);\n\t }\n\t }\n\t\n\t /** *\r\n\t * Wires the grid and the DataView together to keep row selection tied to item ids.\r\n\t * This is useful since, without it, the grid only knows about rows, so if the items\r\n\t * move around, the same rows stay selected instead of the selection moving along\r\n\t * with the items.\r\n\t *\r\n\t * NOTE: This doesn't work with cell selection model.\r\n\t *\r\n\t * @param grid {Slick.Grid} The grid to sync selection with.\r\n\t * @param preserveHidden {Boolean} Whether to keep selected items that go out of the\r\n\t * view due to them getting filtered out.\r\n\t * @param preserveHiddenOnSelectionChange {Boolean} Whether to keep selected items\r\n\t * that are currently out of the view (see preserveHidden) as selected when selection\r\n\t * changes.\r\n\t * @return {Slick.Event} An event that notifies when an internal list of selected row ids\r\n\t * changes. This is useful since, in combination with the above two options, it allows\r\n\t * access to the full list selected row ids, and not just the ones visible to the grid.\r\n\t * @method syncGridSelection\r\n\t */\n\t function syncGridSelection(grid, preserveHidden, preserveHiddenOnSelectionChange) {\n\t var self = this;\n\t var inHandler = void 0;\n\t var selectedRowIds = self.mapRowsToIds(grid.getSelectedRows());\n\t var onSelectedRowIdsChanged = new _slick2.default.Event();\n\t\n\t function setSelectedRowIds(rowIds) {\n\t if (selectedRowIds.join(',') == rowIds.join(',')) {\n\t return;\n\t }\n\t\n\t selectedRowIds = rowIds;\n\t\n\t onSelectedRowIdsChanged.notify({\n\t 'grid': grid,\n\t 'ids': selectedRowIds,\n\t 'dataView': self\n\t }, new _slick2.default.EventData(), self);\n\t }\n\t\n\t function update() {\n\t if (selectedRowIds.length > 0) {\n\t inHandler = true;\n\t var selectedRows = self.mapIdsToRows(selectedRowIds);\n\t if (!preserveHidden) {\n\t setSelectedRowIds(self.mapRowsToIds(selectedRows));\n\t }\n\t grid.setSelectedRows(selectedRows);\n\t inHandler = false;\n\t }\n\t }\n\t\n\t grid.onSelectedRowsChanged.subscribe(function (e, args) {\n\t if (inHandler) {\n\t return;\n\t }\n\t var newSelectedRowIds = self.mapRowsToIds(grid.getSelectedRows());\n\t if (!preserveHiddenOnSelectionChange || !grid.getOptions().multiSelect) {\n\t setSelectedRowIds(newSelectedRowIds);\n\t } else {\n\t // keep the ones that are hidden\n\t var existing = _jquery2.default.grep(selectedRowIds, function (id) {\n\t return self.getRowById(id) === undefined;\n\t });\n\t // add the newly selected ones\n\t setSelectedRowIds(existing.concat(newSelectedRowIds));\n\t }\n\t });\n\t\n\t this.onRowsChanged.subscribe(update);\n\t\n\t this.onRowCountChanged.subscribe(update);\n\t\n\t return onSelectedRowIdsChanged;\n\t }\n\t\n\t function syncGridCellCssStyles(grid, key) {\n\t var hashById = void 0;\n\t var inHandler = void 0;\n\t\n\t // since this method can be called after the cell styles have been set,\n\t // get the existing ones right away\n\t storeCellCssStyles(grid.getCellCssStyles(key));\n\t\n\t function storeCellCssStyles(hash) {\n\t hashById = {};\n\t for (var row in hash) {\n\t var id = rows[row][idProperty];\n\t hashById[id] = hash[row];\n\t }\n\t }\n\t\n\t function update() {\n\t if (hashById) {\n\t inHandler = true;\n\t ensureRowsByIdCache();\n\t var newHash = {};\n\t for (var id in hashById) {\n\t var row = rowsById[id];\n\t if (row != undefined) {\n\t newHash[row] = hashById[id];\n\t }\n\t }\n\t grid.setCellCssStyles(key, newHash);\n\t inHandler = false;\n\t }\n\t }\n\t\n\t grid.onCellCssStylesChanged.subscribe(function (e, args) {\n\t if (inHandler) {\n\t return;\n\t }\n\t if (key != args.key) {\n\t return;\n\t }\n\t if (args.hash) {\n\t storeCellCssStyles(args.hash);\n\t }\n\t });\n\t\n\t this.onRowsChanged.subscribe(update);\n\t\n\t this.onRowCountChanged.subscribe(update);\n\t }\n\t\n\t _jquery2.default.extend(this, {\n\t // methods\n\t 'beginUpdate': beginUpdate,\n\t 'endUpdate': endUpdate,\n\t 'setPagingOptions': setPagingOptions,\n\t 'getPagingInfo': getPagingInfo,\n\t 'getItems': getItems,\n\t 'setItems': setItems,\n\t 'setFilter': setFilter,\n\t 'sort': sort,\n\t 'fastSort': fastSort,\n\t 'reSort': reSort,\n\t 'setGrouping': setGrouping,\n\t 'getGrouping': getGrouping,\n\t 'groupBy': groupBy,\n\t 'setAggregators': setAggregators,\n\t 'collapseAllGroups': collapseAllGroups,\n\t 'expandAllGroups': expandAllGroups,\n\t 'collapseGroup': collapseGroup,\n\t 'expandGroup': expandGroup,\n\t 'getGroups': getGroups,\n\t 'getIdxById': getIdxById,\n\t 'getRowById': getRowById,\n\t 'getItemById': getItemById,\n\t 'getItemByIdx': getItemByIdx,\n\t 'mapRowsToIds': mapRowsToIds,\n\t 'mapIdsToRows': mapIdsToRows,\n\t 'setRefreshHints': setRefreshHints,\n\t 'setFilterArgs': setFilterArgs,\n\t 'refresh': refresh,\n\t 'updateItem': updateItem,\n\t 'insertItem': insertItem,\n\t 'addItem': addItem,\n\t 'deleteItem': deleteItem,\n\t 'syncGridSelection': syncGridSelection,\n\t 'syncGridCellCssStyles': syncGridCellCssStyles,\n\t\n\t // data provider methods\n\t 'getLength': getLength,\n\t 'getItem': getItem,\n\t 'getItemMetadata': getItemMetadata,\n\t\n\t // events\n\t 'onRowCountChanged': onRowCountChanged,\n\t 'onRowsChanged': onRowsChanged,\n\t 'onPagingInfoChanged': onPagingInfoChanged\n\t });\n\t}\n\t\n\tfunction AvgAggregator(field) {\n\t this.field_ = field;\n\t\n\t this.init = function () {\n\t this.count_ = 0;\n\t this.nonNullCount_ = 0;\n\t this.sum_ = 0;\n\t };\n\t\n\t this.accumulate = function (item) {\n\t var val = item[this.field_];\n\t this.count_++;\n\t if (val != null && val !== '' && !isNaN(val)) {\n\t this.nonNullCount_++;\n\t this.sum_ += parseFloat(val);\n\t }\n\t };\n\t\n\t this.storeResult = function (groupTotals) {\n\t if (!groupTotals.avg) {\n\t groupTotals.avg = {};\n\t }\n\t if (this.nonNullCount_ != 0) {\n\t groupTotals.avg[this.field_] = this.sum_ / this.nonNullCount_;\n\t }\n\t };\n\t}\n\t\n\tfunction MinAggregator(field) {\n\t this.field_ = field;\n\t\n\t this.init = function () {\n\t this.min_ = null;\n\t };\n\t\n\t this.accumulate = function (item) {\n\t var val = item[this.field_];\n\t if (val != null && val !== '' && !isNaN(val)) {\n\t if (this.min_ == null || val < this.min_) {\n\t this.min_ = val;\n\t }\n\t }\n\t };\n\t\n\t this.storeResult = function (groupTotals) {\n\t if (!groupTotals.min) {\n\t groupTotals.min = {};\n\t }\n\t groupTotals.min[this.field_] = this.min_;\n\t };\n\t}\n\t\n\tfunction MaxAggregator(field) {\n\t this.field_ = field;\n\t\n\t this.init = function () {\n\t this.max_ = null;\n\t };\n\t\n\t this.accumulate = function (item) {\n\t var val = item[this.field_];\n\t if (val != null && val !== '' && !isNaN(val)) {\n\t if (this.max_ == null || val > this.max_) {\n\t this.max_ = val;\n\t }\n\t }\n\t };\n\t\n\t this.storeResult = function (groupTotals) {\n\t if (!groupTotals.max) {\n\t groupTotals.max = {};\n\t }\n\t groupTotals.max[this.field_] = this.max_;\n\t };\n\t}\n\t\n\tfunction SumAggregator(field) {\n\t this.field_ = field;\n\t\n\t this.init = function () {\n\t this.sum_ = null;\n\t };\n\t\n\t this.accumulate = function (item) {\n\t var val = item[this.field_];\n\t if (val != null && val !== '' && !isNaN(val)) {\n\t this.sum_ += parseFloat(val);\n\t }\n\t };\n\t\n\t this.storeResult = function (groupTotals) {\n\t if (!groupTotals.sum) {\n\t groupTotals.sum = {};\n\t }\n\t groupTotals.sum[this.field_] = this.sum_;\n\t };\n\t}\n\n/***/ }),\n/* 28 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _slick = __webpack_require__(1);\n\t\n\tvar _slick2 = _interopRequireDefault(_slick);\n\t\n\tvar _flatpickr = __webpack_require__(32);\n\t\n\tvar _flatpickr2 = _interopRequireDefault(_flatpickr);\n\t\n\tvar _jquery = __webpack_require__(2);\n\t\n\tvar _jquery2 = _interopRequireDefault(_jquery);\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\t\n\tvar keyCode = _slick2.default.keyCode;\n\t\n\t/** *\r\n\t * Contains basic SlickGrid editors.\r\n\t * @module Editors\r\n\t * @namespace Slick\r\n\t */\n\t\n\t//import 'flatpickr/dist/flatpickr.min.css';\n\t\n\tvar Editors = {\n\t Text: TextEditor,\n\t Integer: IntegerEditor,\n\t Float: FloatEditor,\n\t Date: DateEditor,\n\t YesNoSelect: YesNoSelectEditor,\n\t Checkbox: CheckboxEditor,\n\t LongText: LongTextEditor\n\t};\n\t\n\t_slick2.default.Editors = Editors;\n\texports.default = Editors;\n\t\n\t\n\tfunction TextEditor(args) {\n\t var $input = void 0;\n\t var defaultValue = void 0;\n\t\n\t this.init = function () {\n\t $input = (0, _jquery2.default)(\"\").appendTo(args.container).bind('keydown.nav', function (e) {\n\t if (e.keyCode === keyCode.LEFT || e.keyCode === keyCode.RIGHT) {\n\t e.stopImmediatePropagation();\n\t }\n\t }).focus().select();\n\t };\n\t\n\t this.destroy = function () {\n\t $input.remove();\n\t };\n\t\n\t this.focus = function () {\n\t $input.focus();\n\t };\n\t\n\t this.getValue = function () {\n\t return $input.val();\n\t };\n\t\n\t this.setValue = function (val) {\n\t $input.val(val);\n\t };\n\t\n\t this.loadValue = function (item) {\n\t defaultValue = item[args.column.field] || '';\n\t $input.val(defaultValue);\n\t $input[0].defaultValue = defaultValue;\n\t $input.select();\n\t };\n\t\n\t this.serializeValue = function () {\n\t return $input.val();\n\t };\n\t\n\t this.applyValue = function (item, state) {\n\t item[args.column.field] = state;\n\t };\n\t\n\t this.isValueChanged = function () {\n\t return !($input.val() == '' && defaultValue == null) && $input.val() != defaultValue;\n\t };\n\t\n\t this.validate = function () {\n\t var valid = true;\n\t var msg = null;\n\t if (args.column.validator) {\n\t var validationResults = args.column.validator($input.val(), args);\n\t valid = validationResults.valid;\n\t msg = validationResults.msg;\n\t }\n\t\n\t return {\n\t valid: true,\n\t msg: null\n\t };\n\t };\n\t\n\t this.init();\n\t}\n\t\n\tfunction IntegerEditor(args) {\n\t var $input = void 0;\n\t var defaultValue = void 0;\n\t\n\t this.init = function () {\n\t $input = (0, _jquery2.default)(\"\");\n\t\n\t $input.bind('keydown.nav', function (e) {\n\t if (e.keyCode === keyCode.LEFT || e.keyCode === keyCode.RIGHT) {\n\t e.stopImmediatePropagation();\n\t }\n\t });\n\t\n\t $input.appendTo(args.container);\n\t $input.focus().select();\n\t };\n\t\n\t this.destroy = function () {\n\t $input.remove();\n\t };\n\t\n\t this.focus = function () {\n\t $input.focus();\n\t };\n\t\n\t this.loadValue = function (item) {\n\t defaultValue = item[args.column.field];\n\t $input.val(defaultValue);\n\t $input[0].defaultValue = defaultValue;\n\t $input.select();\n\t };\n\t\n\t this.serializeValue = function () {\n\t return parseInt($input.val(), 10) || 0;\n\t };\n\t\n\t this.applyValue = function (item, state) {\n\t item[args.column.field] = state;\n\t };\n\t\n\t this.isValueChanged = function () {\n\t return !($input.val() == '' && defaultValue == null) && $input.val() != defaultValue;\n\t };\n\t\n\t this.validate = function () {\n\t if (isNaN($input.val())) {\n\t return {\n\t valid: false,\n\t msg: 'Please enter a valid integer'\n\t };\n\t }\n\t\n\t if (args.column.validator) {\n\t var validationResults = args.column.validator($input.val());\n\t if (!validationResults.valid) {\n\t return validationResults;\n\t }\n\t }\n\t\n\t return {\n\t valid: true,\n\t msg: null\n\t };\n\t };\n\t\n\t this.init();\n\t}\n\t\n\tfunction FloatEditor(args) {\n\t var $input = void 0;\n\t var defaultValue = void 0;\n\t var scope = this;\n\t\n\t this.init = function () {\n\t $input = (0, _jquery2.default)(\"\");\n\t\n\t $input.bind('keydown.nav', function (e) {\n\t if (e.keyCode === keyCode.LEFT || e.keyCode === keyCode.RIGHT) {\n\t e.stopImmediatePropagation();\n\t }\n\t });\n\t\n\t $input.appendTo(args.container);\n\t $input.focus().select();\n\t };\n\t\n\t this.destroy = function () {\n\t $input.remove();\n\t };\n\t\n\t this.focus = function () {\n\t $input.focus();\n\t };\n\t\n\t function getDecimalPlaces() {\n\t // returns the number of fixed decimal places or null\n\t var rtn = args.column.editorFixedDecimalPlaces;\n\t if (typeof rtn == 'undefined') {\n\t rtn = FloatEditor.DefaultDecimalPlaces;\n\t }\n\t return !rtn && rtn !== 0 ? null : rtn;\n\t }\n\t\n\t this.loadValue = function (item) {\n\t defaultValue = item[args.column.field];\n\t\n\t var decPlaces = getDecimalPlaces();\n\t if (decPlaces !== null && (defaultValue || defaultValue === 0) && defaultValue.toFixed) {\n\t defaultValue = defaultValue.toFixed(decPlaces);\n\t }\n\t\n\t $input.val(defaultValue);\n\t $input[0].defaultValue = defaultValue;\n\t $input.select();\n\t };\n\t\n\t this.serializeValue = function () {\n\t var rtn = parseFloat($input.val()) || 0;\n\t\n\t var decPlaces = getDecimalPlaces();\n\t if (decPlaces !== null && (rtn || rtn === 0) && rtn.toFixed) {\n\t rtn = parseFloat(rtn.toFixed(decPlaces));\n\t }\n\t\n\t return rtn;\n\t };\n\t\n\t this.applyValue = function (item, state) {\n\t item[args.column.field] = state;\n\t };\n\t\n\t this.isValueChanged = function () {\n\t return !($input.val() == '' && defaultValue == null) && $input.val() != defaultValue;\n\t };\n\t\n\t this.validate = function () {\n\t if (isNaN($input.val())) {\n\t return {\n\t valid: false,\n\t msg: 'Please enter a valid number'\n\t };\n\t }\n\t\n\t if (args.column.validator) {\n\t var validationResults = args.column.validator($input.val(), args);\n\t if (!validationResults.valid) {\n\t return validationResults;\n\t }\n\t }\n\t\n\t return {\n\t valid: true,\n\t msg: null\n\t };\n\t };\n\t\n\t this.init();\n\t}\n\t\n\tFloatEditor.DefaultDecimalPlaces = null;\n\t\n\t/**\r\n\t * see https://chmln.github.io/flatpickr/#options - pass as column.options.date = {}\r\n\t * @param args\r\n\t * @constructor\r\n\t */\n\tfunction DateEditor(args) {\n\t var $input = void 0,\n\t flatInstance = void 0,\n\t defaultDate = void 0,\n\t options = args.column.options && args.column.options.date ? args.column.options.date : {};\n\t\n\t this.init = function () {\n\t defaultDate = options.defaultDate = args.item[args.column.field];\n\t\n\t $input = (0, _jquery2.default)('');\n\t $input.appendTo(args.container);\n\t $input.focus().val(defaultDate).select();\n\t flatInstance = (0, _flatpickr2.default)($input[0], options);\n\t };\n\t\n\t this.destroy = function () {\n\t flatInstance.destroy();\n\t $input.remove();\n\t };\n\t\n\t this.show = function () {\n\t flatInstance.open();\n\t flatInstance.positionCalendar();\n\t };\n\t\n\t this.hide = function () {\n\t flatInstance.close();\n\t };\n\t\n\t this.position = function (position) {\n\t //todo: fix how scrolling is affected\n\t flatInstance.positionCalendar();\n\t };\n\t\n\t this.focus = function () {\n\t $input.focus();\n\t };\n\t\n\t this.loadValue = function (item) {\n\t defaultDate = item[args.column.field];\n\t $input.val(defaultDate);\n\t $input.select();\n\t };\n\t\n\t this.serializeValue = function () {\n\t return $input.val();\n\t };\n\t\n\t this.applyValue = function (item, state) {\n\t item[args.column.field] = state;\n\t };\n\t\n\t this.isValueChanged = function () {\n\t return !($input.val() == '' && defaultDate == null) && $input.val() != defaultDate;\n\t };\n\t\n\t this.validate = function () {\n\t if (args.column.validator) {\n\t var validationResults = args.column.validator($input.val(), args);\n\t if (!validationResults.valid) {\n\t return validationResults;\n\t }\n\t }\n\t\n\t return {\n\t valid: true,\n\t msg: null\n\t };\n\t };\n\t\n\t this.init();\n\t}\n\t\n\tfunction YesNoSelectEditor(args) {\n\t var $select = void 0;\n\t var defaultValue = void 0;\n\t var scope = this;\n\t\n\t this.init = function () {\n\t $select = (0, _jquery2.default)(\"\");\n\t $select.appendTo(args.container);\n\t $select.focus();\n\t };\n\t\n\t this.destroy = function () {\n\t $select.remove();\n\t };\n\t\n\t this.focus = function () {\n\t $select.focus();\n\t };\n\t\n\t this.loadValue = function (item) {\n\t $select.val((defaultValue = item[args.column.field]) ? 'yes' : 'no');\n\t $select.select();\n\t };\n\t\n\t this.serializeValue = function () {\n\t return $select.val() == 'yes';\n\t };\n\t\n\t this.applyValue = function (item, state) {\n\t item[args.column.field] = state;\n\t };\n\t\n\t this.isValueChanged = function () {\n\t return $select.val() != defaultValue;\n\t };\n\t\n\t this.validate = function () {\n\t var valid = true;\n\t var msg = null;\n\t if (args.column.validator) {\n\t var validationResults = args.column.validator($select.val(), args);\n\t valid = validationResults.valid;\n\t msg = validationResults.msg;\n\t }\n\t\n\t return {\n\t valid: true,\n\t msg: null\n\t };\n\t };\n\t\n\t this.init();\n\t}\n\t\n\tfunction CheckboxEditor(args) {\n\t var $select = void 0;\n\t var defaultValue = void 0;\n\t var scope = this;\n\t\n\t this.init = function () {\n\t $select = (0, _jquery2.default)(\"\");\n\t $select.appendTo(args.container);\n\t $select.focus();\n\t };\n\t\n\t this.destroy = function () {\n\t $select.remove();\n\t };\n\t\n\t this.focus = function () {\n\t $select.focus();\n\t };\n\t\n\t this.loadValue = function (item) {\n\t defaultValue = !!item[args.column.field];\n\t if (defaultValue) {\n\t $select.prop('checked', true);\n\t } else {\n\t $select.prop('checked', false);\n\t }\n\t };\n\t\n\t this.serializeValue = function () {\n\t return $select.prop('checked');\n\t };\n\t\n\t this.applyValue = function (item, state) {\n\t item[args.column.field] = state;\n\t };\n\t\n\t this.isValueChanged = function () {\n\t return this.serializeValue() !== defaultValue;\n\t };\n\t\n\t this.validate = function () {\n\t var valid = true;\n\t var msg = null;\n\t if (args.column.validator) {\n\t var validationResults = args.column.validator($select.val(), args);\n\t valid = validationResults.valid;\n\t msg = validationResults.msg;\n\t }\n\t\n\t return {\n\t valid: true,\n\t msg: null\n\t };\n\t };\n\t\n\t this.init();\n\t}\n\t\n\tfunction PercentCompleteEditor(args) {\n\t console.error('PercentCompleteEditor is derecated');\n\t}\n\t\n\t/*\r\n\t * An example of a \"detached\" editor.\r\n\t * The UI is added onto document BODY and .position(), .show() and .hide() are implemented.\r\n\t * KeyDown events are also handled to provide handling for Tab, Shift-Tab, Esc and Ctrl-Enter.\r\n\t */\n\tfunction LongTextEditor(args) {\n\t var $input = void 0,\n\t $wrapper = void 0;\n\t var defaultValue = void 0;\n\t var scope = this;\n\t\n\t this.init = function () {\n\t var $container = (0, _jquery2.default)('body');\n\t\n\t $wrapper = (0, _jquery2.default)(\"\").appendTo($container);\n\t $input = (0, _jquery2.default)(\"\").appendTo($wrapper);\n\t\n\t (0, _jquery2.default)(\"
\").appendTo($wrapper);\n\t\n\t $wrapper.find('button:first').bind('click', this.save);\n\t $wrapper.find('button:last').bind('click', this.cancel);\n\t $input.bind('keydown', this.handleKeyDown);\n\t\n\t scope.position(args.position);\n\t $input.focus().select();\n\t };\n\t\n\t this.handleKeyDown = function (e) {\n\t if (e.which == keyCode.ENTER && e.ctrlKey) {\n\t scope.save();\n\t } else if (e.which == keyCode.ESCAPE) {\n\t e.preventDefault();\n\t scope.cancel();\n\t } else if (e.which == keyCode.TAB && e.shiftKey) {\n\t e.preventDefault();\n\t args.grid.navigatePrev();\n\t } else if (e.which == keyCode.TAB) {\n\t e.preventDefault();\n\t args.grid.navigateNext();\n\t }\n\t };\n\t\n\t this.save = function () {\n\t args.commitChanges();\n\t };\n\t\n\t this.cancel = function () {\n\t $input.val(defaultValue);\n\t args.cancelChanges();\n\t };\n\t\n\t this.hide = function () {\n\t $wrapper.hide();\n\t };\n\t\n\t this.show = function () {\n\t $wrapper.show();\n\t };\n\t\n\t this.position = function (position) {\n\t $wrapper.css('top', position.top - 5).css('left', position.left - 5);\n\t };\n\t\n\t this.destroy = function () {\n\t $wrapper.remove();\n\t };\n\t\n\t this.focus = function () {\n\t $input.focus();\n\t };\n\t\n\t this.loadValue = function (item) {\n\t $input.val(defaultValue = item[args.column.field]);\n\t $input.select();\n\t };\n\t\n\t this.serializeValue = function () {\n\t return $input.val();\n\t };\n\t\n\t this.applyValue = function (item, state) {\n\t item[args.column.field] = state;\n\t };\n\t\n\t this.isValueChanged = function () {\n\t return !($input.val() == '' && defaultValue == null) && $input.val() != defaultValue;\n\t };\n\t\n\t this.validate = function () {\n\t var valid = true;\n\t var msg = null;\n\t if (args.column.validator) {\n\t var validationResults = args.column.validator($select.val(), args);\n\t valid = validationResults.valid;\n\t msg = validationResults.msg;\n\t }\n\t\n\t return {\n\t valid: true,\n\t msg: null\n\t };\n\t };\n\t\n\t this.init();\n\t}\n\n/***/ }),\n/* 29 */\n/***/ (function(module, exports) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\tfunction PercentCompleteFormatter(row, cell, value, columnDef, dataContext) {\n\t if (value == null || value === '') {\n\t return '-';\n\t } else if (value < 50) {\n\t return '' + value + '%';\n\t } else {\n\t return '' + value + '%';\n\t }\n\t}\n\t\n\tfunction PercentCompleteBarFormatter(row, cell, value, columnDef, dataContext) {\n\t if (value == null || value === '') {\n\t return '';\n\t }\n\t\n\t var color = void 0;\n\t\n\t if (value < 30) {\n\t color = 'red';\n\t } else if (value < 70) {\n\t color = 'silver';\n\t } else {\n\t color = 'green';\n\t }\n\t\n\t return \"\";\n\t}\n\t\n\tfunction YesNoFormatter(row, cell, value, columnDef, dataContext) {\n\t return value ? 'Yes' : 'No';\n\t}\n\t\n\tfunction CheckmarkFormatter(row, cell, value, columnDef, dataContext) {\n\t return value ? '✔' : '';\n\t}\n\t\n\texports.default = {\n\t PercentComplete: PercentCompleteFormatter,\n\t PercentCompleteBar: PercentCompleteBarFormatter,\n\t YesNo: YesNoFormatter,\n\t Checkmark: CheckmarkFormatter\n\t};\n\n/***/ }),\n/* 30 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _jquery = __webpack_require__(2);\n\t\n\tvar _jquery2 = _interopRequireDefault(_jquery);\n\t\n\tvar _interact = __webpack_require__(5);\n\t\n\tvar _interact2 = _interopRequireDefault(_interact);\n\t\n\tvar _slick = __webpack_require__(1);\n\t\n\tvar _slick2 = _interopRequireDefault(_slick);\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\t\n\t// Slick.Grid globals pretense\n\t_slick2.default.Grid = SlickGrid; /**\r\n\t * @license\r\n\t * (c) 2009-2013 Michael Leibman\r\n\t * michael{dot}leibman{at}gmail{dot}com\r\n\t * http://github.com/mleibman/slickgrid\r\n\t *\r\n\t * Distributed under MIT license.\r\n\t * All rights reserved.\r\n\t *\r\n\t * SlickGrid v2.2\r\n\t *\r\n\t * NOTES:\r\n\t * Cell/row DOM manipulations are done directly bypassing jQuery's DOM manipulation methods.\r\n\t * This increases the speed dramatically, but can only be done safely because there are no event handlers\r\n\t * or data associated with any cell/row DOM nodes. Cell editors must make sure they implement .destroy()\r\n\t * and do proper cleanup.\r\n\t */\n\t\n\texports.default = SlickGrid;\n\t\n\t// shared across all grids on the page\n\t\n\tvar scrollbarDimensions;\n\tvar maxSupportedCssHeight; // browser's breaking point\n\t\n\t// ////////////////////////////////////////////////////////////////////////////////////////////\n\t// SlickGrid class implementation (available as Slick.Grid)\n\t\n\t/**\r\n\t * Creates a new instance of the grid.\r\n\t * @class SlickGrid\r\n\t * @constructor\r\n\t * @param {Node} container Container node to create the grid in.\r\n\t * @param {Array,Object} data An array of objects for databinding.\r\n\t * @param {Array} columns An array of column definitions.\r\n\t * @param {Object} options Grid options.\r\n\t **/\n\tfunction SlickGrid(container, data, columns, options) {\n\t // settings\n\t var defaults = {\n\t explicitInitialization: false,\n\t rowHeight: 25,\n\t defaultColumnWidth: 80,\n\t enableAddRow: false,\n\t leaveSpaceForNewRows: false,\n\t editable: false,\n\t autoEdit: true,\n\t enableCellNavigation: true,\n\t enableColumnReorder: true,\n\t asyncEditorLoading: false,\n\t asyncEditorLoadDelay: 100,\n\t forceFitColumns: false,\n\t enableAsyncPostRender: false,\n\t asyncPostRenderDelay: 50,\n\t enableAsyncPostRenderCleanup: false,\n\t asyncPostRenderCleanupDelay: 40,\n\t autoHeight: false,\n\t editorLock: _slick2.default.GlobalEditorLock,\n\t showHeaderRow: false,\n\t headerRowHeight: 25,\n\t createFooterRow: false,\n\t showFooterRow: false,\n\t footerRowHeight: 25,\n\t showTopPanel: false,\n\t topPanelHeight: 25,\n\t formatterFactory: null,\n\t editorFactory: null,\n\t cellFlashingCssClass: 'flashing',\n\t selectedCellCssClass: 'selected',\n\t multiSelect: true,\n\t enableTextSelectionOnCells: false,\n\t dataItemColumnValueExtractor: null,\n\t fullWidthRows: false,\n\t multiColumnSort: false,\n\t defaultFormatter: defaultFormatter,\n\t forceSyncScrolling: false,\n\t addNewRowCssClass: 'new-row'\n\t };\n\t\n\t var columnDefaults = {\n\t name: '',\n\t resizable: true,\n\t sortable: false,\n\t minWidth: 30,\n\t rerenderOnResize: false,\n\t headerCssClass: null,\n\t defaultSortAsc: true,\n\t focusable: true,\n\t selectable: true\n\t };\n\t\n\t // scroller\n\t var th; // virtual height\n\t var h; // real scrollable height\n\t var ph; // page height\n\t var n; // number of pages\n\t var cj; // \"jumpiness\" coefficient\n\t\n\t var page = 0; // current page\n\t var offset = 0; // current page offset\n\t var vScrollDir = 1;\n\t\n\t // private\n\t var initialized = false;\n\t var $container;\n\t var uid = 'slickgrid_' + Math.round(1000000 * Math.random());\n\t var self = this;\n\t var $focusSink, $focusSink2;\n\t var $headerScroller;\n\t var $headers;\n\t var $headerRow, $headerRowScroller, $headerRowSpacer;\n\t var $footerRow, $footerRowScroller, $footerRowSpacer;\n\t var $topPanelScroller;\n\t var $topPanel;\n\t var $viewport;\n\t var $canvas;\n\t var $style;\n\t var $boundAncestors;\n\t var stylesheet, columnCssRulesL, columnCssRulesR;\n\t var viewportH, viewportW;\n\t var canvasWidth;\n\t var viewportHasHScroll, viewportHasVScroll;\n\t var headerColumnWidthDiff = 0,\n\t headerColumnHeightDiff = 0,\n\t // border+padding\n\t cellWidthDiff = 0,\n\t cellHeightDiff = 0,\n\t jQueryNewWidthBehaviour = false;\n\t var absoluteColumnMinWidth;\n\t\n\t var tabbingDirection = 1;\n\t var activePosX;\n\t var activeRow, activeCell;\n\t var activeCellNode = null;\n\t var currentEditor = null;\n\t var serializedEditorValue;\n\t var editController;\n\t\n\t var rowsCache = {};\n\t var renderedRows = 0;\n\t var numVisibleRows;\n\t var prevScrollTop = 0;\n\t var scrollTop = 0;\n\t var lastRenderedScrollTop = 0;\n\t var lastRenderedScrollLeft = 0;\n\t var prevScrollLeft = 0;\n\t var scrollLeft = 0;\n\t\n\t var selectionModel;\n\t var selectedRows = [];\n\t\n\t var plugins = [];\n\t var cellCssClasses = {};\n\t\n\t var columnsById = {};\n\t var sortColumns = [];\n\t var columnPosLeft = [];\n\t var columnPosRight = [];\n\t\n\t // async call handles\n\t var h_editorLoader = null;\n\t var h_render = null;\n\t var h_postrender = null;\n\t var h_postrenderCleanup = null;\n\t var postProcessedRows = {};\n\t var postProcessToRow = null;\n\t var postProcessFromRow = null;\n\t var postProcessedCleanupQueue = [];\n\t var postProcessgroupId = 0;\n\t\n\t // perf counters\n\t var counter_rows_rendered = 0;\n\t var counter_rows_removed = 0;\n\t\n\t // These two variables work around a bug with inertial scrolling in Webkit/Blink on Mac.\n\t // See http://crbug.com/312427.\n\t var rowNodeFromLastMouseWheelEvent; // this node must not be deleted while inertial scrolling\n\t var zombieRowNodeFromLastMouseWheelEvent; // node that was hidden instead of getting deleted\n\t var zombieRowCacheFromLastMouseWheelEvent; // row cache for above node\n\t var zombieRowPostProcessedFromLastMouseWheelEvent; // post processing references for above node\n\t\n\t // store css attributes if display:none is active in container or parent\n\t var cssShow = { position: 'absolute', visibility: 'hidden', display: 'block' };\n\t var $hiddenParents;\n\t var oldProps = [];\n\t\n\t // ////////////////////////////////////////////////////////////////////////////////////////////\n\t // Initialization\n\t\n\t function init() {\n\t $container = (0, _jquery2.default)(container);\n\t if ($container.length < 1) {\n\t throw new Error('SlickGrid requires a valid container, ' + container + ' does not exist in the DOM.');\n\t }\n\t\n\t cacheCssForHiddenInit();\n\t\n\t // calculate these only once and share between grid instances\n\t maxSupportedCssHeight = maxSupportedCssHeight || getMaxSupportedCssHeight();\n\t scrollbarDimensions = scrollbarDimensions || measureScrollbar();\n\t\n\t options = _jquery2.default.extend({}, defaults, options);\n\t validateAndEnforceOptions();\n\t columnDefaults.width = options.defaultColumnWidth;\n\t\n\t columnsById = {};\n\t for (var i = 0; i < columns.length; i++) {\n\t var m = columns[i] = _jquery2.default.extend({}, columnDefaults, columns[i]);\n\t columnsById[m.id] = i;\n\t if (m.minWidth && m.width < m.minWidth) {\n\t m.width = m.minWidth;\n\t }\n\t if (m.maxWidth && m.width > m.maxWidth) {\n\t m.width = m.maxWidth;\n\t }\n\t }\n\t\n\t editController = {\n\t 'commitCurrentEdit': commitCurrentEdit,\n\t 'cancelCurrentEdit': cancelCurrentEdit\n\t };\n\t\n\t $container.empty().css('overflow', 'hidden').css('outline', 0).addClass(uid).addClass('ui-widget');\n\t\n\t // set up a positioning container if needed\n\t if (!/relative|absolute|fixed/.test($container.css('position'))) {\n\t $container.css('position', 'relative');\n\t }\n\t\n\t $focusSink = (0, _jquery2.default)(\"\").appendTo($container);\n\t\n\t $headerScroller = (0, _jquery2.default)(\"\").appendTo($container);\n\t $headers = (0, _jquery2.default)(\"\").appendTo($headerScroller);\n\t $headers.width(getHeadersWidth());\n\t\n\t $headerRowScroller = (0, _jquery2.default)(\"\").appendTo($container);\n\t $headerRow = (0, _jquery2.default)(\"\").appendTo($headerRowScroller);\n\t $headerRowSpacer = (0, _jquery2.default)(\"\").css('width', getCanvasWidth() + scrollbarDimensions.width + 'px').appendTo($headerRowScroller);\n\t\n\t $topPanelScroller = (0, _jquery2.default)(\"\").appendTo($container);\n\t $topPanel = (0, _jquery2.default)(\"\").appendTo($topPanelScroller);\n\t\n\t if (!options.showTopPanel) {\n\t $topPanelScroller.hide();\n\t }\n\t\n\t if (!options.showHeaderRow) {\n\t $headerRowScroller.hide();\n\t }\n\t\n\t $viewport = (0, _jquery2.default)(\"
\").appendTo($container);\n\t $viewport.css('overflow-y', options.autoHeight ? 'hidden' : 'auto');\n\t\n\t $canvas = (0, _jquery2.default)(\"\").appendTo($viewport);\n\t\n\t if (options.createFooterRow) {\n\t $footerRowScroller = (0, _jquery2.default)(\"\").appendTo($container);\n\t $footerRow = (0, _jquery2.default)(\"\").appendTo($footerRowScroller);\n\t $footerRowSpacer = (0, _jquery2.default)(\"\").css('width', getCanvasWidth() + scrollbarDimensions.width + 'px').appendTo($footerRowScroller);\n\t\n\t if (!options.showFooterRow) {\n\t $footerRowScroller.hide();\n\t }\n\t }\n\t\n\t $focusSink2 = $focusSink.clone().appendTo($container);\n\t\n\t if (!options.explicitInitialization) {\n\t finishInitialization();\n\t }\n\t }\n\t\n\t function finishInitialization() {\n\t if (!initialized) {\n\t initialized = true;\n\t\n\t viewportW = parseFloat(_jquery2.default.css($container[0], 'width', true));\n\t\n\t // header columns and cells may have different padding/border skewing width calculations (box-sizing, hello?)\n\t // calculate the diff so we can set consistent sizes\n\t measureCellPaddingAndBorder();\n\t\n\t // for usability reasons, all text selection in SlickGrid is disabled\n\t // with the exception of input and textarea elements (selection must\n\t // be enabled there so that editors work as expected); note that\n\t // selection in grid cells (grid body) is already unavailable in\n\t // all browsers except IE\n\t disableSelection($headers); // disable all text selection in header (including input and textarea)\n\t\n\t if (!options.enableTextSelectionOnCells) {\n\t // disable text selection in grid cells except in input and textarea elements\n\t // (this is IE-specific, because selectstart event will only fire in IE)\n\t $viewport.bind('selectstart.ui', function (event) {\n\t return (0, _jquery2.default)(event.target).is('input,textarea');\n\t });\n\t }\n\t\n\t updateColumnCaches();\n\t createColumnHeaders();\n\t setupColumnSort();\n\t createCssRules();\n\t resizeCanvas();\n\t bindAncestorScrollEvents();\n\t\n\t $container.bind('resize.slickgrid', resizeCanvas);\n\t $viewport\n\t // .bind(\"click\", handleClick)\n\t .bind('scroll', handleScroll);\n\t $headerScroller.bind('contextmenu', handleHeaderContextMenu).bind('click', handleHeaderClick).delegate('.slick-header-column', 'mouseenter', handleHeaderMouseEnter).delegate('.slick-header-column', 'mouseleave', handleHeaderMouseLeave);\n\t $headerRowScroller.bind('scroll', handleHeaderRowScroll);\n\t\n\t if (options.createFooterRow) {\n\t $footerRowScroller.bind('scroll', handleFooterRowScroll);\n\t }\n\t\n\t $focusSink.add($focusSink2).bind('keydown', handleKeyDown);\n\t $canvas.bind('keydown', handleKeyDown).bind('click', handleClick).bind('dblclick', handleDblClick).bind('contextmenu', handleContextMenu).delegate('.slick-cell', 'mouseenter', handleMouseEnter).delegate('.slick-cell', 'mouseleave', handleMouseLeave);\n\t\n\t // legacy support for drag events\n\t (0, _interact2.default)($canvas[0]).allowFrom('div.slick-cell').draggable({\n\t onmove: handleDrag,\n\t onstart: handleDragStart,\n\t onend: handleDragEnd\n\t }).styleCursor(false);\n\t\n\t // Work around http://crbug.com/312427.\n\t if (navigator.userAgent.toLowerCase().match(/webkit/) && navigator.userAgent.toLowerCase().match(/macintosh/)) {\n\t $canvas.bind('mousewheel', handleMouseWheel);\n\t }\n\t restoreCssFromHiddenInit();\n\t }\n\t }\n\t\n\t function cacheCssForHiddenInit() {\n\t // handle display:none on container or container parents\n\t $hiddenParents = $container.parents().addBack().not(':visible');\n\t $hiddenParents.each(function () {\n\t var old = {};\n\t for (var name in cssShow) {\n\t old[name] = this.style[name];\n\t this.style[name] = cssShow[name];\n\t }\n\t oldProps.push(old);\n\t });\n\t }\n\t\n\t function restoreCssFromHiddenInit() {\n\t // finish handle display:none on container or container parents\n\t // - put values back the way they were\n\t $hiddenParents.each(function (i) {\n\t var old = oldProps[i];\n\t for (var name in cssShow) {\n\t this.style[name] = old[name];\n\t }\n\t });\n\t }\n\t\n\t function registerPlugin(plugin) {\n\t plugins.unshift(plugin);\n\t plugin.init(self);\n\t }\n\t\n\t function unregisterPlugin(plugin) {\n\t for (var i = plugins.length; i >= 0; i--) {\n\t if (plugins[i] === plugin) {\n\t if (plugins[i].destroy) {\n\t plugins[i].destroy();\n\t }\n\t plugins.splice(i, 1);\n\t break;\n\t }\n\t }\n\t }\n\t\n\t function setSelectionModel(model) {\n\t if (selectionModel) {\n\t selectionModel.onSelectedRangesChanged.unsubscribe(handleSelectedRangesChanged);\n\t if (selectionModel.destroy) {\n\t selectionModel.destroy();\n\t }\n\t }\n\t\n\t selectionModel = model;\n\t if (selectionModel) {\n\t selectionModel.init(self);\n\t selectionModel.onSelectedRangesChanged.subscribe(handleSelectedRangesChanged);\n\t }\n\t }\n\t\n\t function getSelectionModel() {\n\t return selectionModel;\n\t }\n\t\n\t function getCanvasNode() {\n\t return $canvas[0];\n\t }\n\t\n\t function measureScrollbar() {\n\t var $c = (0, _jquery2.default)(\"\").appendTo('body');\n\t var dim = {\n\t width: $c.width() - $c[0].clientWidth,\n\t height: $c.height() - $c[0].clientHeight\n\t };\n\t $c.remove();\n\t return dim;\n\t }\n\t\n\t function getHeadersWidth() {\n\t var headersWidth = 0;\n\t for (var i = 0, ii = columns.length; i < ii; i++) {\n\t var width = columns[i].width;\n\t headersWidth += width;\n\t }\n\t headersWidth += scrollbarDimensions.width;\n\t return Math.max(headersWidth, viewportW) + 1000;\n\t }\n\t\n\t function getCanvasWidth() {\n\t var availableWidth = viewportHasVScroll ? viewportW - scrollbarDimensions.width : viewportW;\n\t var rowWidth = 0;\n\t var i = columns.length;\n\t while (i--) {\n\t rowWidth += columns[i].width;\n\t }\n\t return options.fullWidthRows ? Math.max(rowWidth, availableWidth) : rowWidth;\n\t }\n\t\n\t function updateCanvasWidth(forceColumnWidthsUpdate) {\n\t var oldCanvasWidth = canvasWidth;\n\t canvasWidth = getCanvasWidth();\n\t\n\t if (canvasWidth != oldCanvasWidth) {\n\t $canvas.width(canvasWidth);\n\t $headerRow.width(canvasWidth);\n\t if (options.createFooterRow) {\n\t $footerRow.width(canvasWidth);\n\t }\n\t $headers.width(getHeadersWidth());\n\t viewportHasHScroll = canvasWidth > viewportW - scrollbarDimensions.width;\n\t }\n\t\n\t var w = canvasWidth + (viewportHasVScroll ? scrollbarDimensions.width : 0);\n\t $headerRowSpacer.width(w);\n\t if (options.createFooterRow) {\n\t $footerRowSpacer.width(w);\n\t }\n\t\n\t if (canvasWidth != oldCanvasWidth || forceColumnWidthsUpdate) {\n\t applyColumnWidths();\n\t }\n\t }\n\t\n\t function disableSelection($target) {\n\t if ($target && $target.jquery) {\n\t $target.attr('unselectable', 'on').css('MozUserSelect', 'none').bind('selectstart.ui', function () {\n\t return false;\n\t }); // from jquery:ui.core.js 1.7.2\n\t }\n\t }\n\t\n\t function getMaxSupportedCssHeight() {\n\t var supportedHeight = 1000000;\n\t // FF reports the height back but still renders blank after ~6M px\n\t var testUpTo = navigator.userAgent.toLowerCase().match(/firefox/) ? 6000000 : 1000000000;\n\t var div = (0, _jquery2.default)(\"\").appendTo(document.body);\n\t\n\t while (true) {\n\t var test = supportedHeight * 2;\n\t div.css('height', test);\n\t if (test > testUpTo || div.height() !== test) {\n\t break;\n\t } else {\n\t supportedHeight = test;\n\t }\n\t }\n\t\n\t div.remove();\n\t return supportedHeight;\n\t }\n\t\n\t // TODO: this is static. need to handle page mutation.\n\t function bindAncestorScrollEvents() {\n\t var elem = $canvas[0];\n\t while ((elem = elem.parentNode) != document.body && elem != null) {\n\t // bind to scroll containers only\n\t if (elem == $viewport[0] || elem.scrollWidth != elem.clientWidth || elem.scrollHeight != elem.clientHeight) {\n\t var $elem = (0, _jquery2.default)(elem);\n\t if (!$boundAncestors) {\n\t $boundAncestors = $elem;\n\t } else {\n\t $boundAncestors = $boundAncestors.add($elem);\n\t }\n\t $elem.bind('scroll.' + uid, handleActiveCellPositionChange);\n\t }\n\t }\n\t }\n\t\n\t function unbindAncestorScrollEvents() {\n\t if (!$boundAncestors) {\n\t return;\n\t }\n\t $boundAncestors.unbind('scroll.' + uid);\n\t $boundAncestors = null;\n\t }\n\t\n\t function updateColumnHeader(columnId, title, toolTip) {\n\t if (!initialized) {\n\t return;\n\t }\n\t var idx = getColumnIndex(columnId);\n\t if (idx == null) {\n\t return;\n\t }\n\t\n\t var columnDef = columns[idx];\n\t var $header = $headers.children().eq(idx);\n\t if ($header) {\n\t if (title !== undefined) {\n\t columns[idx].name = title;\n\t }\n\t if (toolTip !== undefined) {\n\t columns[idx].toolTip = toolTip;\n\t }\n\t\n\t trigger(self.onBeforeHeaderCellDestroy, {\n\t 'node': $header[0],\n\t 'column': columnDef,\n\t 'grid': self\n\t });\n\t\n\t $header.attr('title', toolTip || '').children().eq(0).html(title);\n\t\n\t trigger(self.onHeaderCellRendered, {\n\t 'node': $header[0],\n\t 'column': columnDef,\n\t 'grid': self\n\t });\n\t }\n\t }\n\t\n\t function getHeaderRow() {\n\t return $headerRow[0];\n\t }\n\t\n\t function getFooterRow() {\n\t return $footerRow[0];\n\t }\n\t\n\t function getHeaderRowColumn(columnId) {\n\t var idx = getColumnIndex(columnId);\n\t var $header = $headerRow.children().eq(idx);\n\t return $header && $header[0];\n\t }\n\t\n\t function getFooterRowColumn(columnId) {\n\t var idx = getColumnIndex(columnId);\n\t var $footer = $footerRow.children().eq(idx);\n\t return $footer && $footer[0];\n\t }\n\t\n\t function createColumnHeaders() {\n\t function onMouseEnter() {\n\t (0, _jquery2.default)(this).addClass('ui-state-hover');\n\t }\n\t\n\t function onMouseLeave() {\n\t (0, _jquery2.default)(this).removeClass('ui-state-hover');\n\t }\n\t\n\t $headers.find('.slick-header-column').each(function () {\n\t var columnDef = (0, _jquery2.default)(this).data('column');\n\t if (columnDef) {\n\t trigger(self.onBeforeHeaderCellDestroy, {\n\t 'node': this,\n\t 'column': columnDef,\n\t 'grid': self\n\t });\n\t }\n\t });\n\t $headers.empty();\n\t $headers.width(getHeadersWidth());\n\t\n\t $headerRow.find('.slick-headerrow-column').each(function () {\n\t var columnDef = (0, _jquery2.default)(this).data('column');\n\t if (columnDef) {\n\t trigger(self.onBeforeHeaderRowCellDestroy, {\n\t 'node': this,\n\t 'column': columnDef,\n\t 'grid': self\n\t });\n\t }\n\t });\n\t $headerRow.empty();\n\t\n\t if (options.createFooterRow) {\n\t $footerRow.find('.slick-footerrow-column').each(function () {\n\t var columnDef = (0, _jquery2.default)(this).data('column');\n\t if (columnDef) {\n\t trigger(self.onBeforeFooterRowCellDestroy, {\n\t 'node': this,\n\t 'column': columnDef\n\t });\n\t }\n\t });\n\t $footerRow.empty();\n\t }\n\t\n\t for (var i = 0; i < columns.length; i++) {\n\t var m = columns[i];\n\t\n\t var header = (0, _jquery2.default)(\"\").html(\"\" + m.name + '').width(m.width - headerColumnWidthDiff).attr('id', '' + uid + m.id).attr('title', m.toolTip || '').data('column', m).addClass(m.headerCssClass || '').appendTo($headers);\n\t\n\t if (options.enableColumnReorder || m.sortable) {\n\t header.on('mouseenter', onMouseEnter).on('mouseleave', onMouseLeave);\n\t }\n\t\n\t if (m.sortable) {\n\t header.addClass('slick-header-sortable');\n\t header.append(\"\");\n\t }\n\t\n\t trigger(self.onHeaderCellRendered, {\n\t 'node': header[0],\n\t 'column': m,\n\t 'grid': self\n\t });\n\t\n\t if (options.showHeaderRow) {\n\t var headerRowCell = (0, _jquery2.default)(\"\").data('column', m).appendTo($headerRow);\n\t\n\t trigger(self.onHeaderRowCellRendered, {\n\t 'node': headerRowCell[0],\n\t 'column': m,\n\t 'grid': self\n\t });\n\t }\n\t if (options.createFooterRow && options.showFooterRow) {\n\t var footerRowCell = (0, _jquery2.default)(\"\").data('column', m).appendTo($footerRow);\n\t\n\t trigger(self.onFooterRowCellRendered, {\n\t 'node': footerRowCell[0],\n\t 'column': m\n\t });\n\t }\n\t }\n\t\n\t setSortColumns(sortColumns);\n\t setupColumnResize();\n\t if (options.enableColumnReorder) {\n\t setupColumnReorder();\n\t }\n\t }\n\t\n\t function setupColumnSort() {\n\t $headers.click(function (e) {\n\t // temporary workaround for a bug in jQuery 1.7.1 (http://bugs.jquery.com/ticket/11328)\n\t e.metaKey = e.metaKey || e.ctrlKey;\n\t\n\t if ((0, _jquery2.default)(e.target).hasClass('slick-resizable-handle')) {\n\t return;\n\t }\n\t\n\t var $col = (0, _jquery2.default)(e.target).closest('.slick-header-column');\n\t if (!$col.length) {\n\t return;\n\t }\n\t\n\t var column = $col.data('column');\n\t if (column.sortable) {\n\t if (!getEditorLock().commitCurrentEdit()) {\n\t return;\n\t }\n\t\n\t var sortOpts = null;\n\t var i = 0;\n\t for (; i < sortColumns.length; i++) {\n\t if (sortColumns[i].columnId == column.id) {\n\t sortOpts = sortColumns[i];\n\t sortOpts.sortAsc = !sortOpts.sortAsc;\n\t break;\n\t }\n\t }\n\t\n\t if (e.metaKey && options.multiColumnSort) {\n\t if (sortOpts) {\n\t sortColumns.splice(i, 1);\n\t }\n\t } else {\n\t if (!e.shiftKey && !e.metaKey || !options.multiColumnSort) {\n\t sortColumns = [];\n\t }\n\t\n\t if (!sortOpts) {\n\t sortOpts = { columnId: column.id, sortAsc: column.defaultSortAsc };\n\t sortColumns.push(sortOpts);\n\t } else if (sortColumns.length == 0) {\n\t sortColumns.push(sortOpts);\n\t }\n\t }\n\t\n\t setSortColumns(sortColumns);\n\t\n\t if (!options.multiColumnSort) {\n\t trigger(self.onSort, {\n\t multiColumnSort: false,\n\t sortCol: column,\n\t sortAsc: sortOpts.sortAsc,\n\t grid: self\n\t }, e);\n\t } else {\n\t trigger(self.onSort, {\n\t multiColumnSort: true,\n\t sortCols: _jquery2.default.map(sortColumns, function (col) {\n\t return { sortCol: columns[getColumnIndex(col.columnId)], sortAsc: col.sortAsc };\n\t }),\n\t grid: self\n\t }, e);\n\t }\n\t }\n\t });\n\t }\n\t\n\t /**\r\n\t * Refactored to use interactjs\r\n\t */\n\t function setupColumnReorder() {\n\t var x = 0;\n\t var delta = 0;\n\t var placeholder = document.createElement('div');\n\t\n\t placeholder.className = 'interact-placeholder';\n\t\n\t (0, _interact2.default)('.slick-header-column').ignoreFrom('.slick-resizable-handle').draggable({\n\t inertia: true,\n\t // keep the element within the area of it's parent\n\t restrict: {\n\t restriction: 'parent',\n\t endOnly: true,\n\t elementRect: { top: 0, left: 0, bottom: 0, right: 0 }\n\t },\n\t // enable autoScroll\n\t autoScroll: true,\n\t axis: 'x',\n\t onstart: function onstart(event) {\n\t x = 0;\n\t delta = event.target.offsetWidth;\n\t\n\t // get old order\n\t $headers.find('.slick-header-column').each(function (index) {\n\t (0, _jquery2.default)(this).data('index', index);\n\t });\n\t\n\t placeholder.style.height = event.target.offsetHeight + 'px';\n\t placeholder.style.width = delta + 'px';\n\t\n\t (0, _jquery2.default)(event.target).after(placeholder).css({\n\t position: 'absolute',\n\t zIndex: 1000,\n\t marginLeft: (0, _jquery2.default)(event.target).position().left\n\t });\n\t },\n\t\n\t onmove: function onmove(event) {\n\t x += event.dx;\n\t event.target.style.transform = 'translate3d(' + x + 'px, -3px, 100px)';\n\t // event.target.style.marginLeft = x + 'px';\n\t },\n\t\n\t onend: function onend(event) {\n\t x = 0;\n\t delta = 0;\n\t (0, _jquery2.default)(event.target).css({\n\t position: 'relative',\n\t zIndex: '',\n\t marginLeft: 0,\n\t transform: 'none'\n\t });\n\t\n\t placeholder.parentNode.removeChild(placeholder);\n\t var newColumns = [];\n\t\n\t $headers.find('.slick-header-column').each(function (index) {\n\t newColumns.push(columns[(0, _jquery2.default)(this).data('index')]);\n\t (0, _jquery2.default)(this).removeData('index');\n\t });\n\t\n\t setColumns(newColumns);\n\t trigger(self.onColumnsReordered, { grid: self });\n\t setupColumnResize();\n\t }\n\t }).dropzone({\n\t accept: '.slick-header-column',\n\t\n\t ondragenter: function ondragenter(event) {\n\t event.target.classList.add('interact-drop-active');\n\t event.relatedTarget.classList.add('interact-can-drop');\n\t },\n\t\n\t ondragleave: function ondragleave(event) {\n\t event.target.classList.remove('interact-drop-active');\n\t event.relatedTarget.classList.remove('interact-can-drop');\n\t },\n\t\n\t ondrop: function ondrop(event) {\n\t event.target.classList.remove('interact-drop-active');\n\t event.relatedTarget.classList.remove('interact-can-drop');\n\t (0, _jquery2.default)(event.target)[x > 0 ? 'after' : 'before'](event.relatedTarget);\n\t }\n\t }).styleCursor(false);\n\t }\n\t\n\t function setupColumnResize() {\n\t var $col, j, c, pageX, columnElements, minPageX, maxPageX, firstResizable, lastResizable;\n\t columnElements = $headers.children();\n\t columnElements.find('.slick-resizable-handle').remove();\n\t columnElements.each(function (i, e) {\n\t if (columns[i].resizable) {\n\t if (firstResizable === undefined) {\n\t firstResizable = i;\n\t }\n\t lastResizable = i;\n\t }\n\t });\n\t if (firstResizable === undefined) {\n\t return;\n\t }\n\t columnElements.each(function (i, element) {\n\t if (i < firstResizable || options.forceFitColumns && i >= lastResizable) {\n\t return;\n\t }\n\t $col = (0, _jquery2.default)(element);\n\t\n\t var $handle = (0, _jquery2.default)(\"\");\n\t $handle.appendTo(element);\n\t\n\t if ($col.data('resizable')) return;\n\t\n\t var activeColumn = columns[i];\n\t if (activeColumn.resizable) {\n\t $col.data('resizable', true);\n\t (0, _interact2.default)(element).resizable({\n\t preserveAspectRatio: false,\n\t edges: { left: true, right: true, bottom: false, top: false }\n\t }).on('resizestart', function (event) {\n\t if (!getEditorLock().commitCurrentEdit()) {\n\t return false;\n\t }\n\t activeColumn.previousWidth = event.rect.width;\n\t event.target.classList.add('slick-header-column-active');\n\t }).on('resizemove', function (event) {\n\t var x = event.dx;\n\t var width = activeColumn.width += x;\n\t\n\t if (activeColumn.minWidth > 0 && activeColumn.minWidth > width) width = activeColumn.minWidth;else if (activeColumn.maxWidth > 0 && activeColumn.maxWidth < width) width = activeColumn.maxWidth;\n\t\n\t activeColumn.width = width;\n\t\n\t if (options.forceFitColumns) {\n\t autosizeColumns();\n\t }\n\t applyColumnHeaderWidths();\n\t if (options.syncColumnCellResize) {\n\t applyColumnWidths();\n\t }\n\t }).on('resizeend', function (event) {\n\t event.target.classList.remove('slick-header-column-active');\n\t invalidateAllRows();\n\t updateCanvasWidth(true);\n\t render();\n\t trigger(self.onColumnsResized, { grid: self });\n\t });\n\t }\n\t });\n\t }\n\t\n\t function getVBoxDelta($el) {\n\t var p = ['borderTopWidth', 'borderBottomWidth', 'paddingTop', 'paddingBottom'];\n\t var delta = 0;\n\t _jquery2.default.each(p, function (n, val) {\n\t delta += parseFloat($el.css(val)) || 0;\n\t });\n\t return delta;\n\t }\n\t\n\t function measureCellPaddingAndBorder() {\n\t var el;\n\t var h = ['borderLeftWidth', 'borderRightWidth', 'paddingLeft', 'paddingRight'];\n\t var v = ['borderTopWidth', 'borderBottomWidth', 'paddingTop', 'paddingBottom'];\n\t\n\t // jquery prior to version 1.8 handles .width setter/getter as a direct css write/read\n\t // jquery 1.8 changed .width to read the true inner element width if box-sizing is set to border-box, and introduced a setter for .outerWidth\n\t // so for equivalent functionality, prior to 1.8 use .width, and after use .outerWidth\n\t var verArray = _jquery2.default.fn.jquery.split('.');\n\t jQueryNewWidthBehaviour = verArray[0] == 1 && verArray[1] >= 8 || verArray[0] >= 2;\n\t\n\t el = (0, _jquery2.default)(\"
-
\").appendTo($headers);\n\t headerColumnWidthDiff = headerColumnHeightDiff = 0;\n\t if (el.css('box-sizing') != 'border-box' && el.css('-moz-box-sizing') != 'border-box' && el.css('-webkit-box-sizing') != 'border-box') {\n\t _jquery2.default.each(h, function (n, val) {\n\t headerColumnWidthDiff += parseFloat(el.css(val)) || 0;\n\t });\n\t _jquery2.default.each(v, function (n, val) {\n\t headerColumnHeightDiff += parseFloat(el.css(val)) || 0;\n\t });\n\t }\n\t el.remove();\n\t\n\t var r = (0, _jquery2.default)(\"\").appendTo($canvas);\n\t el = (0, _jquery2.default)(\"
-
\").appendTo(r);\n\t cellWidthDiff = cellHeightDiff = 0;\n\t if (el.css('box-sizing') != 'border-box' && el.css('-moz-box-sizing') != 'border-box' && el.css('-webkit-box-sizing') != 'border-box') {\n\t _jquery2.default.each(h, function (n, val) {\n\t cellWidthDiff += parseFloat(el.css(val)) || 0;\n\t });\n\t _jquery2.default.each(v, function (n, val) {\n\t cellHeightDiff += parseFloat(el.css(val)) || 0;\n\t });\n\t }\n\t r.remove();\n\t\n\t absoluteColumnMinWidth = Math.max(headerColumnWidthDiff, cellWidthDiff);\n\t }\n\t\n\t function createCssRules() {\n\t $style = (0, _jquery2.default)(\"\").appendTo((0, _jquery2.default)(\"head\"));\n\t var rowHeight = options.rowHeight - cellHeightDiff;\n\t if ($style[0].styleSheet) {\n\t // IE\n\t $style[0].styleSheet.cssText = \"\";\n\t } else {\n\t $style[0].appendChild(document.createTextNode(\"\"));\n\t }\n\t\n\t var sheet = $style[0].sheet;\n\t var index = 0;\n\t addCSSRule(sheet, \".\" + uid + \" .slick-header-column\", \"left: 0;\", index++);\n\t addCSSRule(sheet, \".\" + uid + \" .slick-top-panel\", \"height:\" + options.topPanelHeight + \"px;\", index++);\n\t addCSSRule(sheet, \".\" + uid + \" .slick-headerrow-columns\", \"height:\" + options.headerRowHeight + \"px;\", index++);\n\t addCSSRule(sheet, \".\" + uid + \" .slick-cell\", \"height:\" + rowHeight + \"px;\", index++);\n\t addCSSRule(sheet, \".\" + uid + \" .slick-row\", \"height:\" + options.rowHeight + \"px;\", index++);\n\t\n\t for (var i = 0; i < columns.length; i++) {\n\t addCSSRule(sheet, \".\" + uid + \" .l\" + i, \"\", index++);\n\t addCSSRule(sheet, \".\" + uid + \" .r\" + i, \"\", index++);\n\t }\n\t }\n\t\n\t function addCSSRule(sheet, selector, rules, index) {\n\t if (sheet.insertRule) {\n\t sheet.insertRule(selector + \"{\" + rules + \"}\", index);\n\t } else {\n\t sheet.addRule(selector, rules, index);\n\t }\n\t }\n\t\n\t function getColumnCssRules(idx) {\n\t if (!stylesheet) {\n\t var sheets = document.styleSheets;\n\t for (var i = 0; i < sheets.length; i++) {\n\t if ((sheets[i].ownerNode || sheets[i].owningElement) == $style[0]) {\n\t stylesheet = sheets[i];\n\t break;\n\t }\n\t }\n\t\n\t if (!stylesheet) {\n\t throw new Error('Cannot find stylesheet.');\n\t }\n\t\n\t // find and cache column CSS rules\n\t columnCssRulesL = [];\n\t columnCssRulesR = [];\n\t var cssRules = stylesheet.cssRules || stylesheet.rules;\n\t var matches, columnIdx;\n\t for (var i = 0; i < cssRules.length; i++) {\n\t var selector = cssRules[i].selectorText;\n\t if (matches = /\\.l\\d+/.exec(selector)) {\n\t columnIdx = parseInt(matches[0].substr(2, matches[0].length - 2), 10);\n\t columnCssRulesL[columnIdx] = cssRules[i];\n\t } else if (matches = /\\.r\\d+/.exec(selector)) {\n\t columnIdx = parseInt(matches[0].substr(2, matches[0].length - 2), 10);\n\t columnCssRulesR[columnIdx] = cssRules[i];\n\t }\n\t }\n\t }\n\t\n\t return {\n\t 'left': columnCssRulesL[idx],\n\t 'right': columnCssRulesR[idx]\n\t };\n\t }\n\t\n\t function removeCssRules() {\n\t $style.remove();\n\t stylesheet = null;\n\t }\n\t\n\t function destroy() {\n\t getEditorLock().cancelCurrentEdit();\n\t\n\t trigger(self.onBeforeDestroy, { grid: self });\n\t\n\t var i = plugins.length;\n\t while (i--) {\n\t unregisterPlugin(plugins[i]);\n\t }\n\t\n\t unbindAncestorScrollEvents();\n\t $container.unbind('.slickgrid');\n\t removeCssRules();\n\t\n\t $container.empty().removeClass(uid);\n\t }\n\t\n\t // ////////////////////////////////////////////////////////////////////////////////////////////\n\t // General\n\t\n\t function trigger(evt, args, e) {\n\t e = e || new _slick2.default.EventData();\n\t args = args || {};\n\t args.grid = self;\n\t return evt.notify(args, e, self);\n\t }\n\t\n\t function getEditorLock() {\n\t return options.editorLock;\n\t }\n\t\n\t function getEditController() {\n\t return editController;\n\t }\n\t\n\t function getColumnIndex(id) {\n\t return columnsById[id];\n\t }\n\t\n\t function autosizeColumns() {\n\t var i,\n\t c,\n\t widths = [],\n\t shrinkLeeway = 0,\n\t total = 0,\n\t prevTotal,\n\t availWidth = viewportHasVScroll ? viewportW - scrollbarDimensions.width : viewportW;\n\t\n\t for (i = 0; i < columns.length; i++) {\n\t c = columns[i];\n\t widths.push(c.width);\n\t total += c.width;\n\t if (c.resizable) {\n\t shrinkLeeway += c.width - Math.max(c.minWidth, absoluteColumnMinWidth);\n\t }\n\t }\n\t\n\t // shrink\n\t prevTotal = total;\n\t while (total > availWidth && shrinkLeeway) {\n\t var shrinkProportion = (total - availWidth) / shrinkLeeway;\n\t for (i = 0; i < columns.length && total > availWidth; i++) {\n\t c = columns[i];\n\t var width = widths[i];\n\t if (!c.resizable || width <= c.minWidth || width <= absoluteColumnMinWidth) {\n\t continue;\n\t }\n\t var absMinWidth = Math.max(c.minWidth, absoluteColumnMinWidth);\n\t var shrinkSize = Math.floor(shrinkProportion * (width - absMinWidth)) || 1;\n\t shrinkSize = Math.min(shrinkSize, width - absMinWidth);\n\t total -= shrinkSize;\n\t shrinkLeeway -= shrinkSize;\n\t widths[i] -= shrinkSize;\n\t }\n\t if (prevTotal <= total) {\n\t // avoid infinite loop\n\t break;\n\t }\n\t prevTotal = total;\n\t }\n\t\n\t // grow\n\t prevTotal = total;\n\t while (total < availWidth) {\n\t var growProportion = availWidth / total;\n\t for (i = 0; i < columns.length && total < availWidth; i++) {\n\t c = columns[i];\n\t var currentWidth = widths[i];\n\t var growSize;\n\t\n\t if (!c.resizable || c.maxWidth <= currentWidth) {\n\t growSize = 0;\n\t } else {\n\t growSize = Math.min(Math.floor(growProportion * currentWidth) - currentWidth, c.maxWidth - currentWidth || 1000000) || 1;\n\t }\n\t total += growSize;\n\t widths[i] += total <= availWidth ? growSize : 0;\n\t }\n\t if (prevTotal >= total) {\n\t // avoid infinite loop\n\t break;\n\t }\n\t prevTotal = total;\n\t }\n\t\n\t var reRender = false;\n\t for (i = 0; i < columns.length; i++) {\n\t if (columns[i].rerenderOnResize && columns[i].width != widths[i]) {\n\t reRender = true;\n\t }\n\t columns[i].width = widths[i];\n\t }\n\t\n\t applyColumnHeaderWidths();\n\t updateCanvasWidth(true);\n\t if (reRender) {\n\t invalidateAllRows();\n\t render();\n\t }\n\t }\n\t\n\t function applyColumnHeaderWidths() {\n\t if (!initialized) {\n\t return;\n\t }\n\t var h;\n\t for (var i = 0, headers = $headers.children('[id]'), ii = headers.length; i < ii; i++) {\n\t h = (0, _jquery2.default)(headers[i]);\n\t if (jQueryNewWidthBehaviour) {\n\t if (h.outerWidth() !== columns[i].width) {\n\t h.outerWidth(columns[i].width);\n\t }\n\t } else {\n\t if (h.width() !== columns[i].width - headerColumnWidthDiff) {\n\t h.width(columns[i].width - headerColumnWidthDiff);\n\t }\n\t }\n\t }\n\t\n\t updateColumnCaches();\n\t }\n\t\n\t function applyColumnWidths() {\n\t var x = 0,\n\t w,\n\t rule;\n\t for (var i = 0; i < columns.length; i++) {\n\t w = columns[i].width;\n\t\n\t rule = getColumnCssRules(i);\n\t rule.left.style.left = x + 'px';\n\t rule.right.style.right = canvasWidth - x - w + 'px';\n\t\n\t x += columns[i].width;\n\t }\n\t }\n\t\n\t function setSortColumn(columnId, ascending) {\n\t setSortColumns([{ columnId: columnId, sortAsc: ascending }]);\n\t }\n\t\n\t function setSortColumns(cols) {\n\t sortColumns = cols;\n\t\n\t var headerColumnEls = $headers.children();\n\t headerColumnEls.removeClass('slick-header-column-sorted').find('.slick-sort-indicator').removeClass('slick-sort-indicator-asc slick-sort-indicator-desc');\n\t\n\t _jquery2.default.each(sortColumns, function (i, col) {\n\t if (col.sortAsc == null) {\n\t col.sortAsc = true;\n\t }\n\t var columnIndex = getColumnIndex(col.columnId);\n\t if (columnIndex != null) {\n\t headerColumnEls.eq(columnIndex).addClass('slick-header-column-sorted').find('.slick-sort-indicator').addClass(col.sortAsc ? 'slick-sort-indicator-asc' : 'slick-sort-indicator-desc');\n\t }\n\t });\n\t }\n\t\n\t function getSortColumns() {\n\t return sortColumns;\n\t }\n\t\n\t function handleSelectedRangesChanged(e, ranges) {\n\t selectedRows = [];\n\t var hash = {};\n\t for (var i = 0; i < ranges.length; i++) {\n\t for (var j = ranges[i].fromRow; j <= ranges[i].toRow; j++) {\n\t if (!hash[j]) {\n\t // prevent duplicates\n\t selectedRows.push(j);\n\t hash[j] = {};\n\t }\n\t for (var k = ranges[i].fromCell; k <= ranges[i].toCell; k++) {\n\t if (canCellBeSelected(j, k)) {\n\t hash[j][columns[k].id] = options.selectedCellCssClass;\n\t }\n\t }\n\t }\n\t }\n\t\n\t setCellCssStyles(options.selectedCellCssClass, hash);\n\t\n\t trigger(self.onSelectedRowsChanged, { rows: getSelectedRows(), grid: self }, e);\n\t }\n\t\n\t function getColumns() {\n\t return columns;\n\t }\n\t\n\t function updateColumnCaches() {\n\t // Pre-calculate cell boundaries.\n\t columnPosLeft = [];\n\t columnPosRight = [];\n\t var x = 0;\n\t for (var i = 0, ii = columns.length; i < ii; i++) {\n\t columnPosLeft[i] = x;\n\t columnPosRight[i] = x + columns[i].width;\n\t x += columns[i].width;\n\t }\n\t }\n\t\n\t function setColumns(columnDefinitions) {\n\t columns = columnDefinitions;\n\t\n\t columnsById = {};\n\t for (var i = 0; i < columns.length; i++) {\n\t var m = columns[i] = _jquery2.default.extend({}, columnDefaults, columns[i]);\n\t columnsById[m.id] = i;\n\t if (m.minWidth && m.width < m.minWidth) {\n\t m.width = m.minWidth;\n\t }\n\t if (m.maxWidth && m.width > m.maxWidth) {\n\t m.width = m.maxWidth;\n\t }\n\t }\n\t\n\t updateColumnCaches();\n\t\n\t if (initialized) {\n\t invalidateAllRows();\n\t createColumnHeaders();\n\t removeCssRules();\n\t createCssRules();\n\t resizeCanvas();\n\t applyColumnWidths();\n\t handleScroll();\n\t }\n\t }\n\t\n\t function getOptions() {\n\t return options;\n\t }\n\t\n\t function setOptions(args) {\n\t if (!getEditorLock().commitCurrentEdit()) {\n\t return;\n\t }\n\t\n\t makeActiveCellNormal();\n\t\n\t if (options.enableAddRow !== args.enableAddRow) {\n\t invalidateRow(getDataLength());\n\t }\n\t\n\t options = _jquery2.default.extend(options, args);\n\t validateAndEnforceOptions();\n\t\n\t $viewport.css('overflow-y', options.autoHeight ? 'hidden' : 'auto');\n\t render();\n\t }\n\t\n\t function validateAndEnforceOptions() {\n\t if (options.autoHeight) {\n\t options.leaveSpaceForNewRows = false;\n\t }\n\t }\n\t\n\t function setData(newData, scrollToTop) {\n\t data = newData;\n\t invalidateAllRows();\n\t updateRowCount();\n\t if (scrollToTop) {\n\t scrollTo(0);\n\t }\n\t }\n\t\n\t function getData() {\n\t return data;\n\t }\n\t\n\t function getDataLength() {\n\t if (data.getLength) {\n\t return data.getLength();\n\t } else {\n\t return data.length;\n\t }\n\t }\n\t\n\t function getDataLengthIncludingAddNew() {\n\t return getDataLength() + (options.enableAddRow ? 1 : 0);\n\t }\n\t\n\t function getDataItem(i) {\n\t if (data.getItem) {\n\t return data.getItem(i);\n\t } else {\n\t return data[i];\n\t }\n\t }\n\t\n\t function getTopPanel() {\n\t return $topPanel[0];\n\t }\n\t\n\t function setTopPanelVisibility(visible) {\n\t if (options.showTopPanel != visible) {\n\t options.showTopPanel = visible;\n\t if (visible) {\n\t $topPanelScroller.slideDown('fast', resizeCanvas);\n\t } else {\n\t $topPanelScroller.slideUp('fast', resizeCanvas);\n\t }\n\t }\n\t }\n\t\n\t function setHeaderRowVisibility(visible) {\n\t if (options.showHeaderRow != visible) {\n\t options.showHeaderRow = visible;\n\t if (visible) {\n\t $headerRowScroller.slideDown('fast', resizeCanvas);\n\t } else {\n\t $headerRowScroller.slideUp('fast', resizeCanvas);\n\t }\n\t }\n\t }\n\t\n\t function setFooterRowVisibility(visible) {\n\t if (options.showFooterRow != visible) {\n\t options.showFooterRow = visible;\n\t if (visible) {\n\t $footerRowScroller.slideDown('fast', resizeCanvas);\n\t } else {\n\t $footerRowScroller.slideUp('fast', resizeCanvas);\n\t }\n\t }\n\t }\n\t\n\t function getContainerNode() {\n\t return $container.get(0);\n\t }\n\t\n\t // ////////////////////////////////////////////////////////////////////////////////////////////\n\t // Rendering / Scrolling\n\t\n\t function getRowTop(row) {\n\t return options.rowHeight * row - offset;\n\t }\n\t\n\t function getRowFromPosition(y) {\n\t return Math.floor((y + offset) / options.rowHeight);\n\t }\n\t\n\t function scrollTo(y) {\n\t y = Math.max(y, 0);\n\t y = Math.min(y, th - viewportH + (viewportHasHScroll ? scrollbarDimensions.height : 0));\n\t\n\t var oldOffset = offset;\n\t\n\t page = Math.min(n - 1, Math.floor(y / ph));\n\t offset = Math.round(page * cj);\n\t var newScrollTop = y - offset;\n\t\n\t if (offset != oldOffset) {\n\t var range = getVisibleRange(newScrollTop);\n\t cleanupRows(range);\n\t updateRowPositions();\n\t }\n\t\n\t if (prevScrollTop != newScrollTop) {\n\t vScrollDir = prevScrollTop + oldOffset < newScrollTop + offset ? 1 : -1;\n\t $viewport[0].scrollTop = lastRenderedScrollTop = scrollTop = prevScrollTop = newScrollTop;\n\t\n\t trigger(self.onViewportChanged, { grid: self });\n\t }\n\t }\n\t\n\t function defaultFormatter(row, cell, value, columnDef, dataContext) {\n\t if (value == null) {\n\t return '';\n\t } else {\n\t return (value + '').replace(/&/g, '&').replace(//g, '>');\n\t }\n\t }\n\t\n\t function getFormatter(row, column) {\n\t var rowMetadata = data.getItemMetadata && data.getItemMetadata(row);\n\t\n\t // look up by id, then index\n\t var columnOverrides = rowMetadata && rowMetadata.columns && (rowMetadata.columns[column.id] || rowMetadata.columns[getColumnIndex(column.id)]);\n\t\n\t return columnOverrides && columnOverrides.formatter || rowMetadata && rowMetadata.formatter || column.formatter || options.formatterFactory && options.formatterFactory.getFormatter(column) || options.defaultFormatter;\n\t }\n\t\n\t function getEditor(row, cell) {\n\t var column = columns[cell];\n\t var rowMetadata = data.getItemMetadata && data.getItemMetadata(row);\n\t var columnMetadata = rowMetadata && rowMetadata.columns;\n\t\n\t if (columnMetadata && columnMetadata[column.id] && columnMetadata[column.id].editor !== undefined) {\n\t return columnMetadata[column.id].editor;\n\t }\n\t if (columnMetadata && columnMetadata[cell] && columnMetadata[cell].editor !== undefined) {\n\t return columnMetadata[cell].editor;\n\t }\n\t\n\t return column.editor || options.editorFactory && options.editorFactory.getEditor(column);\n\t }\n\t\n\t function getDataItemValueForColumn(item, columnDef) {\n\t if (options.dataItemColumnValueExtractor) {\n\t return options.dataItemColumnValueExtractor(item, columnDef);\n\t }\n\t return item[columnDef.field];\n\t }\n\t\n\t function appendRowHtml(stringArray, row, range, dataLength) {\n\t var d = getDataItem(row);\n\t var dataLoading = row < dataLength && !d;\n\t var rowCss = 'slick-row' + (dataLoading ? ' loading' : '') + (row === activeRow ? ' active' : '') + (row % 2 == 1 ? ' odd' : ' even');\n\t\n\t if (!d) {\n\t rowCss += ' ' + options.addNewRowCssClass;\n\t }\n\t\n\t var metadata = data.getItemMetadata && data.getItemMetadata(row);\n\t\n\t if (metadata && metadata.cssClasses) {\n\t rowCss += ' ' + metadata.cssClasses;\n\t }\n\t\n\t stringArray.push(\"
\");\n\t\n\t var colspan, m;\n\t for (var i = 0, ii = columns.length; i < ii; i++) {\n\t m = columns[i];\n\t colspan = 1;\n\t if (metadata && metadata.columns) {\n\t var columnData = metadata.columns[m.id] || metadata.columns[i];\n\t colspan = columnData && columnData.colspan || 1;\n\t if (colspan === '*') {\n\t colspan = ii - i;\n\t }\n\t }\n\t\n\t // Do not render cells outside of the viewport.\n\t if (columnPosRight[Math.min(ii - 1, i + colspan - 1)] > range.leftPx) {\n\t if (columnPosLeft[i] > range.rightPx) {\n\t // All columns to the right are outside the range.\n\t break;\n\t }\n\t\n\t appendCellHtml(stringArray, row, i, colspan, d);\n\t }\n\t\n\t if (colspan > 1) {\n\t i += colspan - 1;\n\t }\n\t }\n\t\n\t stringArray.push('
');\n\t }\n\t\n\t function appendCellHtml(stringArray, row, cell, colspan, item) {\n\t // stringArray: stringBuilder containing the HTML parts\n\t // row, cell: row and column index\n\t // colspan: HTML colspan\n\t // item: grid data for row\n\t\n\t var m = columns[cell];\n\t var cellCss = 'slick-cell l' + cell + ' r' + Math.min(columns.length - 1, cell + colspan - 1) + (m.cssClass ? ' ' + m.cssClass : '');\n\t if (row === activeRow && cell === activeCell) {\n\t cellCss += ' active';\n\t }\n\t\n\t // TODO: merge them together in the setter\n\t for (var key in cellCssClasses) {\n\t if (cellCssClasses[key][row] && cellCssClasses[key][row][m.id]) {\n\t cellCss += ' ' + cellCssClasses[key][row][m.id];\n\t }\n\t }\n\t\n\t stringArray.push(\"
\");\n\t\n\t // if there is a corresponding row (if not, this is the Add New row or this data hasn't been loaded yet)\n\t if (item) {\n\t var value = getDataItemValueForColumn(item, m);\n\t stringArray.push(getFormatter(row, m)(row, cell, value, m, item));\n\t }\n\t\n\t stringArray.push('
');\n\t\n\t rowsCache[row].cellRenderQueue.push(cell);\n\t rowsCache[row].cellColSpans[cell] = colspan;\n\t }\n\t\n\t function cleanupRows(rangeToKeep) {\n\t for (var i in rowsCache) {\n\t if ((i = parseInt(i, 10)) !== activeRow && (i < rangeToKeep.top || i > rangeToKeep.bottom)) {\n\t removeRowFromCache(i);\n\t }\n\t }\n\t if (options.enableAsyncPostRenderCleanup) {\n\t startPostProcessingCleanup();\n\t }\n\t }\n\t\n\t function invalidate() {\n\t updateRowCount();\n\t invalidateAllRows();\n\t render();\n\t }\n\t\n\t function invalidateAllRows() {\n\t if (currentEditor) {\n\t makeActiveCellNormal();\n\t }\n\t for (var row in rowsCache) {\n\t removeRowFromCache(row);\n\t }\n\t if (options.enableAsyncPostRenderCleanup) {\n\t startPostProcessingCleanup();\n\t }\n\t }\n\t\n\t function queuePostProcessedRowForCleanup(cacheEntry, postProcessedRow, rowIdx) {\n\t postProcessgroupId++;\n\t\n\t // store and detach node for later async cleanup\n\t for (var columnIdx in postProcessedRow) {\n\t if (postProcessedRow.hasOwnProperty(columnIdx)) {\n\t postProcessedCleanupQueue.push({\n\t actionType: 'C',\n\t groupId: postProcessgroupId,\n\t node: cacheEntry.cellNodesByColumnIdx[columnIdx | 0],\n\t columnIdx: columnIdx | 0,\n\t rowIdx: rowIdx\n\t });\n\t }\n\t }\n\t postProcessedCleanupQueue.push({\n\t actionType: 'R',\n\t groupId: postProcessgroupId,\n\t node: cacheEntry.rowNode\n\t });\n\t (0, _jquery2.default)(cacheEntry.rowNode).detach();\n\t }\n\t\n\t function queuePostProcessedCellForCleanup(cellnode, columnIdx, rowIdx) {\n\t postProcessedCleanupQueue.push({\n\t actionType: 'C',\n\t groupId: postProcessgroupId,\n\t node: cellnode,\n\t columnIdx: columnIdx,\n\t rowIdx: rowIdx\n\t });\n\t (0, _jquery2.default)(cellnode).detach();\n\t }\n\t\n\t function removeRowFromCache(row) {\n\t var cacheEntry = rowsCache[row];\n\t if (!cacheEntry) {\n\t return;\n\t }\n\t\n\t if (rowNodeFromLastMouseWheelEvent === cacheEntry.rowNode) {\n\t cacheEntry.rowNode.style.display = 'none';\n\t zombieRowNodeFromLastMouseWheelEvent = rowNodeFromLastMouseWheelEvent;\n\t zombieRowCacheFromLastMouseWheelEvent = cacheEntry;\n\t zombieRowPostProcessedFromLastMouseWheelEvent = postProcessedRows[row];\n\t // ignore post processing cleanup in this case - it will be dealt with later\n\t } else {\n\t if (options.enableAsyncPostRenderCleanup && postProcessedRows[row]) {\n\t queuePostProcessedRowForCleanup(cacheEntry, postProcessedRows[row], row);\n\t } else {\n\t $canvas[0].removeChild(cacheEntry.rowNode);\n\t }\n\t }\n\t\n\t delete rowsCache[row];\n\t delete postProcessedRows[row];\n\t renderedRows--;\n\t counter_rows_removed++;\n\t }\n\t\n\t function invalidateRows(rows) {\n\t var i, rl;\n\t if (!rows || !rows.length) {\n\t return;\n\t }\n\t vScrollDir = 0;\n\t for (i = 0, rl = rows.length; i < rl; i++) {\n\t if (currentEditor && activeRow === rows[i]) {\n\t makeActiveCellNormal();\n\t }\n\t if (rowsCache[rows[i]]) {\n\t removeRowFromCache(rows[i]);\n\t }\n\t }\n\t if (options.enableAsyncPostRenderCleanup) {\n\t startPostProcessingCleanup();\n\t }\n\t }\n\t\n\t function invalidateRow(row) {\n\t invalidateRows([row]);\n\t }\n\t\n\t function updateCell(row, cell) {\n\t var cellNode = getCellNode(row, cell);\n\t if (!cellNode) {\n\t return;\n\t }\n\t\n\t var m = columns[cell],\n\t d = getDataItem(row);\n\t if (currentEditor && activeRow === row && activeCell === cell) {\n\t currentEditor.loadValue(d);\n\t } else {\n\t cellNode.innerHTML = d ? getFormatter(row, m)(row, cell, getDataItemValueForColumn(d, m), m, d) : '';\n\t invalidatePostProcessingResults(row);\n\t }\n\t }\n\t\n\t function updateRow(row) {\n\t var cacheEntry = rowsCache[row];\n\t if (!cacheEntry) {\n\t return;\n\t }\n\t\n\t ensureCellNodesInRowsCache(row);\n\t\n\t var d = getDataItem(row);\n\t\n\t for (var columnIdx in cacheEntry.cellNodesByColumnIdx) {\n\t if (!cacheEntry.cellNodesByColumnIdx.hasOwnProperty(columnIdx)) {\n\t continue;\n\t }\n\t\n\t columnIdx = columnIdx | 0;\n\t var m = columns[columnIdx],\n\t node = cacheEntry.cellNodesByColumnIdx[columnIdx];\n\t\n\t if (row === activeRow && columnIdx === activeCell && currentEditor) {\n\t currentEditor.loadValue(d);\n\t } else if (d) {\n\t node.innerHTML = getFormatter(row, m)(row, columnIdx, getDataItemValueForColumn(d, m), m, d);\n\t } else {\n\t node.innerHTML = '';\n\t }\n\t }\n\t\n\t invalidatePostProcessingResults(row);\n\t }\n\t\n\t function getViewportHeight() {\n\t return parseFloat(_jquery2.default.css($container[0], 'height', true)) - parseFloat(_jquery2.default.css($container[0], 'paddingTop', true)) - parseFloat(_jquery2.default.css($container[0], 'paddingBottom', true)) - parseFloat(_jquery2.default.css($headerScroller[0], 'height')) - getVBoxDelta($headerScroller) - (options.showTopPanel ? options.topPanelHeight + getVBoxDelta($topPanelScroller) : 0) - (options.showHeaderRow ? options.headerRowHeight + getVBoxDelta($headerRowScroller) : 0) - (options.createFooterRow && options.showFooterRow ? options.footerRowHeight + getVBoxDelta($footerRowScroller) : 0);\n\t }\n\t\n\t function resizeCanvas() {\n\t if (!initialized) {\n\t return;\n\t }\n\t if (options.autoHeight) {\n\t viewportH = options.rowHeight * getDataLengthIncludingAddNew();\n\t } else {\n\t viewportH = getViewportHeight();\n\t }\n\t\n\t numVisibleRows = Math.ceil(viewportH / options.rowHeight);\n\t viewportW = parseFloat(_jquery2.default.css($container[0], 'width', true));\n\t if (!options.autoHeight) {\n\t $viewport.height(viewportH);\n\t }\n\t\n\t if (options.forceFitColumns) {\n\t autosizeColumns();\n\t }\n\t\n\t updateRowCount();\n\t handleScroll();\n\t // Since the width has changed, force the render() to reevaluate virtually rendered cells.\n\t lastRenderedScrollLeft = -1;\n\t render();\n\t }\n\t\n\t function updateRowCount() {\n\t if (!initialized) {\n\t return;\n\t }\n\t\n\t var dataLengthIncludingAddNew = getDataLengthIncludingAddNew();\n\t var numberOfRows = dataLengthIncludingAddNew + (options.leaveSpaceForNewRows ? numVisibleRows - 1 : 0);\n\t\n\t var oldViewportHasVScroll = viewportHasVScroll;\n\t // with autoHeight, we do not need to accommodate the vertical scroll bar\n\t viewportHasVScroll = !options.autoHeight && numberOfRows * options.rowHeight > viewportH;\n\t viewportHasHScroll = canvasWidth > viewportW - scrollbarDimensions.width;\n\t\n\t makeActiveCellNormal();\n\t\n\t // remove the rows that are now outside of the data range\n\t // this helps avoid redundant calls to .removeRow() when the size of the data decreased by thousands of rows\n\t var l = dataLengthIncludingAddNew - 1;\n\t for (var i in rowsCache) {\n\t if (i > l) {\n\t removeRowFromCache(i);\n\t }\n\t }\n\t if (options.enableAsyncPostRenderCleanup) {\n\t startPostProcessingCleanup();\n\t }\n\t\n\t if (activeCellNode && activeRow > l) {\n\t resetActiveCell();\n\t }\n\t\n\t var oldH = h;\n\t th = Math.max(options.rowHeight * numberOfRows, viewportH - scrollbarDimensions.height);\n\t if (th < maxSupportedCssHeight) {\n\t // just one page\n\t h = ph = th;\n\t n = 1;\n\t cj = 0;\n\t } else {\n\t // break into pages\n\t h = maxSupportedCssHeight;\n\t ph = h / 100;\n\t n = Math.floor(th / ph);\n\t cj = (th - h) / (n - 1);\n\t }\n\t\n\t if (h !== oldH) {\n\t $canvas.css('height', h);\n\t scrollTop = $viewport[0].scrollTop;\n\t }\n\t\n\t var oldScrollTopInRange = scrollTop + offset <= th - viewportH;\n\t\n\t if (th == 0 || scrollTop == 0) {\n\t page = offset = 0;\n\t } else if (oldScrollTopInRange) {\n\t // maintain virtual position\n\t scrollTo(scrollTop + offset);\n\t } else {\n\t // scroll to bottom\n\t scrollTo(th - viewportH);\n\t }\n\t\n\t if (h != oldH && options.autoHeight) {\n\t resizeCanvas();\n\t }\n\t\n\t if (options.forceFitColumns && oldViewportHasVScroll != viewportHasVScroll) {\n\t autosizeColumns();\n\t }\n\t updateCanvasWidth(false);\n\t }\n\t\n\t function getVisibleRange(viewportTop, viewportLeft) {\n\t if (viewportTop == null) {\n\t viewportTop = scrollTop;\n\t }\n\t if (viewportLeft == null) {\n\t viewportLeft = scrollLeft;\n\t }\n\t\n\t return {\n\t top: getRowFromPosition(viewportTop),\n\t bottom: getRowFromPosition(viewportTop + viewportH) + 1,\n\t leftPx: viewportLeft,\n\t rightPx: viewportLeft + viewportW\n\t };\n\t }\n\t\n\t function getRenderedRange(viewportTop, viewportLeft) {\n\t var range = getVisibleRange(viewportTop, viewportLeft);\n\t var buffer = Math.round(viewportH / options.rowHeight);\n\t var minBuffer = 3;\n\t\n\t if (vScrollDir == -1) {\n\t range.top -= buffer;\n\t range.bottom += minBuffer;\n\t } else if (vScrollDir == 1) {\n\t range.top -= minBuffer;\n\t range.bottom += buffer;\n\t } else {\n\t range.top -= minBuffer;\n\t range.bottom += minBuffer;\n\t }\n\t\n\t range.top = Math.max(0, range.top);\n\t range.bottom = Math.min(getDataLengthIncludingAddNew() - 1, range.bottom);\n\t\n\t range.leftPx -= viewportW;\n\t range.rightPx += viewportW;\n\t\n\t range.leftPx = Math.max(0, range.leftPx);\n\t range.rightPx = Math.min(canvasWidth, range.rightPx);\n\t\n\t return range;\n\t }\n\t\n\t function ensureCellNodesInRowsCache(row) {\n\t var cacheEntry = rowsCache[row];\n\t if (cacheEntry) {\n\t if (cacheEntry.cellRenderQueue.length) {\n\t var lastChild = cacheEntry.rowNode.lastChild;\n\t while (cacheEntry.cellRenderQueue.length) {\n\t var columnIdx = cacheEntry.cellRenderQueue.pop();\n\t cacheEntry.cellNodesByColumnIdx[columnIdx] = lastChild;\n\t lastChild = lastChild.previousSibling;\n\t }\n\t }\n\t }\n\t }\n\t\n\t function cleanUpCells(range, row) {\n\t var totalCellsRemoved = 0;\n\t var cacheEntry = rowsCache[row];\n\t\n\t // Remove cells outside the range.\n\t var cellsToRemove = [];\n\t for (var i in cacheEntry.cellNodesByColumnIdx) {\n\t // I really hate it when people mess with Array.prototype.\n\t if (!cacheEntry.cellNodesByColumnIdx.hasOwnProperty(i)) {\n\t continue;\n\t }\n\t\n\t // This is a string, so it needs to be cast back to a number.\n\t i = i | 0;\n\t\n\t var colspan = cacheEntry.cellColSpans[i];\n\t if (columnPosLeft[i] > range.rightPx || columnPosRight[Math.min(columns.length - 1, i + colspan - 1)] < range.leftPx) {\n\t if (!(row == activeRow && i == activeCell)) {\n\t cellsToRemove.push(i);\n\t }\n\t }\n\t }\n\t\n\t var cellToRemove, node;\n\t postProcessgroupId++;\n\t while ((cellToRemove = cellsToRemove.pop()) != null) {\n\t node = cacheEntry.cellNodesByColumnIdx[cellToRemove];\n\t if (options.enableAsyncPostRenderCleanup && postProcessedRows[row] && postProcessedRows[row][cellToRemove]) {\n\t queuePostProcessedCellForCleanup(node, cellToRemove, row);\n\t } else {\n\t cacheEntry.rowNode.removeChild(node);\n\t }\n\t\n\t delete cacheEntry.cellColSpans[cellToRemove];\n\t delete cacheEntry.cellNodesByColumnIdx[cellToRemove];\n\t if (postProcessedRows[row]) {\n\t delete postProcessedRows[row][cellToRemove];\n\t }\n\t totalCellsRemoved++;\n\t }\n\t }\n\t\n\t function cleanUpAndRenderCells(range) {\n\t var cacheEntry;\n\t var stringArray = [];\n\t var processedRows = [];\n\t var cellsAdded;\n\t var totalCellsAdded = 0;\n\t var colspan;\n\t\n\t for (var row = range.top, btm = range.bottom; row <= btm; row++) {\n\t cacheEntry = rowsCache[row];\n\t if (!cacheEntry) {\n\t continue;\n\t }\n\t\n\t // cellRenderQueue populated in renderRows() needs to be cleared first\n\t ensureCellNodesInRowsCache(row);\n\t\n\t cleanUpCells(range, row);\n\t\n\t // Render missing cells.\n\t cellsAdded = 0;\n\t\n\t var metadata = data.getItemMetadata && data.getItemMetadata(row);\n\t metadata = metadata && metadata.columns;\n\t\n\t var d = getDataItem(row);\n\t\n\t // TODO: shorten this loop (index? heuristics? binary search?)\n\t for (var i = 0, ii = columns.length; i < ii; i++) {\n\t // Cells to the right are outside the range.\n\t if (columnPosLeft[i] > range.rightPx) {\n\t break;\n\t }\n\t\n\t // Already rendered.\n\t if ((colspan = cacheEntry.cellColSpans[i]) != null) {\n\t i += colspan > 1 ? colspan - 1 : 0;\n\t continue;\n\t }\n\t\n\t colspan = 1;\n\t if (metadata) {\n\t var columnData = metadata[columns[i].id] || metadata[i];\n\t colspan = columnData && columnData.colspan || 1;\n\t if (colspan === '*') {\n\t colspan = ii - i;\n\t }\n\t }\n\t\n\t if (columnPosRight[Math.min(ii - 1, i + colspan - 1)] > range.leftPx) {\n\t appendCellHtml(stringArray, row, i, colspan, d);\n\t cellsAdded++;\n\t }\n\t\n\t i += colspan > 1 ? colspan - 1 : 0;\n\t }\n\t\n\t if (cellsAdded) {\n\t totalCellsAdded += cellsAdded;\n\t processedRows.push(row);\n\t }\n\t }\n\t\n\t if (!stringArray.length) {\n\t return;\n\t }\n\t\n\t var x = document.createElement('div');\n\t x.innerHTML = stringArray.join('');\n\t\n\t var processedRow;\n\t var node;\n\t while ((processedRow = processedRows.pop()) != null) {\n\t cacheEntry = rowsCache[processedRow];\n\t var columnIdx;\n\t while ((columnIdx = cacheEntry.cellRenderQueue.pop()) != null) {\n\t node = x.lastChild;\n\t cacheEntry.rowNode.appendChild(node);\n\t cacheEntry.cellNodesByColumnIdx[columnIdx] = node;\n\t }\n\t }\n\t }\n\t\n\t function renderRows(range) {\n\t var parentNode = $canvas[0],\n\t stringArray = [],\n\t rows = [],\n\t needToReselectCell = false,\n\t dataLength = getDataLength();\n\t\n\t for (var i = range.top, ii = range.bottom; i <= ii; i++) {\n\t if (rowsCache[i]) {\n\t continue;\n\t }\n\t renderedRows++;\n\t rows.push(i);\n\t\n\t // Create an entry right away so that appendRowHtml() can\n\t // start populatating it.\n\t rowsCache[i] = {\n\t 'rowNode': null,\n\t\n\t // ColSpans of rendered cells (by column idx).\n\t // Can also be used for checking whether a cell has been rendered.\n\t 'cellColSpans': [],\n\t\n\t // Cell nodes (by column idx). Lazy-populated by ensureCellNodesInRowsCache().\n\t 'cellNodesByColumnIdx': [],\n\t\n\t // Column indices of cell nodes that have been rendered, but not yet indexed in\n\t // cellNodesByColumnIdx. These are in the same order as cell nodes added at the\n\t // end of the row.\n\t 'cellRenderQueue': []\n\t };\n\t\n\t appendRowHtml(stringArray, i, range, dataLength);\n\t if (activeCellNode && activeRow === i) {\n\t needToReselectCell = true;\n\t }\n\t counter_rows_rendered++;\n\t }\n\t\n\t if (!rows.length) {\n\t return;\n\t }\n\t\n\t var x = document.createElement('div');\n\t x.innerHTML = stringArray.join('');\n\t\n\t for (var i = 0, ii = rows.length; i < ii; i++) {\n\t rowsCache[rows[i]].rowNode = parentNode.appendChild(x.firstChild);\n\t }\n\t\n\t if (needToReselectCell) {\n\t activeCellNode = getCellNode(activeRow, activeCell);\n\t }\n\t }\n\t\n\t function startPostProcessing() {\n\t if (!options.enableAsyncPostRender) {\n\t return;\n\t }\n\t clearTimeout(h_postrender);\n\t h_postrender = setTimeout(asyncPostProcessRows, options.asyncPostRenderDelay);\n\t }\n\t\n\t function startPostProcessingCleanup() {\n\t if (!options.enableAsyncPostRenderCleanup) {\n\t return;\n\t }\n\t clearTimeout(h_postrenderCleanup);\n\t h_postrenderCleanup = setTimeout(asyncPostProcessCleanupRows, options.asyncPostRenderCleanupDelay);\n\t }\n\t\n\t function invalidatePostProcessingResults(row) {\n\t // change status of columns to be re-rendered\n\t for (var columnIdx in postProcessedRows[row]) {\n\t if (postProcessedRows[row].hasOwnProperty(columnIdx)) {\n\t postProcessedRows[row][columnIdx] = 'C';\n\t }\n\t }\n\t postProcessFromRow = Math.min(postProcessFromRow, row);\n\t postProcessToRow = Math.max(postProcessToRow, row);\n\t startPostProcessing();\n\t }\n\t\n\t function updateRowPositions() {\n\t for (var row in rowsCache) {\n\t rowsCache[row].rowNode.style.top = getRowTop(row) + 'px';\n\t }\n\t }\n\t\n\t function render() {\n\t if (!initialized) {\n\t return;\n\t }\n\t var visible = getVisibleRange();\n\t var rendered = getRenderedRange();\n\t\n\t // remove rows no longer in the viewport\n\t cleanupRows(rendered);\n\t\n\t // add new rows & missing cells in existing rows\n\t if (lastRenderedScrollLeft != scrollLeft) {\n\t cleanUpAndRenderCells(rendered);\n\t }\n\t\n\t // render missing rows\n\t renderRows(rendered);\n\t\n\t postProcessFromRow = visible.top;\n\t postProcessToRow = Math.min(getDataLengthIncludingAddNew() - 1, visible.bottom);\n\t startPostProcessing();\n\t\n\t lastRenderedScrollTop = scrollTop;\n\t lastRenderedScrollLeft = scrollLeft;\n\t h_render = null;\n\t }\n\t\n\t function handleHeaderRowScroll() {\n\t var scrollLeft = $headerRowScroller[0].scrollLeft;\n\t if (scrollLeft != $viewport[0].scrollLeft) {\n\t $viewport[0].scrollLeft = scrollLeft;\n\t }\n\t }\n\t\n\t function handleFooterRowScroll() {\n\t var scrollLeft = $footerRowScroller[0].scrollLeft;\n\t if (scrollLeft != $viewport[0].scrollLeft) {\n\t $viewport[0].scrollLeft = scrollLeft;\n\t }\n\t }\n\t\n\t function handleScroll() {\n\t scrollTop = $viewport[0].scrollTop;\n\t scrollLeft = $viewport[0].scrollLeft;\n\t var vScrollDist = Math.abs(scrollTop - prevScrollTop);\n\t var hScrollDist = Math.abs(scrollLeft - prevScrollLeft);\n\t\n\t if (hScrollDist) {\n\t prevScrollLeft = scrollLeft;\n\t $headerScroller[0].scrollLeft = scrollLeft;\n\t $topPanelScroller[0].scrollLeft = scrollLeft;\n\t $headerRowScroller[0].scrollLeft = scrollLeft;\n\t if (options.createFooterRow) {\n\t $footerRowScroller[0].scrollLeft = scrollLeft;\n\t }\n\t }\n\t\n\t if (vScrollDist) {\n\t vScrollDir = prevScrollTop < scrollTop ? 1 : -1;\n\t prevScrollTop = scrollTop;\n\t\n\t // switch virtual pages if needed\n\t if (vScrollDist < viewportH) {\n\t scrollTo(scrollTop + offset);\n\t } else {\n\t var oldOffset = offset;\n\t if (h == viewportH) {\n\t page = 0;\n\t } else {\n\t page = Math.min(n - 1, Math.floor(scrollTop * ((th - viewportH) / (h - viewportH)) * (1 / ph)));\n\t }\n\t offset = Math.round(page * cj);\n\t if (oldOffset != offset) {\n\t invalidateAllRows();\n\t }\n\t }\n\t }\n\t\n\t if (hScrollDist || vScrollDist) {\n\t if (h_render) {\n\t clearTimeout(h_render);\n\t }\n\t\n\t if (Math.abs(lastRenderedScrollTop - scrollTop) > 20 || Math.abs(lastRenderedScrollLeft - scrollLeft) > 20) {\n\t if (options.forceSyncScrolling || Math.abs(lastRenderedScrollTop - scrollTop) < viewportH && Math.abs(lastRenderedScrollLeft - scrollLeft) < viewportW) {\n\t render();\n\t } else {\n\t h_render = setTimeout(render, 50);\n\t }\n\t\n\t trigger(self.onViewportChanged, { grid: self });\n\t }\n\t }\n\t\n\t trigger(self.onScroll, { scrollLeft: scrollLeft, scrollTop: scrollTop, grid: self });\n\t }\n\t\n\t function asyncPostProcessRows() {\n\t var dataLength = getDataLength();\n\t while (postProcessFromRow <= postProcessToRow) {\n\t var row = vScrollDir >= 0 ? postProcessFromRow++ : postProcessToRow--;\n\t var cacheEntry = rowsCache[row];\n\t if (!cacheEntry || row >= dataLength) {\n\t continue;\n\t }\n\t\n\t if (!postProcessedRows[row]) {\n\t postProcessedRows[row] = {};\n\t }\n\t\n\t ensureCellNodesInRowsCache(row);\n\t for (var columnIdx in cacheEntry.cellNodesByColumnIdx) {\n\t if (!cacheEntry.cellNodesByColumnIdx.hasOwnProperty(columnIdx)) {\n\t continue;\n\t }\n\t\n\t columnIdx = columnIdx | 0;\n\t\n\t var m = columns[columnIdx];\n\t var processedStatus = postProcessedRows[row][columnIdx]; // C=cleanup and re-render, R=rendered\n\t if (m.asyncPostRender && processedStatus !== 'R') {\n\t var node = cacheEntry.cellNodesByColumnIdx[columnIdx];\n\t if (node) {\n\t m.asyncPostRender(node, row, getDataItem(row), m, processedStatus === 'C');\n\t }\n\t postProcessedRows[row][columnIdx] = 'R';\n\t }\n\t }\n\t\n\t h_postrender = setTimeout(asyncPostProcessRows, options.asyncPostRenderDelay);\n\t return;\n\t }\n\t }\n\t\n\t function asyncPostProcessCleanupRows() {\n\t if (postProcessedCleanupQueue.length > 0) {\n\t var groupId = postProcessedCleanupQueue[0].groupId;\n\t\n\t // loop through all queue members with this groupID\n\t while (postProcessedCleanupQueue.length > 0 && postProcessedCleanupQueue[0].groupId == groupId) {\n\t var entry = postProcessedCleanupQueue.shift();\n\t if (entry.actionType == 'R') {\n\t (0, _jquery2.default)(entry.node).remove();\n\t }\n\t if (entry.actionType == 'C') {\n\t var column = columns[entry.columnIdx];\n\t if (column.asyncPostRenderCleanup && entry.node) {\n\t // cleanup must also remove element\n\t column.asyncPostRenderCleanup(entry.node, entry.rowIdx, column);\n\t }\n\t }\n\t }\n\t\n\t // call this function again after the specified delay\n\t h_postrenderCleanup = setTimeout(asyncPostProcessCleanupRows, options.asyncPostRenderCleanupDelay);\n\t }\n\t }\n\t\n\t function updateCellCssStylesOnRenderedRows(addedHash, removedHash) {\n\t var node, columnId, addedRowHash, removedRowHash;\n\t for (var row in rowsCache) {\n\t removedRowHash = removedHash && removedHash[row];\n\t addedRowHash = addedHash && addedHash[row];\n\t\n\t if (removedRowHash) {\n\t for (columnId in removedRowHash) {\n\t if (!addedRowHash || removedRowHash[columnId] != addedRowHash[columnId]) {\n\t node = getCellNode(row, getColumnIndex(columnId));\n\t if (node) {\n\t (0, _jquery2.default)(node).removeClass(removedRowHash[columnId]);\n\t }\n\t }\n\t }\n\t }\n\t\n\t if (addedRowHash) {\n\t for (columnId in addedRowHash) {\n\t if (!removedRowHash || removedRowHash[columnId] != addedRowHash[columnId]) {\n\t node = getCellNode(row, getColumnIndex(columnId));\n\t if (node) {\n\t (0, _jquery2.default)(node).addClass(addedRowHash[columnId]);\n\t }\n\t }\n\t }\n\t }\n\t }\n\t }\n\t\n\t function addCellCssStyles(key, hash) {\n\t if (cellCssClasses[key]) {\n\t throw \"addCellCssStyles: cell CSS hash with key '\" + key + \"' already exists.\";\n\t }\n\t\n\t cellCssClasses[key] = hash;\n\t updateCellCssStylesOnRenderedRows(hash, null);\n\t\n\t trigger(self.onCellCssStylesChanged, { 'key': key, 'hash': hash, 'grid': self });\n\t }\n\t\n\t function removeCellCssStyles(key) {\n\t if (!cellCssClasses[key]) {\n\t return;\n\t }\n\t\n\t updateCellCssStylesOnRenderedRows(null, cellCssClasses[key]);\n\t delete cellCssClasses[key];\n\t\n\t trigger(self.onCellCssStylesChanged, { 'key': key, 'hash': null, 'grid': self });\n\t }\n\t\n\t function setCellCssStyles(key, hash) {\n\t var prevHash = cellCssClasses[key];\n\t\n\t cellCssClasses[key] = hash;\n\t updateCellCssStylesOnRenderedRows(hash, prevHash);\n\t\n\t trigger(self.onCellCssStylesChanged, { 'key': key, 'hash': hash, 'grid': self });\n\t }\n\t\n\t function getCellCssStyles(key) {\n\t return cellCssClasses[key];\n\t }\n\t\n\t function flashCell(row, cell, speed) {\n\t speed = speed || 100;\n\t if (rowsCache[row]) {\n\t var toggleCellClass = function toggleCellClass(times) {\n\t if (!times) {\n\t return;\n\t }\n\t setTimeout(function () {\n\t $cell.queue(function () {\n\t $cell.toggleClass(options.cellFlashingCssClass).dequeue();\n\t toggleCellClass(times - 1);\n\t });\n\t }, speed);\n\t };\n\t\n\t var $cell = (0, _jquery2.default)(getCellNode(row, cell));\n\t\n\t toggleCellClass(4);\n\t }\n\t }\n\t\n\t // ////////////////////////////////////////////////////////////////////////////////////////////\n\t // Interactivity\n\t\n\t function handleMouseWheel(e) {\n\t var rowNode = (0, _jquery2.default)(e.target).closest('.slick-row')[0];\n\t if (rowNode != rowNodeFromLastMouseWheelEvent) {\n\t if (zombieRowNodeFromLastMouseWheelEvent && zombieRowNodeFromLastMouseWheelEvent != rowNode) {\n\t if (options.enableAsyncPostRenderCleanup && zombieRowPostProcessedFromLastMouseWheelEvent) {\n\t queuePostProcessedRowForCleanup(zombieRowCacheFromLastMouseWheelEvent, zombieRowPostProcessedFromLastMouseWheelEvent);\n\t } else {\n\t $canvas[0].removeChild(zombieRowNodeFromLastMouseWheelEvent);\n\t }\n\t zombieRowNodeFromLastMouseWheelEvent = null;\n\t zombieRowCacheFromLastMouseWheelEvent = null;\n\t zombieRowPostProcessedFromLastMouseWheelEvent = null;\n\t\n\t if (options.enableAsyncPostRenderCleanup) {\n\t startPostProcessingCleanup();\n\t }\n\t }\n\t rowNodeFromLastMouseWheelEvent = rowNode;\n\t }\n\t }\n\t\n\t function handleDragStart(interactEvent) {\n\t var event = _jquery2.default.Event(interactEvent.originalEvent.type, interactEvent.originalEvent);\n\t var cell = getCellFromEvent(event);\n\t if (!cell || !cellExists(cell.row, cell.cell)) {\n\t return false;\n\t }\n\t\n\t var retval = trigger(self.onDragStart, interactEvent, event);\n\t if (event.isImmediatePropagationStopped()) {\n\t return retval;\n\t }\n\t\n\t return false;\n\t }\n\t\n\t function handleDrag(interactEvent) {\n\t var event = _jquery2.default.Event(interactEvent.originalEvent.type, interactEvent.originalEvent);\n\t return trigger(self.onDrag, interactEvent, event);\n\t }\n\t\n\t function handleDragEnd(interactEvent) {\n\t trigger(self.onDragEnd, interactEvent, _jquery2.default.Event('mousedown'));\n\t }\n\t\n\t function handleKeyDown(e) {\n\t trigger(self.onKeyDown, { row: activeRow, cell: activeCell, grid: self }, e);\n\t var handled = e.isImmediatePropagationStopped();\n\t var keyCode = _slick2.default.keyCode;\n\t\n\t if (!handled) {\n\t if (!e.shiftKey && !e.altKey && !e.ctrlKey) {\n\t // editor may specify an array of keys to bubble\n\t if (options.editable && currentEditor && currentEditor.keyCaptureList) {\n\t if (currentEditor.keyCaptureList.indexOf(e.which) > -1) {\n\t return;\n\t }\n\t }\n\t if (e.which == keyCode.ESCAPE) {\n\t if (!getEditorLock().isActive()) {\n\t return; // no editing mode to cancel, allow bubbling and default processing (exit without cancelling the event)\n\t }\n\t cancelEditAndSetFocus();\n\t } else if (e.which == keyCode.PAGE_DOWN) {\n\t navigatePageDown();\n\t handled = true;\n\t } else if (e.which == keyCode.PAGE_UP) {\n\t navigatePageUp();\n\t handled = true;\n\t } else if (e.which == keyCode.LEFT) {\n\t handled = navigateLeft();\n\t } else if (e.which == keyCode.RIGHT) {\n\t handled = navigateRight();\n\t } else if (e.which == keyCode.UP) {\n\t handled = navigateUp();\n\t } else if (e.which == keyCode.DOWN) {\n\t handled = navigateDown();\n\t } else if (e.which == keyCode.TAB) {\n\t handled = navigateNext();\n\t } else if (e.which == keyCode.ENTER) {\n\t if (options.editable) {\n\t if (currentEditor) {\n\t // adding new row\n\t if (activeRow === getDataLength()) {\n\t navigateDown();\n\t } else {\n\t commitEditAndSetFocus();\n\t }\n\t } else {\n\t if (getEditorLock().commitCurrentEdit()) {\n\t makeActiveCellEditable();\n\t }\n\t }\n\t }\n\t handled = true;\n\t }\n\t } else if (e.which == keyCode.TAB && e.shiftKey && !e.ctrlKey && !e.altKey) {\n\t handled = navigatePrev();\n\t }\n\t }\n\t\n\t if (handled) {\n\t // the event has been handled so don't let parent element (bubbling/propagation) or browser (default) handle it\n\t e.stopPropagation();\n\t e.preventDefault();\n\t try {\n\t e.originalEvent.keyCode = 0; // prevent default behaviour for special keys in IE browsers (F3, F5, etc.)\n\t }\n\t // ignore exceptions - setting the original event's keycode throws access denied exception for \"Ctrl\"\n\t // (hitting control key only, nothing else), \"Shift\" (maybe others)\n\t catch (error) {}\n\t }\n\t }\n\t\n\t function handleClick(e) {\n\t if (!currentEditor) {\n\t // if this click resulted in some cell child node getting focus,\n\t // don't steal it back - keyboard events will still bubble up\n\t // IE9+ seems to default DIVs to tabIndex=0 instead of -1, so check for cell clicks directly.\n\t if (e.target != document.activeElement || (0, _jquery2.default)(e.target).hasClass('slick-cell')) {\n\t setFocus();\n\t }\n\t }\n\t\n\t var cell = getCellFromEvent(e);\n\t if (!cell || currentEditor !== null && activeRow == cell.row && activeCell == cell.cell) {\n\t return;\n\t }\n\t\n\t trigger(self.onClick, { row: cell.row, cell: cell.cell, grid: self }, e);\n\t if (e.isImmediatePropagationStopped()) {\n\t return;\n\t }\n\t\n\t if ((activeCell != cell.cell || activeRow != cell.row) && canCellBeActive(cell.row, cell.cell)) {\n\t if (!getEditorLock().isActive() || getEditorLock().commitCurrentEdit()) {\n\t scrollRowIntoView(cell.row, false);\n\t setActiveCellInternal(getCellNode(cell.row, cell.cell));\n\t }\n\t }\n\t }\n\t\n\t function handleContextMenu(e) {\n\t var $cell = (0, _jquery2.default)(e.target).closest('.slick-cell', $canvas);\n\t if ($cell.length === 0) {\n\t return;\n\t }\n\t\n\t // are we editing this cell?\n\t if (activeCellNode === $cell[0] && currentEditor !== null) {\n\t return;\n\t }\n\t\n\t trigger(self.onContextMenu, { grid: self }, e);\n\t }\n\t\n\t function handleDblClick(e) {\n\t var cell = getCellFromEvent(e);\n\t if (!cell || currentEditor !== null && activeRow == cell.row && activeCell == cell.cell) {\n\t return;\n\t }\n\t\n\t trigger(self.onDblClick, { row: cell.row, cell: cell.cell, grid: self }, e);\n\t if (e.isImmediatePropagationStopped()) {\n\t return;\n\t }\n\t\n\t if (options.editable) {\n\t gotoCell(cell.row, cell.cell, true);\n\t }\n\t }\n\t\n\t function handleHeaderMouseEnter(e) {\n\t trigger(self.onHeaderMouseEnter, {\n\t 'column': (0, _jquery2.default)(this).data('column'),\n\t 'grid': self\n\t }, e);\n\t }\n\t\n\t function handleHeaderMouseLeave(e) {\n\t trigger(self.onHeaderMouseLeave, {\n\t 'column': (0, _jquery2.default)(this).data('column'),\n\t 'grid': self\n\t }, e);\n\t }\n\t\n\t function handleHeaderContextMenu(e) {\n\t var $header = (0, _jquery2.default)(e.target).closest('.slick-header-column', '.slick-header-columns');\n\t var column = $header && $header.data('column');\n\t trigger(self.onHeaderContextMenu, { column: column, grid: self }, e);\n\t }\n\t\n\t function handleHeaderClick(e) {\n\t var $header = (0, _jquery2.default)(e.target).closest('.slick-header-column', '.slick-header-columns');\n\t var column = $header && $header.data('column');\n\t if (column) {\n\t trigger(self.onHeaderClick, { column: column, grid: self }, e);\n\t }\n\t }\n\t\n\t function handleMouseEnter(e) {\n\t trigger(self.onMouseEnter, { grid: self }, e);\n\t }\n\t\n\t function handleMouseLeave(e) {\n\t trigger(self.onMouseLeave, { grid: self }, e);\n\t }\n\t\n\t function cellExists(row, cell) {\n\t return !(row < 0 || row >= getDataLength() || cell < 0 || cell >= columns.length);\n\t }\n\t\n\t function getCellFromPoint(x, y) {\n\t var row = getRowFromPosition(y);\n\t var cell = 0;\n\t\n\t var w = 0;\n\t for (var i = 0; i < columns.length && w < x; i++) {\n\t w += columns[i].width;\n\t cell++;\n\t }\n\t\n\t if (cell < 0) {\n\t cell = 0;\n\t }\n\t\n\t return { row: row, cell: cell - 1 };\n\t }\n\t\n\t function getCellFromNode(cellNode) {\n\t // read column number from .l CSS class\n\t var cls = /l\\d+/.exec(cellNode.className);\n\t if (!cls) {\n\t throw 'getCellFromNode: cannot get cell - ' + cellNode.className;\n\t }\n\t return parseInt(cls[0].substr(1, cls[0].length - 1), 10);\n\t }\n\t\n\t function getRowFromNode(rowNode) {\n\t for (var row in rowsCache) {\n\t if (rowsCache[row].rowNode === rowNode) {\n\t return row | 0;\n\t }\n\t }\n\t\n\t return null;\n\t }\n\t\n\t function getCellFromEvent(e) {\n\t var $cell = (0, _jquery2.default)(e.target).closest('.slick-cell', $canvas);\n\t if (!$cell.length) {\n\t return null;\n\t }\n\t\n\t var row = getRowFromNode($cell[0].parentNode);\n\t var cell = getCellFromNode($cell[0]);\n\t\n\t if (row == null || cell == null) {\n\t return null;\n\t } else {\n\t return {\n\t 'row': row,\n\t 'cell': cell\n\t };\n\t }\n\t }\n\t\n\t function getCellNodeBox(row, cell) {\n\t if (!cellExists(row, cell)) {\n\t return null;\n\t }\n\t\n\t var y1 = getRowTop(row);\n\t var y2 = y1 + options.rowHeight - 1;\n\t var x1 = 0;\n\t for (var i = 0; i < cell; i++) {\n\t x1 += columns[i].width;\n\t }\n\t var x2 = x1 + columns[cell].width;\n\t\n\t return {\n\t top: y1,\n\t left: x1,\n\t bottom: y2,\n\t right: x2\n\t };\n\t }\n\t\n\t // ////////////////////////////////////////////////////////////////////////////////////////////\n\t // Cell switching\n\t\n\t function resetActiveCell() {\n\t setActiveCellInternal(null, false);\n\t }\n\t\n\t function setFocus() {\n\t if (tabbingDirection == -1) {\n\t $focusSink[0].focus();\n\t } else {\n\t $focusSink2[0].focus();\n\t }\n\t }\n\t\n\t function scrollCellIntoView(row, cell, doPaging) {\n\t scrollRowIntoView(row, doPaging);\n\t\n\t var colspan = getColspan(row, cell);\n\t var left = columnPosLeft[cell],\n\t right = columnPosRight[cell + (colspan > 1 ? colspan - 1 : 0)],\n\t scrollRight = scrollLeft + viewportW;\n\t\n\t if (left < scrollLeft) {\n\t $viewport.scrollLeft(left);\n\t handleScroll();\n\t render();\n\t } else if (right > scrollRight) {\n\t $viewport.scrollLeft(Math.min(left, right - $viewport[0].clientWidth));\n\t handleScroll();\n\t render();\n\t }\n\t }\n\t\n\t function setActiveCellInternal(newCell, opt_editMode) {\n\t if (activeCellNode !== null) {\n\t makeActiveCellNormal();\n\t (0, _jquery2.default)(activeCellNode).removeClass('active');\n\t if (rowsCache[activeRow]) {\n\t (0, _jquery2.default)(rowsCache[activeRow].rowNode).removeClass('active');\n\t }\n\t }\n\t\n\t var activeCellChanged = activeCellNode !== newCell;\n\t activeCellNode = newCell;\n\t\n\t if (activeCellNode != null) {\n\t activeRow = getRowFromNode(activeCellNode.parentNode);\n\t activeCell = activePosX = getCellFromNode(activeCellNode);\n\t\n\t if (opt_editMode == null) {\n\t opt_editMode = activeRow == getDataLength() || options.autoEdit;\n\t }\n\t\n\t (0, _jquery2.default)(activeCellNode).addClass('active');\n\t (0, _jquery2.default)(rowsCache[activeRow].rowNode).addClass('active');\n\t\n\t if (options.editable && opt_editMode && isCellPotentiallyEditable(activeRow, activeCell)) {\n\t clearTimeout(h_editorLoader);\n\t\n\t if (options.asyncEditorLoading) {\n\t h_editorLoader = setTimeout(function () {\n\t makeActiveCellEditable();\n\t }, options.asyncEditorLoadDelay);\n\t } else {\n\t makeActiveCellEditable();\n\t }\n\t }\n\t } else {\n\t activeRow = activeCell = null;\n\t }\n\t\n\t if (activeCellChanged) {\n\t trigger(self.onActiveCellChanged, getActiveCell());\n\t }\n\t }\n\t\n\t function clearTextSelection() {\n\t if (document.selection && document.selection.empty) {\n\t try {\n\t // IE fails here if selected element is not in dom\n\t document.selection.empty();\n\t } catch (e) {}\n\t } else if (window.getSelection) {\n\t var sel = window.getSelection();\n\t if (sel && sel.removeAllRanges) {\n\t sel.removeAllRanges();\n\t }\n\t }\n\t }\n\t\n\t function isCellPotentiallyEditable(row, cell) {\n\t var dataLength = getDataLength();\n\t // is the data for this row loaded?\n\t if (row < dataLength && !getDataItem(row)) {\n\t return false;\n\t }\n\t\n\t // are we in the Add New row? can we create new from this cell?\n\t if (columns[cell].cannotTriggerInsert && row >= dataLength) {\n\t return false;\n\t }\n\t\n\t // does this cell have an editor?\n\t if (!getEditor(row, cell)) {\n\t return false;\n\t }\n\t\n\t return true;\n\t }\n\t\n\t function makeActiveCellNormal() {\n\t if (!currentEditor) {\n\t return;\n\t }\n\t trigger(self.onBeforeCellEditorDestroy, { editor: currentEditor, grid: self });\n\t currentEditor.destroy();\n\t currentEditor = null;\n\t\n\t if (activeCellNode) {\n\t var d = getDataItem(activeRow);\n\t (0, _jquery2.default)(activeCellNode).removeClass('editable invalid');\n\t if (d) {\n\t var column = columns[activeCell];\n\t var formatter = getFormatter(activeRow, column);\n\t activeCellNode.innerHTML = formatter(activeRow, activeCell, getDataItemValueForColumn(d, column), column, d, self);\n\t invalidatePostProcessingResults(activeRow);\n\t }\n\t }\n\t\n\t // if there previously was text selected on a page (such as selected text in the edit cell just removed),\n\t // IE can't set focus to anything else correctly\n\t if (navigator.userAgent.toLowerCase().match(/msie/)) {\n\t clearTextSelection();\n\t }\n\t\n\t getEditorLock().deactivate(editController);\n\t }\n\t\n\t function makeActiveCellEditable(editor) {\n\t if (!activeCellNode) {\n\t return;\n\t }\n\t if (!options.editable) {\n\t throw 'Grid : makeActiveCellEditable : should never get called when options.editable is false';\n\t }\n\t\n\t // cancel pending async call if there is one\n\t clearTimeout(h_editorLoader);\n\t\n\t if (!isCellPotentiallyEditable(activeRow, activeCell)) {\n\t return;\n\t }\n\t\n\t var columnDef = columns[activeCell];\n\t var item = getDataItem(activeRow);\n\t\n\t if (trigger(self.onBeforeEditCell, {\n\t row: activeRow,\n\t cell: activeCell,\n\t item: item,\n\t column: columnDef,\n\t grid: self\n\t }) === false) {\n\t setFocus();\n\t return;\n\t }\n\t\n\t getEditorLock().activate(editController);\n\t (0, _jquery2.default)(activeCellNode).addClass('editable');\n\t\n\t var useEditor = editor || getEditor(activeRow, activeCell);\n\t\n\t // don't clear the cell if a custom editor is passed through\n\t if (!editor && !useEditor.suppressClearOnEdit) {\n\t activeCellNode.innerHTML = '';\n\t }\n\t\n\t currentEditor = new useEditor({\n\t grid: self,\n\t gridPosition: absBox($container[0]),\n\t position: absBox(activeCellNode),\n\t container: activeCellNode,\n\t column: columnDef,\n\t item: item || {},\n\t commitChanges: commitEditAndSetFocus,\n\t cancelChanges: cancelEditAndSetFocus\n\t });\n\t\n\t if (item) {\n\t currentEditor.loadValue(item);\n\t }\n\t\n\t serializedEditorValue = currentEditor.serializeValue();\n\t\n\t if (currentEditor.position) {\n\t handleActiveCellPositionChange();\n\t }\n\t }\n\t\n\t function commitEditAndSetFocus() {\n\t // if the commit fails, it would do so due to a validation error\n\t // if so, do not steal the focus from the editor\n\t if (getEditorLock().commitCurrentEdit()) {\n\t setFocus();\n\t if (options.autoEdit) {\n\t navigateDown();\n\t }\n\t }\n\t }\n\t\n\t function cancelEditAndSetFocus() {\n\t if (getEditorLock().cancelCurrentEdit()) {\n\t setFocus();\n\t }\n\t }\n\t\n\t function absBox(elem) {\n\t var box = {\n\t top: elem.offsetTop,\n\t left: elem.offsetLeft,\n\t bottom: 0,\n\t right: 0,\n\t width: (0, _jquery2.default)(elem).outerWidth(),\n\t height: (0, _jquery2.default)(elem).outerHeight(),\n\t visible: true\n\t };\n\t box.bottom = box.top + box.height;\n\t box.right = box.left + box.width;\n\t\n\t // walk up the tree\n\t var offsetParent = elem.offsetParent;\n\t while ((elem = elem.parentNode) != document.body) {\n\t if (elem == null) break;\n\t\n\t if (box.visible && elem.scrollHeight != elem.offsetHeight && (0, _jquery2.default)(elem).css('overflowY') != 'visible') {\n\t box.visible = box.bottom > elem.scrollTop && box.top < elem.scrollTop + elem.clientHeight;\n\t }\n\t\n\t if (box.visible && elem.scrollWidth != elem.offsetWidth && (0, _jquery2.default)(elem).css('overflowX') != 'visible') {\n\t box.visible = box.right > elem.scrollLeft && box.left < elem.scrollLeft + elem.clientWidth;\n\t }\n\t\n\t box.left -= elem.scrollLeft;\n\t box.top -= elem.scrollTop;\n\t\n\t if (elem === offsetParent) {\n\t box.left += elem.offsetLeft;\n\t box.top += elem.offsetTop;\n\t offsetParent = elem.offsetParent;\n\t }\n\t\n\t box.bottom = box.top + box.height;\n\t box.right = box.left + box.width;\n\t }\n\t\n\t return box;\n\t }\n\t\n\t function getActiveCellPosition() {\n\t return absBox(activeCellNode);\n\t }\n\t\n\t function getGridPosition() {\n\t return absBox($container[0]);\n\t }\n\t\n\t function handleActiveCellPositionChange() {\n\t if (!activeCellNode) {\n\t return;\n\t }\n\t\n\t trigger(self.onActiveCellPositionChanged, { grid: self });\n\t\n\t if (currentEditor) {\n\t var cellBox = getActiveCellPosition();\n\t if (currentEditor.show && currentEditor.hide) {\n\t if (!cellBox.visible) {\n\t currentEditor.hide();\n\t } else {\n\t currentEditor.show();\n\t }\n\t }\n\t\n\t if (currentEditor.position) {\n\t currentEditor.position(cellBox);\n\t }\n\t }\n\t }\n\t\n\t function getCellEditor() {\n\t return currentEditor;\n\t }\n\t\n\t function getActiveCell() {\n\t if (!activeCellNode) {\n\t return null;\n\t } else {\n\t return { row: activeRow, cell: activeCell, grid: self };\n\t }\n\t }\n\t\n\t function getActiveCellNode() {\n\t return activeCellNode;\n\t }\n\t\n\t function scrollRowIntoView(row, doPaging) {\n\t var rowAtTop = row * options.rowHeight;\n\t var rowAtBottom = (row + 1) * options.rowHeight - viewportH + (viewportHasHScroll ? scrollbarDimensions.height : 0);\n\t\n\t // need to page down?\n\t if ((row + 1) * options.rowHeight > scrollTop + viewportH + offset) {\n\t scrollTo(doPaging ? rowAtTop : rowAtBottom);\n\t render();\n\t }\n\t // or page up?\n\t else if (row * options.rowHeight < scrollTop + offset) {\n\t scrollTo(doPaging ? rowAtBottom : rowAtTop);\n\t render();\n\t }\n\t }\n\t\n\t function scrollRowToTop(row) {\n\t scrollTo(row * options.rowHeight);\n\t render();\n\t }\n\t\n\t function scrollPage(dir) {\n\t var deltaRows = dir * numVisibleRows;\n\t scrollTo((getRowFromPosition(scrollTop) + deltaRows) * options.rowHeight);\n\t render();\n\t\n\t if (options.enableCellNavigation && activeRow != null) {\n\t var row = activeRow + deltaRows;\n\t var dataLengthIncludingAddNew = getDataLengthIncludingAddNew();\n\t if (row >= dataLengthIncludingAddNew) {\n\t row = dataLengthIncludingAddNew - 1;\n\t }\n\t if (row < 0) {\n\t row = 0;\n\t }\n\t\n\t var cell = 0,\n\t prevCell = null;\n\t var prevActivePosX = activePosX;\n\t while (cell <= activePosX) {\n\t if (canCellBeActive(row, cell)) {\n\t prevCell = cell;\n\t }\n\t cell += getColspan(row, cell);\n\t }\n\t\n\t if (prevCell !== null) {\n\t setActiveCellInternal(getCellNode(row, prevCell));\n\t activePosX = prevActivePosX;\n\t } else {\n\t resetActiveCell();\n\t }\n\t }\n\t }\n\t\n\t function navigatePageDown() {\n\t scrollPage(1);\n\t }\n\t\n\t function navigatePageUp() {\n\t scrollPage(-1);\n\t }\n\t\n\t function getColspan(row, cell) {\n\t var metadata = data.getItemMetadata && data.getItemMetadata(row);\n\t if (!metadata || !metadata.columns) {\n\t return 1;\n\t }\n\t\n\t var columnData = metadata.columns[columns[cell].id] || metadata.columns[cell];\n\t var colspan = columnData && columnData.colspan;\n\t if (colspan === '*') {\n\t colspan = columns.length - cell;\n\t } else {\n\t colspan = colspan || 1;\n\t }\n\t\n\t return colspan;\n\t }\n\t\n\t function findFirstFocusableCell(row) {\n\t var cell = 0;\n\t while (cell < columns.length) {\n\t if (canCellBeActive(row, cell)) {\n\t return cell;\n\t }\n\t cell += getColspan(row, cell);\n\t }\n\t return null;\n\t }\n\t\n\t function findLastFocusableCell(row) {\n\t var cell = 0;\n\t var lastFocusableCell = null;\n\t while (cell < columns.length) {\n\t if (canCellBeActive(row, cell)) {\n\t lastFocusableCell = cell;\n\t }\n\t cell += getColspan(row, cell);\n\t }\n\t return lastFocusableCell;\n\t }\n\t\n\t function gotoRight(row, cell, posX) {\n\t if (cell >= columns.length) {\n\t return null;\n\t }\n\t\n\t do {\n\t cell += getColspan(row, cell);\n\t } while (cell < columns.length && !canCellBeActive(row, cell));\n\t\n\t if (cell < columns.length) {\n\t return {\n\t 'row': row,\n\t 'cell': cell,\n\t 'posX': cell\n\t };\n\t }\n\t return null;\n\t }\n\t\n\t function gotoLeft(row, cell, posX) {\n\t if (cell <= 0) {\n\t return null;\n\t }\n\t\n\t var firstFocusableCell = findFirstFocusableCell(row);\n\t if (firstFocusableCell === null || firstFocusableCell >= cell) {\n\t return null;\n\t }\n\t\n\t var prev = {\n\t 'row': row,\n\t 'cell': firstFocusableCell,\n\t 'posX': firstFocusableCell\n\t };\n\t var pos;\n\t while (true) {\n\t pos = gotoRight(prev.row, prev.cell, prev.posX);\n\t if (!pos) {\n\t return null;\n\t }\n\t if (pos.cell >= cell) {\n\t return prev;\n\t }\n\t prev = pos;\n\t }\n\t }\n\t\n\t function gotoDown(row, cell, posX) {\n\t var prevCell;\n\t var dataLengthIncludingAddNew = getDataLengthIncludingAddNew();\n\t while (true) {\n\t if (++row >= dataLengthIncludingAddNew) {\n\t return null;\n\t }\n\t\n\t prevCell = cell = 0;\n\t while (cell <= posX) {\n\t prevCell = cell;\n\t cell += getColspan(row, cell);\n\t }\n\t\n\t if (canCellBeActive(row, prevCell)) {\n\t return {\n\t 'row': row,\n\t 'cell': prevCell,\n\t 'posX': posX\n\t };\n\t }\n\t }\n\t }\n\t\n\t function gotoUp(row, cell, posX) {\n\t var prevCell;\n\t while (true) {\n\t if (--row < 0) {\n\t return null;\n\t }\n\t\n\t prevCell = cell = 0;\n\t while (cell <= posX) {\n\t prevCell = cell;\n\t cell += getColspan(row, cell);\n\t }\n\t\n\t if (canCellBeActive(row, prevCell)) {\n\t return {\n\t 'row': row,\n\t 'cell': prevCell,\n\t 'posX': posX\n\t };\n\t }\n\t }\n\t }\n\t\n\t function gotoNext(row, cell, posX) {\n\t if (row == null && cell == null) {\n\t row = cell = posX = 0;\n\t if (canCellBeActive(row, cell)) {\n\t return {\n\t 'row': row,\n\t 'cell': cell,\n\t 'posX': cell\n\t };\n\t }\n\t }\n\t\n\t var pos = gotoRight(row, cell, posX);\n\t if (pos) {\n\t return pos;\n\t }\n\t\n\t var firstFocusableCell = null;\n\t var dataLengthIncludingAddNew = getDataLengthIncludingAddNew();\n\t while (++row < dataLengthIncludingAddNew) {\n\t firstFocusableCell = findFirstFocusableCell(row);\n\t if (firstFocusableCell !== null) {\n\t return {\n\t 'row': row,\n\t 'cell': firstFocusableCell,\n\t 'posX': firstFocusableCell\n\t };\n\t }\n\t }\n\t return null;\n\t }\n\t\n\t function gotoPrev(row, cell, posX) {\n\t if (row == null && cell == null) {\n\t row = getDataLengthIncludingAddNew() - 1;\n\t cell = posX = columns.length - 1;\n\t if (canCellBeActive(row, cell)) {\n\t return {\n\t 'row': row,\n\t 'cell': cell,\n\t 'posX': cell\n\t };\n\t }\n\t }\n\t\n\t var pos;\n\t var lastSelectableCell;\n\t while (!pos) {\n\t pos = gotoLeft(row, cell, posX);\n\t if (pos) {\n\t break;\n\t }\n\t if (--row < 0) {\n\t return null;\n\t }\n\t\n\t cell = 0;\n\t lastSelectableCell = findLastFocusableCell(row);\n\t if (lastSelectableCell !== null) {\n\t pos = {\n\t 'row': row,\n\t 'cell': lastSelectableCell,\n\t 'posX': lastSelectableCell\n\t };\n\t }\n\t }\n\t return pos;\n\t }\n\t\n\t function navigateRight() {\n\t return navigate('right');\n\t }\n\t\n\t function navigateLeft() {\n\t return navigate('left');\n\t }\n\t\n\t function navigateDown() {\n\t return navigate('down');\n\t }\n\t\n\t function navigateUp() {\n\t return navigate('up');\n\t }\n\t\n\t function navigateNext() {\n\t return navigate('next');\n\t }\n\t\n\t function navigatePrev() {\n\t return navigate('prev');\n\t }\n\t\n\t /**\r\n\t * @param {string} dir Navigation direction.\r\n\t * @return {boolean} Whether navigation resulted in a change of active cell.\r\n\t */\n\t function navigate(dir) {\n\t if (!options.enableCellNavigation) {\n\t return false;\n\t }\n\t\n\t if (!activeCellNode && dir != 'prev' && dir != 'next') {\n\t return false;\n\t }\n\t\n\t if (!getEditorLock().commitCurrentEdit()) {\n\t return true;\n\t }\n\t setFocus();\n\t\n\t var tabbingDirections = {\n\t 'up': -1,\n\t 'down': 1,\n\t 'left': -1,\n\t 'right': 1,\n\t 'prev': -1,\n\t 'next': 1\n\t };\n\t tabbingDirection = tabbingDirections[dir];\n\t\n\t var stepFunctions = {\n\t 'up': gotoUp,\n\t 'down': gotoDown,\n\t 'left': gotoLeft,\n\t 'right': gotoRight,\n\t 'prev': gotoPrev,\n\t 'next': gotoNext\n\t };\n\t var stepFn = stepFunctions[dir];\n\t var pos = stepFn(activeRow, activeCell, activePosX);\n\t if (pos) {\n\t var isAddNewRow = pos.row == getDataLength();\n\t scrollCellIntoView(pos.row, pos.cell, !isAddNewRow);\n\t setActiveCellInternal(getCellNode(pos.row, pos.cell));\n\t activePosX = pos.posX;\n\t return true;\n\t } else {\n\t setActiveCellInternal(getCellNode(activeRow, activeCell));\n\t return false;\n\t }\n\t }\n\t\n\t function getCellNode(row, cell) {\n\t if (rowsCache[row]) {\n\t ensureCellNodesInRowsCache(row);\n\t return rowsCache[row].cellNodesByColumnIdx[cell];\n\t }\n\t return null;\n\t }\n\t\n\t function setActiveCell(row, cell) {\n\t if (!initialized) {\n\t return;\n\t }\n\t if (row > getDataLength() || row < 0 || cell >= columns.length || cell < 0) {\n\t return;\n\t }\n\t\n\t if (!options.enableCellNavigation) {\n\t return;\n\t }\n\t\n\t scrollCellIntoView(row, cell, false);\n\t setActiveCellInternal(getCellNode(row, cell), false);\n\t }\n\t\n\t function canCellBeActive(row, cell) {\n\t if (!options.enableCellNavigation || row >= getDataLengthIncludingAddNew() || row < 0 || cell >= columns.length || cell < 0) {\n\t return false;\n\t }\n\t\n\t var rowMetadata = data.getItemMetadata && data.getItemMetadata(row);\n\t if (rowMetadata && typeof rowMetadata.focusable === 'boolean') {\n\t return rowMetadata.focusable;\n\t }\n\t\n\t var columnMetadata = rowMetadata && rowMetadata.columns;\n\t if (columnMetadata && columnMetadata[columns[cell].id] && typeof columnMetadata[columns[cell].id].focusable === 'boolean') {\n\t return columnMetadata[columns[cell].id].focusable;\n\t }\n\t if (columnMetadata && columnMetadata[cell] && typeof columnMetadata[cell].focusable === 'boolean') {\n\t return columnMetadata[cell].focusable;\n\t }\n\t\n\t return columns[cell].focusable;\n\t }\n\t\n\t function canCellBeSelected(row, cell) {\n\t if (row >= getDataLength() || row < 0 || cell >= columns.length || cell < 0) {\n\t return false;\n\t }\n\t\n\t var rowMetadata = data.getItemMetadata && data.getItemMetadata(row);\n\t if (rowMetadata && typeof rowMetadata.selectable === 'boolean') {\n\t return rowMetadata.selectable;\n\t }\n\t\n\t var columnMetadata = rowMetadata && rowMetadata.columns && (rowMetadata.columns[columns[cell].id] || rowMetadata.columns[cell]);\n\t if (columnMetadata && typeof columnMetadata.selectable === 'boolean') {\n\t return columnMetadata.selectable;\n\t }\n\t\n\t return columns[cell].selectable;\n\t }\n\t\n\t function gotoCell(row, cell, forceEdit) {\n\t if (!initialized) {\n\t return;\n\t }\n\t if (!canCellBeActive(row, cell)) {\n\t return;\n\t }\n\t\n\t if (!getEditorLock().commitCurrentEdit()) {\n\t return;\n\t }\n\t\n\t scrollCellIntoView(row, cell, false);\n\t\n\t var newCell = getCellNode(row, cell);\n\t\n\t // if selecting the 'add new' row, start editing right away\n\t setActiveCellInternal(newCell, forceEdit || row === getDataLength() || options.autoEdit);\n\t\n\t // if no editor was created, set the focus back on the grid\n\t if (!currentEditor) {\n\t setFocus();\n\t }\n\t }\n\t\n\t // ////////////////////////////////////////////////////////////////////////////////////////////\n\t // IEditor implementation for the editor lock\n\t\n\t function commitCurrentEdit() {\n\t var item = getDataItem(activeRow);\n\t var column = columns[activeCell];\n\t\n\t if (currentEditor) {\n\t if (currentEditor.isValueChanged()) {\n\t var validationResults = currentEditor.validate();\n\t\n\t if (validationResults.valid) {\n\t if (activeRow < getDataLength()) {\n\t var editCommand = {\n\t row: activeRow,\n\t cell: activeCell,\n\t editor: currentEditor,\n\t serializedValue: currentEditor.serializeValue(),\n\t prevSerializedValue: serializedEditorValue,\n\t execute: function execute() {\n\t this.editor.applyValue(item, this.serializedValue);\n\t updateRow(this.row);\n\t trigger(self.onCellChange, {\n\t row: activeRow,\n\t cell: activeCell,\n\t item: item,\n\t grid: self\n\t });\n\t },\n\t undo: function undo() {\n\t this.editor.applyValue(item, this.prevSerializedValue);\n\t updateRow(this.row);\n\t trigger(self.onCellChange, {\n\t row: activeRow,\n\t cell: activeCell,\n\t item: item,\n\t grid: self\n\t });\n\t }\n\t };\n\t\n\t if (options.editCommandHandler) {\n\t makeActiveCellNormal();\n\t options.editCommandHandler(item, column, editCommand);\n\t } else {\n\t editCommand.execute();\n\t makeActiveCellNormal();\n\t }\n\t } else {\n\t var newItem = {};\n\t currentEditor.applyValue(newItem, currentEditor.serializeValue());\n\t makeActiveCellNormal();\n\t trigger(self.onAddNewRow, { item: newItem, column: column, grid: self });\n\t }\n\t\n\t // check whether the lock has been re-acquired by event handlers\n\t return !getEditorLock().isActive();\n\t } else {\n\t // Re-add the CSS class to trigger transitions, if any.\n\t (0, _jquery2.default)(activeCellNode).removeClass('invalid');\n\t (0, _jquery2.default)(activeCellNode).width(); // force layout\n\t (0, _jquery2.default)(activeCellNode).addClass('invalid');\n\t\n\t trigger(self.onValidationError, {\n\t editor: currentEditor,\n\t cellNode: activeCellNode,\n\t validationResults: validationResults,\n\t row: activeRow,\n\t cell: activeCell,\n\t column: column,\n\t grid: self\n\t });\n\t\n\t currentEditor.focus();\n\t return false;\n\t }\n\t }\n\t\n\t makeActiveCellNormal();\n\t }\n\t return true;\n\t }\n\t\n\t function cancelCurrentEdit() {\n\t makeActiveCellNormal();\n\t return true;\n\t }\n\t\n\t function rowsToRanges(rows) {\n\t var ranges = [];\n\t var lastCell = columns.length - 1;\n\t for (var i = 0; i < rows.length; i++) {\n\t ranges.push(new _slick2.default.Range(rows[i], 0, rows[i], lastCell));\n\t }\n\t return ranges;\n\t }\n\t\n\t function getSelectedRows() {\n\t if (!selectionModel) {\n\t throw 'Selection model is not set';\n\t }\n\t return selectedRows;\n\t }\n\t\n\t function setSelectedRows(rows) {\n\t if (!selectionModel) {\n\t throw 'Selection model is not set';\n\t }\n\t selectionModel.setSelectedRanges(rowsToRanges(rows));\n\t }\n\t\n\t // ////////////////////////////////////////////////////////////////////////////////////////////\n\t // Debug\n\t\n\t this.debug = function () {\n\t var s = '';\n\t\n\t s += '\\n' + 'counter_rows_rendered: ' + counter_rows_rendered;\n\t s += '\\n' + 'counter_rows_removed: ' + counter_rows_removed;\n\t s += '\\n' + 'renderedRows: ' + renderedRows;\n\t s += '\\n' + 'numVisibleRows: ' + numVisibleRows;\n\t s += '\\n' + 'maxSupportedCssHeight: ' + maxSupportedCssHeight;\n\t s += '\\n' + 'n(umber of pages): ' + n;\n\t s += '\\n' + '(current) page: ' + page;\n\t s += '\\n' + 'page height (ph): ' + ph;\n\t s += '\\n' + 'vScrollDir: ' + vScrollDir;\n\t\n\t alert(s);\n\t };\n\t\n\t // a debug helper to be able to access private members\n\t this.eval = function (expr) {\n\t return eval(expr);\n\t };\n\t\n\t // ////////////////////////////////////////////////////////////////////////////////////////////\n\t // Public API\n\t\n\t _jquery2.default.extend(this, {\n\t 'slickGridVersion': '2.2.4',\n\t\n\t // Events\n\t 'onScroll': new _slick2.default.Event(),\n\t 'onSort': new _slick2.default.Event(),\n\t 'onHeaderMouseEnter': new _slick2.default.Event(),\n\t 'onHeaderMouseLeave': new _slick2.default.Event(),\n\t 'onHeaderContextMenu': new _slick2.default.Event(),\n\t 'onHeaderClick': new _slick2.default.Event(),\n\t 'onHeaderCellRendered': new _slick2.default.Event(),\n\t 'onBeforeHeaderCellDestroy': new _slick2.default.Event(),\n\t 'onHeaderRowCellRendered': new _slick2.default.Event(),\n\t 'onFooterRowCellRendered': new _slick2.default.Event(),\n\t 'onBeforeHeaderRowCellDestroy': new _slick2.default.Event(),\n\t 'onBeforeFooterRowCellDestroy': new _slick2.default.Event(),\n\t 'onMouseEnter': new _slick2.default.Event(),\n\t 'onMouseLeave': new _slick2.default.Event(),\n\t 'onClick': new _slick2.default.Event(),\n\t 'onDblClick': new _slick2.default.Event(),\n\t 'onContextMenu': new _slick2.default.Event(),\n\t 'onKeyDown': new _slick2.default.Event(),\n\t 'onAddNewRow': new _slick2.default.Event(),\n\t 'onValidationError': new _slick2.default.Event(),\n\t 'onViewportChanged': new _slick2.default.Event(),\n\t 'onColumnsReordered': new _slick2.default.Event(),\n\t 'onColumnsResized': new _slick2.default.Event(),\n\t 'onCellChange': new _slick2.default.Event(),\n\t 'onBeforeEditCell': new _slick2.default.Event(),\n\t 'onBeforeCellEditorDestroy': new _slick2.default.Event(),\n\t 'onBeforeDestroy': new _slick2.default.Event(),\n\t 'onActiveCellChanged': new _slick2.default.Event(),\n\t 'onActiveCellPositionChanged': new _slick2.default.Event(),\n\t 'onDragInit': new _slick2.default.Event(),\n\t 'onDragStart': new _slick2.default.Event(),\n\t 'onDrag': new _slick2.default.Event(),\n\t 'onDragEnd': new _slick2.default.Event(),\n\t 'onSelectedRowsChanged': new _slick2.default.Event(),\n\t 'onCellCssStylesChanged': new _slick2.default.Event(),\n\t\n\t // Methods\n\t 'registerPlugin': registerPlugin,\n\t 'unregisterPlugin': unregisterPlugin,\n\t 'getColumns': getColumns,\n\t 'setColumns': setColumns,\n\t 'getColumnIndex': getColumnIndex,\n\t 'updateColumnHeader': updateColumnHeader,\n\t 'setSortColumn': setSortColumn,\n\t 'setSortColumns': setSortColumns,\n\t 'getSortColumns': getSortColumns,\n\t 'autosizeColumns': autosizeColumns,\n\t 'getOptions': getOptions,\n\t 'setOptions': setOptions,\n\t 'getData': getData,\n\t 'getDataLength': getDataLength,\n\t 'getDataItem': getDataItem,\n\t 'setData': setData,\n\t 'getSelectionModel': getSelectionModel,\n\t 'setSelectionModel': setSelectionModel,\n\t 'getSelectedRows': getSelectedRows,\n\t 'setSelectedRows': setSelectedRows,\n\t 'getContainerNode': getContainerNode,\n\t\n\t 'render': render,\n\t 'invalidate': invalidate,\n\t 'invalidateRow': invalidateRow,\n\t 'invalidateRows': invalidateRows,\n\t 'invalidateAllRows': invalidateAllRows,\n\t 'updateCell': updateCell,\n\t 'updateRow': updateRow,\n\t 'getViewport': getVisibleRange,\n\t 'getRenderedRange': getRenderedRange,\n\t 'resizeCanvas': resizeCanvas,\n\t 'updateRowCount': updateRowCount,\n\t 'scrollRowIntoView': scrollRowIntoView,\n\t 'scrollRowToTop': scrollRowToTop,\n\t 'scrollCellIntoView': scrollCellIntoView,\n\t 'getCanvasNode': getCanvasNode,\n\t 'focus': setFocus,\n\t\n\t 'getCellFromPoint': getCellFromPoint,\n\t 'getCellFromEvent': getCellFromEvent,\n\t 'getActiveCell': getActiveCell,\n\t 'setActiveCell': setActiveCell,\n\t 'getActiveCellNode': getActiveCellNode,\n\t 'getActiveCellPosition': getActiveCellPosition,\n\t 'resetActiveCell': resetActiveCell,\n\t 'editActiveCell': makeActiveCellEditable,\n\t 'getCellEditor': getCellEditor,\n\t 'getCellNode': getCellNode,\n\t 'getCellNodeBox': getCellNodeBox,\n\t 'canCellBeSelected': canCellBeSelected,\n\t 'canCellBeActive': canCellBeActive,\n\t 'navigatePrev': navigatePrev,\n\t 'navigateNext': navigateNext,\n\t 'navigateUp': navigateUp,\n\t 'navigateDown': navigateDown,\n\t 'navigateLeft': navigateLeft,\n\t 'navigateRight': navigateRight,\n\t 'navigatePageUp': navigatePageUp,\n\t 'navigatePageDown': navigatePageDown,\n\t 'gotoCell': gotoCell,\n\t 'getTopPanel': getTopPanel,\n\t 'setTopPanelVisibility': setTopPanelVisibility,\n\t 'setHeaderRowVisibility': setHeaderRowVisibility,\n\t 'getHeaderRow': getHeaderRow,\n\t 'getHeaderRowColumn': getHeaderRowColumn,\n\t 'setFooterRowVisibility': setFooterRowVisibility,\n\t 'getFooterRow': getFooterRow,\n\t 'getFooterRowColumn': getFooterRowColumn,\n\t 'getGridPosition': getGridPosition,\n\t 'flashCell': flashCell,\n\t 'addCellCssStyles': addCellCssStyles,\n\t 'setCellCssStyles': setCellCssStyles,\n\t 'removeCellCssStyles': removeCellCssStyles,\n\t 'getCellCssStyles': getCellCssStyles,\n\t\n\t 'init': finishInitialization,\n\t 'destroy': destroy,\n\t\n\t // IEditor implementation\n\t 'getEditorLock': getEditorLock,\n\t 'getEditController': getEditController\n\t });\n\t\n\t init();\n\t}\n\n/***/ }),\n/* 31 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _jquery = __webpack_require__(2);\n\t\n\tvar _jquery2 = _interopRequireDefault(_jquery);\n\t\n\tvar _slick = __webpack_require__(1);\n\t\n\tvar _slick2 = _interopRequireDefault(_slick);\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\t\n\texports.default = GroupItemMetadataProvider;\n\t\n\t/***\r\n\t * Provides item metadata for group (Slick.Group) and totals (Slick.Totals) rows produced by the DataView.\r\n\t * This metadata overrides the default behavior and formatting of those rows so that they appear and function\r\n\t * correctly when processed by the grid.\r\n\t *\r\n\t * This class also acts as a grid plugin providing event handlers to expand & collapse groups.\r\n\t * If \"grid.registerPlugin(...)\" is not called, expand & collapse will not work.\r\n\t *\r\n\t * @class GroupItemMetadataProvider\r\n\t * @module Data\r\n\t * @namespace Slick.Data\r\n\t * @constructor\r\n\t * @param options\r\n\t */\n\t\n\tfunction GroupItemMetadataProvider(options) {\n\t var _grid = void 0;\n\t var _defaults = {\n\t groupCssClass: \"slick-group\",\n\t groupTitleCssClass: \"slick-group-title\",\n\t totalsCssClass: \"slick-group-totals\",\n\t groupFocusable: true,\n\t totalsFocusable: false,\n\t toggleCssClass: \"slick-group-toggle\",\n\t toggleExpandedCssClass: \"expanded\",\n\t toggleCollapsedCssClass: \"collapsed\",\n\t enableExpandCollapse: true,\n\t groupFormatter: defaultGroupCellFormatter,\n\t totalsFormatter: defaultTotalsCellFormatter\n\t };\n\t\n\t options = _jquery2.default.extend(true, {}, _defaults, options);\n\t\n\t function defaultGroupCellFormatter(row, cell, value, columnDef, item) {\n\t if (!options.enableExpandCollapse) {\n\t return item.title;\n\t }\n\t\n\t var indentation = item.level * 15 + \"px\";\n\t\n\t return \"\" + \"\" + \"\" + item.title + \"\";\n\t }\n\t\n\t function defaultTotalsCellFormatter(row, cell, value, columnDef, item) {\n\t return columnDef.groupTotalsFormatter && columnDef.groupTotalsFormatter(item, columnDef) || \"\";\n\t }\n\t\n\t function init(grid) {\n\t _grid = grid;\n\t _grid.onClick.subscribe(handleGridClick);\n\t _grid.onKeyDown.subscribe(handleGridKeyDown);\n\t }\n\t\n\t function destroy() {\n\t if (_grid) {\n\t _grid.onClick.unsubscribe(handleGridClick);\n\t _grid.onKeyDown.unsubscribe(handleGridKeyDown);\n\t }\n\t }\n\t\n\t function handleGridClick(e, args) {\n\t var item = this.getDataItem(args.row);\n\t if (item && item instanceof _slick2.default.Group && (0, _jquery2.default)(e.target).hasClass(options.toggleCssClass)) {\n\t var range = _grid.getRenderedRange();\n\t this.getData().setRefreshHints({\n\t ignoreDiffsBefore: range.top,\n\t ignoreDiffsAfter: range.bottom + 1\n\t });\n\t\n\t if (item.collapsed) {\n\t this.getData().expandGroup(item.groupingKey);\n\t } else {\n\t this.getData().collapseGroup(item.groupingKey);\n\t }\n\t\n\t e.stopImmediatePropagation();\n\t e.preventDefault();\n\t }\n\t }\n\t\n\t // TODO: add -/+ handling\n\t function handleGridKeyDown(e) {\n\t if (options.enableExpandCollapse && e.which == _slick2.default.keyCode.SPACE) {\n\t var activeCell = this.getActiveCell();\n\t if (activeCell) {\n\t var item = this.getDataItem(activeCell.row);\n\t if (item && item instanceof _slick2.default.Group) {\n\t var range = _grid.getRenderedRange();\n\t this.getData().setRefreshHints({\n\t ignoreDiffsBefore: range.top,\n\t ignoreDiffsAfter: range.bottom + 1\n\t });\n\t\n\t if (item.collapsed) {\n\t this.getData().expandGroup(item.groupingKey);\n\t } else {\n\t this.getData().collapseGroup(item.groupingKey);\n\t }\n\t\n\t e.stopImmediatePropagation();\n\t e.preventDefault();\n\t }\n\t }\n\t }\n\t }\n\t\n\t function getGroupRowMetadata(item) {\n\t return {\n\t selectable: false,\n\t focusable: options.groupFocusable,\n\t cssClasses: options.groupCssClass,\n\t columns: {\n\t 0: {\n\t colspan: \"*\",\n\t formatter: options.groupFormatter,\n\t editor: null\n\t }\n\t }\n\t };\n\t }\n\t\n\t function getTotalsRowMetadata(item) {\n\t return {\n\t selectable: false,\n\t focusable: options.totalsFocusable,\n\t cssClasses: options.totalsCssClass,\n\t formatter: options.totalsFormatter,\n\t editor: null\n\t };\n\t }\n\t\n\t return {\n\t init: init,\n\t destroy: destroy,\n\t getGroupRowMetadata: getGroupRowMetadata,\n\t getTotalsRowMetadata: getTotalsRowMetadata\n\t };\n\t}\n\n/***/ }),\n/* 32 */\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"flatpickr\");\n\n/***/ })\n/******/ ])));\n\n\n// WEBPACK FOOTER //\n// slick.es6.min.js"," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\texports: {},\n \t\t\tid: moduleId,\n \t\t\tloaded: false\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.loaded = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"/\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(0);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap 8c7bca7696891a656754","/** *\r\n * Contains core SlickGrid classes.\r\n * @module Core\r\n * @namespace Slick\r\n */\r\nconst Slick = {\r\n Event: Event,\r\n EventData: EventData,\r\n EventHandler: EventHandler,\r\n Range: Range,\r\n NonDataRow: NonDataItem,\r\n Group: Group,\r\n GroupTotals: GroupTotals,\r\n EditorLock: EditorLock,\r\n /** *\r\n * A global singleton editor lock.\r\n * @class GlobalEditorLock\r\n * @static\r\n * @constructor\r\n */\r\n GlobalEditorLock: new EditorLock(),\r\n TreeColumns: TreeColumns,\r\n\r\n keyCode: {\r\n BACKSPACE: 8,\r\n DELETE: 46,\r\n DOWN: 40,\r\n END: 35,\r\n ENTER: 13,\r\n ESCAPE: 27,\r\n HOME: 36,\r\n INSERT: 45,\r\n LEFT: 37,\r\n PAGE_DOWN: 34,\r\n PAGE_UP: 33,\r\n RIGHT: 39,\r\n TAB: 9,\r\n UP: 38,\r\n SPACE: 32\r\n }\r\n};\r\n\r\nexport default Slick;\r\n\r\n/***\r\n * An event object for passing data to event handlers and letting them control propagation.\r\n *
This is pretty much identical to how W3C and jQuery implement events.
\r\n * @class EventData\r\n * @constructor\r\n */\r\nfunction EventData() {\r\n var isPropagationStopped = false;\r\n var isImmediatePropagationStopped = false;\r\n\r\n /***\r\n * Stops event from propagating up the DOM tree.\r\n * @method stopPropagation\r\n */\r\n this.stopPropagation = function() {\r\n isPropagationStopped = true;\r\n };\r\n\r\n /***\r\n * Returns whether stopPropagation was called on this event object.\r\n * @method isPropagationStopped\r\n * @return {Boolean}\r\n */\r\n this.isPropagationStopped = function() {\r\n return isPropagationStopped;\r\n };\r\n\r\n /***\r\n * Prevents the rest of the handlers from being executed.\r\n * @method stopImmediatePropagation\r\n */\r\n this.stopImmediatePropagation = function() {\r\n isImmediatePropagationStopped = true;\r\n };\r\n\r\n /***\r\n * Returns whether stopImmediatePropagation was called on this event object.\\\r\n * @method isImmediatePropagationStopped\r\n * @return {Boolean}\r\n */\r\n this.isImmediatePropagationStopped = function() {\r\n return isImmediatePropagationStopped;\r\n }\r\n}\r\n\r\n/***\r\n * A simple publisher-subscriber implementation.\r\n * @class Event\r\n * @constructor\r\n */\r\nfunction Event() {\r\n var handlers = [];\r\n\r\n /***\r\n * Adds an event handler to be called when the event is fired.\r\n *
Event handler will receive two arguments - an EventData and the data\r\n * object the event was fired with.
\r\n * @method subscribe\r\n * @param fn {Function} Event handler.\r\n */\r\n this.subscribe = function(fn) {\r\n handlers.push(fn);\r\n };\r\n\r\n /***\r\n * Removes an event handler added with subscribe(fn).\r\n * @method unsubscribe\r\n * @param fn {Function} Event handler to be removed.\r\n */\r\n this.unsubscribe = function(fn) {\r\n for (var i = handlers.length - 1; i >= 0; i--) {\r\n if (handlers[i] === fn) {\r\n handlers.splice(i, 1);\r\n }\r\n }\r\n };\r\n\r\n /***\r\n * Fires an event notifying all subscribers.\r\n * @method notify\r\n * @param args {Object} Additional data object to be passed to all handlers.\r\n * @param e {EventData}\r\n * Optional.\r\n * An EventData object to be passed to all handlers.\r\n * For DOM events, an existing W3C/jQuery event object can be passed in.\r\n * @param scope {Object}\r\n * Optional.\r\n * The scope (\"this\") within which the handler will be executed.\r\n * If not specified, the scope will be set to the Event instance.\r\n */\r\n this.notify = function(args, e, scope) {\r\n e = e || new EventData();\r\n scope = scope || this;\r\n\r\n var returnValue;\r\n for (var i = 0; i < handlers.length && !(e.isPropagationStopped() || e.isImmediatePropagationStopped()); i++) {\r\n returnValue = handlers[i].call(scope, e, args);\r\n }\r\n\r\n return returnValue;\r\n };\r\n}\r\n\r\nfunction EventHandler() {\r\n var handlers = [];\r\n\r\n this.subscribe = function(event, handler) {\r\n handlers.push({\r\n event: event,\r\n handler: handler\r\n });\r\n event.subscribe(handler);\r\n\r\n return this; // allow chaining\r\n };\r\n\r\n this.unsubscribe = function(event, handler) {\r\n var i = handlers.length;\r\n while (i--) {\r\n if (handlers[i].event === event && handlers[i].handler === handler) {\r\n handlers.splice(i, 1);\r\n event.unsubscribe(handler);\r\n return;\r\n }\r\n }\r\n\r\n return this; // allow chaining\r\n };\r\n\r\n this.unsubscribeAll = function() {\r\n var i = handlers.length;\r\n while (i--) {\r\n handlers[i].event.unsubscribe(handlers[i].handler);\r\n }\r\n handlers = [];\r\n\r\n return this; // allow chaining\r\n }\r\n}\r\n\r\n/***\r\n * A structure containing a range of cells.\r\n * @class Range\r\n * @constructor\r\n * @param fromRow {Integer} Starting row.\r\n * @param fromCell {Integer} Starting cell.\r\n * @param toRow {Integer} Optional. Ending row. Defaults to fromRow.\r\n * @param toCell {Integer} Optional. Ending cell. Defaults to fromCell.\r\n */\r\nfunction Range(fromRow, fromCell, toRow, toCell) {\r\n if (toRow === undefined && toCell === undefined) {\r\n toRow = fromRow;\r\n toCell = fromCell;\r\n }\r\n\r\n /***\r\n * @property fromRow\r\n * @type {Integer}\r\n */\r\n this.fromRow = Math.min(fromRow, toRow);\r\n\r\n /***\r\n * @property fromCell\r\n * @type {Integer}\r\n */\r\n this.fromCell = Math.min(fromCell, toCell);\r\n\r\n /***\r\n * @property toRow\r\n * @type {Integer}\r\n */\r\n this.toRow = Math.max(fromRow, toRow);\r\n\r\n /***\r\n * @property toCell\r\n * @type {Integer}\r\n */\r\n this.toCell = Math.max(fromCell, toCell);\r\n\r\n /***\r\n * Returns whether a range represents a single row.\r\n * @method isSingleRow\r\n * @return {Boolean}\r\n */\r\n this.isSingleRow = function() {\r\n return this.fromRow == this.toRow;\r\n };\r\n\r\n /***\r\n * Returns whether a range represents a single cell.\r\n * @method isSingleCell\r\n * @return {Boolean}\r\n */\r\n this.isSingleCell = function() {\r\n return this.fromRow == this.toRow && this.fromCell == this.toCell;\r\n };\r\n\r\n /***\r\n * Returns whether a range contains a given cell.\r\n * @method contains\r\n * @param row {Integer}\r\n * @param cell {Integer}\r\n * @return {Boolean}\r\n */\r\n this.contains = function(row, cell) {\r\n return row >= this.fromRow && row <= this.toRow && cell >= this.fromCell && cell <= this.toCell;\r\n };\r\n\r\n /***\r\n * Returns a readable representation of a range.\r\n * @method toString\r\n * @return {String}\r\n */\r\n this.toString = function() {\r\n if (this.isSingleCell()) {\r\n return \"(\" + this.fromRow + \":\" + this.fromCell + \")\";\r\n } else {\r\n return \"(\" + this.fromRow + \":\" + this.fromCell + \" - \" + this.toRow + \":\" + this.toCell + \")\";\r\n }\r\n }\r\n}\r\n\r\n\r\n/***\r\n * A base class that all special / non-data rows (like Group and GroupTotals) derive from.\r\n * @class NonDataItem\r\n * @constructor\r\n */\r\nfunction NonDataItem() {\r\n this.__nonDataRow = true;\r\n}\r\n\r\n\r\n/***\r\n * Information about a group of rows.\r\n * @class Group\r\n * @extends Slick.NonDataItem\r\n * @constructor\r\n */\r\nfunction Group() {\r\n this.__group = true;\r\n\r\n /**\r\n * Grouping level, starting with 0.\r\n * @property level\r\n * @type {Number}\r\n */\r\n this.level = 0;\r\n\r\n /***\r\n * Number of rows in the group.\r\n * @property count\r\n * @type {Integer}\r\n */\r\n this.count = 0;\r\n\r\n /***\r\n * Grouping value.\r\n * @property value\r\n * @type {Object}\r\n */\r\n this.value = null;\r\n\r\n /***\r\n * Formatted display value of the group.\r\n * @property title\r\n * @type {String}\r\n */\r\n this.title = null;\r\n\r\n /***\r\n * Whether a group is collapsed.\r\n * @property collapsed\r\n * @type {Boolean}\r\n */\r\n this.collapsed = false;\r\n\r\n /***\r\n * GroupTotals, if any.\r\n * @property totals\r\n * @type {GroupTotals}\r\n */\r\n this.totals = null;\r\n\r\n /**\r\n * Rows that are part of the group.\r\n * @property rows\r\n * @type {Array}\r\n */\r\n this.rows = [];\r\n\r\n /**\r\n * Sub-groups that are part of the group.\r\n * @property groups\r\n * @type {Array}\r\n */\r\n this.groups = null;\r\n\r\n /**\r\n * A unique key used to identify the group. This key can be used in calls to DataView\r\n * collapseGroup() or expandGroup().\r\n * @property groupingKey\r\n * @type {Object}\r\n */\r\n this.groupingKey = null;\r\n}\r\n\r\nGroup.prototype = new NonDataItem();\r\n\r\n/***\r\n * Compares two Group instances.\r\n * @method equals\r\n * @return {Boolean}\r\n * @param group {Group} Group instance to compare to.\r\n */\r\nGroup.prototype.equals = function(group) {\r\n return this.value === group.value && this.count === group.count && this.collapsed === group.collapsed && this.title === group.title;\r\n};\r\n\r\n/***\r\n * Information about group totals.\r\n * An instance of GroupTotals will be created for each totals row and passed to the aggregators\r\n * so that they can store arbitrary data in it. That data can later be accessed by group totals\r\n * formatters during the display.\r\n * @class GroupTotals\r\n * @extends Slick.NonDataItem\r\n * @constructor\r\n */\r\nfunction GroupTotals() {\r\n this.__groupTotals = true;\r\n\r\n /***\r\n * Parent Group.\r\n * @param group\r\n * @type {Group}\r\n */\r\n this.group = null;\r\n\r\n /***\r\n * Whether the totals have been fully initialized / calculated.\r\n * Will be set to false for lazy-calculated group totals.\r\n * @param initialized\r\n * @type {Boolean}\r\n */\r\n this.initialized = false;\r\n}\r\n\r\nGroupTotals.prototype = new NonDataItem();\r\n\r\n/***\r\n * A locking helper to track the active edit controller and ensure that only a single controller\r\n * can be active at a time. This prevents a whole class of state and validation synchronization\r\n * issues. An edit controller (such as SlickGrid) can query if an active edit is in progress\r\n * and attempt a commit or cancel before proceeding.\r\n * @class EditorLock\r\n * @constructor\r\n */\r\nfunction EditorLock() {\r\n var activeEditController = null;\r\n\r\n /***\r\n * Returns true if a specified edit controller is active (has the edit lock).\r\n * If the parameter is not specified, returns true if any edit controller is active.\r\n * @method isActive\r\n * @param editController {EditController}\r\n * @return {Boolean}\r\n */\r\n this.isActive = function(editController) {\r\n return (editController ? activeEditController === editController : activeEditController !== null);\r\n };\r\n\r\n /***\r\n * Sets the specified edit controller as the active edit controller (acquire edit lock).\r\n * If another edit controller is already active, and exception will be thrown.\r\n * @method activate\r\n * @param editController {EditController} edit controller acquiring the lock\r\n */\r\n this.activate = function(editController) {\r\n if (editController === activeEditController) { // already activated?\r\n return;\r\n }\r\n if (activeEditController !== null) {\r\n throw \"SlickGrid.EditorLock.activate: an editController is still active, can't activate another editController\";\r\n }\r\n if (!editController.commitCurrentEdit) {\r\n throw \"SlickGrid.EditorLock.activate: editController must implement .commitCurrentEdit()\";\r\n }\r\n if (!editController.cancelCurrentEdit) {\r\n throw \"SlickGrid.EditorLock.activate: editController must implement .cancelCurrentEdit()\";\r\n }\r\n activeEditController = editController;\r\n };\r\n\r\n /***\r\n * Unsets the specified edit controller as the active edit controller (release edit lock).\r\n * If the specified edit controller is not the active one, an exception will be thrown.\r\n * @method deactivate\r\n * @param editController {EditController} edit controller releasing the lock\r\n */\r\n this.deactivate = function(editController) {\r\n if (activeEditController !== editController) {\r\n throw \"SlickGrid.EditorLock.deactivate: specified editController is not the currently active one\";\r\n }\r\n activeEditController = null;\r\n };\r\n\r\n /***\r\n * Attempts to commit the current edit by calling \"commitCurrentEdit\" method on the active edit\r\n * controller and returns whether the commit attempt was successful (commit may fail due to validation\r\n * errors, etc.). Edit controller's \"commitCurrentEdit\" must return true if the commit has succeeded\r\n * and false otherwise. If no edit controller is active, returns true.\r\n * @method commitCurrentEdit\r\n * @return {Boolean}\r\n */\r\n this.commitCurrentEdit = function() {\r\n return (activeEditController ? activeEditController.commitCurrentEdit() : true);\r\n };\r\n\r\n /***\r\n * Attempts to cancel the current edit by calling \"cancelCurrentEdit\" method on the active edit\r\n * controller and returns whether the edit was successfully cancelled. If no edit controller is\r\n * active, returns true.\r\n * @method cancelCurrentEdit\r\n * @return {Boolean}\r\n */\r\n this.cancelCurrentEdit = function cancelCurrentEdit() {\r\n return (activeEditController ? activeEditController.cancelCurrentEdit() : true);\r\n };\r\n}\r\n\r\n/**\r\n *\r\n * @param {Array} treeColumns Array com levels of columns\r\n * @returns {{hasDepth: 'hasDepth', getTreeColumns: 'getTreeColumns', extractColumns: 'extractColumns', getDepth: 'getDepth', getColumnsInDepth: 'getColumnsInDepth', getColumnsInGroup: 'getColumnsInGroup', visibleColumns: 'visibleColumns', filter: 'filter', reOrder: reOrder}}\r\n * @constructor\r\n */\r\nfunction TreeColumns(treeColumns) {\r\n\r\n var columnsById = {};\r\n\r\n function init() {\r\n mapToId(treeColumns);\r\n }\r\n\r\n function mapToId(columns) {\r\n columns.forEach(function(column) {\r\n columnsById[column.id] = column;\r\n\r\n if (column.columns) mapToId(column.columns);\r\n });\r\n }\r\n\r\n function filter(node, condition) {\r\n\r\n return node.filter(function(column) {\r\n\r\n var valid = condition.call(column);\r\n\r\n if (valid && column.columns) column.columns = filter(column.columns, condition);\r\n\r\n return valid && (!column.columns || column.columns.length);\r\n });\r\n\r\n }\r\n\r\n function sort(columns, grid) {\r\n columns.sort(function(a, b) {\r\n var indexA = getOrDefault(grid.getColumnIndex(a.id)),\r\n indexB = getOrDefault(grid.getColumnIndex(b.id));\r\n\r\n return indexA - indexB;\r\n })\r\n .forEach(function(column) {\r\n if (column.columns) sort(column.columns, grid);\r\n });\r\n }\r\n\r\n function getOrDefault(value) {\r\n return typeof value === 'undefined' ? -1 : value;\r\n }\r\n\r\n function getDepth(node) {\r\n if (node.length) for (var i in node)\r\n return getDepth(node[i]);\r\n else if (node.columns) return 1 + getDepth(node.columns);\r\n else return 1;\r\n }\r\n\r\n function getColumnsInDepth(node, depth, current) {\r\n var columns = [];\r\n current = current || 0;\r\n\r\n if (depth == current) {\r\n\r\n if (node.length) node.forEach(function(n) {\r\n if (n.columns) n.extractColumns = function() {\r\n return extractColumns(n);\r\n };\r\n });\r\n\r\n return node;\r\n } else for (var i in node)\r\n if (node[i].columns) {\r\n columns = columns.concat(getColumnsInDepth(node[i].columns, depth, current + 1));\r\n }\r\n\r\n return columns;\r\n }\r\n\r\n function extractColumns(node) {\r\n var result = [];\r\n\r\n if (node.hasOwnProperty('length')) {\r\n\r\n for (var i = 0; i < node.length; i++)\r\n result = result.concat(extractColumns(node[i]));\r\n\r\n } else {\r\n\r\n if (node.hasOwnProperty('columns'))\r\n\r\n result = result.concat(extractColumns(node.columns));\r\n\r\n else return node;\r\n\r\n }\r\n\r\n return result;\r\n }\r\n\r\n function cloneTreeColumns() {\r\n return $.extend(true, [], treeColumns);\r\n }\r\n\r\n init();\r\n\r\n this.hasDepth = function() {\r\n\r\n for (var i in treeColumns)\r\n if (treeColumns[i].hasOwnProperty('columns')) return true;\r\n\r\n return false;\r\n };\r\n\r\n this.getTreeColumns = function() {\r\n return treeColumns;\r\n };\r\n\r\n this.extractColumns = function() {\r\n return this.hasDepth() ? extractColumns(treeColumns) : treeColumns;\r\n };\r\n\r\n this.getDepth = function() {\r\n return getDepth(treeColumns);\r\n };\r\n\r\n this.getColumnsInDepth = function(depth) {\r\n return getColumnsInDepth(treeColumns, depth);\r\n };\r\n\r\n this.getColumnsInGroup = function(groups) {\r\n return extractColumns(groups);\r\n };\r\n\r\n this.visibleColumns = function() {\r\n return filter(cloneTreeColumns(), function() {\r\n return this.visible;\r\n });\r\n };\r\n\r\n this.filter = function(condition) {\r\n return filter(cloneTreeColumns(), condition);\r\n };\r\n\r\n this.reOrder = function(grid) {\r\n return sort(treeColumns, grid);\r\n };\r\n\r\n this.getById = function(id) {\r\n return columnsById[id];\r\n };\r\n\r\n this.getInIds = function(ids) {\r\n return ids.map(function(id) {\r\n return columnsById[id];\r\n });\r\n }\r\n}\r\n\n\n\n// WEBPACK FOOTER //\n// ../src/slick.core.js","module.exports = require(\"jquery\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"jquery\"\n// module id = 2\n// module chunks = 0","import $ from 'jquery';\r\nimport Slick from '../../src/slick.core';\r\n\r\nexport default CellRangeDecorator;\r\n\r\n/** *\r\n * Displays an overlay on top of a given cell range.\r\n *\r\n * TODO:\r\n * Currently, it blocks mouse events to DOM nodes behind it.\r\n * Use FF and WebKit-specific 'pointer-events' CSS style, or some kind of event forwarding.\r\n * Could also construct the borders separately using 4 individual DIVs.\r\n *\r\n * @param {Grid} grid\r\n * @param {Object} options\r\n */\r\nfunction CellRangeDecorator(grid, options){\r\n let _elem;\r\n const _defaults = {\r\n selectionCssClass: 'slick-range-decorator',\r\n selectionCss: {\r\n zIndex: '9999',\r\n border: '2px dashed red'\r\n }\r\n };\r\n\r\n options = Object.assign({}, _defaults, options);\r\n\r\n function show(range){\r\n if (!_elem){\r\n _elem = $('
', {css: options.selectionCss})\r\n .addClass(options.selectionCssClass)\r\n .css('position', 'absolute')\r\n .appendTo(grid.getCanvasNode());\r\n }\r\n\r\n const from = grid.getCellNodeBox(range.fromRow, range.fromCell);\r\n const to = grid.getCellNodeBox(range.toRow, range.toCell);\r\n\r\n _elem.css({\r\n top: from.top - 1,\r\n left: from.left - 1,\r\n height: to.bottom - from.top - 2,\r\n width: to.right - from.left - 2\r\n });\r\n\r\n return _elem;\r\n }\r\n\r\n function hide(){\r\n if (_elem){\r\n _elem.remove();\r\n _elem = null;\r\n }\r\n }\r\n\r\n Object.assign(this, {\r\n show,\r\n hide\r\n });\r\n}\r\n\n\n\n// WEBPACK FOOTER //\n// ../plugins/slick.cellrangedecorator/slick.cellrangedecorator.js","import $ from 'jquery';\r\nimport Slick from '../../src/slick.core';\r\nimport CellRangeDecorator from '../slick.cellrangedecorator/slick.cellrangedecorator';\r\n\r\nexport default CellRangeSelector;\r\n\r\nfunction CellRangeSelector(options){\r\n let _grid;\r\n let _canvas;\r\n let _dragging;\r\n let _decorator;\r\n let _range = {};\r\n\r\n const _self = this;\r\n const _handler = new Slick.EventHandler();\r\n const _defaults = {\r\n selectionCss: {\r\n // 'border': '2px dashed blue'\r\n }\r\n };\r\n\r\n function init(grid){\r\n options = Object.assign({}, _defaults, options);\r\n _decorator = new CellRangeDecorator(grid, options);\r\n _grid = grid;\r\n _canvas = _grid.getCanvasNode();\r\n _handler\r\n .subscribe(_grid.onDragInit, handleDragInit)\r\n .subscribe(_grid.onDragStart, handleDragStart)\r\n .subscribe(_grid.onDrag, handleDrag)\r\n .subscribe(_grid.onDragEnd, handleDragEnd);\r\n }\r\n\r\n function destroy(){\r\n _handler.unsubscribeAll();\r\n }\r\n\r\n function handleDragInit(e, dd){\r\n // prevent the grid from cancelling drag'n'drop by default\r\n e.stopImmediatePropagation();\r\n }\r\n\r\n function handleDragStart(jqueryEvent, interactEvent){\r\n const cell = _grid.getCellFromEvent(interactEvent.originalEvent);\r\n if (_self.onBeforeCellRangeSelected.notify(cell) !== false){\r\n if (_grid.canCellBeSelected(cell.row, cell.cell)){\r\n _dragging = true;\r\n // jqueryEvent.stopImmediatePropagation();\r\n }\r\n }\r\n if (!_dragging){\r\n return;\r\n }\r\n\r\n _grid.focus();\r\n\r\n const start = _grid.getCellFromPoint(\r\n interactEvent.x0 - $(_canvas).offset().left,\r\n interactEvent.y0 - $(_canvas).offset().top\r\n );\r\n\r\n _range = {\r\n start,\r\n end: {}\r\n };\r\n\r\n return _decorator.show(new Slick.Range(start.row, start.cell));\r\n }\r\n\r\n function handleDrag(e, interactEvent){\r\n if (!_dragging){\r\n return;\r\n }\r\n // e.stopImmediatePropagation();\r\n\r\n const end = _grid.getCellFromPoint(\r\n interactEvent.pageX - $(_canvas).offset().left,\r\n interactEvent.pageY - $(_canvas).offset().top);\r\n\r\n if (!_grid.canCellBeSelected(end.row, end.cell)){\r\n return;\r\n }\r\n\r\n _range.end = end;\r\n _decorator.show(new Slick.Range(_range.start.row, _range.start.cell, end.row, end.cell));\r\n }\r\n\r\n function handleDragEnd(e){\r\n if (!_dragging){\r\n return;\r\n }\r\n\r\n _dragging = false;\r\n // e.stopImmediatePropagation();\r\n\r\n _decorator.hide();\r\n _self.onCellRangeSelected.notify({\r\n range: new Slick.Range(\r\n _range.start.row,\r\n _range.start.cell,\r\n _range.end.row,\r\n _range.end.cell\r\n )\r\n });\r\n _range = {};\r\n }\r\n\r\n Object.assign(this, {\r\n init,\r\n destroy,\r\n\r\n onBeforeCellRangeSelected: new Slick.Event(),\r\n onCellRangeSelected: new Slick.Event()\r\n });\r\n}\r\n\n\n\n// WEBPACK FOOTER //\n// ../plugins/slick.cellrangeselector/slick.cellrangeselector.js","/**\r\n * interact.js v1.2.6\r\n *\r\n * Copyright (c) 2012-2015 Taye Adeyemi \r\n * Open source under the MIT License.\r\n * https://raw.github.com/taye/interact.js/master/LICENSE\r\n *\r\n * This file has been monkey patched to pass the originalEvent on to drag events\r\n */\r\n(function(realWindow){\r\n 'use strict';\r\n\r\n // return early if there's no window to work with (eg. Node.js)\r\n if (!realWindow){ return; }\r\n\r\n var // get wrapped window if using Shadow DOM polyfill\r\n window = (function(){\r\n // create a TextNode\r\n var el = realWindow.document.createTextNode('');\r\n\r\n // check if it's wrapped by a polyfill\r\n if (el.ownerDocument !== realWindow.document\r\n && typeof realWindow.wrap === 'function'\r\n && realWindow.wrap(el) === el){\r\n // return wrapped window\r\n return realWindow.wrap(realWindow);\r\n }\r\n\r\n // no Shadow DOM polyfil or native implementation\r\n return realWindow;\r\n }()),\r\n\r\n document = window.document,\r\n DocumentFragment = window.DocumentFragment || blank,\r\n SVGElement = window.SVGElement || blank,\r\n SVGSVGElement = window.SVGSVGElement || blank,\r\n SVGElementInstance = window.SVGElementInstance || blank,\r\n HTMLElement = window.HTMLElement || window.Element,\r\n\r\n PointerEvent = (window.PointerEvent || window.MSPointerEvent),\r\n pEventTypes,\r\n\r\n hypot = Math.hypot || function(x, y){ return Math.sqrt(x * x + y * y); },\r\n\r\n tmpXY = {}, // reduce object creation in getXY()\r\n\r\n documents = [], // all documents being listened to\r\n\r\n interactables = [], // all set interactables\r\n interactions = [], // all interactions\r\n\r\n dynamicDrop = false,\r\n\r\n // {\r\n // type: {\r\n // selectors: ['selector', ...],\r\n // contexts : [document, ...],\r\n // listeners: [[listener, useCapture], ...]\r\n // }\r\n // }\r\n delegatedEvents = {},\r\n\r\n defaultOptions = {\r\n base: {\r\n accept: null,\r\n actionChecker: null,\r\n styleCursor: true,\r\n preventDefault: 'auto',\r\n origin: { x: 0, y: 0 },\r\n deltaSource: 'page',\r\n allowFrom: null,\r\n ignoreFrom: null,\r\n _context: document,\r\n dropChecker: null\r\n },\r\n\r\n drag: {\r\n enabled: false,\r\n manualStart: true,\r\n max: Infinity,\r\n maxPerElement: 1,\r\n\r\n snap: null,\r\n restrict: null,\r\n inertia: null,\r\n autoScroll: null,\r\n\r\n axis: 'xy'\r\n },\r\n\r\n drop: {\r\n enabled: false,\r\n accept: null,\r\n overlap: 'pointer'\r\n },\r\n\r\n resize: {\r\n enabled: false,\r\n manualStart: false,\r\n max: Infinity,\r\n maxPerElement: 1,\r\n\r\n snap: null,\r\n restrict: null,\r\n inertia: null,\r\n autoScroll: null,\r\n\r\n square: false,\r\n preserveAspectRatio: false,\r\n axis: 'xy',\r\n\r\n // use default margin\r\n margin: NaN,\r\n\r\n // object with props left, right, top, bottom which are\r\n // true/false values to resize when the pointer is over that edge,\r\n // CSS selectors to match the handles for each direction\r\n // or the Elements for each handle\r\n edges: null,\r\n\r\n // a value of 'none' will limit the resize rect to a minimum of 0x0\r\n // 'negate' will alow the rect to have negative width/height\r\n // 'reposition' will keep the width/height positive by swapping\r\n // the top and bottom edges and/or swapping the left and right edges\r\n invert: 'none'\r\n },\r\n\r\n gesture: {\r\n manualStart: false,\r\n enabled: false,\r\n max: Infinity,\r\n maxPerElement: 1,\r\n\r\n restrict: null\r\n },\r\n\r\n perAction: {\r\n manualStart: false,\r\n max: Infinity,\r\n maxPerElement: 1,\r\n\r\n snap: {\r\n enabled: false,\r\n endOnly: false,\r\n range: Infinity,\r\n targets: null,\r\n offsets: null,\r\n\r\n relativePoints: null\r\n },\r\n\r\n restrict: {\r\n enabled: false,\r\n endOnly: false\r\n },\r\n\r\n autoScroll: {\r\n enabled: false,\r\n container: null, // the item that is scrolled (Window or HTMLElement)\r\n margin: 60,\r\n speed: 300 // the scroll speed in pixels per second\r\n },\r\n\r\n inertia: {\r\n enabled: false,\r\n resistance: 10, // the lambda in exponential decay\r\n minSpeed: 100, // target speed must be above this for inertia to start\r\n endSpeed: 10, // the speed at which inertia is slow enough to stop\r\n allowResume: true, // allow resuming an action in inertia phase\r\n zeroResumeDelta: true, // if an action is resumed after launch, set dx/dy to 0\r\n smoothEndDuration: 300 // animate to snap/restrict endOnly if there's no inertia\r\n }\r\n },\r\n\r\n _holdDuration: 600\r\n },\r\n\r\n // Things related to autoScroll\r\n autoScroll = {\r\n interaction: null,\r\n i: null, // the handle returned by window.setInterval\r\n x: 0, y: 0, // Direction each pulse is to scroll in\r\n\r\n // scroll the window by the values in scroll.x/y\r\n scroll: function(){\r\n var options = autoScroll.interaction.target.options[autoScroll.interaction.prepared.name].autoScroll,\r\n container = options.container || getWindow(autoScroll.interaction.element),\r\n now = new Date().getTime(),\r\n // change in time in seconds\r\n dtx = (now - autoScroll.prevTimeX) / 1000,\r\n dty = (now - autoScroll.prevTimeY) / 1000,\r\n vx, vy, sx, sy;\r\n\r\n // displacement\r\n if (options.velocity){\r\n vx = options.velocity.x;\r\n vy = options.velocity.y;\r\n }\r\n else {\r\n vx = vy = options.speed;\r\n }\r\n\r\n sx = vx * dtx;\r\n sy = vy * dty;\r\n\r\n if (sx >= 1 || sy >= 1){\r\n if (isWindow(container)){\r\n container.scrollBy(autoScroll.x * sx, autoScroll.y * sy);\r\n }\r\n else if (container){\r\n container.scrollLeft += autoScroll.x * sx;\r\n container.scrollTop += autoScroll.y * sy;\r\n }\r\n\r\n if (sx >= 1) autoScroll.prevTimeX = now;\r\n if (sy >= 1) autoScroll.prevTimeY = now;\r\n }\r\n\r\n if (autoScroll.isScrolling){\r\n cancelFrame(autoScroll.i);\r\n autoScroll.i = reqFrame(autoScroll.scroll);\r\n }\r\n },\r\n\r\n isScrolling: false,\r\n prevTimeX: 0,\r\n prevTimeY: 0,\r\n\r\n start: function(interaction){\r\n autoScroll.isScrolling = true;\r\n cancelFrame(autoScroll.i);\r\n\r\n autoScroll.interaction = interaction;\r\n autoScroll.prevTimeX = new Date().getTime();\r\n autoScroll.prevTimeY = new Date().getTime();\r\n autoScroll.i = reqFrame(autoScroll.scroll);\r\n },\r\n\r\n stop: function(){\r\n autoScroll.isScrolling = false;\r\n cancelFrame(autoScroll.i);\r\n }\r\n },\r\n\r\n // Does the browser support touch input?\r\n supportsTouch = (('ontouchstart' in window) || window.DocumentTouch && document instanceof window.DocumentTouch),\r\n\r\n // Does the browser support PointerEvents\r\n supportsPointerEvent = PointerEvent && !/Chrome/.test(navigator.userAgent),\r\n\r\n // Less Precision with touch input\r\n margin = supportsTouch || supportsPointerEvent ? 20 : 10,\r\n\r\n pointerMoveTolerance = 1,\r\n\r\n // for ignoring browser's simulated mouse events\r\n prevTouchTime = 0,\r\n\r\n // Allow this many interactions to happen simultaneously\r\n maxInteractions = Infinity,\r\n\r\n // Check if is IE9 or older\r\n actionCursors = (document.all && !window.atob) ? {\r\n drag: 'move',\r\n resizex: 'e-resize',\r\n resizey: 's-resize',\r\n resizexy: 'se-resize',\r\n\r\n resizetop: 'n-resize',\r\n resizeleft: 'w-resize',\r\n resizebottom: 's-resize',\r\n resizeright: 'e-resize',\r\n resizetopleft: 'se-resize',\r\n resizebottomright: 'se-resize',\r\n resizetopright: 'ne-resize',\r\n resizebottomleft: 'ne-resize',\r\n\r\n gesture: ''\r\n } : {\r\n drag: 'move',\r\n resizex: 'ew-resize',\r\n resizey: 'ns-resize',\r\n resizexy: 'nwse-resize',\r\n\r\n resizetop: 'ns-resize',\r\n resizeleft: 'ew-resize',\r\n resizebottom: 'ns-resize',\r\n resizeright: 'ew-resize',\r\n resizetopleft: 'nwse-resize',\r\n resizebottomright: 'nwse-resize',\r\n resizetopright: 'nesw-resize',\r\n resizebottomleft: 'nesw-resize',\r\n\r\n gesture: ''\r\n },\r\n\r\n actionIsEnabled = {\r\n drag: true,\r\n resize: true,\r\n gesture: true\r\n },\r\n\r\n // because Webkit and Opera still use 'mousewheel' event type\r\n wheelEvent = 'onmousewheel' in document ? 'mousewheel' : 'wheel',\r\n\r\n eventTypes = [\r\n 'dragstart',\r\n 'dragmove',\r\n 'draginertiastart',\r\n 'dragend',\r\n 'dragenter',\r\n 'dragleave',\r\n 'dropactivate',\r\n 'dropdeactivate',\r\n 'dropmove',\r\n 'drop',\r\n 'resizestart',\r\n 'resizemove',\r\n 'resizeinertiastart',\r\n 'resizeend',\r\n 'gesturestart',\r\n 'gesturemove',\r\n 'gestureinertiastart',\r\n 'gestureend',\r\n\r\n 'down',\r\n 'move',\r\n 'up',\r\n 'cancel',\r\n 'tap',\r\n 'doubletap',\r\n 'hold'\r\n ],\r\n\r\n globalEvents = {},\r\n\r\n // Opera Mobile must be handled differently\r\n isOperaMobile = navigator.appName == 'Opera' &&\r\n supportsTouch &&\r\n navigator.userAgent.match('Presto'),\r\n\r\n // scrolling doesn't change the result of getClientRects on iOS 7\r\n isIOS7 = (/iP(hone|od|ad)/.test(navigator.platform)\r\n && /OS 7[^\\d]/.test(navigator.appVersion)),\r\n\r\n // prefix matchesSelector\r\n prefixedMatchesSelector = 'matches' in Element.prototype ?\r\n 'matches' : 'webkitMatchesSelector' in Element.prototype ?\r\n 'webkitMatchesSelector' : 'mozMatchesSelector' in Element.prototype ?\r\n 'mozMatchesSelector' : 'oMatchesSelector' in Element.prototype ?\r\n 'oMatchesSelector' : 'msMatchesSelector',\r\n\r\n // will be polyfill function if browser is IE8\r\n ie8MatchesSelector,\r\n\r\n // native requestAnimationFrame or polyfill\r\n reqFrame = realWindow.requestAnimationFrame,\r\n cancelFrame = realWindow.cancelAnimationFrame,\r\n\r\n // Events wrapper\r\n events = (function(){\r\n var useAttachEvent = ('attachEvent' in window) && !('addEventListener' in window),\r\n addEvent = useAttachEvent ? 'attachEvent' : 'addEventListener',\r\n removeEvent = useAttachEvent ? 'detachEvent' : 'removeEventListener',\r\n on = useAttachEvent ? 'on' : '',\r\n\r\n elements = [],\r\n targets = [],\r\n attachedListeners = [];\r\n\r\n function add(element, type, listener, useCapture){\r\n var elementIndex = indexOf(elements, element),\r\n target = targets[elementIndex];\r\n\r\n if (!target){\r\n target = {\r\n events: {},\r\n typeCount: 0\r\n };\r\n\r\n elementIndex = elements.push(element) - 1;\r\n targets.push(target);\r\n\r\n attachedListeners.push((useAttachEvent ? {\r\n supplied: [],\r\n wrapped: [],\r\n useCount: []\r\n } : null));\r\n }\r\n\r\n if (!target.events[type]){\r\n target.events[type] = [];\r\n target.typeCount++;\r\n }\r\n\r\n if (!contains(target.events[type], listener)){\r\n var ret;\r\n\r\n if (useAttachEvent){\r\n var listeners = attachedListeners[elementIndex],\r\n listenerIndex = indexOf(listeners.supplied, listener);\r\n\r\n var wrapped = listeners.wrapped[listenerIndex] || function(event){\r\n if (!event.immediatePropagationStopped){\r\n event.target = event.srcElement;\r\n event.currentTarget = element;\r\n\r\n event.preventDefault = event.preventDefault || preventDef;\r\n event.stopPropagation = event.stopPropagation || stopProp;\r\n event.stopImmediatePropagation = event.stopImmediatePropagation || stopImmProp;\r\n\r\n if (/mouse|click/.test(event.type)){\r\n event.pageX = event.clientX + getWindow(element).document.documentElement.scrollLeft;\r\n event.pageY = event.clientY + getWindow(element).document.documentElement.scrollTop;\r\n }\r\n\r\n listener(event);\r\n }\r\n };\r\n\r\n ret = element[addEvent](on + type, wrapped, Boolean(useCapture));\r\n\r\n if (listenerIndex === -1){\r\n listeners.supplied.push(listener);\r\n listeners.wrapped.push(wrapped);\r\n listeners.useCount.push(1);\r\n }\r\n else {\r\n listeners.useCount[listenerIndex]++;\r\n }\r\n }\r\n else {\r\n ret = element[addEvent](type, listener, useCapture || false);\r\n }\r\n target.events[type].push(listener);\r\n\r\n return ret;\r\n }\r\n }\r\n\r\n function remove(element, type, listener, useCapture){\r\n var i,\r\n elementIndex = indexOf(elements, element),\r\n target = targets[elementIndex],\r\n listeners,\r\n listenerIndex,\r\n wrapped = listener;\r\n\r\n if (!target || !target.events){\r\n return;\r\n }\r\n\r\n if (useAttachEvent){\r\n listeners = attachedListeners[elementIndex];\r\n listenerIndex = indexOf(listeners.supplied, listener);\r\n wrapped = listeners.wrapped[listenerIndex];\r\n }\r\n\r\n if (type === 'all'){\r\n for (type in target.events){\r\n if (target.events.hasOwnProperty(type)){\r\n remove(element, type, 'all');\r\n }\r\n }\r\n return;\r\n }\r\n\r\n if (target.events[type]){\r\n var len = target.events[type].length;\r\n\r\n if (listener === 'all'){\r\n for (i = 0; i < len; i++){\r\n remove(element, type, target.events[type][i], Boolean(useCapture));\r\n }\r\n return;\r\n } else {\r\n for (i = 0; i < len; i++){\r\n if (target.events[type][i] === listener){\r\n element[removeEvent](on + type, wrapped, useCapture || false);\r\n target.events[type].splice(i, 1);\r\n\r\n if (useAttachEvent && listeners){\r\n listeners.useCount[listenerIndex]--;\r\n if (listeners.useCount[listenerIndex] === 0){\r\n listeners.supplied.splice(listenerIndex, 1);\r\n listeners.wrapped.splice(listenerIndex, 1);\r\n listeners.useCount.splice(listenerIndex, 1);\r\n }\r\n }\r\n\r\n break;\r\n }\r\n }\r\n }\r\n\r\n if (target.events[type] && target.events[type].length === 0){\r\n target.events[type] = null;\r\n target.typeCount--;\r\n }\r\n }\r\n\r\n if (!target.typeCount){\r\n targets.splice(elementIndex, 1);\r\n elements.splice(elementIndex, 1);\r\n attachedListeners.splice(elementIndex, 1);\r\n }\r\n }\r\n\r\n function preventDef(){\r\n this.returnValue = false;\r\n }\r\n\r\n function stopProp(){\r\n this.cancelBubble = true;\r\n }\r\n\r\n function stopImmProp(){\r\n this.cancelBubble = true;\r\n this.immediatePropagationStopped = true;\r\n }\r\n\r\n return {\r\n add: add,\r\n remove: remove,\r\n useAttachEvent: useAttachEvent,\r\n\r\n _elements: elements,\r\n _targets: targets,\r\n _attachedListeners: attachedListeners\r\n };\r\n }());\r\n\r\n function blank(){}\r\n\r\n function isElement(o){\r\n if (!o || (typeof o !== 'object')){ return false; }\r\n\r\n var _window = getWindow(o) || window;\r\n\r\n return (/object|function/.test(typeof _window.Element)\r\n ? o instanceof _window.Element // DOM2\r\n : o.nodeType === 1 && typeof o.nodeName === 'string');\r\n }\r\n function isWindow(thing){ return thing === window || !!(thing && thing.Window) && (thing instanceof thing.Window); }\r\n function isDocFrag(thing){ return !!thing && thing instanceof DocumentFragment; }\r\n function isArray(thing){\r\n return isObject(thing)\r\n && (typeof thing.length !== undefined)\r\n && isFunction(thing.splice);\r\n }\r\n function isObject(thing){ return !!thing && (typeof thing === 'object'); }\r\n function isFunction(thing){ return typeof thing === 'function'; }\r\n function isNumber(thing){ return typeof thing === 'number'; }\r\n function isBool(thing){ return typeof thing === 'boolean'; }\r\n function isString(thing){ return typeof thing === 'string'; }\r\n\r\n function trySelector(value){\r\n if (!isString(value)){ return false; }\r\n\r\n // an exception will be raised if it is invalid\r\n document.querySelector(value);\r\n return true;\r\n }\r\n\r\n function extend(dest, source){\r\n for (var prop in source){\r\n dest[prop] = source[prop];\r\n }\r\n return dest;\r\n }\r\n\r\n var prefixedPropREs = {\r\n webkit: /(Movement[XY]|Radius[XY]|RotationAngle|Force)$/\r\n };\r\n\r\n function pointerExtend(dest, source){\r\n for (var prop in source){\r\n var deprecated = false;\r\n\r\n // skip deprecated prefixed properties\r\n for (var vendor in prefixedPropREs){\r\n if (prop.indexOf(vendor) === 0 && prefixedPropREs[vendor].test(prop)){\r\n deprecated = true;\r\n break;\r\n }\r\n }\r\n\r\n if (!deprecated){\r\n dest[prop] = source[prop];\r\n }\r\n }\r\n return dest;\r\n }\r\n\r\n function copyCoords(dest, src){\r\n dest.page = dest.page || {};\r\n dest.page.x = src.page.x;\r\n dest.page.y = src.page.y;\r\n\r\n dest.client = dest.client || {};\r\n dest.client.x = src.client.x;\r\n dest.client.y = src.client.y;\r\n\r\n dest.timeStamp = src.timeStamp;\r\n }\r\n\r\n function setEventXY(targetObj, pointers, interaction){\r\n var pointer = (pointers.length > 1\r\n ? pointerAverage(pointers)\r\n : pointers[0]);\r\n\r\n getPageXY(pointer, tmpXY, interaction);\r\n targetObj.page.x = tmpXY.x;\r\n targetObj.page.y = tmpXY.y;\r\n\r\n getClientXY(pointer, tmpXY, interaction);\r\n targetObj.client.x = tmpXY.x;\r\n targetObj.client.y = tmpXY.y;\r\n\r\n targetObj.timeStamp = new Date().getTime();\r\n }\r\n\r\n function setEventDeltas(targetObj, prev, cur){\r\n targetObj.page.x = cur.page.x - prev.page.x;\r\n targetObj.page.y = cur.page.y - prev.page.y;\r\n targetObj.client.x = cur.client.x - prev.client.x;\r\n targetObj.client.y = cur.client.y - prev.client.y;\r\n targetObj.timeStamp = new Date().getTime() - prev.timeStamp;\r\n\r\n // set pointer velocity\r\n var dt = Math.max(targetObj.timeStamp / 1000, 0.001);\r\n targetObj.page.speed = hypot(targetObj.page.x, targetObj.page.y) / dt;\r\n targetObj.page.vx = targetObj.page.x / dt;\r\n targetObj.page.vy = targetObj.page.y / dt;\r\n\r\n targetObj.client.speed = hypot(targetObj.client.x, targetObj.page.y) / dt;\r\n targetObj.client.vx = targetObj.client.x / dt;\r\n targetObj.client.vy = targetObj.client.y / dt;\r\n }\r\n\r\n function isNativePointer(pointer){\r\n return (pointer instanceof window.Event\r\n || (supportsTouch && window.Touch && pointer instanceof window.Touch));\r\n }\r\n\r\n // Get specified X/Y coords for mouse or event.touches[0]\r\n function getXY(type, pointer, xy){\r\n xy = xy || {};\r\n type = type || 'page';\r\n\r\n xy.x = pointer[type + 'X'];\r\n xy.y = pointer[type + 'Y'];\r\n\r\n return xy;\r\n }\r\n\r\n function getPageXY(pointer, page){\r\n page = page || {};\r\n\r\n // Opera Mobile handles the viewport and scrolling oddly\r\n if (isOperaMobile && isNativePointer(pointer)){\r\n getXY('screen', pointer, page);\r\n\r\n page.x += window.scrollX;\r\n page.y += window.scrollY;\r\n }\r\n else {\r\n getXY('page', pointer, page);\r\n }\r\n\r\n return page;\r\n }\r\n\r\n function getClientXY(pointer, client){\r\n client = client || {};\r\n\r\n if (isOperaMobile && isNativePointer(pointer)){\r\n // Opera Mobile handles the viewport and scrolling oddly\r\n getXY('screen', pointer, client);\r\n }\r\n else {\r\n getXY('client', pointer, client);\r\n }\r\n\r\n return client;\r\n }\r\n\r\n function getScrollXY(win){\r\n win = win || window;\r\n return {\r\n x: win.scrollX || win.document.documentElement.scrollLeft,\r\n y: win.scrollY || win.document.documentElement.scrollTop\r\n };\r\n }\r\n\r\n function getPointerId(pointer){\r\n return isNumber(pointer.pointerId) ? pointer.pointerId : pointer.identifier;\r\n }\r\n\r\n function getActualElement(element){\r\n return (element instanceof SVGElementInstance\r\n ? element.correspondingUseElement\r\n : element);\r\n }\r\n\r\n function getWindow(node){\r\n if (isWindow(node)){\r\n return node;\r\n }\r\n\r\n var rootNode = (node.ownerDocument || node);\r\n\r\n return rootNode.defaultView || rootNode.parentWindow || window;\r\n }\r\n\r\n function getElementClientRect(element){\r\n var clientRect = (element instanceof SVGElement\r\n ? element.getBoundingClientRect()\r\n : element.getClientRects()[0]);\r\n\r\n return clientRect && {\r\n left: clientRect.left,\r\n right: clientRect.right,\r\n top: clientRect.top,\r\n bottom: clientRect.bottom,\r\n width: clientRect.width || clientRect.right - clientRect.left,\r\n height: clientRect.height || clientRect.bottom - clientRect.top\r\n };\r\n }\r\n\r\n function getElementRect(element){\r\n var clientRect = getElementClientRect(element);\r\n\r\n if (!isIOS7 && clientRect){\r\n var scroll = getScrollXY(getWindow(element));\r\n\r\n clientRect.left += scroll.x;\r\n clientRect.right += scroll.x;\r\n clientRect.top += scroll.y;\r\n clientRect.bottom += scroll.y;\r\n }\r\n\r\n return clientRect;\r\n }\r\n\r\n function getTouchPair(event){\r\n var touches = [];\r\n\r\n // array of touches is supplied\r\n if (isArray(event)){\r\n touches[0] = event[0];\r\n touches[1] = event[1];\r\n }\r\n // an event\r\n else {\r\n if (event.type === 'touchend'){\r\n if (event.touches.length === 1){\r\n touches[0] = event.touches[0];\r\n touches[1] = event.changedTouches[0];\r\n }\r\n else if (event.touches.length === 0){\r\n touches[0] = event.changedTouches[0];\r\n touches[1] = event.changedTouches[1];\r\n }\r\n }\r\n else {\r\n touches[0] = event.touches[0];\r\n touches[1] = event.touches[1];\r\n }\r\n }\r\n\r\n return touches;\r\n }\r\n\r\n function pointerAverage(pointers){\r\n var average = {\r\n pageX: 0,\r\n pageY: 0,\r\n clientX: 0,\r\n clientY: 0,\r\n screenX: 0,\r\n screenY: 0\r\n };\r\n var prop;\r\n\r\n for (var i = 0; i < pointers.length; i++){\r\n for (prop in average){\r\n average[prop] += pointers[i][prop];\r\n }\r\n }\r\n for (prop in average){\r\n average[prop] /= pointers.length;\r\n }\r\n\r\n return average;\r\n }\r\n\r\n function touchBBox(event){\r\n if (!event.length && !(event.touches && event.touches.length > 1)){\r\n return;\r\n }\r\n\r\n var touches = getTouchPair(event),\r\n minX = Math.min(touches[0].pageX, touches[1].pageX),\r\n minY = Math.min(touches[0].pageY, touches[1].pageY),\r\n maxX = Math.max(touches[0].pageX, touches[1].pageX),\r\n maxY = Math.max(touches[0].pageY, touches[1].pageY);\r\n\r\n return {\r\n x: minX,\r\n y: minY,\r\n left: minX,\r\n top: minY,\r\n width: maxX - minX,\r\n height: maxY - minY\r\n };\r\n }\r\n\r\n function touchDistance(event, deltaSource){\r\n deltaSource = deltaSource || defaultOptions.deltaSource;\r\n\r\n var sourceX = deltaSource + 'X',\r\n sourceY = deltaSource + 'Y',\r\n touches = getTouchPair(event);\r\n\r\n var dx = touches[0][sourceX] - touches[1][sourceX],\r\n dy = touches[0][sourceY] - touches[1][sourceY];\r\n\r\n return hypot(dx, dy);\r\n }\r\n\r\n function touchAngle(event, prevAngle, deltaSource){\r\n deltaSource = deltaSource || defaultOptions.deltaSource;\r\n\r\n var sourceX = deltaSource + 'X',\r\n sourceY = deltaSource + 'Y',\r\n touches = getTouchPair(event),\r\n dx = touches[0][sourceX] - touches[1][sourceX],\r\n dy = touches[0][sourceY] - touches[1][sourceY],\r\n angle = 180 * Math.atan(dy / dx) / Math.PI;\r\n\r\n if (isNumber(prevAngle)){\r\n var dr = angle - prevAngle,\r\n drClamped = dr % 360;\r\n\r\n if (drClamped > 315){\r\n angle -= 360 + (angle / 360) | 0 * 360;\r\n }\r\n else if (drClamped > 135){\r\n angle -= 180 + (angle / 360) | 0 * 360;\r\n }\r\n else if (drClamped < -315){\r\n angle += 360 + (angle / 360) | 0 * 360;\r\n }\r\n else if (drClamped < -135){\r\n angle += 180 + (angle / 360) | 0 * 360;\r\n }\r\n }\r\n\r\n return angle;\r\n }\r\n\r\n function getOriginXY(interactable, element){\r\n var origin = interactable\r\n ? interactable.options.origin\r\n : defaultOptions.origin;\r\n\r\n if (origin === 'parent'){\r\n origin = parentElement(element);\r\n }\r\n else if (origin === 'self'){\r\n origin = interactable.getRect(element);\r\n }\r\n else if (trySelector(origin)){\r\n origin = closest(element, origin) || { x: 0, y: 0 };\r\n }\r\n\r\n if (isFunction(origin)){\r\n origin = origin(interactable && element);\r\n }\r\n\r\n if (isElement(origin)){\r\n origin = getElementRect(origin);\r\n }\r\n\r\n origin.x = ('x' in origin) ? origin.x : origin.left;\r\n origin.y = ('y' in origin) ? origin.y : origin.top;\r\n\r\n return origin;\r\n }\r\n\r\n // http://stackoverflow.com/a/5634528/2280888\r\n function _getQBezierValue(t, p1, p2, p3){\r\n var iT = 1 - t;\r\n return iT * iT * p1 + 2 * iT * t * p2 + t * t * p3;\r\n }\r\n\r\n function getQuadraticCurvePoint(startX, startY, cpX, cpY, endX, endY, position){\r\n return {\r\n x: _getQBezierValue(position, startX, cpX, endX),\r\n y: _getQBezierValue(position, startY, cpY, endY)\r\n };\r\n }\r\n\r\n // http://gizma.com/easing/\r\n function easeOutQuad(t, b, c, d){\r\n t /= d;\r\n return -c * t * (t - 2) + b;\r\n }\r\n\r\n function nodeContains(parent, child){\r\n while (child){\r\n if (child === parent){\r\n return true;\r\n }\r\n\r\n child = child.parentNode;\r\n }\r\n\r\n return false;\r\n }\r\n\r\n function closest(child, selector){\r\n var parent = parentElement(child);\r\n\r\n while (isElement(parent)){\r\n if (matchesSelector(parent, selector)){ return parent; }\r\n\r\n parent = parentElement(parent);\r\n }\r\n\r\n return null;\r\n }\r\n\r\n function parentElement(node){\r\n var parent = node.parentNode;\r\n\r\n if (isDocFrag(parent)){\r\n // skip past #shado-root fragments\r\n while ((parent = parent.host) && isDocFrag(parent)){}\r\n\r\n return parent;\r\n }\r\n\r\n return parent;\r\n }\r\n\r\n function inContext(interactable, element){\r\n return interactable._context === element.ownerDocument\r\n || nodeContains(interactable._context, element);\r\n }\r\n\r\n function testIgnore(interactable, interactableElement, element){\r\n var ignoreFrom = interactable.options.ignoreFrom;\r\n\r\n if (!ignoreFrom || !isElement(element)){ return false; }\r\n\r\n if (isString(ignoreFrom)){\r\n return matchesUpTo(element, ignoreFrom, interactableElement);\r\n }\r\n else if (isElement(ignoreFrom)){\r\n return nodeContains(ignoreFrom, element);\r\n }\r\n\r\n return false;\r\n }\r\n\r\n function testAllow(interactable, interactableElement, element){\r\n var allowFrom = interactable.options.allowFrom;\r\n\r\n if (!allowFrom){ return true; }\r\n\r\n if (!isElement(element)){ return false; }\r\n\r\n if (isString(allowFrom)){\r\n return matchesUpTo(element, allowFrom, interactableElement);\r\n }\r\n else if (isElement(allowFrom)){\r\n return nodeContains(allowFrom, element);\r\n }\r\n\r\n return false;\r\n }\r\n\r\n function checkAxis(axis, interactable){\r\n if (!interactable){ return false; }\r\n\r\n var thisAxis = interactable.options.drag.axis;\r\n\r\n return (axis === 'xy' || thisAxis === 'xy' || thisAxis === axis);\r\n }\r\n\r\n function checkSnap(interactable, action){\r\n var options = interactable.options;\r\n\r\n if (/^resize/.test(action)){\r\n action = 'resize';\r\n }\r\n\r\n return options[action].snap && options[action].snap.enabled;\r\n }\r\n\r\n function checkRestrict(interactable, action){\r\n var options = interactable.options;\r\n\r\n if (/^resize/.test(action)){\r\n action = 'resize';\r\n }\r\n\r\n return options[action].restrict && options[action].restrict.enabled;\r\n }\r\n\r\n function checkAutoScroll(interactable, action){\r\n var options = interactable.options;\r\n\r\n if (/^resize/.test(action)){\r\n action = 'resize';\r\n }\r\n\r\n return options[action].autoScroll && options[action].autoScroll.enabled;\r\n }\r\n\r\n function withinInteractionLimit(interactable, element, action){\r\n var options = interactable.options,\r\n maxActions = options[action.name].max,\r\n maxPerElement = options[action.name].maxPerElement,\r\n activeInteractions = 0,\r\n targetCount = 0,\r\n targetElementCount = 0;\r\n\r\n for (var i = 0, len = interactions.length; i < len; i++){\r\n var interaction = interactions[i],\r\n otherAction = interaction.prepared.name,\r\n active = interaction.interacting();\r\n\r\n if (!active){ continue; }\r\n\r\n activeInteractions++;\r\n\r\n if (activeInteractions >= maxInteractions){\r\n return false;\r\n }\r\n\r\n if (interaction.target !== interactable){ continue; }\r\n\r\n targetCount += (otherAction === action.name) | 0;\r\n\r\n if (targetCount >= maxActions){\r\n return false;\r\n }\r\n\r\n if (interaction.element === element){\r\n targetElementCount++;\r\n\r\n if (otherAction !== action.name || targetElementCount >= maxPerElement){\r\n return false;\r\n }\r\n }\r\n }\r\n\r\n return maxInteractions > 0;\r\n }\r\n\r\n // Test for the element that's \"above\" all other qualifiers\r\n function indexOfDeepestElement(elements){\r\n var dropzone,\r\n deepestZone = elements[0],\r\n index = deepestZone ? 0 : -1,\r\n parent,\r\n deepestZoneParents = [],\r\n dropzoneParents = [],\r\n child,\r\n i,\r\n n;\r\n\r\n for (i = 1; i < elements.length; i++){\r\n dropzone = elements[i];\r\n\r\n // an element might belong to multiple selector dropzones\r\n if (!dropzone || dropzone === deepestZone){\r\n continue;\r\n }\r\n\r\n if (!deepestZone){\r\n deepestZone = dropzone;\r\n index = i;\r\n continue;\r\n }\r\n\r\n // check if the deepest or current are document.documentElement or document.rootElement\r\n // - if the current dropzone is, do nothing and continue\r\n if (dropzone.parentNode === dropzone.ownerDocument){\r\n continue;\r\n }\r\n // - if deepest is, update with the current dropzone and continue to next\r\n else if (deepestZone.parentNode === dropzone.ownerDocument){\r\n deepestZone = dropzone;\r\n index = i;\r\n continue;\r\n }\r\n\r\n if (!deepestZoneParents.length){\r\n parent = deepestZone;\r\n while (parent.parentNode && parent.parentNode !== parent.ownerDocument){\r\n deepestZoneParents.unshift(parent);\r\n parent = parent.parentNode;\r\n }\r\n }\r\n\r\n // if this element is an svg element and the current deepest is\r\n // an HTMLElement\r\n if (deepestZone instanceof HTMLElement\r\n && dropzone instanceof SVGElement\r\n && !(dropzone instanceof SVGSVGElement)){\r\n if (dropzone === deepestZone.parentNode){\r\n continue;\r\n }\r\n\r\n parent = dropzone.ownerSVGElement;\r\n }\r\n else {\r\n parent = dropzone;\r\n }\r\n\r\n dropzoneParents = [];\r\n\r\n while (parent.parentNode !== parent.ownerDocument){\r\n dropzoneParents.unshift(parent);\r\n parent = parent.parentNode;\r\n }\r\n\r\n n = 0;\r\n\r\n // get (position of last common ancestor) + 1\r\n while (dropzoneParents[n] && dropzoneParents[n] === deepestZoneParents[n]){\r\n n++;\r\n }\r\n\r\n var parents = [\r\n dropzoneParents[n - 1],\r\n dropzoneParents[n],\r\n deepestZoneParents[n]\r\n ];\r\n\r\n child = parents[0].lastChild;\r\n\r\n while (child){\r\n if (child === parents[1]){\r\n deepestZone = dropzone;\r\n index = i;\r\n deepestZoneParents = [];\r\n\r\n break;\r\n }\r\n else if (child === parents[2]){\r\n break;\r\n }\r\n\r\n child = child.previousSibling;\r\n }\r\n }\r\n\r\n return index;\r\n }\r\n\r\n function Interaction(){\r\n this.target = null; // current interactable being interacted with\r\n this.element = null; // the target element of the interactable\r\n this.dropTarget = null; // the dropzone a drag target might be dropped into\r\n this.dropElement = null; // the element at the time of checking\r\n this.prevDropTarget = null; // the dropzone that was recently dragged away from\r\n this.prevDropElement = null; // the element at the time of checking\r\n\r\n this.prepared = { // action that's ready to be fired on next move event\r\n name: null,\r\n axis: null,\r\n edges: null\r\n };\r\n\r\n this.matches = []; // all selectors that are matched by target element\r\n this.matchElements = []; // corresponding elements\r\n\r\n this.inertiaStatus = {\r\n active: false,\r\n smoothEnd: false,\r\n ending: false,\r\n\r\n startEvent: null,\r\n upCoords: {},\r\n\r\n xe: 0, ye: 0,\r\n sx: 0, sy: 0,\r\n\r\n t0: 0,\r\n vx0: 0, vys: 0,\r\n duration: 0,\r\n\r\n resumeDx: 0,\r\n resumeDy: 0,\r\n\r\n lambda_v0: 0,\r\n one_ve_v0: 0,\r\n i: null\r\n };\r\n\r\n if (isFunction(Function.prototype.bind)){\r\n this.boundInertiaFrame = this.inertiaFrame.bind(this);\r\n this.boundSmoothEndFrame = this.smoothEndFrame.bind(this);\r\n }\r\n else {\r\n var that = this;\r\n\r\n this.boundInertiaFrame = function(){ return that.inertiaFrame(); };\r\n this.boundSmoothEndFrame = function(){ return that.smoothEndFrame(); };\r\n }\r\n\r\n this.activeDrops = {\r\n dropzones: [], // the dropzones that are mentioned below\r\n elements: [], // elements of dropzones that accept the target draggable\r\n rects: [] // the rects of the elements mentioned above\r\n };\r\n\r\n // keep track of added pointers\r\n this.pointers = [];\r\n this.pointerIds = [];\r\n this.downTargets = [];\r\n this.downTimes = [];\r\n this.holdTimers = [];\r\n\r\n // Previous native pointer move event coordinates\r\n this.prevCoords = {\r\n page: { x: 0, y: 0 },\r\n client: { x: 0, y: 0 },\r\n timeStamp: 0\r\n };\r\n // current native pointer move event coordinates\r\n this.curCoords = {\r\n page: { x: 0, y: 0 },\r\n client: { x: 0, y: 0 },\r\n timeStamp: 0\r\n };\r\n\r\n // Starting InteractEvent pointer coordinates\r\n this.startCoords = {\r\n page: { x: 0, y: 0 },\r\n client: { x: 0, y: 0 },\r\n timeStamp: 0\r\n };\r\n\r\n // Change in coordinates and time of the pointer\r\n this.pointerDelta = {\r\n page: { x: 0, y: 0, vx: 0, vy: 0, speed: 0 },\r\n client: { x: 0, y: 0, vx: 0, vy: 0, speed: 0 },\r\n timeStamp: 0\r\n };\r\n\r\n this.downEvent = null; // pointerdown/mousedown/touchstart event\r\n this.downPointer = {};\r\n\r\n this._eventTarget = null;\r\n this._curEventTarget = null;\r\n\r\n this.prevEvent = null; // previous action event\r\n this.tapTime = 0; // time of the most recent tap event\r\n this.prevTap = null;\r\n\r\n this.startOffset = { left: 0, right: 0, top: 0, bottom: 0 };\r\n this.restrictOffset = { left: 0, right: 0, top: 0, bottom: 0 };\r\n this.snapOffsets = [];\r\n\r\n this.gesture = {\r\n start: { x: 0, y: 0 },\r\n\r\n startDistance: 0, // distance between two touches of touchStart\r\n prevDistance: 0,\r\n distance: 0,\r\n\r\n scale: 1, // gesture.distance / gesture.startDistance\r\n\r\n startAngle: 0, // angle of line joining two touches\r\n prevAngle: 0 // angle of the previous gesture event\r\n };\r\n\r\n this.snapStatus = {\r\n x: 0, y: 0,\r\n dx: 0, dy: 0,\r\n realX: 0, realY: 0,\r\n snappedX: 0, snappedY: 0,\r\n targets: [],\r\n locked: false,\r\n changed: false\r\n };\r\n\r\n this.restrictStatus = {\r\n dx: 0, dy: 0,\r\n restrictedX: 0, restrictedY: 0,\r\n snap: null,\r\n restricted: false,\r\n changed: false\r\n };\r\n\r\n this.restrictStatus.snap = this.snapStatus;\r\n\r\n this.pointerIsDown = false;\r\n this.pointerWasMoved = false;\r\n this.gesturing = false;\r\n this.dragging = false;\r\n this.resizing = false;\r\n this.resizeAxes = 'xy';\r\n\r\n this.mouse = false;\r\n\r\n interactions.push(this);\r\n }\r\n\r\n Interaction.prototype = {\r\n getPageXY: function(pointer, xy){ return getPageXY(pointer, xy, this); },\r\n getClientXY: function(pointer, xy){ return getClientXY(pointer, xy, this); },\r\n setEventXY: function(target, ptr){ return setEventXY(target, ptr, this); },\r\n\r\n pointerOver: function(pointer, event, eventTarget){\r\n if (this.prepared.name || !this.mouse){ return; }\r\n\r\n var curMatches = [],\r\n curMatchElements = [],\r\n prevTargetElement = this.element;\r\n\r\n this.addPointer(pointer);\r\n\r\n if (this.target\r\n && (testIgnore(this.target, this.element, eventTarget)\r\n || !testAllow(this.target, this.element, eventTarget))){\r\n // if the eventTarget should be ignored or shouldn't be allowed\r\n // clear the previous target\r\n this.target = null;\r\n this.element = null;\r\n this.matches = [];\r\n this.matchElements = [];\r\n }\r\n\r\n var elementInteractable = interactables.get(eventTarget),\r\n elementAction = (elementInteractable\r\n && !testIgnore(elementInteractable, eventTarget, eventTarget)\r\n && testAllow(elementInteractable, eventTarget, eventTarget)\r\n && validateAction(\r\n elementInteractable.getAction(pointer, event, this, eventTarget),\r\n elementInteractable));\r\n\r\n if (elementAction && !withinInteractionLimit(elementInteractable, eventTarget, elementAction)){\r\n elementAction = null;\r\n }\r\n\r\n function pushCurMatches(interactable, selector){\r\n if (interactable\r\n && inContext(interactable, eventTarget)\r\n && !testIgnore(interactable, eventTarget, eventTarget)\r\n && testAllow(interactable, eventTarget, eventTarget)\r\n && matchesSelector(eventTarget, selector)){\r\n curMatches.push(interactable);\r\n curMatchElements.push(eventTarget);\r\n }\r\n }\r\n\r\n if (elementAction){\r\n this.target = elementInteractable;\r\n this.element = eventTarget;\r\n this.matches = [];\r\n this.matchElements = [];\r\n }\r\n else {\r\n interactables.forEachSelector(pushCurMatches);\r\n\r\n if (this.validateSelector(pointer, event, curMatches, curMatchElements)){\r\n this.matches = curMatches;\r\n this.matchElements = curMatchElements;\r\n\r\n this.pointerHover(pointer, event, this.matches, this.matchElements);\r\n events.add(eventTarget, supportsPointerEvent ?\r\n pEventTypes.move :\r\n 'mousemove',\r\n listeners.pointerHover);\r\n }\r\n else if (this.target){\r\n if (nodeContains(prevTargetElement, eventTarget)){\r\n this.pointerHover(pointer, event, this.matches, this.matchElements);\r\n events.add(this.element, supportsPointerEvent ?\r\n pEventTypes.move :\r\n 'mousemove',\r\n listeners.pointerHover);\r\n }\r\n else {\r\n this.target = null;\r\n this.element = null;\r\n this.matches = [];\r\n this.matchElements = [];\r\n }\r\n }\r\n }\r\n },\r\n\r\n // Check what action would be performed on pointerMove target if a mouse\r\n // button were pressed and change the cursor accordingly\r\n pointerHover: function(pointer, event, eventTarget, curEventTarget, matches, matchElements){\r\n var target = this.target;\r\n\r\n if (!this.prepared.name && this.mouse){\r\n var action;\r\n\r\n // update pointer coords for defaultActionChecker to use\r\n this.setEventXY(this.curCoords, [pointer]);\r\n\r\n if (matches){\r\n action = this.validateSelector(pointer, event, matches, matchElements);\r\n }\r\n else if (target){\r\n action = validateAction(target.getAction(this.pointers[0], event, this, this.element), this.target);\r\n }\r\n\r\n if (target && target.options.styleCursor){\r\n if (action){\r\n target._doc.documentElement.style.cursor = getActionCursor(action);\r\n }\r\n else {\r\n target._doc.documentElement.style.cursor = '';\r\n }\r\n }\r\n }\r\n else if (this.prepared.name){\r\n this.checkAndPreventDefault(event, target, this.element);\r\n }\r\n },\r\n\r\n pointerOut: function(pointer, event, eventTarget){\r\n if (this.prepared.name){ return; }\r\n\r\n // Remove temporary event listeners for selector Interactables\r\n if (!interactables.get(eventTarget)){\r\n events.remove(eventTarget,\r\n supportsPointerEvent ? pEventTypes.move : 'mousemove',\r\n listeners.pointerHover);\r\n }\r\n\r\n if (this.target && this.target.options.styleCursor && !this.interacting()){\r\n this.target._doc.documentElement.style.cursor = '';\r\n }\r\n },\r\n\r\n selectorDown: function(pointer, event, eventTarget, curEventTarget){\r\n var that = this,\r\n // copy event to be used in timeout for IE8\r\n eventCopy = events.useAttachEvent ? extend({}, event) : event,\r\n element = eventTarget,\r\n pointerIndex = this.addPointer(pointer),\r\n action;\r\n\r\n this.holdTimers[pointerIndex] = setTimeout(function(){\r\n that.pointerHold(events.useAttachEvent ? eventCopy : pointer, eventCopy, eventTarget, curEventTarget);\r\n }, defaultOptions._holdDuration);\r\n\r\n this.pointerIsDown = true;\r\n\r\n // Check if the down event hits the current inertia target\r\n if (this.inertiaStatus.active && this.target.selector){\r\n // climb up the DOM tree from the event target\r\n while (isElement(element)){\r\n // if this element is the current inertia target element\r\n if (element === this.element\r\n // and the prospective action is the same as the ongoing one\r\n && validateAction(this.target.getAction(pointer, event, this, this.element), this.target).name === this.prepared.name){\r\n // stop inertia so that the next move will be a normal one\r\n cancelFrame(this.inertiaStatus.i);\r\n this.inertiaStatus.active = false;\r\n\r\n this.collectEventTargets(pointer, event, eventTarget, 'down');\r\n return;\r\n }\r\n element = parentElement(element);\r\n }\r\n }\r\n\r\n // do nothing if interacting\r\n if (this.interacting()){\r\n this.collectEventTargets(pointer, event, eventTarget, 'down');\r\n return;\r\n }\r\n\r\n function pushMatches(interactable, selector, context){\r\n var elements = ie8MatchesSelector\r\n ? context.querySelectorAll(selector)\r\n : undefined;\r\n\r\n if (inContext(interactable, element)\r\n && !testIgnore(interactable, element, eventTarget)\r\n && testAllow(interactable, element, eventTarget)\r\n && matchesSelector(element, selector, elements)){\r\n that.matches.push(interactable);\r\n that.matchElements.push(element);\r\n }\r\n }\r\n\r\n // update pointer coords for defaultActionChecker to use\r\n this.setEventXY(this.curCoords, [pointer]);\r\n this.downEvent = event;\r\n\r\n while (isElement(element) && !action){\r\n this.matches = [];\r\n this.matchElements = [];\r\n\r\n interactables.forEachSelector(pushMatches);\r\n\r\n action = this.validateSelector(pointer, event, this.matches, this.matchElements);\r\n element = parentElement(element);\r\n }\r\n\r\n if (action){\r\n this.prepared.name = action.name;\r\n this.prepared.axis = action.axis;\r\n this.prepared.edges = action.edges;\r\n\r\n this.collectEventTargets(pointer, event, eventTarget, 'down');\r\n\r\n return this.pointerDown(pointer, event, eventTarget, curEventTarget, action);\r\n }\r\n else {\r\n // do these now since pointerDown isn't being called from here\r\n this.downTimes[pointerIndex] = new Date().getTime();\r\n this.downTargets[pointerIndex] = eventTarget;\r\n pointerExtend(this.downPointer, pointer);\r\n\r\n copyCoords(this.prevCoords, this.curCoords);\r\n this.pointerWasMoved = false;\r\n }\r\n\r\n this.collectEventTargets(pointer, event, eventTarget, 'down');\r\n },\r\n\r\n // Determine action to be performed on next pointerMove and add appropriate\r\n // style and event Listeners\r\n pointerDown: function(pointer, event, eventTarget, curEventTarget, forceAction){\r\n if (!forceAction && !this.inertiaStatus.active && this.pointerWasMoved && this.prepared.name){\r\n this.checkAndPreventDefault(event, this.target, this.element);\r\n\r\n return;\r\n }\r\n\r\n this.pointerIsDown = true;\r\n this.downEvent = event;\r\n\r\n var pointerIndex = this.addPointer(pointer),\r\n action;\r\n\r\n // If it is the second touch of a multi-touch gesture, keep the\r\n // target the same and get a new action if a target was set by the\r\n // first touch\r\n if (this.pointerIds.length > 1 && this.target._element === this.element){\r\n var newAction = validateAction(forceAction || this.target.getAction(pointer, event, this, this.element), this.target);\r\n\r\n if (withinInteractionLimit(this.target, this.element, newAction)){\r\n action = newAction;\r\n }\r\n\r\n this.prepared.name = null;\r\n }\r\n // Otherwise, set the target if there is no action prepared\r\n else if (!this.prepared.name){\r\n var interactable = interactables.get(curEventTarget);\r\n\r\n if (interactable\r\n && !testIgnore(interactable, curEventTarget, eventTarget)\r\n && testAllow(interactable, curEventTarget, eventTarget)\r\n && (action = validateAction(forceAction || interactable.getAction(pointer, event, this, curEventTarget), interactable, eventTarget))\r\n && withinInteractionLimit(interactable, curEventTarget, action)){\r\n this.target = interactable;\r\n this.element = curEventTarget;\r\n }\r\n }\r\n\r\n var target = this.target,\r\n options = target && target.options;\r\n\r\n if (target && (forceAction || !this.prepared.name)){\r\n action = action || validateAction(forceAction || target.getAction(pointer, event, this, curEventTarget), target, this.element);\r\n\r\n this.setEventXY(this.startCoords, this.pointers);\r\n\r\n if (!action){ return; }\r\n\r\n if (options.styleCursor){\r\n target._doc.documentElement.style.cursor = getActionCursor(action);\r\n }\r\n\r\n this.resizeAxes = action.name === 'resize' ? action.axis : null;\r\n\r\n if (action === 'gesture' && this.pointerIds.length < 2){\r\n action = null;\r\n }\r\n\r\n this.prepared.name = action.name;\r\n this.prepared.axis = action.axis;\r\n this.prepared.edges = action.edges;\r\n\r\n this.snapStatus.snappedX = this.snapStatus.snappedY =\r\n this.restrictStatus.restrictedX = this.restrictStatus.restrictedY = NaN;\r\n\r\n this.downTimes[pointerIndex] = new Date().getTime();\r\n this.downTargets[pointerIndex] = eventTarget;\r\n pointerExtend(this.downPointer, pointer);\r\n\r\n copyCoords(this.prevCoords, this.startCoords);\r\n this.pointerWasMoved = false;\r\n\r\n this.checkAndPreventDefault(event, target, this.element);\r\n }\r\n // if inertia is active try to resume action\r\n else if (this.inertiaStatus.active\r\n && curEventTarget === this.element\r\n && validateAction(target.getAction(pointer, event, this, this.element), target).name === this.prepared.name){\r\n cancelFrame(this.inertiaStatus.i);\r\n this.inertiaStatus.active = false;\r\n\r\n this.checkAndPreventDefault(event, target, this.element);\r\n }\r\n },\r\n\r\n setModifications: function(coords, preEnd){\r\n var target = this.target,\r\n shouldMove = true,\r\n shouldSnap = checkSnap(target, this.prepared.name) && (!target.options[this.prepared.name].snap.endOnly || preEnd),\r\n shouldRestrict = checkRestrict(target, this.prepared.name) && (!target.options[this.prepared.name].restrict.endOnly || preEnd);\r\n\r\n if (shouldSnap){ this.setSnapping(coords); } else { this.snapStatus.locked = false; }\r\n if (shouldRestrict){ this.setRestriction(coords); } else { this.restrictStatus.restricted = false; }\r\n\r\n if (shouldSnap && this.snapStatus.locked && !this.snapStatus.changed){\r\n shouldMove = shouldRestrict && this.restrictStatus.restricted && this.restrictStatus.changed;\r\n }\r\n else if (shouldRestrict && this.restrictStatus.restricted && !this.restrictStatus.changed){\r\n shouldMove = false;\r\n }\r\n\r\n return shouldMove;\r\n },\r\n\r\n setStartOffsets: function(action, interactable, element){\r\n var rect = interactable.getRect(element),\r\n origin = getOriginXY(interactable, element),\r\n snap = interactable.options[this.prepared.name].snap,\r\n restrict = interactable.options[this.prepared.name].restrict,\r\n width, height;\r\n\r\n if (rect){\r\n this.startOffset.left = this.startCoords.page.x - rect.left;\r\n this.startOffset.top = this.startCoords.page.y - rect.top;\r\n\r\n this.startOffset.right = rect.right - this.startCoords.page.x;\r\n this.startOffset.bottom = rect.bottom - this.startCoords.page.y;\r\n\r\n if ('width' in rect){ width = rect.width; }\r\n else { width = rect.right - rect.left; }\r\n if ('height' in rect){ height = rect.height; }\r\n else { height = rect.bottom - rect.top; }\r\n }\r\n else {\r\n this.startOffset.left = this.startOffset.top = this.startOffset.right = this.startOffset.bottom = 0;\r\n }\r\n\r\n this.snapOffsets.splice(0);\r\n\r\n var snapOffset = snap && snap.offset === 'startCoords'\r\n ? {\r\n x: this.startCoords.page.x - origin.x,\r\n y: this.startCoords.page.y - origin.y\r\n }\r\n : snap && snap.offset || { x: 0, y: 0 };\r\n\r\n if (rect && snap && snap.relativePoints && snap.relativePoints.length){\r\n for (var i = 0; i < snap.relativePoints.length; i++){\r\n this.snapOffsets.push({\r\n x: this.startOffset.left - (width * snap.relativePoints[i].x) + snapOffset.x,\r\n y: this.startOffset.top - (height * snap.relativePoints[i].y) + snapOffset.y\r\n });\r\n }\r\n }\r\n else {\r\n this.snapOffsets.push(snapOffset);\r\n }\r\n\r\n if (rect && restrict.elementRect){\r\n this.restrictOffset.left = this.startOffset.left - (width * restrict.elementRect.left);\r\n this.restrictOffset.top = this.startOffset.top - (height * restrict.elementRect.top);\r\n\r\n this.restrictOffset.right = this.startOffset.right - (width * (1 - restrict.elementRect.right));\r\n this.restrictOffset.bottom = this.startOffset.bottom - (height * (1 - restrict.elementRect.bottom));\r\n }\r\n else {\r\n this.restrictOffset.left = this.restrictOffset.top = this.restrictOffset.right = this.restrictOffset.bottom = 0;\r\n }\r\n },\r\n\r\n /* \\\r\n * Interaction.start\r\n [ method ]\r\n *\r\n * Start an action with the given Interactable and Element as tartgets. The\r\n * action must be enabled for the target Interactable and an appropriate number\r\n * of pointers must be held down – 1 for drag/resize, 2 for gesture.\r\n *\r\n * Use it with `interactable.able({ manualStart: false })` to always\r\n * [start actions manually](https://github.com/taye/interact.js/issues/114)\r\n *\r\n - action (object) The action to be performed - drag, resize, etc.\r\n - interactable (Interactable) The Interactable to target\r\n - element (Element) The DOM Element to target\r\n = (object) interact\r\n **\r\n | interact(target)\r\n | .draggable({\r\n | // disable the default drag start by down->move\r\n | manualStart: true\r\n | })\r\n | // start dragging after the user holds the pointer down\r\n | .on('hold', function (event) {\r\n | var interaction = event.interaction;\r\n |\r\n | if (!interaction.interacting()) {\r\n | interaction.start({ name: 'drag' },\r\n | event.interactable,\r\n | event.currentTarget);\r\n | }\r\n | });\r\n \\*/\r\n start: function(action, interactable, element){\r\n if (this.interacting()\r\n || !this.pointerIsDown\r\n || this.pointerIds.length < (action.name === 'gesture' ? 2 : 1)){\r\n return;\r\n }\r\n\r\n // if this interaction had been removed after stopping\r\n // add it back\r\n if (indexOf(interactions, this) === -1){\r\n interactions.push(this);\r\n }\r\n\r\n // set the startCoords if there was no prepared action\r\n if (!this.prepared.name){\r\n this.setEventXY(this.startCoords);\r\n }\r\n\r\n this.prepared.name = action.name;\r\n this.prepared.axis = action.axis;\r\n this.prepared.edges = action.edges;\r\n this.target = interactable;\r\n this.element = element;\r\n\r\n this.setStartOffsets(action.name, interactable, element);\r\n this.setModifications(this.startCoords.page);\r\n\r\n this.prevEvent = this[this.prepared.name + 'Start'](this.downEvent);\r\n },\r\n\r\n pointerMove: function(pointer, event, eventTarget, curEventTarget, preEnd){\r\n if (this.inertiaStatus.active){\r\n var pageUp = this.inertiaStatus.upCoords.page;\r\n var clientUp = this.inertiaStatus.upCoords.client;\r\n\r\n var inertiaPosition = {\r\n pageX: pageUp.x + this.inertiaStatus.sx,\r\n pageY: pageUp.y + this.inertiaStatus.sy,\r\n clientX: clientUp.x + this.inertiaStatus.sx,\r\n clientY: clientUp.y + this.inertiaStatus.sy\r\n };\r\n\r\n this.setEventXY(this.curCoords, [inertiaPosition]);\r\n }\r\n else {\r\n this.recordPointer(pointer);\r\n this.setEventXY(this.curCoords, this.pointers);\r\n }\r\n\r\n var duplicateMove = (this.curCoords.page.x === this.prevCoords.page.x\r\n && this.curCoords.page.y === this.prevCoords.page.y\r\n && this.curCoords.client.x === this.prevCoords.client.x\r\n && this.curCoords.client.y === this.prevCoords.client.y);\r\n\r\n var dx, dy,\r\n pointerIndex = this.mouse ? 0 : indexOf(this.pointerIds, getPointerId(pointer));\r\n\r\n // register movement greater than pointerMoveTolerance\r\n if (this.pointerIsDown && !this.pointerWasMoved){\r\n dx = this.curCoords.client.x - this.startCoords.client.x;\r\n dy = this.curCoords.client.y - this.startCoords.client.y;\r\n\r\n this.pointerWasMoved = hypot(dx, dy) > pointerMoveTolerance;\r\n }\r\n\r\n if (!duplicateMove && (!this.pointerIsDown || this.pointerWasMoved)){\r\n if (this.pointerIsDown){\r\n clearTimeout(this.holdTimers[pointerIndex]);\r\n }\r\n\r\n this.collectEventTargets(pointer, event, eventTarget, 'move');\r\n }\r\n\r\n if (!this.pointerIsDown){ return; }\r\n\r\n if (duplicateMove && this.pointerWasMoved && !preEnd){\r\n this.checkAndPreventDefault(event, this.target, this.element);\r\n return;\r\n }\r\n\r\n // set pointer coordinate, time changes and speeds\r\n setEventDeltas(this.pointerDelta, this.prevCoords, this.curCoords);\r\n\r\n if (!this.prepared.name){ return; }\r\n\r\n if (this.pointerWasMoved\r\n // ignore movement while inertia is active\r\n && (!this.inertiaStatus.active || (pointer instanceof InteractEvent && /inertiastart/.test(pointer.type)))){\r\n // if just starting an action, calculate the pointer speed now\r\n if (!this.interacting()){\r\n setEventDeltas(this.pointerDelta, this.prevCoords, this.curCoords);\r\n\r\n // check if a drag is in the correct axis\r\n if (this.prepared.name === 'drag'){\r\n var absX = Math.abs(dx),\r\n absY = Math.abs(dy),\r\n targetAxis = this.target.options.drag.axis,\r\n axis = (absX > absY ? 'x' : absX < absY ? 'y' : 'xy');\r\n\r\n // if the movement isn't in the axis of the interactable\r\n if (axis !== 'xy' && targetAxis !== 'xy' && targetAxis !== axis){\r\n // cancel the prepared action\r\n this.prepared.name = null;\r\n\r\n // then try to get a drag from another ineractable\r\n\r\n var element = eventTarget;\r\n\r\n // check element interactables\r\n while (isElement(element)){\r\n var elementInteractable = interactables.get(element);\r\n\r\n if (elementInteractable\r\n && elementInteractable !== this.target\r\n && !elementInteractable.options.drag.manualStart\r\n && elementInteractable.getAction(this.downPointer, this.downEvent, this, element).name === 'drag'\r\n && checkAxis(axis, elementInteractable)){\r\n this.prepared.name = 'drag';\r\n this.target = elementInteractable;\r\n this.element = element;\r\n break;\r\n }\r\n\r\n element = parentElement(element);\r\n }\r\n\r\n // if there's no drag from element interactables,\r\n // check the selector interactables\r\n if (!this.prepared.name){\r\n var thisInteraction = this;\r\n\r\n var getDraggable = function(interactable, selector, context){\r\n var elements = ie8MatchesSelector\r\n ? context.querySelectorAll(selector)\r\n : undefined;\r\n\r\n if (interactable === thisInteraction.target){ return; }\r\n\r\n if (inContext(interactable, eventTarget)\r\n && !interactable.options.drag.manualStart\r\n && !testIgnore(interactable, element, eventTarget)\r\n && testAllow(interactable, element, eventTarget)\r\n && matchesSelector(element, selector, elements)\r\n && interactable.getAction(thisInteraction.downPointer, thisInteraction.downEvent, thisInteraction, element).name === 'drag'\r\n && checkAxis(axis, interactable)\r\n && withinInteractionLimit(interactable, element, 'drag')){\r\n return interactable;\r\n }\r\n };\r\n\r\n element = eventTarget;\r\n\r\n while (isElement(element)){\r\n var selectorInteractable = interactables.forEachSelector(getDraggable);\r\n\r\n if (selectorInteractable){\r\n this.prepared.name = 'drag';\r\n this.target = selectorInteractable;\r\n this.element = element;\r\n break;\r\n }\r\n\r\n element = parentElement(element);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n var starting = !!this.prepared.name && !this.interacting();\r\n\r\n if (starting\r\n && (this.target.options[this.prepared.name].manualStart\r\n || !withinInteractionLimit(this.target, this.element, this.prepared))){\r\n this.stop(event);\r\n return;\r\n }\r\n\r\n if (this.prepared.name && this.target){\r\n if (starting){\r\n this.start(this.prepared, this.target, this.element);\r\n }\r\n\r\n var shouldMove = this.setModifications(this.curCoords.page, preEnd);\r\n\r\n // move if snapping or restriction doesn't prevent it\r\n if (shouldMove || starting){\r\n this.prevEvent = this[this.prepared.name + 'Move'](event);\r\n }\r\n\r\n this.checkAndPreventDefault(event, this.target, this.element);\r\n }\r\n }\r\n\r\n copyCoords(this.prevCoords, this.curCoords);\r\n\r\n if (this.dragging || this.resizing){\r\n this.autoScrollMove(pointer);\r\n }\r\n },\r\n\r\n dragStart: function(event){\r\n var dragEvent = new InteractEvent(this, event, 'drag', 'start', this.element);\r\n\r\n dragEvent.originalEvent = event;\r\n this.dragging = true;\r\n this.target.fire(dragEvent);\r\n\r\n // reset active dropzones\r\n this.activeDrops.dropzones = [];\r\n this.activeDrops.elements = [];\r\n this.activeDrops.rects = [];\r\n\r\n if (!this.dynamicDrop){\r\n this.setActiveDrops(this.element);\r\n }\r\n\r\n var dropEvents = this.getDropEvents(event, dragEvent);\r\n\r\n if (dropEvents.activate){\r\n this.fireActiveDrops(dropEvents.activate);\r\n }\r\n\r\n return dragEvent;\r\n },\r\n\r\n dragMove: function(event){\r\n var target = this.target,\r\n dragEvent = new InteractEvent(this, event, 'drag', 'move', this.element),\r\n draggableElement = this.element,\r\n drop = this.getDrop(dragEvent, event, draggableElement);\r\n\r\n dragEvent.originalEvent = event;\r\n\r\n this.dropTarget = drop.dropzone;\r\n this.dropElement = drop.element;\r\n\r\n var dropEvents = this.getDropEvents(event, dragEvent);\r\n\r\n target.fire(dragEvent);\r\n\r\n if (dropEvents.leave){ this.prevDropTarget.fire(dropEvents.leave); }\r\n if (dropEvents.enter){ this.dropTarget.fire(dropEvents.enter); }\r\n if (dropEvents.move){ this.dropTarget.fire(dropEvents.move); }\r\n\r\n this.prevDropTarget = this.dropTarget;\r\n this.prevDropElement = this.dropElement;\r\n\r\n return dragEvent;\r\n },\r\n\r\n resizeStart: function(event){\r\n var resizeEvent = new InteractEvent(this, event, 'resize', 'start', this.element);\r\n\r\n if (this.prepared.edges){\r\n var startRect = this.target.getRect(this.element);\r\n\r\n /*\r\n * When using the `resizable.square` or `resizable.preserveAspectRatio` options, resizing from one edge\r\n * will affect another. E.g. with `resizable.square`, resizing to make the right edge larger will make\r\n * the bottom edge larger by the same amount. We call these 'linked' edges. Any linked edges will depend\r\n * on the active edges and the edge being interacted with.\r\n */\r\n if (this.target.options.resize.square || this.target.options.resize.preserveAspectRatio){\r\n var linkedEdges = extend({}, this.prepared.edges);\r\n\r\n linkedEdges.top = linkedEdges.top || (linkedEdges.left && !linkedEdges.bottom);\r\n linkedEdges.left = linkedEdges.left || (linkedEdges.top && !linkedEdges.right);\r\n linkedEdges.bottom = linkedEdges.bottom || (linkedEdges.right && !linkedEdges.top);\r\n linkedEdges.right = linkedEdges.right || (linkedEdges.bottom && !linkedEdges.left);\r\n\r\n this.prepared._linkedEdges = linkedEdges;\r\n }\r\n else {\r\n this.prepared._linkedEdges = null;\r\n }\r\n\r\n // if using `resizable.preserveAspectRatio` option, record aspect ratio at the start of the resize\r\n if (this.target.options.resize.preserveAspectRatio){\r\n this.resizeStartAspectRatio = startRect.width / startRect.height;\r\n }\r\n\r\n this.resizeRects = {\r\n start: startRect,\r\n current: extend({}, startRect),\r\n restricted: extend({}, startRect),\r\n previous: extend({}, startRect),\r\n delta: {\r\n left: 0, right: 0, width: 0,\r\n top: 0, bottom: 0, height: 0\r\n }\r\n };\r\n\r\n resizeEvent.rect = this.resizeRects.restricted;\r\n resizeEvent.deltaRect = this.resizeRects.delta;\r\n }\r\n\r\n this.target.fire(resizeEvent);\r\n\r\n this.resizing = true;\r\n\r\n return resizeEvent;\r\n },\r\n\r\n resizeMove: function(event){\r\n var resizeEvent = new InteractEvent(this, event, 'resize', 'move', this.element);\r\n\r\n var edges = this.prepared.edges,\r\n invert = this.target.options.resize.invert,\r\n invertible = invert === 'reposition' || invert === 'negate';\r\n\r\n if (edges){\r\n var dx = resizeEvent.dx,\r\n dy = resizeEvent.dy,\r\n\r\n start = this.resizeRects.start,\r\n current = this.resizeRects.current,\r\n restricted = this.resizeRects.restricted,\r\n delta = this.resizeRects.delta,\r\n previous = extend(this.resizeRects.previous, restricted),\r\n\r\n originalEdges = edges;\r\n\r\n // `resize.preserveAspectRatio` takes precedence over `resize.square`\r\n if (this.target.options.resize.preserveAspectRatio){\r\n var resizeStartAspectRatio = this.resizeStartAspectRatio;\r\n\r\n edges = this.prepared._linkedEdges;\r\n\r\n if ((originalEdges.left && originalEdges.bottom)\r\n || (originalEdges.right && originalEdges.top)){\r\n dy = -dx / resizeStartAspectRatio;\r\n }\r\n else if (originalEdges.left || originalEdges.right){ dy = dx / resizeStartAspectRatio; }\r\n else if (originalEdges.top || originalEdges.bottom){ dx = dy * resizeStartAspectRatio; }\r\n }\r\n else if (this.target.options.resize.square){\r\n edges = this.prepared._linkedEdges;\r\n\r\n if ((originalEdges.left && originalEdges.bottom)\r\n || (originalEdges.right && originalEdges.top)){\r\n dy = -dx;\r\n }\r\n else if (originalEdges.left || originalEdges.right){ dy = dx; }\r\n else if (originalEdges.top || originalEdges.bottom){ dx = dy; }\r\n }\r\n\r\n // update the 'current' rect without modifications\r\n if (edges.top){ current.top += dy; }\r\n if (edges.bottom){ current.bottom += dy; }\r\n if (edges.left){ current.left += dx; }\r\n if (edges.right){ current.right += dx; }\r\n\r\n if (invertible){\r\n // if invertible, copy the current rect\r\n extend(restricted, current);\r\n\r\n if (invert === 'reposition'){\r\n // swap edge values if necessary to keep width/height positive\r\n var swap;\r\n\r\n if (restricted.top > restricted.bottom){\r\n swap = restricted.top;\r\n\r\n restricted.top = restricted.bottom;\r\n restricted.bottom = swap;\r\n }\r\n if (restricted.left > restricted.right){\r\n swap = restricted.left;\r\n\r\n restricted.left = restricted.right;\r\n restricted.right = swap;\r\n }\r\n }\r\n }\r\n else {\r\n // if not invertible, restrict to minimum of 0x0 rect\r\n restricted.top = Math.min(current.top, start.bottom);\r\n restricted.bottom = Math.max(current.bottom, start.top);\r\n restricted.left = Math.min(current.left, start.right);\r\n restricted.right = Math.max(current.right, start.left);\r\n }\r\n\r\n restricted.width = restricted.right - restricted.left;\r\n restricted.height = restricted.bottom - restricted.top;\r\n\r\n for (var edge in restricted){\r\n delta[edge] = restricted[edge] - previous[edge];\r\n }\r\n\r\n resizeEvent.edges = this.prepared.edges;\r\n resizeEvent.rect = restricted;\r\n resizeEvent.deltaRect = delta;\r\n }\r\n\r\n this.target.fire(resizeEvent);\r\n\r\n return resizeEvent;\r\n },\r\n\r\n gestureStart: function(event){\r\n var gestureEvent = new InteractEvent(this, event, 'gesture', 'start', this.element);\r\n\r\n gestureEvent.ds = 0;\r\n\r\n this.gesture.startDistance = this.gesture.prevDistance = gestureEvent.distance;\r\n this.gesture.startAngle = this.gesture.prevAngle = gestureEvent.angle;\r\n this.gesture.scale = 1;\r\n\r\n this.gesturing = true;\r\n\r\n this.target.fire(gestureEvent);\r\n\r\n return gestureEvent;\r\n },\r\n\r\n gestureMove: function(event){\r\n if (!this.pointerIds.length){\r\n return this.prevEvent;\r\n }\r\n\r\n var gestureEvent;\r\n\r\n gestureEvent = new InteractEvent(this, event, 'gesture', 'move', this.element);\r\n gestureEvent.ds = gestureEvent.scale - this.gesture.scale;\r\n\r\n this.target.fire(gestureEvent);\r\n\r\n this.gesture.prevAngle = gestureEvent.angle;\r\n this.gesture.prevDistance = gestureEvent.distance;\r\n\r\n if (gestureEvent.scale !== Infinity &&\r\n gestureEvent.scale !== null &&\r\n gestureEvent.scale !== undefined &&\r\n !isNaN(gestureEvent.scale)){\r\n this.gesture.scale = gestureEvent.scale;\r\n }\r\n\r\n return gestureEvent;\r\n },\r\n\r\n pointerHold: function(pointer, event, eventTarget){\r\n this.collectEventTargets(pointer, event, eventTarget, 'hold');\r\n },\r\n\r\n pointerUp: function(pointer, event, eventTarget, curEventTarget){\r\n var pointerIndex = this.mouse ? 0 : indexOf(this.pointerIds, getPointerId(pointer));\r\n\r\n clearTimeout(this.holdTimers[pointerIndex]);\r\n\r\n this.collectEventTargets(pointer, event, eventTarget, 'up');\r\n this.collectEventTargets(pointer, event, eventTarget, 'tap');\r\n\r\n this.pointerEnd(pointer, event, eventTarget, curEventTarget);\r\n\r\n this.removePointer(pointer);\r\n },\r\n\r\n pointerCancel: function(pointer, event, eventTarget, curEventTarget){\r\n var pointerIndex = this.mouse ? 0 : indexOf(this.pointerIds, getPointerId(pointer));\r\n\r\n clearTimeout(this.holdTimers[pointerIndex]);\r\n\r\n this.collectEventTargets(pointer, event, eventTarget, 'cancel');\r\n this.pointerEnd(pointer, event, eventTarget, curEventTarget);\r\n\r\n this.removePointer(pointer);\r\n },\r\n\r\n // http://www.quirksmode.org/dom/events/click.html\r\n // >Events leading to dblclick\r\n //\r\n // IE8 doesn't fire down event before dblclick.\r\n // This workaround tries to fire a tap and doubletap after dblclick\r\n ie8Dblclick: function(pointer, event, eventTarget){\r\n if (this.prevTap\r\n && event.clientX === this.prevTap.clientX\r\n && event.clientY === this.prevTap.clientY\r\n && eventTarget === this.prevTap.target){\r\n this.downTargets[0] = eventTarget;\r\n this.downTimes[0] = new Date().getTime();\r\n this.collectEventTargets(pointer, event, eventTarget, 'tap');\r\n }\r\n },\r\n\r\n // End interact move events and stop auto-scroll unless inertia is enabled\r\n pointerEnd: function(pointer, event, eventTarget, curEventTarget){\r\n var endEvent,\r\n target = this.target,\r\n options = target && target.options,\r\n inertiaOptions = options && this.prepared.name && options[this.prepared.name].inertia,\r\n inertiaStatus = this.inertiaStatus;\r\n\r\n if (this.interacting()){\r\n if (inertiaStatus.active && !inertiaStatus.ending){ return; }\r\n\r\n var pointerSpeed,\r\n now = new Date().getTime(),\r\n inertiaPossible = false,\r\n inertia = false,\r\n smoothEnd = false,\r\n endSnap = checkSnap(target, this.prepared.name) && options[this.prepared.name].snap.endOnly,\r\n endRestrict = checkRestrict(target, this.prepared.name) && options[this.prepared.name].restrict.endOnly,\r\n dx = 0,\r\n dy = 0,\r\n startEvent;\r\n\r\n if (this.dragging){\r\n if (options.drag.axis === 'x'){ pointerSpeed = Math.abs(this.pointerDelta.client.vx); }\r\n else if (options.drag.axis === 'y'){ pointerSpeed = Math.abs(this.pointerDelta.client.vy); }\r\n else /* options.drag.axis === 'xy'*/{ pointerSpeed = this.pointerDelta.client.speed; }\r\n }\r\n else {\r\n pointerSpeed = this.pointerDelta.client.speed;\r\n }\r\n\r\n // check if inertia should be started\r\n inertiaPossible = (inertiaOptions && inertiaOptions.enabled\r\n && this.prepared.name !== 'gesture'\r\n && event !== inertiaStatus.startEvent);\r\n\r\n inertia = (inertiaPossible\r\n && (now - this.curCoords.timeStamp) < 50\r\n && pointerSpeed > inertiaOptions.minSpeed\r\n && pointerSpeed > inertiaOptions.endSpeed);\r\n\r\n if (inertiaPossible && !inertia && (endSnap || endRestrict)){\r\n var snapRestrict = {};\r\n\r\n snapRestrict.snap = snapRestrict.restrict = snapRestrict;\r\n\r\n if (endSnap){\r\n this.setSnapping(this.curCoords.page, snapRestrict);\r\n if (snapRestrict.locked){\r\n dx += snapRestrict.dx;\r\n dy += snapRestrict.dy;\r\n }\r\n }\r\n\r\n if (endRestrict){\r\n this.setRestriction(this.curCoords.page, snapRestrict);\r\n if (snapRestrict.restricted){\r\n dx += snapRestrict.dx;\r\n dy += snapRestrict.dy;\r\n }\r\n }\r\n\r\n if (dx || dy){\r\n smoothEnd = true;\r\n }\r\n }\r\n\r\n if (inertia || smoothEnd){\r\n copyCoords(inertiaStatus.upCoords, this.curCoords);\r\n\r\n this.pointers[0] = inertiaStatus.startEvent = startEvent =\r\n new InteractEvent(this, event, this.prepared.name, 'inertiastart', this.element);\r\n\r\n inertiaStatus.t0 = now;\r\n\r\n target.fire(inertiaStatus.startEvent);\r\n\r\n if (inertia){\r\n inertiaStatus.vx0 = this.pointerDelta.client.vx;\r\n inertiaStatus.vy0 = this.pointerDelta.client.vy;\r\n inertiaStatus.v0 = pointerSpeed;\r\n\r\n this.calcInertia(inertiaStatus);\r\n\r\n var page = extend({}, this.curCoords.page),\r\n origin = getOriginXY(target, this.element),\r\n statusObject;\r\n\r\n page.x = page.x + inertiaStatus.xe - origin.x;\r\n page.y = page.y + inertiaStatus.ye - origin.y;\r\n\r\n statusObject = {\r\n useStatusXY: true,\r\n x: page.x,\r\n y: page.y,\r\n dx: 0,\r\n dy: 0,\r\n snap: null\r\n };\r\n\r\n statusObject.snap = statusObject;\r\n\r\n dx = dy = 0;\r\n\r\n if (endSnap){\r\n var snap = this.setSnapping(this.curCoords.page, statusObject);\r\n\r\n if (snap.locked){\r\n dx += snap.dx;\r\n dy += snap.dy;\r\n }\r\n }\r\n\r\n if (endRestrict){\r\n var restrict = this.setRestriction(this.curCoords.page, statusObject);\r\n\r\n if (restrict.restricted){\r\n dx += restrict.dx;\r\n dy += restrict.dy;\r\n }\r\n }\r\n\r\n inertiaStatus.modifiedXe += dx;\r\n inertiaStatus.modifiedYe += dy;\r\n\r\n inertiaStatus.i = reqFrame(this.boundInertiaFrame);\r\n }\r\n else {\r\n inertiaStatus.smoothEnd = true;\r\n inertiaStatus.xe = dx;\r\n inertiaStatus.ye = dy;\r\n\r\n inertiaStatus.sx = inertiaStatus.sy = 0;\r\n\r\n inertiaStatus.i = reqFrame(this.boundSmoothEndFrame);\r\n }\r\n\r\n inertiaStatus.active = true;\r\n return;\r\n }\r\n\r\n if (endSnap || endRestrict){\r\n // fire a move event at the snapped coordinates\r\n this.pointerMove(pointer, event, eventTarget, curEventTarget, true);\r\n }\r\n }\r\n\r\n if (this.dragging){\r\n endEvent = new InteractEvent(this, event, 'drag', 'end', this.element);\r\n\r\n var draggableElement = this.element,\r\n drop = this.getDrop(endEvent, event, draggableElement);\r\n\r\n this.dropTarget = drop.dropzone;\r\n this.dropElement = drop.element;\r\n\r\n var dropEvents = this.getDropEvents(event, endEvent);\r\n\r\n if (dropEvents.leave){ this.prevDropTarget.fire(dropEvents.leave); }\r\n if (dropEvents.enter){ this.dropTarget.fire(dropEvents.enter); }\r\n if (dropEvents.drop){ this.dropTarget.fire(dropEvents.drop); }\r\n if (dropEvents.deactivate){\r\n this.fireActiveDrops(dropEvents.deactivate);\r\n }\r\n\r\n target.fire(endEvent);\r\n }\r\n else if (this.resizing){\r\n endEvent = new InteractEvent(this, event, 'resize', 'end', this.element);\r\n target.fire(endEvent);\r\n }\r\n else if (this.gesturing){\r\n endEvent = new InteractEvent(this, event, 'gesture', 'end', this.element);\r\n target.fire(endEvent);\r\n }\r\n\r\n this.stop(event);\r\n },\r\n\r\n collectDrops: function(element){\r\n var drops = [],\r\n elements = [],\r\n i;\r\n\r\n element = element || this.element;\r\n\r\n // collect all dropzones and their elements which qualify for a drop\r\n for (i = 0; i < interactables.length; i++){\r\n if (!interactables[i].options.drop.enabled){ continue; }\r\n\r\n var current = interactables[i],\r\n accept = current.options.drop.accept;\r\n\r\n // test the draggable element against the dropzone's accept setting\r\n if ((isElement(accept) && accept !== element)\r\n || (isString(accept)\r\n && !matchesSelector(element, accept))){\r\n continue;\r\n }\r\n\r\n // query for new elements if necessary\r\n var dropElements = current.selector ? current._context.querySelectorAll(current.selector) : [current._element];\r\n\r\n for (var j = 0, len = dropElements.length; j < len; j++){\r\n var currentElement = dropElements[j];\r\n\r\n if (currentElement === element){\r\n continue;\r\n }\r\n\r\n drops.push(current);\r\n elements.push(currentElement);\r\n }\r\n }\r\n\r\n return {\r\n dropzones: drops,\r\n elements: elements\r\n };\r\n },\r\n\r\n fireActiveDrops: function(event){\r\n var i,\r\n current,\r\n currentElement,\r\n prevElement;\r\n\r\n // loop through all active dropzones and trigger event\r\n for (i = 0; i < this.activeDrops.dropzones.length; i++){\r\n current = this.activeDrops.dropzones[i];\r\n currentElement = this.activeDrops.elements[i];\r\n\r\n // prevent trigger of duplicate events on same element\r\n if (currentElement !== prevElement){\r\n // set current element as event target\r\n event.target = currentElement;\r\n current.fire(event);\r\n }\r\n prevElement = currentElement;\r\n }\r\n },\r\n\r\n // Collect a new set of possible drops and save them in activeDrops.\r\n // setActiveDrops should always be called when a drag has just started or a\r\n // drag event happens while dynamicDrop is true\r\n setActiveDrops: function(dragElement){\r\n // get dropzones and their elements that could receive the draggable\r\n var possibleDrops = this.collectDrops(dragElement, true);\r\n\r\n this.activeDrops.dropzones = possibleDrops.dropzones;\r\n this.activeDrops.elements = possibleDrops.elements;\r\n this.activeDrops.rects = [];\r\n\r\n for (var i = 0; i < this.activeDrops.dropzones.length; i++){\r\n this.activeDrops.rects[i] = this.activeDrops.dropzones[i].getRect(this.activeDrops.elements[i]);\r\n }\r\n },\r\n\r\n getDrop: function(dragEvent, event, dragElement){\r\n var validDrops = [];\r\n\r\n if (dynamicDrop){\r\n this.setActiveDrops(dragElement);\r\n }\r\n\r\n // collect all dropzones and their elements which qualify for a drop\r\n for (var j = 0; j < this.activeDrops.dropzones.length; j++){\r\n var current = this.activeDrops.dropzones[j],\r\n currentElement = this.activeDrops.elements[j],\r\n rect = this.activeDrops.rects[j];\r\n\r\n validDrops.push(current.dropCheck(dragEvent, event, this.target, dragElement, currentElement, rect)\r\n ? currentElement\r\n : null);\r\n }\r\n\r\n // get the most appropriate dropzone based on DOM depth and order\r\n var dropIndex = indexOfDeepestElement(validDrops),\r\n dropzone = this.activeDrops.dropzones[dropIndex] || null,\r\n element = this.activeDrops.elements[dropIndex] || null;\r\n\r\n return {\r\n dropzone: dropzone,\r\n element: element\r\n };\r\n },\r\n\r\n getDropEvents: function(pointerEvent, dragEvent){\r\n var dropEvents = {\r\n enter: null,\r\n leave: null,\r\n activate: null,\r\n deactivate: null,\r\n move: null,\r\n drop: null\r\n };\r\n\r\n if (this.dropElement !== this.prevDropElement){\r\n // if there was a prevDropTarget, create a dragleave event\r\n if (this.prevDropTarget){\r\n dropEvents.leave = {\r\n target: this.prevDropElement,\r\n dropzone: this.prevDropTarget,\r\n relatedTarget: dragEvent.target,\r\n draggable: dragEvent.interactable,\r\n dragEvent: dragEvent,\r\n interaction: this,\r\n timeStamp: dragEvent.timeStamp,\r\n type: 'dragleave'\r\n };\r\n\r\n dragEvent.dragLeave = this.prevDropElement;\r\n dragEvent.prevDropzone = this.prevDropTarget;\r\n }\r\n // if the dropTarget is not null, create a dragenter event\r\n if (this.dropTarget){\r\n dropEvents.enter = {\r\n target: this.dropElement,\r\n dropzone: this.dropTarget,\r\n relatedTarget: dragEvent.target,\r\n draggable: dragEvent.interactable,\r\n dragEvent: dragEvent,\r\n interaction: this,\r\n timeStamp: dragEvent.timeStamp,\r\n type: 'dragenter'\r\n };\r\n\r\n dragEvent.dragEnter = this.dropElement;\r\n dragEvent.dropzone = this.dropTarget;\r\n }\r\n }\r\n\r\n if (dragEvent.type === 'dragend' && this.dropTarget){\r\n dropEvents.drop = {\r\n target: this.dropElement,\r\n dropzone: this.dropTarget,\r\n relatedTarget: dragEvent.target,\r\n draggable: dragEvent.interactable,\r\n dragEvent: dragEvent,\r\n interaction: this,\r\n timeStamp: dragEvent.timeStamp,\r\n type: 'drop'\r\n };\r\n\r\n dragEvent.dropzone = this.dropTarget;\r\n }\r\n if (dragEvent.type === 'dragstart'){\r\n dropEvents.activate = {\r\n target: null,\r\n dropzone: null,\r\n relatedTarget: dragEvent.target,\r\n draggable: dragEvent.interactable,\r\n dragEvent: dragEvent,\r\n interaction: this,\r\n timeStamp: dragEvent.timeStamp,\r\n type: 'dropactivate'\r\n };\r\n }\r\n if (dragEvent.type === 'dragend'){\r\n dropEvents.deactivate = {\r\n target: null,\r\n dropzone: null,\r\n relatedTarget: dragEvent.target,\r\n draggable: dragEvent.interactable,\r\n dragEvent: dragEvent,\r\n interaction: this,\r\n timeStamp: dragEvent.timeStamp,\r\n type: 'dropdeactivate'\r\n };\r\n }\r\n if (dragEvent.type === 'dragmove' && this.dropTarget){\r\n dropEvents.move = {\r\n target: this.dropElement,\r\n dropzone: this.dropTarget,\r\n relatedTarget: dragEvent.target,\r\n draggable: dragEvent.interactable,\r\n dragEvent: dragEvent,\r\n interaction: this,\r\n dragmove: dragEvent,\r\n timeStamp: dragEvent.timeStamp,\r\n type: 'dropmove'\r\n };\r\n dragEvent.dropzone = this.dropTarget;\r\n }\r\n\r\n return dropEvents;\r\n },\r\n\r\n currentAction: function(){\r\n return (this.dragging && 'drag') || (this.resizing && 'resize') || (this.gesturing && 'gesture') || null;\r\n },\r\n\r\n interacting: function(){\r\n return this.dragging || this.resizing || this.gesturing;\r\n },\r\n\r\n clearTargets: function(){\r\n this.target = this.element = null;\r\n\r\n this.dropTarget = this.dropElement = this.prevDropTarget = this.prevDropElement = null;\r\n },\r\n\r\n stop: function(event){\r\n if (this.interacting()){\r\n autoScroll.stop();\r\n this.matches = [];\r\n this.matchElements = [];\r\n\r\n var target = this.target;\r\n\r\n if (target.options.styleCursor){\r\n target._doc.documentElement.style.cursor = '';\r\n }\r\n\r\n // prevent Default only if were previously interacting\r\n if (event && isFunction(event.preventDefault)){\r\n this.checkAndPreventDefault(event, target, this.element);\r\n }\r\n\r\n if (this.dragging){\r\n this.activeDrops.dropzones = this.activeDrops.elements = this.activeDrops.rects = null;\r\n }\r\n }\r\n\r\n this.clearTargets();\r\n\r\n this.pointerIsDown = this.snapStatus.locked = this.dragging = this.resizing = this.gesturing = false;\r\n this.prepared.name = this.prevEvent = null;\r\n this.inertiaStatus.resumeDx = this.inertiaStatus.resumeDy = 0;\r\n\r\n // remove pointers if their ID isn't in this.pointerIds\r\n for (var i = 0; i < this.pointers.length; i++){\r\n if (indexOf(this.pointerIds, getPointerId(this.pointers[i])) === -1){\r\n this.pointers.splice(i, 1);\r\n }\r\n }\r\n },\r\n\r\n inertiaFrame: function(){\r\n var inertiaStatus = this.inertiaStatus,\r\n options = this.target.options[this.prepared.name].inertia,\r\n lambda = options.resistance,\r\n t = new Date().getTime() / 1000 - inertiaStatus.t0;\r\n\r\n if (t < inertiaStatus.te){\r\n var progress = 1 - (Math.exp(-lambda * t) - inertiaStatus.lambda_v0) / inertiaStatus.one_ve_v0;\r\n\r\n if (inertiaStatus.modifiedXe === inertiaStatus.xe && inertiaStatus.modifiedYe === inertiaStatus.ye){\r\n inertiaStatus.sx = inertiaStatus.xe * progress;\r\n inertiaStatus.sy = inertiaStatus.ye * progress;\r\n }\r\n else {\r\n var quadPoint = getQuadraticCurvePoint(\r\n 0, 0,\r\n inertiaStatus.xe, inertiaStatus.ye,\r\n inertiaStatus.modifiedXe, inertiaStatus.modifiedYe,\r\n progress);\r\n\r\n inertiaStatus.sx = quadPoint.x;\r\n inertiaStatus.sy = quadPoint.y;\r\n }\r\n\r\n this.pointerMove(inertiaStatus.startEvent, inertiaStatus.startEvent);\r\n\r\n inertiaStatus.i = reqFrame(this.boundInertiaFrame);\r\n }\r\n else {\r\n inertiaStatus.ending = true;\r\n\r\n inertiaStatus.sx = inertiaStatus.modifiedXe;\r\n inertiaStatus.sy = inertiaStatus.modifiedYe;\r\n\r\n this.pointerMove(inertiaStatus.startEvent, inertiaStatus.startEvent);\r\n this.pointerEnd(inertiaStatus.startEvent, inertiaStatus.startEvent);\r\n\r\n inertiaStatus.active = inertiaStatus.ending = false;\r\n }\r\n },\r\n\r\n smoothEndFrame: function(){\r\n var inertiaStatus = this.inertiaStatus,\r\n t = new Date().getTime() - inertiaStatus.t0,\r\n duration = this.target.options[this.prepared.name].inertia.smoothEndDuration;\r\n\r\n if (t < duration){\r\n inertiaStatus.sx = easeOutQuad(t, 0, inertiaStatus.xe, duration);\r\n inertiaStatus.sy = easeOutQuad(t, 0, inertiaStatus.ye, duration);\r\n\r\n this.pointerMove(inertiaStatus.startEvent, inertiaStatus.startEvent);\r\n\r\n inertiaStatus.i = reqFrame(this.boundSmoothEndFrame);\r\n }\r\n else {\r\n inertiaStatus.ending = true;\r\n\r\n inertiaStatus.sx = inertiaStatus.xe;\r\n inertiaStatus.sy = inertiaStatus.ye;\r\n\r\n this.pointerMove(inertiaStatus.startEvent, inertiaStatus.startEvent);\r\n this.pointerEnd(inertiaStatus.startEvent, inertiaStatus.startEvent);\r\n\r\n inertiaStatus.smoothEnd =\r\n inertiaStatus.active = inertiaStatus.ending = false;\r\n }\r\n },\r\n\r\n addPointer: function(pointer){\r\n var id = getPointerId(pointer),\r\n index = this.mouse ? 0 : indexOf(this.pointerIds, id);\r\n\r\n if (index === -1){\r\n index = this.pointerIds.length;\r\n }\r\n\r\n this.pointerIds[index] = id;\r\n this.pointers[index] = pointer;\r\n\r\n return index;\r\n },\r\n\r\n removePointer: function(pointer){\r\n var id = getPointerId(pointer),\r\n index = this.mouse ? 0 : indexOf(this.pointerIds, id);\r\n\r\n if (index === -1){ return; }\r\n\r\n this.pointers.splice(index, 1);\r\n this.pointerIds.splice(index, 1);\r\n this.downTargets.splice(index, 1);\r\n this.downTimes.splice(index, 1);\r\n this.holdTimers.splice(index, 1);\r\n },\r\n\r\n recordPointer: function(pointer){\r\n var index = this.mouse ? 0 : indexOf(this.pointerIds, getPointerId(pointer));\r\n\r\n if (index === -1){ return; }\r\n\r\n this.pointers[index] = pointer;\r\n },\r\n\r\n collectEventTargets: function(pointer, event, eventTarget, eventType){\r\n var pointerIndex = this.mouse ? 0 : indexOf(this.pointerIds, getPointerId(pointer));\r\n\r\n // do not fire a tap event if the pointer was moved before being lifted\r\n if (eventType === 'tap' && (this.pointerWasMoved\r\n // or if the pointerup target is different to the pointerdown target\r\n || !(this.downTargets[pointerIndex] && this.downTargets[pointerIndex] === eventTarget))){\r\n return;\r\n }\r\n\r\n var targets = [],\r\n elements = [],\r\n element = eventTarget;\r\n\r\n function collectSelectors(interactable, selector, context){\r\n var els = ie8MatchesSelector\r\n ? context.querySelectorAll(selector)\r\n : undefined;\r\n\r\n if (interactable._iEvents[eventType]\r\n && isElement(element)\r\n && inContext(interactable, element)\r\n && !testIgnore(interactable, element, eventTarget)\r\n && testAllow(interactable, element, eventTarget)\r\n && matchesSelector(element, selector, els)){\r\n targets.push(interactable);\r\n elements.push(element);\r\n }\r\n }\r\n\r\n while (element){\r\n if (interact.isSet(element) && interact(element)._iEvents[eventType]){\r\n targets.push(interact(element));\r\n elements.push(element);\r\n }\r\n\r\n interactables.forEachSelector(collectSelectors);\r\n\r\n element = parentElement(element);\r\n }\r\n\r\n // create the tap event even if there are no listeners so that\r\n // doubletap can still be created and fired\r\n if (targets.length || eventType === 'tap'){\r\n this.firePointers(pointer, event, eventTarget, targets, elements, eventType);\r\n }\r\n },\r\n\r\n firePointers: function(pointer, event, eventTarget, targets, elements, eventType){\r\n var pointerIndex = this.mouse ? 0 : indexOf(this.pointerIds, getPointerId(pointer)),\r\n pointerEvent = {},\r\n i,\r\n // for tap events\r\n interval, createNewDoubleTap;\r\n\r\n // if it's a doubletap then the event properties would have been\r\n // copied from the tap event and provided as the pointer argument\r\n if (eventType === 'doubletap'){\r\n pointerEvent = pointer;\r\n }\r\n else {\r\n pointerExtend(pointerEvent, event);\r\n if (event !== pointer){\r\n pointerExtend(pointerEvent, pointer);\r\n }\r\n\r\n pointerEvent.preventDefault = preventOriginalDefault;\r\n pointerEvent.stopPropagation = InteractEvent.prototype.stopPropagation;\r\n pointerEvent.stopImmediatePropagation = InteractEvent.prototype.stopImmediatePropagation;\r\n pointerEvent.interaction = this;\r\n\r\n pointerEvent.timeStamp = new Date().getTime();\r\n pointerEvent.originalEvent = event;\r\n pointerEvent.originalPointer = pointer;\r\n pointerEvent.type = eventType;\r\n pointerEvent.pointerId = getPointerId(pointer);\r\n pointerEvent.pointerType = this.mouse ? 'mouse' : !supportsPointerEvent ? 'touch'\r\n : isString(pointer.pointerType)\r\n ? pointer.pointerType\r\n : [,, 'touch', 'pen', 'mouse'][pointer.pointerType];\r\n }\r\n\r\n if (eventType === 'tap'){\r\n pointerEvent.dt = pointerEvent.timeStamp - this.downTimes[pointerIndex];\r\n\r\n interval = pointerEvent.timeStamp - this.tapTime;\r\n createNewDoubleTap = !!(this.prevTap && this.prevTap.type !== 'doubletap'\r\n && this.prevTap.target === pointerEvent.target\r\n && interval < 500);\r\n\r\n pointerEvent.double = createNewDoubleTap;\r\n\r\n this.tapTime = pointerEvent.timeStamp;\r\n }\r\n\r\n for (i = 0; i < targets.length; i++){\r\n pointerEvent.currentTarget = elements[i];\r\n pointerEvent.interactable = targets[i];\r\n targets[i].fire(pointerEvent);\r\n\r\n if (pointerEvent.immediatePropagationStopped\r\n || (pointerEvent.propagationStopped && elements[i + 1] !== pointerEvent.currentTarget)){\r\n break;\r\n }\r\n }\r\n\r\n if (createNewDoubleTap){\r\n var doubleTap = {};\r\n\r\n extend(doubleTap, pointerEvent);\r\n\r\n doubleTap.dt = interval;\r\n doubleTap.type = 'doubletap';\r\n\r\n this.collectEventTargets(doubleTap, event, eventTarget, 'doubletap');\r\n\r\n this.prevTap = doubleTap;\r\n }\r\n else if (eventType === 'tap'){\r\n this.prevTap = pointerEvent;\r\n }\r\n },\r\n\r\n validateSelector: function(pointer, event, matches, matchElements){\r\n for (var i = 0, len = matches.length; i < len; i++){\r\n var match = matches[i],\r\n matchElement = matchElements[i],\r\n action = validateAction(match.getAction(pointer, event, this, matchElement), match);\r\n\r\n if (action && withinInteractionLimit(match, matchElement, action)){\r\n this.target = match;\r\n this.element = matchElement;\r\n\r\n return action;\r\n }\r\n }\r\n },\r\n\r\n setSnapping: function(pageCoords, status){\r\n var snap = this.target.options[this.prepared.name].snap,\r\n targets = [],\r\n target,\r\n page,\r\n i;\r\n\r\n status = status || this.snapStatus;\r\n\r\n if (status.useStatusXY){\r\n page = { x: status.x, y: status.y };\r\n }\r\n else {\r\n var origin = getOriginXY(this.target, this.element);\r\n\r\n page = extend({}, pageCoords);\r\n\r\n page.x -= origin.x;\r\n page.y -= origin.y;\r\n }\r\n\r\n status.realX = page.x;\r\n status.realY = page.y;\r\n\r\n page.x = page.x - this.inertiaStatus.resumeDx;\r\n page.y = page.y - this.inertiaStatus.resumeDy;\r\n\r\n var len = snap.targets ? snap.targets.length : 0;\r\n\r\n for (var relIndex = 0; relIndex < this.snapOffsets.length; relIndex++){\r\n var relative = {\r\n x: page.x - this.snapOffsets[relIndex].x,\r\n y: page.y - this.snapOffsets[relIndex].y\r\n };\r\n\r\n for (i = 0; i < len; i++){\r\n if (isFunction(snap.targets[i])){\r\n target = snap.targets[i](relative.x, relative.y, this);\r\n }\r\n else {\r\n target = snap.targets[i];\r\n }\r\n\r\n if (!target){ continue; }\r\n\r\n targets.push({\r\n x: isNumber(target.x) ? (target.x + this.snapOffsets[relIndex].x) : relative.x,\r\n y: isNumber(target.y) ? (target.y + this.snapOffsets[relIndex].y) : relative.y,\r\n\r\n range: isNumber(target.range) ? target.range : snap.range\r\n });\r\n }\r\n }\r\n\r\n var closest = {\r\n target: null,\r\n inRange: false,\r\n distance: 0,\r\n range: 0,\r\n dx: 0,\r\n dy: 0\r\n };\r\n\r\n for (i = 0, len = targets.length; i < len; i++){\r\n target = targets[i];\r\n\r\n var range = target.range,\r\n dx = target.x - page.x,\r\n dy = target.y - page.y,\r\n distance = hypot(dx, dy),\r\n inRange = distance <= range;\r\n\r\n // Infinite targets count as being out of range\r\n // compared to non infinite ones that are in range\r\n if (range === Infinity && closest.inRange && closest.range !== Infinity){\r\n inRange = false;\r\n }\r\n\r\n if (!closest.target || (inRange\r\n // is the closest target in range?\r\n ? (closest.inRange && range !== Infinity\r\n // the pointer is relatively deeper in this target\r\n ? distance / range < closest.distance / closest.range\r\n // this target has Infinite range and the closest doesn't\r\n : (range === Infinity && closest.range !== Infinity)\r\n // OR this target is closer that the previous closest\r\n || distance < closest.distance)\r\n // The other is not in range and the pointer is closer to this target\r\n : (!closest.inRange && distance < closest.distance))){\r\n if (range === Infinity){\r\n inRange = true;\r\n }\r\n\r\n closest.target = target;\r\n closest.distance = distance;\r\n closest.range = range;\r\n closest.inRange = inRange;\r\n closest.dx = dx;\r\n closest.dy = dy;\r\n\r\n status.range = range;\r\n }\r\n }\r\n\r\n var snapChanged;\r\n\r\n if (closest.target){\r\n snapChanged = (status.snappedX !== closest.target.x || status.snappedY !== closest.target.y);\r\n\r\n status.snappedX = closest.target.x;\r\n status.snappedY = closest.target.y;\r\n }\r\n else {\r\n snapChanged = true;\r\n\r\n status.snappedX = NaN;\r\n status.snappedY = NaN;\r\n }\r\n\r\n status.dx = closest.dx;\r\n status.dy = closest.dy;\r\n\r\n status.changed = (snapChanged || (closest.inRange && !status.locked));\r\n status.locked = closest.inRange;\r\n\r\n return status;\r\n },\r\n\r\n setRestriction: function(pageCoords, status){\r\n var target = this.target,\r\n restrict = target && target.options[this.prepared.name].restrict,\r\n restriction = restrict && restrict.restriction,\r\n page;\r\n\r\n if (!restriction){\r\n return status;\r\n }\r\n\r\n status = status || this.restrictStatus;\r\n\r\n page = status.useStatusXY\r\n ? page = { x: status.x, y: status.y }\r\n : page = extend({}, pageCoords);\r\n\r\n if (status.snap && status.snap.locked){\r\n page.x += status.snap.dx || 0;\r\n page.y += status.snap.dy || 0;\r\n }\r\n\r\n page.x -= this.inertiaStatus.resumeDx;\r\n page.y -= this.inertiaStatus.resumeDy;\r\n\r\n status.dx = 0;\r\n status.dy = 0;\r\n status.restricted = false;\r\n\r\n var rect, restrictedX, restrictedY;\r\n\r\n if (isString(restriction)){\r\n if (restriction === 'parent'){\r\n restriction = parentElement(this.element);\r\n }\r\n else if (restriction === 'self'){\r\n restriction = target.getRect(this.element);\r\n }\r\n else {\r\n restriction = closest(this.element, restriction);\r\n }\r\n\r\n if (!restriction){ return status; }\r\n }\r\n\r\n if (isFunction(restriction)){\r\n restriction = restriction(page.x, page.y, this.element);\r\n }\r\n\r\n if (isElement(restriction)){\r\n restriction = getElementRect(restriction);\r\n }\r\n\r\n rect = restriction;\r\n\r\n if (!restriction){\r\n restrictedX = page.x;\r\n restrictedY = page.y;\r\n }\r\n // object is assumed to have\r\n // x, y, width, height or\r\n // left, top, right, bottom\r\n else if ('x' in restriction && 'y' in restriction){\r\n restrictedX = Math.max(Math.min(rect.x + rect.width - this.restrictOffset.right, page.x), rect.x + this.restrictOffset.left);\r\n restrictedY = Math.max(Math.min(rect.y + rect.height - this.restrictOffset.bottom, page.y), rect.y + this.restrictOffset.top);\r\n }\r\n else {\r\n restrictedX = Math.max(Math.min(rect.right - this.restrictOffset.right, page.x), rect.left + this.restrictOffset.left);\r\n restrictedY = Math.max(Math.min(rect.bottom - this.restrictOffset.bottom, page.y), rect.top + this.restrictOffset.top);\r\n }\r\n\r\n status.dx = restrictedX - page.x;\r\n status.dy = restrictedY - page.y;\r\n\r\n status.changed = status.restrictedX !== restrictedX || status.restrictedY !== restrictedY;\r\n status.restricted = !!(status.dx || status.dy);\r\n\r\n status.restrictedX = restrictedX;\r\n status.restrictedY = restrictedY;\r\n\r\n return status;\r\n },\r\n\r\n checkAndPreventDefault: function(event, interactable, element){\r\n if (!(interactable = interactable || this.target)){ return; }\r\n\r\n var options = interactable.options,\r\n prevent = options.preventDefault;\r\n\r\n if (prevent === 'auto' && element && !/^(input|select|textarea)$/i.test(event.target.nodeName)){\r\n // do not preventDefault on pointerdown if the prepared action is a drag\r\n // and dragging can only start from a certain direction - this allows\r\n // a touch to pan the viewport if a drag isn't in the right direction\r\n if (/down|start/i.test(event.type)\r\n && this.prepared.name === 'drag' && options.drag.axis !== 'xy'){\r\n return;\r\n }\r\n\r\n // with manualStart, only preventDefault while interacting\r\n if (options[this.prepared.name] && options[this.prepared.name].manualStart\r\n && !this.interacting()){\r\n return;\r\n }\r\n\r\n event.preventDefault();\r\n return;\r\n }\r\n\r\n if (prevent === 'always'){\r\n event.preventDefault();\r\n return;\r\n }\r\n },\r\n\r\n calcInertia: function(status){\r\n var inertiaOptions = this.target.options[this.prepared.name].inertia,\r\n lambda = inertiaOptions.resistance,\r\n inertiaDur = -Math.log(inertiaOptions.endSpeed / status.v0) / lambda;\r\n\r\n status.x0 = this.prevEvent.pageX;\r\n status.y0 = this.prevEvent.pageY;\r\n status.t0 = status.startEvent.timeStamp / 1000;\r\n status.sx = status.sy = 0;\r\n\r\n status.modifiedXe = status.xe = (status.vx0 - inertiaDur) / lambda;\r\n status.modifiedYe = status.ye = (status.vy0 - inertiaDur) / lambda;\r\n status.te = inertiaDur;\r\n\r\n status.lambda_v0 = lambda / status.v0;\r\n status.one_ve_v0 = 1 - inertiaOptions.endSpeed / status.v0;\r\n },\r\n\r\n autoScrollMove: function(pointer){\r\n if (!(this.interacting()\r\n && checkAutoScroll(this.target, this.prepared.name))){\r\n return;\r\n }\r\n\r\n if (this.inertiaStatus.active){\r\n autoScroll.x = autoScroll.y = 0;\r\n return;\r\n }\r\n\r\n var top,\r\n right,\r\n bottom,\r\n left,\r\n options = this.target.options[this.prepared.name].autoScroll,\r\n container = options.container || getWindow(this.element);\r\n\r\n if (isWindow(container)){\r\n left = pointer.clientX < autoScroll.margin;\r\n top = pointer.clientY < autoScroll.margin;\r\n right = pointer.clientX > container.innerWidth - autoScroll.margin;\r\n bottom = pointer.clientY > container.innerHeight - autoScroll.margin;\r\n }\r\n else {\r\n var rect = getElementClientRect(container);\r\n\r\n left = pointer.clientX < rect.left + autoScroll.margin;\r\n top = pointer.clientY < rect.top + autoScroll.margin;\r\n right = pointer.clientX > rect.right - autoScroll.margin;\r\n bottom = pointer.clientY > rect.bottom - autoScroll.margin;\r\n }\r\n\r\n autoScroll.x = (right ? 1 : left ? -1 : 0);\r\n autoScroll.y = (bottom ? 1 : top ? -1 : 0);\r\n\r\n if (!autoScroll.isScrolling){\r\n // set the autoScroll properties to those of the target\r\n autoScroll.margin = options.margin;\r\n autoScroll.speed = options.speed;\r\n\r\n autoScroll.start(this);\r\n }\r\n },\r\n\r\n _updateEventTargets: function(target, currentTarget){\r\n this._eventTarget = target;\r\n this._curEventTarget = currentTarget;\r\n }\r\n\r\n };\r\n\r\n function getInteractionFromPointer(pointer, eventType, eventTarget){\r\n var i = 0, len = interactions.length,\r\n mouseEvent = (/mouse/i.test(pointer.pointerType || eventType)\r\n // MSPointerEvent.MSPOINTER_TYPE_MOUSE\r\n || pointer.pointerType === 4),\r\n interaction;\r\n\r\n var id = getPointerId(pointer);\r\n\r\n // try to resume inertia with a new pointer\r\n if (/down|start/i.test(eventType)){\r\n for (i = 0; i < len; i++){\r\n interaction = interactions[i];\r\n\r\n var element = eventTarget;\r\n\r\n if (interaction.inertiaStatus.active && interaction.target.options[interaction.prepared.name].inertia.allowResume\r\n && (interaction.mouse === mouseEvent)){\r\n while (element){\r\n // if the element is the interaction element\r\n if (element === interaction.element){\r\n return interaction;\r\n }\r\n element = parentElement(element);\r\n }\r\n }\r\n }\r\n }\r\n\r\n // if it's a mouse interaction\r\n if (mouseEvent || !supportsTouch || supportsPointerEvent){\r\n // find a mouse interaction that's not in inertia phase\r\n for (i = 0; i < len; i++){\r\n if (interactions[i].mouse && !interactions[i].inertiaStatus.active){\r\n return interactions[i];\r\n }\r\n }\r\n\r\n // find any interaction specifically for mouse.\r\n // if the eventType is a mousedown, and inertia is active\r\n // ignore the interaction\r\n for (i = 0; i < len; i++){\r\n if (interactions[i].mouse && !(/down/.test(eventType) && interactions[i].inertiaStatus.active)){\r\n return interaction;\r\n }\r\n }\r\n\r\n // create a new interaction for mouse\r\n interaction = new Interaction();\r\n interaction.mouse = true;\r\n\r\n return interaction;\r\n }\r\n\r\n // get interaction that has this pointer\r\n for (i = 0; i < len; i++){\r\n if (contains(interactions[i].pointerIds, id)){\r\n return interactions[i];\r\n }\r\n }\r\n\r\n // at this stage, a pointerUp should not return an interaction\r\n if (/up|end|out/i.test(eventType)){\r\n return null;\r\n }\r\n\r\n // get first idle interaction\r\n for (i = 0; i < len; i++){\r\n interaction = interactions[i];\r\n\r\n if ((!interaction.prepared.name || (interaction.target.options.gesture.enabled))\r\n && !interaction.interacting()\r\n && !(!mouseEvent && interaction.mouse)){\r\n return interaction;\r\n }\r\n }\r\n\r\n return new Interaction();\r\n }\r\n\r\n function doOnInteractions(method){\r\n return (function(event){\r\n var interaction,\r\n eventTarget = getActualElement(event.path\r\n ? event.path[0]\r\n : event.target),\r\n curEventTarget = getActualElement(event.currentTarget),\r\n i;\r\n\r\n if (supportsTouch && /touch/.test(event.type)){\r\n prevTouchTime = new Date().getTime();\r\n\r\n for (i = 0; i < event.changedTouches.length; i++){\r\n var pointer = event.changedTouches[i];\r\n\r\n interaction = getInteractionFromPointer(pointer, event.type, eventTarget);\r\n\r\n if (!interaction){ continue; }\r\n\r\n interaction._updateEventTargets(eventTarget, curEventTarget);\r\n\r\n interaction[method](pointer, event, eventTarget, curEventTarget);\r\n }\r\n }\r\n else {\r\n if (!supportsPointerEvent && /mouse/.test(event.type)){\r\n // ignore mouse events while touch interactions are active\r\n for (i = 0; i < interactions.length; i++){\r\n if (!interactions[i].mouse && interactions[i].pointerIsDown){\r\n return;\r\n }\r\n }\r\n\r\n // try to ignore mouse events that are simulated by the browser\r\n // after a touch event\r\n if (new Date().getTime() - prevTouchTime < 500){\r\n return;\r\n }\r\n }\r\n\r\n interaction = getInteractionFromPointer(event, event.type, eventTarget);\r\n\r\n if (!interaction){ return; }\r\n\r\n interaction._updateEventTargets(eventTarget, curEventTarget);\r\n\r\n interaction[method](event, event, eventTarget, curEventTarget);\r\n }\r\n });\r\n }\r\n\r\n function InteractEvent(interaction, event, action, phase, element, related){\r\n var client,\r\n page,\r\n target = interaction.target,\r\n snapStatus = interaction.snapStatus,\r\n restrictStatus = interaction.restrictStatus,\r\n pointers = interaction.pointers,\r\n deltaSource = (target && target.options || defaultOptions).deltaSource,\r\n sourceX = deltaSource + 'X',\r\n sourceY = deltaSource + 'Y',\r\n options = target ? target.options : defaultOptions,\r\n origin = getOriginXY(target, element),\r\n starting = phase === 'start',\r\n ending = phase === 'end',\r\n coords = starting ? interaction.startCoords : interaction.curCoords;\r\n\r\n element = element || interaction.element;\r\n\r\n page = extend({}, coords.page);\r\n client = extend({}, coords.client);\r\n\r\n page.x -= origin.x;\r\n page.y -= origin.y;\r\n\r\n client.x -= origin.x;\r\n client.y -= origin.y;\r\n\r\n var relativePoints = options[action].snap && options[action].snap.relativePoints;\r\n\r\n if (checkSnap(target, action) && !(starting && relativePoints && relativePoints.length)){\r\n this.snap = {\r\n range: snapStatus.range,\r\n locked: snapStatus.locked,\r\n x: snapStatus.snappedX,\r\n y: snapStatus.snappedY,\r\n realX: snapStatus.realX,\r\n realY: snapStatus.realY,\r\n dx: snapStatus.dx,\r\n dy: snapStatus.dy\r\n };\r\n\r\n if (snapStatus.locked){\r\n page.x += snapStatus.dx;\r\n page.y += snapStatus.dy;\r\n client.x += snapStatus.dx;\r\n client.y += snapStatus.dy;\r\n }\r\n }\r\n\r\n if (checkRestrict(target, action) && !(starting && options[action].restrict.elementRect) && restrictStatus.restricted){\r\n page.x += restrictStatus.dx;\r\n page.y += restrictStatus.dy;\r\n client.x += restrictStatus.dx;\r\n client.y += restrictStatus.dy;\r\n\r\n this.restrict = {\r\n dx: restrictStatus.dx,\r\n dy: restrictStatus.dy\r\n };\r\n }\r\n\r\n this.pageX = page.x;\r\n this.pageY = page.y;\r\n this.clientX = client.x;\r\n this.clientY = client.y;\r\n\r\n this.x0 = interaction.startCoords.page.x - origin.x;\r\n this.y0 = interaction.startCoords.page.y - origin.y;\r\n this.clientX0 = interaction.startCoords.client.x - origin.x;\r\n this.clientY0 = interaction.startCoords.client.y - origin.y;\r\n this.ctrlKey = event.ctrlKey;\r\n this.altKey = event.altKey;\r\n this.shiftKey = event.shiftKey;\r\n this.metaKey = event.metaKey;\r\n this.button = event.button;\r\n this.buttons = event.buttons;\r\n this.target = element;\r\n this.t0 = interaction.downTimes[0];\r\n this.type = action + (phase || '');\r\n\r\n this.interaction = interaction;\r\n this.interactable = target;\r\n\r\n var inertiaStatus = interaction.inertiaStatus;\r\n\r\n if (inertiaStatus.active){\r\n this.detail = 'inertia';\r\n }\r\n\r\n if (related){\r\n this.relatedTarget = related;\r\n }\r\n\r\n // end event dx, dy is difference between start and end points\r\n if (ending){\r\n if (deltaSource === 'client'){\r\n this.dx = client.x - interaction.startCoords.client.x;\r\n this.dy = client.y - interaction.startCoords.client.y;\r\n }\r\n else {\r\n this.dx = page.x - interaction.startCoords.page.x;\r\n this.dy = page.y - interaction.startCoords.page.y;\r\n }\r\n }\r\n else if (starting){\r\n this.dx = 0;\r\n this.dy = 0;\r\n }\r\n // copy properties from previousmove if starting inertia\r\n else if (phase === 'inertiastart'){\r\n this.dx = interaction.prevEvent.dx;\r\n this.dy = interaction.prevEvent.dy;\r\n }\r\n else {\r\n if (deltaSource === 'client'){\r\n this.dx = client.x - interaction.prevEvent.clientX;\r\n this.dy = client.y - interaction.prevEvent.clientY;\r\n }\r\n else {\r\n this.dx = page.x - interaction.prevEvent.pageX;\r\n this.dy = page.y - interaction.prevEvent.pageY;\r\n }\r\n }\r\n if (interaction.prevEvent && interaction.prevEvent.detail === 'inertia'\r\n && !inertiaStatus.active\r\n && options[action].inertia && options[action].inertia.zeroResumeDelta){\r\n inertiaStatus.resumeDx += this.dx;\r\n inertiaStatus.resumeDy += this.dy;\r\n\r\n this.dx = this.dy = 0;\r\n }\r\n\r\n if (action === 'resize' && interaction.resizeAxes){\r\n if (options.resize.square){\r\n if (interaction.resizeAxes === 'y'){\r\n this.dx = this.dy;\r\n }\r\n else {\r\n this.dy = this.dx;\r\n }\r\n this.axes = 'xy';\r\n }\r\n else {\r\n this.axes = interaction.resizeAxes;\r\n\r\n if (interaction.resizeAxes === 'x'){\r\n this.dy = 0;\r\n }\r\n else if (interaction.resizeAxes === 'y'){\r\n this.dx = 0;\r\n }\r\n }\r\n }\r\n else if (action === 'gesture'){\r\n this.touches = [pointers[0], pointers[1]];\r\n\r\n if (starting){\r\n this.distance = touchDistance(pointers, deltaSource);\r\n this.box = touchBBox(pointers);\r\n this.scale = 1;\r\n this.ds = 0;\r\n this.angle = touchAngle(pointers, undefined, deltaSource);\r\n this.da = 0;\r\n }\r\n else if (ending || event instanceof InteractEvent){\r\n this.distance = interaction.prevEvent.distance;\r\n this.box = interaction.prevEvent.box;\r\n this.scale = interaction.prevEvent.scale;\r\n this.ds = this.scale - 1;\r\n this.angle = interaction.prevEvent.angle;\r\n this.da = this.angle - interaction.gesture.startAngle;\r\n }\r\n else {\r\n this.distance = touchDistance(pointers, deltaSource);\r\n this.box = touchBBox(pointers);\r\n this.scale = this.distance / interaction.gesture.startDistance;\r\n this.angle = touchAngle(pointers, interaction.gesture.prevAngle, deltaSource);\r\n\r\n this.ds = this.scale - interaction.gesture.prevScale;\r\n this.da = this.angle - interaction.gesture.prevAngle;\r\n }\r\n }\r\n\r\n if (starting){\r\n this.timeStamp = interaction.downTimes[0];\r\n this.dt = 0;\r\n this.duration = 0;\r\n this.speed = 0;\r\n this.velocityX = 0;\r\n this.velocityY = 0;\r\n }\r\n else if (phase === 'inertiastart'){\r\n this.timeStamp = interaction.prevEvent.timeStamp;\r\n this.dt = interaction.prevEvent.dt;\r\n this.duration = interaction.prevEvent.duration;\r\n this.speed = interaction.prevEvent.speed;\r\n this.velocityX = interaction.prevEvent.velocityX;\r\n this.velocityY = interaction.prevEvent.velocityY;\r\n }\r\n else {\r\n this.timeStamp = new Date().getTime();\r\n this.dt = this.timeStamp - interaction.prevEvent.timeStamp;\r\n this.duration = this.timeStamp - interaction.downTimes[0];\r\n\r\n if (event instanceof InteractEvent){\r\n var dx = this[sourceX] - interaction.prevEvent[sourceX],\r\n dy = this[sourceY] - interaction.prevEvent[sourceY],\r\n dt = this.dt / 1000;\r\n\r\n this.speed = hypot(dx, dy) / dt;\r\n this.velocityX = dx / dt;\r\n this.velocityY = dy / dt;\r\n }\r\n // if normal move or end event, use previous user event coords\r\n else {\r\n // speed and velocity in pixels per second\r\n this.speed = interaction.pointerDelta[deltaSource].speed;\r\n this.velocityX = interaction.pointerDelta[deltaSource].vx;\r\n this.velocityY = interaction.pointerDelta[deltaSource].vy;\r\n }\r\n }\r\n\r\n if ((ending || phase === 'inertiastart')\r\n && interaction.prevEvent.speed > 600 && this.timeStamp - interaction.prevEvent.timeStamp < 150){\r\n var angle = 180 * Math.atan2(interaction.prevEvent.velocityY, interaction.prevEvent.velocityX) / Math.PI,\r\n overlap = 22.5;\r\n\r\n if (angle < 0){\r\n angle += 360;\r\n }\r\n\r\n var left = 135 - overlap <= angle && angle < 225 + overlap,\r\n up = 225 - overlap <= angle && angle < 315 + overlap,\r\n\r\n right = !left && (315 - overlap <= angle || angle < 45 + overlap),\r\n down = !up && 45 - overlap <= angle && angle < 135 + overlap;\r\n\r\n this.swipe = {\r\n up: up,\r\n down: down,\r\n left: left,\r\n right: right,\r\n angle: angle,\r\n speed: interaction.prevEvent.speed,\r\n velocity: {\r\n x: interaction.prevEvent.velocityX,\r\n y: interaction.prevEvent.velocityY\r\n }\r\n };\r\n }\r\n }\r\n\r\n InteractEvent.prototype = {\r\n preventDefault: blank,\r\n stopImmediatePropagation: function(){\r\n this.immediatePropagationStopped = this.propagationStopped = true;\r\n },\r\n stopPropagation: function(){\r\n this.propagationStopped = true;\r\n }\r\n };\r\n\r\n function preventOriginalDefault(){\r\n this.originalEvent.preventDefault();\r\n }\r\n\r\n function getActionCursor(action){\r\n var cursor = '';\r\n\r\n if (action.name === 'drag'){\r\n cursor = actionCursors.drag;\r\n }\r\n if (action.name === 'resize'){\r\n if (action.axis){\r\n cursor = actionCursors[action.name + action.axis];\r\n }\r\n else if (action.edges){\r\n var cursorKey = 'resize',\r\n edgeNames = ['top', 'bottom', 'left', 'right'];\r\n\r\n for (var i = 0; i < 4; i++){\r\n if (action.edges[edgeNames[i]]){\r\n cursorKey += edgeNames[i];\r\n }\r\n }\r\n\r\n cursor = actionCursors[cursorKey];\r\n }\r\n }\r\n\r\n return cursor;\r\n }\r\n\r\n function checkResizeEdge(name, value, page, element, interactableElement, rect, margin){\r\n // false, '', undefined, null\r\n if (!value){ return false; }\r\n\r\n // true value, use pointer coords and element rect\r\n if (value === true){\r\n // if dimensions are negative, \"switch\" edges\r\n var width = isNumber(rect.width) ? rect.width : rect.right - rect.left,\r\n height = isNumber(rect.height) ? rect.height : rect.bottom - rect.top;\r\n\r\n if (width < 0){\r\n if (name === 'left'){ name = 'right'; }\r\n else if (name === 'right'){ name = 'left'; }\r\n }\r\n if (height < 0){\r\n if (name === 'top'){ name = 'bottom'; }\r\n else if (name === 'bottom'){ name = 'top'; }\r\n }\r\n\r\n if (name === 'left'){ return page.x < ((width >= 0 ? rect.left : rect.right) + margin); }\r\n if (name === 'top'){ return page.y < ((height >= 0 ? rect.top : rect.bottom) + margin); }\r\n\r\n if (name === 'right'){ return page.x > ((width >= 0 ? rect.right : rect.left) - margin); }\r\n if (name === 'bottom'){ return page.y > ((height >= 0 ? rect.bottom : rect.top) - margin); }\r\n }\r\n\r\n // the remaining checks require an element\r\n if (!isElement(element)){ return false; }\r\n\r\n return isElement(value)\r\n // the value is an element to use as a resize handle\r\n ? value === element\r\n // otherwise check if element matches value as selector\r\n : matchesUpTo(element, value, interactableElement);\r\n }\r\n\r\n function defaultActionChecker(pointer, interaction, element){\r\n var rect = this.getRect(element),\r\n shouldResize = false,\r\n action = null,\r\n resizeAxes = null,\r\n resizeEdges,\r\n page = extend({}, interaction.curCoords.page),\r\n options = this.options;\r\n\r\n if (!rect){ return null; }\r\n\r\n if (actionIsEnabled.resize && options.resize.enabled){\r\n var resizeOptions = options.resize;\r\n\r\n resizeEdges = {\r\n left: false, right: false, top: false, bottom: false\r\n };\r\n\r\n // if using resize.edges\r\n if (isObject(resizeOptions.edges)){\r\n for (var edge in resizeEdges){\r\n resizeEdges[edge] = checkResizeEdge(edge,\r\n resizeOptions.edges[edge],\r\n page,\r\n interaction._eventTarget,\r\n element,\r\n rect,\r\n resizeOptions.margin || margin);\r\n }\r\n\r\n resizeEdges.left = resizeEdges.left && !resizeEdges.right;\r\n resizeEdges.top = resizeEdges.top && !resizeEdges.bottom;\r\n\r\n shouldResize = resizeEdges.left || resizeEdges.right || resizeEdges.top || resizeEdges.bottom;\r\n }\r\n else {\r\n var right = options.resize.axis !== 'y' && page.x > (rect.right - margin),\r\n bottom = options.resize.axis !== 'x' && page.y > (rect.bottom - margin);\r\n\r\n shouldResize = right || bottom;\r\n resizeAxes = (right ? 'x' : '') + (bottom ? 'y' : '');\r\n }\r\n }\r\n\r\n action = shouldResize\r\n ? 'resize'\r\n : actionIsEnabled.drag && options.drag.enabled\r\n ? 'drag'\r\n : null;\r\n\r\n if (actionIsEnabled.gesture\r\n && interaction.pointerIds.length >= 2\r\n && !(interaction.dragging || interaction.resizing)){\r\n action = 'gesture';\r\n }\r\n\r\n if (action){\r\n return {\r\n name: action,\r\n axis: resizeAxes,\r\n edges: resizeEdges\r\n };\r\n }\r\n\r\n return null;\r\n }\r\n\r\n // Check if action is enabled globally and the current target supports it\r\n // If so, return the validated action. Otherwise, return null\r\n function validateAction(action, interactable){\r\n if (!isObject(action)){ return null; }\r\n\r\n var actionName = action.name,\r\n options = interactable.options;\r\n\r\n if (((actionName === 'resize' && options.resize.enabled)\r\n || (actionName === 'drag' && options.drag.enabled)\r\n || (actionName === 'gesture' && options.gesture.enabled))\r\n && actionIsEnabled[actionName]){\r\n if (actionName === 'resize' || actionName === 'resizeyx'){\r\n actionName = 'resizexy';\r\n }\r\n\r\n return action;\r\n }\r\n return null;\r\n }\r\n\r\n var listeners = {},\r\n interactionListeners = [\r\n 'dragStart', 'dragMove', 'resizeStart', 'resizeMove', 'gestureStart', 'gestureMove',\r\n 'pointerOver', 'pointerOut', 'pointerHover', 'selectorDown',\r\n 'pointerDown', 'pointerMove', 'pointerUp', 'pointerCancel', 'pointerEnd',\r\n 'addPointer', 'removePointer', 'recordPointer', 'autoScrollMove'\r\n ];\r\n\r\n for (var i = 0, len = interactionListeners.length; i < len; i++){\r\n var name = interactionListeners[i];\r\n\r\n listeners[name] = doOnInteractions(name);\r\n }\r\n\r\n // bound to the interactable context when a DOM event\r\n // listener is added to a selector interactable\r\n function delegateListener(event, useCapture){\r\n var fakeEvent = {},\r\n delegated = delegatedEvents[event.type],\r\n eventTarget = getActualElement(event.path\r\n ? event.path[0]\r\n : event.target),\r\n element = eventTarget;\r\n\r\n useCapture = useCapture ? true : false;\r\n\r\n // duplicate the event so that currentTarget can be changed\r\n for (var prop in event){\r\n fakeEvent[prop] = event[prop];\r\n }\r\n\r\n fakeEvent.originalEvent = event;\r\n fakeEvent.preventDefault = preventOriginalDefault;\r\n\r\n // climb up document tree looking for selector matches\r\n while (isElement(element)){\r\n for (var i = 0; i < delegated.selectors.length; i++){\r\n var selector = delegated.selectors[i],\r\n context = delegated.contexts[i];\r\n\r\n if (matchesSelector(element, selector)\r\n && nodeContains(context, eventTarget)\r\n && nodeContains(context, element)){\r\n var listeners = delegated.listeners[i];\r\n\r\n fakeEvent.currentTarget = element;\r\n\r\n for (var j = 0; j < listeners.length; j++){\r\n if (listeners[j][1] === useCapture){\r\n listeners[j][0](fakeEvent);\r\n }\r\n }\r\n }\r\n }\r\n\r\n element = parentElement(element);\r\n }\r\n }\r\n\r\n function delegateUseCapture(event){\r\n return delegateListener.call(this, event, true);\r\n }\r\n\r\n interactables.indexOfElement = function indexOfElement(element, context){\r\n context = context || document;\r\n\r\n for (var i = 0; i < this.length; i++){\r\n var interactable = this[i];\r\n\r\n if ((interactable.selector === element\r\n && (interactable._context === context))\r\n || (!interactable.selector && interactable._element === element)){\r\n return i;\r\n }\r\n }\r\n return -1;\r\n };\r\n\r\n interactables.get = function interactableGet(element, options){\r\n return this[this.indexOfElement(element, options && options.context)];\r\n };\r\n\r\n interactables.forEachSelector = function(callback){\r\n for (var i = 0; i < this.length; i++){\r\n var interactable = this[i];\r\n\r\n if (!interactable.selector){\r\n continue;\r\n }\r\n\r\n var ret = callback(interactable, interactable.selector, interactable._context, i, this);\r\n\r\n if (ret !== undefined){\r\n return ret;\r\n }\r\n }\r\n };\r\n\r\n /* \\\r\n * interact\r\n [ method ]\r\n *\r\n * The methods of this variable can be used to set elements as\r\n * interactables and also to change various default settings.\r\n *\r\n * Calling it as a function and passing an element or a valid CSS selector\r\n * string returns an Interactable object which has various methods to\r\n * configure it.\r\n *\r\n - element (Element | string) The HTML or SVG Element to interact with or CSS selector\r\n = (object) An @Interactable\r\n *\r\n > Usage\r\n | interact(document.getElementById('draggable')).draggable(true);\r\n |\r\n | var rectables = interact('rect');\r\n | rectables\r\n | .gesturable(true)\r\n | .on('gesturemove', function (event) {\r\n | // something cool...\r\n | })\r\n | .autoScroll(true);\r\n \\*/\r\n function interact(element, options){\r\n return interactables.get(element, options) || new Interactable(element, options);\r\n }\r\n\r\n /* \\\r\n * Interactable\r\n [ property ]\r\n **\r\n * Object type returned by @interact\r\n \\*/\r\n function Interactable(element, options){\r\n this._element = element;\r\n this._iEvents = this._iEvents || {};\r\n\r\n var _window;\r\n\r\n if (trySelector(element)){\r\n this.selector = element;\r\n\r\n var context = options && options.context;\r\n\r\n _window = context ? getWindow(context) : window;\r\n\r\n if (context && (_window.Node\r\n ? context instanceof _window.Node\r\n : (isElement(context) || context === _window.document))){\r\n this._context = context;\r\n }\r\n }\r\n else {\r\n _window = getWindow(element);\r\n\r\n if (isElement(element, _window)){\r\n if (supportsPointerEvent){\r\n events.add(this._element, pEventTypes.down, listeners.pointerDown);\r\n events.add(this._element, pEventTypes.move, listeners.pointerHover);\r\n }\r\n else {\r\n events.add(this._element, 'mousedown', listeners.pointerDown);\r\n events.add(this._element, 'mousemove', listeners.pointerHover);\r\n events.add(this._element, 'touchstart', listeners.pointerDown);\r\n events.add(this._element, 'touchmove', listeners.pointerHover);\r\n }\r\n }\r\n }\r\n\r\n this._doc = _window.document;\r\n\r\n if (!contains(documents, this._doc)){\r\n listenToDocument(this._doc);\r\n }\r\n\r\n interactables.push(this);\r\n\r\n this.set(options);\r\n }\r\n\r\n Interactable.prototype = {\r\n setOnEvents: function(action, phases){\r\n if (action === 'drop'){\r\n if (isFunction(phases.ondrop)){ this.ondrop = phases.ondrop; }\r\n if (isFunction(phases.ondropactivate)){ this.ondropactivate = phases.ondropactivate; }\r\n if (isFunction(phases.ondropdeactivate)){ this.ondropdeactivate = phases.ondropdeactivate; }\r\n if (isFunction(phases.ondragenter)){ this.ondragenter = phases.ondragenter; }\r\n if (isFunction(phases.ondragleave)){ this.ondragleave = phases.ondragleave; }\r\n if (isFunction(phases.ondropmove)){ this.ondropmove = phases.ondropmove; }\r\n }\r\n else {\r\n action = 'on' + action;\r\n\r\n if (isFunction(phases.onstart)){ this[action + 'start' ] = phases.onstart; }\r\n if (isFunction(phases.onmove)){ this[action + 'move' ] = phases.onmove; }\r\n if (isFunction(phases.onend)){ this[action + 'end' ] = phases.onend; }\r\n if (isFunction(phases.oninertiastart)){ this[action + 'inertiastart' ] = phases.oninertiastart; }\r\n }\r\n\r\n return this;\r\n },\r\n\r\n /* \\\r\n * Interactable.draggable\r\n [ method ]\r\n *\r\n * Gets or sets whether drag actions can be performed on the\r\n * Interactable\r\n *\r\n = (boolean) Indicates if this can be the target of drag events\r\n | var isDraggable = interact('ul li').draggable();\r\n * or\r\n - options (boolean | object) #optional true/false or An object with event listeners to be fired on drag events (object makes the Interactable draggable)\r\n = (object) This Interactable\r\n | interact(element).draggable({\r\n | onstart: function (event) {},\r\n | onmove : function (event) {},\r\n | onend : function (event) {},\r\n |\r\n | // the axis in which the first movement must be\r\n | // for the drag sequence to start\r\n | // 'xy' by default - any direction\r\n | axis: 'x' || 'y' || 'xy',\r\n |\r\n | // max number of drags that can happen concurrently\r\n | // with elements of this Interactable. Infinity by default\r\n | max: Infinity,\r\n |\r\n | // max number of drags that can target the same element+Interactable\r\n | // 1 by default\r\n | maxPerElement: 2\r\n | });\r\n \\*/\r\n draggable: function(options){\r\n if (isObject(options)){\r\n this.options.drag.enabled = options.enabled === false ? false : true;\r\n this.setPerAction('drag', options);\r\n this.setOnEvents('drag', options);\r\n\r\n if (/^x$|^y$|^xy$/.test(options.axis)){\r\n this.options.drag.axis = options.axis;\r\n }\r\n else if (options.axis === null){\r\n delete this.options.drag.axis;\r\n }\r\n\r\n return this;\r\n }\r\n\r\n if (isBool(options)){\r\n this.options.drag.enabled = options;\r\n\r\n return this;\r\n }\r\n\r\n return this.options.drag;\r\n },\r\n\r\n setPerAction: function(action, options){\r\n // for all the default per-action options\r\n for (var option in options){\r\n // if this option exists for this action\r\n if (option in defaultOptions[action]){\r\n // if the option in the options arg is an object value\r\n if (isObject(options[option])){\r\n // duplicate the object\r\n this.options[action][option] = extend(this.options[action][option] || {}, options[option]);\r\n\r\n if (isObject(defaultOptions.perAction[option]) && 'enabled' in defaultOptions.perAction[option]){\r\n this.options[action][option].enabled = options[option].enabled === false ? false : true;\r\n }\r\n }\r\n else if (isBool(options[option]) && isObject(defaultOptions.perAction[option])){\r\n this.options[action][option].enabled = options[option];\r\n }\r\n else if (options[option] !== undefined){\r\n // or if it's not undefined, do a plain assignment\r\n this.options[action][option] = options[option];\r\n }\r\n }\r\n }\r\n },\r\n\r\n /* \\\r\n * Interactable.dropzone\r\n [ method ]\r\n *\r\n * Returns or sets whether elements can be dropped onto this\r\n * Interactable to trigger drop events\r\n *\r\n * Dropzones can receive the following events:\r\n * - `dropactivate` and `dropdeactivate` when an acceptable drag starts and ends\r\n * - `dragenter` and `dragleave` when a draggable enters and leaves the dropzone\r\n * - `dragmove` when a draggable that has entered the dropzone is moved\r\n * - `drop` when a draggable is dropped into this dropzone\r\n *\r\n * Use the `accept` option to allow only elements that match the given CSS selector or element.\r\n *\r\n * Use the `overlap` option to set how drops are checked for. The allowed values are:\r\n * - `'pointer'`, the pointer must be over the dropzone (default)\r\n * - `'center'`, the draggable element's center must be over the dropzone\r\n * - a number from 0-1 which is the `(intersection area) / (draggable area)`.\r\n * e.g. `0.5` for drop to happen when half of the area of the\r\n * draggable is over the dropzone\r\n *\r\n - options (boolean | object | null) #optional The new value to be set.\r\n | interact('.drop').dropzone({\r\n | accept: '.can-drop' || document.getElementById('single-drop'),\r\n | overlap: 'pointer' || 'center' || zeroToOne\r\n | }\r\n = (boolean | object) The current setting or this Interactable\r\n \\*/\r\n dropzone: function(options){\r\n if (isObject(options)){\r\n this.options.drop.enabled = options.enabled === false ? false : true;\r\n this.setOnEvents('drop', options);\r\n\r\n if (/^(pointer|center)$/.test(options.overlap)){\r\n this.options.drop.overlap = options.overlap;\r\n }\r\n else if (isNumber(options.overlap)){\r\n this.options.drop.overlap = Math.max(Math.min(1, options.overlap), 0);\r\n }\r\n if ('accept' in options){\r\n this.options.drop.accept = options.accept;\r\n }\r\n if ('checker' in options){\r\n this.options.drop.checker = options.checker;\r\n }\r\n\r\n return this;\r\n }\r\n\r\n if (isBool(options)){\r\n this.options.drop.enabled = options;\r\n\r\n return this;\r\n }\r\n\r\n return this.options.drop;\r\n },\r\n\r\n dropCheck: function(dragEvent, event, draggable, draggableElement, dropElement, rect){\r\n var dropped = false;\r\n\r\n // if the dropzone has no rect (eg. display: none)\r\n // call the custom dropChecker or just return false\r\n if (!(rect = rect || this.getRect(dropElement))){\r\n return (this.options.drop.checker\r\n ? this.options.drop.checker(dragEvent, event, dropped, this, dropElement, draggable, draggableElement)\r\n : false);\r\n }\r\n\r\n var dropOverlap = this.options.drop.overlap;\r\n\r\n if (dropOverlap === 'pointer'){\r\n var page = getPageXY(dragEvent),\r\n origin = getOriginXY(draggable, draggableElement),\r\n horizontal,\r\n vertical;\r\n\r\n page.x += origin.x;\r\n page.y += origin.y;\r\n\r\n horizontal = (page.x > rect.left) && (page.x < rect.right);\r\n vertical = (page.y > rect.top) && (page.y < rect.bottom);\r\n\r\n dropped = horizontal && vertical;\r\n }\r\n\r\n var dragRect = draggable.getRect(draggableElement);\r\n\r\n if (dropOverlap === 'center'){\r\n var cx = dragRect.left + dragRect.width / 2,\r\n cy = dragRect.top + dragRect.height / 2;\r\n\r\n dropped = cx >= rect.left && cx <= rect.right && cy >= rect.top && cy <= rect.bottom;\r\n }\r\n\r\n if (isNumber(dropOverlap)){\r\n var overlapArea = (Math.max(0, Math.min(rect.right, dragRect.right) - Math.max(rect.left, dragRect.left))\r\n * Math.max(0, Math.min(rect.bottom, dragRect.bottom) - Math.max(rect.top, dragRect.top))),\r\n overlapRatio = overlapArea / (dragRect.width * dragRect.height);\r\n\r\n dropped = overlapRatio >= dropOverlap;\r\n }\r\n\r\n if (this.options.drop.checker){\r\n dropped = this.options.drop.checker(dragEvent, event, dropped, this, dropElement, draggable, draggableElement);\r\n }\r\n\r\n return dropped;\r\n },\r\n\r\n /* \\\r\n * Interactable.dropChecker\r\n [ method ]\r\n *\r\n * DEPRECATED. Use interactable.dropzone({ checker: function... }) instead.\r\n *\r\n * Gets or sets the function used to check if a dragged element is\r\n * over this Interactable.\r\n *\r\n - checker (function) #optional The function that will be called when checking for a drop\r\n = (Function | Interactable) The checker function or this Interactable\r\n *\r\n * The checker function takes the following arguments:\r\n *\r\n - dragEvent (InteractEvent) The related dragmove or dragend event\r\n - event (TouchEvent | PointerEvent | MouseEvent) The user move/up/end Event related to the dragEvent\r\n - dropped (boolean) The value from the default drop checker\r\n - dropzone (Interactable) The dropzone interactable\r\n - dropElement (Element) The dropzone element\r\n - draggable (Interactable) The Interactable being dragged\r\n - draggableElement (Element) The actual element that's being dragged\r\n *\r\n > Usage:\r\n | interact(target)\r\n | .dropChecker(function(dragEvent, // related dragmove or dragend event\r\n | event, // TouchEvent/PointerEvent/MouseEvent\r\n | dropped, // bool result of the default checker\r\n | dropzone, // dropzone Interactable\r\n | dropElement, // dropzone elemnt\r\n | draggable, // draggable Interactable\r\n | draggableElement) {// draggable element\r\n |\r\n | return dropped && event.target.hasAttribute('allow-drop');\r\n | }\r\n \\*/\r\n dropChecker: function(checker){\r\n if (isFunction(checker)){\r\n this.options.drop.checker = checker;\r\n\r\n return this;\r\n }\r\n if (checker === null){\r\n delete this.options.getRect;\r\n\r\n return this;\r\n }\r\n\r\n return this.options.drop.checker;\r\n },\r\n\r\n /* \\\r\n * Interactable.accept\r\n [ method ]\r\n *\r\n * Deprecated. add an `accept` property to the options object passed to\r\n * @Interactable.dropzone instead.\r\n *\r\n * Gets or sets the Element or CSS selector match that this\r\n * Interactable accepts if it is a dropzone.\r\n *\r\n - newValue (Element | string | null) #optional\r\n * If it is an Element, then only that element can be dropped into this dropzone.\r\n * If it is a string, the element being dragged must match it as a selector.\r\n * If it is null, the accept options is cleared - it accepts any element.\r\n *\r\n = (string | Element | null | Interactable) The current accept option if given `undefined` or this Interactable\r\n \\*/\r\n accept: function(newValue){\r\n if (isElement(newValue)){\r\n this.options.drop.accept = newValue;\r\n\r\n return this;\r\n }\r\n\r\n // test if it is a valid CSS selector\r\n if (trySelector(newValue)){\r\n this.options.drop.accept = newValue;\r\n\r\n return this;\r\n }\r\n\r\n if (newValue === null){\r\n delete this.options.drop.accept;\r\n\r\n return this;\r\n }\r\n\r\n return this.options.drop.accept;\r\n },\r\n\r\n /* \\\r\n * Interactable.resizable\r\n [ method ]\r\n *\r\n * Gets or sets whether resize actions can be performed on the\r\n * Interactable\r\n *\r\n = (boolean) Indicates if this can be the target of resize elements\r\n | var isResizeable = interact('input[type=text]').resizable();\r\n * or\r\n - options (boolean | object) #optional true/false or An object with event listeners to be fired on resize events (object makes the Interactable resizable)\r\n = (object) This Interactable\r\n | interact(element).resizable({\r\n | onstart: function (event) {},\r\n | onmove : function (event) {},\r\n | onend : function (event) {},\r\n |\r\n | edges: {\r\n | top : true, // Use pointer coords to check for resize.\r\n | left : false, // Disable resizing from left edge.\r\n | bottom: '.resize-s',// Resize if pointer target matches selector\r\n | right : handleEl // Resize if pointer target is the given Element\r\n | },\r\n |\r\n | // Width and height can be adjusted independently. When `true`, width and\r\n | // height are adjusted at a 1:1 ratio.\r\n | square: false,\r\n |\r\n | // Width and height can be adjusted independently. When `true`, width and\r\n | // height maintain the aspect ratio they had when resizing started.\r\n | preserveAspectRatio: false,\r\n |\r\n | // a value of 'none' will limit the resize rect to a minimum of 0x0\r\n | // 'negate' will allow the rect to have negative width/height\r\n | // 'reposition' will keep the width/height positive by swapping\r\n | // the top and bottom edges and/or swapping the left and right edges\r\n | invert: 'none' || 'negate' || 'reposition'\r\n |\r\n | // limit multiple resizes.\r\n | // See the explanation in the @Interactable.draggable example\r\n | max: Infinity,\r\n | maxPerElement: 1,\r\n | });\r\n \\*/\r\n resizable: function(options){\r\n if (isObject(options)){\r\n this.options.resize.enabled = options.enabled === false ? false : true;\r\n this.setPerAction('resize', options);\r\n this.setOnEvents('resize', options);\r\n\r\n if (/^x$|^y$|^xy$/.test(options.axis)){\r\n this.options.resize.axis = options.axis;\r\n }\r\n else if (options.axis === null){\r\n this.options.resize.axis = defaultOptions.resize.axis;\r\n }\r\n\r\n if (isBool(options.preserveAspectRatio)){\r\n this.options.resize.preserveAspectRatio = options.preserveAspectRatio;\r\n }\r\n else if (isBool(options.square)){\r\n this.options.resize.square = options.square;\r\n }\r\n\r\n return this;\r\n }\r\n if (isBool(options)){\r\n this.options.resize.enabled = options;\r\n\r\n return this;\r\n }\r\n return this.options.resize;\r\n },\r\n\r\n /* \\\r\n * Interactable.squareResize\r\n [ method ]\r\n *\r\n * Deprecated. Add a `square: true || false` property to @Interactable.resizable instead\r\n *\r\n * Gets or sets whether resizing is forced 1:1 aspect\r\n *\r\n = (boolean) Current setting\r\n *\r\n * or\r\n *\r\n - newValue (boolean) #optional\r\n = (object) this Interactable\r\n \\*/\r\n squareResize: function(newValue){\r\n if (isBool(newValue)){\r\n this.options.resize.square = newValue;\r\n\r\n return this;\r\n }\r\n\r\n if (newValue === null){\r\n delete this.options.resize.square;\r\n\r\n return this;\r\n }\r\n\r\n return this.options.resize.square;\r\n },\r\n\r\n /* \\\r\n * Interactable.gesturable\r\n [ method ]\r\n *\r\n * Gets or sets whether multitouch gestures can be performed on the\r\n * Interactable's element\r\n *\r\n = (boolean) Indicates if this can be the target of gesture events\r\n | var isGestureable = interact(element).gesturable();\r\n * or\r\n - options (boolean | object) #optional true/false or An object with event listeners to be fired on gesture events (makes the Interactable gesturable)\r\n = (object) this Interactable\r\n | interact(element).gesturable({\r\n | onstart: function (event) {},\r\n | onmove : function (event) {},\r\n | onend : function (event) {},\r\n |\r\n | // limit multiple gestures.\r\n | // See the explanation in @Interactable.draggable example\r\n | max: Infinity,\r\n | maxPerElement: 1,\r\n | });\r\n \\*/\r\n gesturable: function(options){\r\n if (isObject(options)){\r\n this.options.gesture.enabled = options.enabled === false ? false : true;\r\n this.setPerAction('gesture', options);\r\n this.setOnEvents('gesture', options);\r\n\r\n return this;\r\n }\r\n\r\n if (isBool(options)){\r\n this.options.gesture.enabled = options;\r\n\r\n return this;\r\n }\r\n\r\n return this.options.gesture;\r\n },\r\n\r\n /* \\\r\n * Interactable.autoScroll\r\n [ method ]\r\n **\r\n * Deprecated. Add an `autoscroll` property to the options object\r\n * passed to @Interactable.draggable or @Interactable.resizable instead.\r\n *\r\n * Returns or sets whether dragging and resizing near the edges of the\r\n * window/container trigger autoScroll for this Interactable\r\n *\r\n = (object) Object with autoScroll properties\r\n *\r\n * or\r\n *\r\n - options (object | boolean) #optional\r\n * options can be:\r\n * - an object with margin, distance and interval properties,\r\n * - true or false to enable or disable autoScroll or\r\n = (Interactable) this Interactable\r\n \\*/\r\n autoScroll: function(options){\r\n if (isObject(options)){\r\n options = extend({ actions: ['drag', 'resize']}, options);\r\n }\r\n else if (isBool(options)){\r\n options = { actions: ['drag', 'resize'], enabled: options };\r\n }\r\n\r\n return this.setOptions('autoScroll', options);\r\n },\r\n\r\n /* \\\r\n * Interactable.snap\r\n [ method ]\r\n **\r\n * Deprecated. Add a `snap` property to the options object passed\r\n * to @Interactable.draggable or @Interactable.resizable instead.\r\n *\r\n * Returns or sets if and how action coordinates are snapped. By\r\n * default, snapping is relative to the pointer coordinates. You can\r\n * change this by setting the\r\n * [`elementOrigin`](https://github.com/taye/interact.js/pull/72).\r\n **\r\n = (boolean | object) `false` if snap is disabled; object with snap properties if snap is enabled\r\n **\r\n * or\r\n **\r\n - options (object | boolean | null) #optional\r\n = (Interactable) this Interactable\r\n > Usage\r\n | interact(document.querySelector('#thing')).snap({\r\n | targets: [\r\n | // snap to this specific point\r\n | {\r\n | x: 100,\r\n | y: 100,\r\n | range: 25\r\n | },\r\n | // give this function the x and y page coords and snap to the object returned\r\n | function (x, y) {\r\n | return {\r\n | x: x,\r\n | y: (75 + 50 * Math.sin(x * 0.04)),\r\n | range: 40\r\n | };\r\n | },\r\n | // create a function that snaps to a grid\r\n | interact.createSnapGrid({\r\n | x: 50,\r\n | y: 50,\r\n | range: 10, // optional\r\n | offset: { x: 5, y: 10 } // optional\r\n | })\r\n | ],\r\n | // do not snap during normal movement.\r\n | // Instead, trigger only one snapped move event\r\n | // immediately before the end event.\r\n | endOnly: true,\r\n |\r\n | relativePoints: [\r\n | { x: 0, y: 0 }, // snap relative to the top left of the element\r\n | { x: 1, y: 1 }, // and also to the bottom right\r\n | ],\r\n |\r\n | // offset the snap target coordinates\r\n | // can be an object with x/y or 'startCoords'\r\n | offset: { x: 50, y: 50 }\r\n | }\r\n | });\r\n \\*/\r\n snap: function(options){\r\n var ret = this.setOptions('snap', options);\r\n\r\n if (ret === this){ return this; }\r\n\r\n return ret.drag;\r\n },\r\n\r\n setOptions: function(option, options){\r\n var actions = options && isArray(options.actions)\r\n ? options.actions\r\n : ['drag'];\r\n\r\n var i;\r\n\r\n if (isObject(options) || isBool(options)){\r\n for (i = 0; i < actions.length; i++){\r\n var action = /resize/.test(actions[i]) ? 'resize' : actions[i];\r\n\r\n if (!isObject(this.options[action])){ continue; }\r\n\r\n var thisOption = this.options[action][option];\r\n\r\n if (isObject(options)){\r\n extend(thisOption, options);\r\n thisOption.enabled = options.enabled === false ? false : true;\r\n\r\n if (option === 'snap'){\r\n if (thisOption.mode === 'grid'){\r\n thisOption.targets = [\r\n interact.createSnapGrid(extend({\r\n offset: thisOption.gridOffset || { x: 0, y: 0 }\r\n }, thisOption.grid || {}))\r\n ];\r\n }\r\n else if (thisOption.mode === 'anchor'){\r\n thisOption.targets = thisOption.anchors;\r\n }\r\n else if (thisOption.mode === 'path'){\r\n thisOption.targets = thisOption.paths;\r\n }\r\n\r\n if ('elementOrigin' in options){\r\n thisOption.relativePoints = [options.elementOrigin];\r\n }\r\n }\r\n }\r\n else if (isBool(options)){\r\n thisOption.enabled = options;\r\n }\r\n }\r\n\r\n return this;\r\n }\r\n\r\n var ret = {},\r\n allActions = ['drag', 'resize', 'gesture'];\r\n\r\n for (i = 0; i < allActions.length; i++){\r\n if (option in defaultOptions[allActions[i]]){\r\n ret[allActions[i]] = this.options[allActions[i]][option];\r\n }\r\n }\r\n\r\n return ret;\r\n },\r\n\r\n /* \\\r\n * Interactable.inertia\r\n [ method ]\r\n **\r\n * Deprecated. Add an `inertia` property to the options object passed\r\n * to @Interactable.draggable or @Interactable.resizable instead.\r\n *\r\n * Returns or sets if and how events continue to run after the pointer is released\r\n **\r\n = (boolean | object) `false` if inertia is disabled; `object` with inertia properties if inertia is enabled\r\n **\r\n * or\r\n **\r\n - options (object | boolean | null) #optional\r\n = (Interactable) this Interactable\r\n > Usage\r\n | // enable and use default settings\r\n | interact(element).inertia(true);\r\n |\r\n | // enable and use custom settings\r\n | interact(element).inertia({\r\n | // value greater than 0\r\n | // high values slow the object down more quickly\r\n | resistance : 16,\r\n |\r\n | // the minimum launch speed (pixels per second) that results in inertia start\r\n | minSpeed : 200,\r\n |\r\n | // inertia will stop when the object slows down to this speed\r\n | endSpeed : 20,\r\n |\r\n | // boolean; should actions be resumed when the pointer goes down during inertia\r\n | allowResume : true,\r\n |\r\n | // boolean; should the jump when resuming from inertia be ignored in event.dx/dy\r\n | zeroResumeDelta: false,\r\n |\r\n | // if snap/restrict are set to be endOnly and inertia is enabled, releasing\r\n | // the pointer without triggering inertia will animate from the release\r\n | // point to the snaped/restricted point in the given amount of time (ms)\r\n | smoothEndDuration: 300,\r\n |\r\n | // an array of action types that can have inertia (no gesture)\r\n | actions : ['drag', 'resize']\r\n | });\r\n |\r\n | // reset custom settings and use all defaults\r\n | interact(element).inertia(null);\r\n \\*/\r\n inertia: function(options){\r\n var ret = this.setOptions('inertia', options);\r\n\r\n if (ret === this){ return this; }\r\n\r\n return ret.drag;\r\n },\r\n\r\n getAction: function(pointer, event, interaction, element){\r\n var action = this.defaultActionChecker(pointer, interaction, element);\r\n\r\n if (this.options.actionChecker){\r\n return this.options.actionChecker(pointer, event, action, this, element, interaction);\r\n }\r\n\r\n return action;\r\n },\r\n\r\n defaultActionChecker: defaultActionChecker,\r\n\r\n /* \\\r\n * Interactable.actionChecker\r\n [ method ]\r\n *\r\n * Gets or sets the function used to check action to be performed on\r\n * pointerDown\r\n *\r\n - checker (function | null) #optional A function which takes a pointer event, defaultAction string, interactable, element and interaction as parameters and returns an object with name property 'drag' 'resize' or 'gesture' and optionally an `edges` object with boolean 'top', 'left', 'bottom' and right props.\r\n = (Function | Interactable) The checker function or this Interactable\r\n *\r\n | interact('.resize-drag')\r\n | .resizable(true)\r\n | .draggable(true)\r\n | .actionChecker(function (pointer, event, action, interactable, element, interaction) {\r\n |\r\n | if (interact.matchesSelector(event.target, '.drag-handle') {\r\n | // force drag with handle target\r\n | action.name = drag;\r\n | }\r\n | else {\r\n | // resize from the top and right edges\r\n | action.name = 'resize';\r\n | action.edges = { top: true, right: true };\r\n | }\r\n |\r\n | return action;\r\n | });\r\n \\*/\r\n actionChecker: function(checker){\r\n if (isFunction(checker)){\r\n this.options.actionChecker = checker;\r\n\r\n return this;\r\n }\r\n\r\n if (checker === null){\r\n delete this.options.actionChecker;\r\n\r\n return this;\r\n }\r\n\r\n return this.options.actionChecker;\r\n },\r\n\r\n /* \\\r\n * Interactable.getRect\r\n [ method ]\r\n *\r\n * The default function to get an Interactables bounding rect. Can be\r\n * overridden using @Interactable.rectChecker.\r\n *\r\n - element (Element) #optional The element to measure.\r\n = (object) The object's bounding rectangle.\r\n o {\r\n o top : 0,\r\n o left : 0,\r\n o bottom: 0,\r\n o right : 0,\r\n o width : 0,\r\n o height: 0\r\n o }\r\n \\*/\r\n getRect: function rectCheck(element){\r\n element = element || this._element;\r\n\r\n if (this.selector && !(isElement(element))){\r\n element = this._context.querySelector(this.selector);\r\n }\r\n\r\n return getElementRect(element);\r\n },\r\n\r\n /* \\\r\n * Interactable.rectChecker\r\n [ method ]\r\n *\r\n * Returns or sets the function used to calculate the interactable's\r\n * element's rectangle\r\n *\r\n - checker (function) #optional A function which returns this Interactable's bounding rectangle. See @Interactable.getRect\r\n = (function | object) The checker function or this Interactable\r\n \\*/\r\n rectChecker: function(checker){\r\n if (isFunction(checker)){\r\n this.getRect = checker;\r\n\r\n return this;\r\n }\r\n\r\n if (checker === null){\r\n delete this.options.getRect;\r\n\r\n return this;\r\n }\r\n\r\n return this.getRect;\r\n },\r\n\r\n /* \\\r\n * Interactable.styleCursor\r\n [ method ]\r\n *\r\n * Returns or sets whether the action that would be performed when the\r\n * mouse on the element are checked on `mousemove` so that the cursor\r\n * may be styled appropriately\r\n *\r\n - newValue (boolean) #optional\r\n = (boolean | Interactable) The current setting or this Interactable\r\n \\*/\r\n styleCursor: function(newValue){\r\n if (isBool(newValue)){\r\n this.options.styleCursor = newValue;\r\n\r\n return this;\r\n }\r\n\r\n if (newValue === null){\r\n delete this.options.styleCursor;\r\n\r\n return this;\r\n }\r\n\r\n return this.options.styleCursor;\r\n },\r\n\r\n /* \\\r\n * Interactable.preventDefault\r\n [ method ]\r\n *\r\n * Returns or sets whether to prevent the browser's default behaviour\r\n * in response to pointer events. Can be set to:\r\n * - `'always'` to always prevent\r\n * - `'never'` to never prevent\r\n * - `'auto'` to let interact.js try to determine what would be best\r\n *\r\n - newValue (string) #optional `true`, `false` or `'auto'`\r\n = (string | Interactable) The current setting or this Interactable\r\n \\*/\r\n preventDefault: function(newValue){\r\n if (/^(always|never|auto)$/.test(newValue)){\r\n this.options.preventDefault = newValue;\r\n return this;\r\n }\r\n\r\n if (isBool(newValue)){\r\n this.options.preventDefault = newValue ? 'always' : 'never';\r\n return this;\r\n }\r\n\r\n return this.options.preventDefault;\r\n },\r\n\r\n /* \\\r\n * Interactable.origin\r\n [ method ]\r\n *\r\n * Gets or sets the origin of the Interactable's element. The x and y\r\n * of the origin will be subtracted from action event coordinates.\r\n *\r\n - origin (object | string) #optional An object eg. { x: 0, y: 0 } or string 'parent', 'self' or any CSS selector\r\n * OR\r\n - origin (Element) #optional An HTML or SVG Element whose rect will be used\r\n **\r\n = (object) The current origin or this Interactable\r\n \\*/\r\n origin: function(newValue){\r\n if (trySelector(newValue)){\r\n this.options.origin = newValue;\r\n return this;\r\n }\r\n else if (isObject(newValue)){\r\n this.options.origin = newValue;\r\n return this;\r\n }\r\n\r\n return this.options.origin;\r\n },\r\n\r\n /* \\\r\n * Interactable.deltaSource\r\n [ method ]\r\n *\r\n * Returns or sets the mouse coordinate types used to calculate the\r\n * movement of the pointer.\r\n *\r\n - newValue (string) #optional Use 'client' if you will be scrolling while interacting; Use 'page' if you want autoScroll to work\r\n = (string | object) The current deltaSource or this Interactable\r\n \\*/\r\n deltaSource: function(newValue){\r\n if (newValue === 'page' || newValue === 'client'){\r\n this.options.deltaSource = newValue;\r\n\r\n return this;\r\n }\r\n\r\n return this.options.deltaSource;\r\n },\r\n\r\n /* \\\r\n * Interactable.restrict\r\n [ method ]\r\n **\r\n * Deprecated. Add a `restrict` property to the options object passed to\r\n * @Interactable.draggable, @Interactable.resizable or @Interactable.gesturable instead.\r\n *\r\n * Returns or sets the rectangles within which actions on this\r\n * interactable (after snap calculations) are restricted. By default,\r\n * restricting is relative to the pointer coordinates. You can change\r\n * this by setting the\r\n * [`elementRect`](https://github.com/taye/interact.js/pull/72).\r\n **\r\n - options (object) #optional an object with keys drag, resize, and/or gesture whose values are rects, Elements, CSS selectors, or 'parent' or 'self'\r\n = (object) The current restrictions object or this Interactable\r\n **\r\n | interact(element).restrict({\r\n | // the rect will be `interact.getElementRect(element.parentNode)`\r\n | drag: element.parentNode,\r\n |\r\n | // x and y are relative to the the interactable's origin\r\n | resize: { x: 100, y: 100, width: 200, height: 200 }\r\n | })\r\n |\r\n | interact('.draggable').restrict({\r\n | // the rect will be the selected element's parent\r\n | drag: 'parent',\r\n |\r\n | // do not restrict during normal movement.\r\n | // Instead, trigger only one restricted move event\r\n | // immediately before the end event.\r\n | endOnly: true,\r\n |\r\n | // https://github.com/taye/interact.js/pull/72#issue-41813493\r\n | elementRect: { top: 0, left: 0, bottom: 1, right: 1 }\r\n | });\r\n \\*/\r\n restrict: function(options){\r\n if (!isObject(options)){\r\n return this.setOptions('restrict', options);\r\n }\r\n\r\n var actions = ['drag', 'resize', 'gesture'],\r\n ret;\r\n\r\n for (var i = 0; i < actions.length; i++){\r\n var action = actions[i];\r\n\r\n if (action in options){\r\n var perAction = extend({\r\n actions: [action],\r\n restriction: options[action]\r\n }, options);\r\n\r\n ret = this.setOptions('restrict', perAction);\r\n }\r\n }\r\n\r\n return ret;\r\n },\r\n\r\n /* \\\r\n * Interactable.context\r\n [ method ]\r\n *\r\n * Gets the selector context Node of the Interactable. The default is `window.document`.\r\n *\r\n = (Node) The context Node of this Interactable\r\n **\r\n \\*/\r\n context: function(){\r\n return this._context;\r\n },\r\n\r\n _context: document,\r\n\r\n /* \\\r\n * Interactable.ignoreFrom\r\n [ method ]\r\n *\r\n * If the target of the `mousedown`, `pointerdown` or `touchstart`\r\n * event or any of it's parents match the given CSS selector or\r\n * Element, no drag/resize/gesture is started.\r\n *\r\n - newValue (string | Element | null) #optional a CSS selector string, an Element or `null` to not ignore any elements\r\n = (string | Element | object) The current ignoreFrom value or this Interactable\r\n **\r\n | interact(element, { ignoreFrom: document.getElementById('no-action') });\r\n | // or\r\n | interact(element).ignoreFrom('input, textarea, a');\r\n \\*/\r\n ignoreFrom: function(newValue){\r\n if (trySelector(newValue)){ // CSS selector to match event.target\r\n this.options.ignoreFrom = newValue;\r\n return this;\r\n }\r\n\r\n if (isElement(newValue)){ // specific element\r\n this.options.ignoreFrom = newValue;\r\n return this;\r\n }\r\n\r\n return this.options.ignoreFrom;\r\n },\r\n\r\n /* \\\r\n * Interactable.allowFrom\r\n [ method ]\r\n *\r\n * A drag/resize/gesture is started only If the target of the\r\n * `mousedown`, `pointerdown` or `touchstart` event or any of it's\r\n * parents match the given CSS selector or Element.\r\n *\r\n - newValue (string | Element | null) #optional a CSS selector string, an Element or `null` to allow from any element\r\n = (string | Element | object) The current allowFrom value or this Interactable\r\n **\r\n | interact(element, { allowFrom: document.getElementById('drag-handle') });\r\n | // or\r\n | interact(element).allowFrom('.handle');\r\n \\*/\r\n allowFrom: function(newValue){\r\n if (trySelector(newValue)){ // CSS selector to match event.target\r\n this.options.allowFrom = newValue;\r\n return this;\r\n }\r\n\r\n if (isElement(newValue)){ // specific element\r\n this.options.allowFrom = newValue;\r\n return this;\r\n }\r\n\r\n return this.options.allowFrom;\r\n },\r\n\r\n /* \\\r\n * Interactable.element\r\n [ method ]\r\n *\r\n * If this is not a selector Interactable, it returns the element this\r\n * interactable represents\r\n *\r\n = (Element) HTML / SVG Element\r\n \\*/\r\n element: function(){\r\n return this._element;\r\n },\r\n\r\n /* \\\r\n * Interactable.fire\r\n [ method ]\r\n *\r\n * Calls listeners for the given InteractEvent type bound globally\r\n * and directly to this Interactable\r\n *\r\n - iEvent (InteractEvent) The InteractEvent object to be fired on this Interactable\r\n = (Interactable) this Interactable\r\n \\*/\r\n fire: function(iEvent){\r\n if (!(iEvent && iEvent.type) || !contains(eventTypes, iEvent.type)){\r\n return this;\r\n }\r\n\r\n var listeners,\r\n i,\r\n len,\r\n onEvent = 'on' + iEvent.type,\r\n funcName = '';\r\n\r\n // Interactable#on() listeners\r\n if (iEvent.type in this._iEvents){\r\n listeners = this._iEvents[iEvent.type];\r\n\r\n for (i = 0, len = listeners.length; i < len && !iEvent.immediatePropagationStopped; i++){\r\n funcName = listeners[i].name;\r\n listeners[i](iEvent);\r\n }\r\n }\r\n\r\n // interactable.onevent listener\r\n if (isFunction(this[onEvent])){\r\n funcName = this[onEvent].name;\r\n this[onEvent](iEvent);\r\n }\r\n\r\n // interact.on() listeners\r\n if (iEvent.type in globalEvents && (listeners = globalEvents[iEvent.type])){\r\n for (i = 0, len = listeners.length; i < len && !iEvent.immediatePropagationStopped; i++){\r\n funcName = listeners[i].name;\r\n listeners[i](iEvent);\r\n }\r\n }\r\n\r\n return this;\r\n },\r\n\r\n /* \\\r\n * Interactable.on\r\n [ method ]\r\n *\r\n * Binds a listener for an InteractEvent or DOM event.\r\n *\r\n - eventType (string | array | object) The types of events to listen for\r\n - listener (function) The function to be called on the given event(s)\r\n - useCapture (boolean) #optional useCapture flag for addEventListener\r\n = (object) This Interactable\r\n \\*/\r\n on: function(eventType, listener, useCapture){\r\n var i;\r\n\r\n if (isString(eventType) && eventType.search(' ') !== -1){\r\n eventType = eventType.trim().split(/ +/);\r\n }\r\n\r\n if (isArray(eventType)){\r\n for (i = 0; i < eventType.length; i++){\r\n this.on(eventType[i], listener, useCapture);\r\n }\r\n\r\n return this;\r\n }\r\n\r\n if (isObject(eventType)){\r\n for (var prop in eventType){\r\n this.on(prop, eventType[prop], listener);\r\n }\r\n\r\n return this;\r\n }\r\n\r\n if (eventType === 'wheel'){\r\n eventType = wheelEvent;\r\n }\r\n\r\n // convert to boolean\r\n useCapture = useCapture ? true : false;\r\n\r\n if (contains(eventTypes, eventType)){\r\n // if this type of event was never bound to this Interactable\r\n if (!(eventType in this._iEvents)){\r\n this._iEvents[eventType] = [listener];\r\n }\r\n else {\r\n this._iEvents[eventType].push(listener);\r\n }\r\n }\r\n // delegated event for selector\r\n else if (this.selector){\r\n if (!delegatedEvents[eventType]){\r\n delegatedEvents[eventType] = {\r\n selectors: [],\r\n contexts: [],\r\n listeners: []\r\n };\r\n\r\n // add delegate listener functions\r\n for (i = 0; i < documents.length; i++){\r\n events.add(documents[i], eventType, delegateListener);\r\n events.add(documents[i], eventType, delegateUseCapture, true);\r\n }\r\n }\r\n\r\n var delegated = delegatedEvents[eventType],\r\n index;\r\n\r\n for (index = delegated.selectors.length - 1; index >= 0; index--){\r\n if (delegated.selectors[index] === this.selector\r\n && delegated.contexts[index] === this._context){\r\n break;\r\n }\r\n }\r\n\r\n if (index === -1){\r\n index = delegated.selectors.length;\r\n\r\n delegated.selectors.push(this.selector);\r\n delegated.contexts.push(this._context);\r\n delegated.listeners.push([]);\r\n }\r\n\r\n // keep listener and useCapture flag\r\n delegated.listeners[index].push([listener, useCapture]);\r\n }\r\n else {\r\n events.add(this._element, eventType, listener, useCapture);\r\n }\r\n\r\n return this;\r\n },\r\n\r\n /* \\\r\n * Interactable.off\r\n [ method ]\r\n *\r\n * Removes an InteractEvent or DOM event listener\r\n *\r\n - eventType (string | array | object) The types of events that were listened for\r\n - listener (function) The listener function to be removed\r\n - useCapture (boolean) #optional useCapture flag for removeEventListener\r\n = (object) This Interactable\r\n \\*/\r\n off: function(eventType, listener, useCapture){\r\n var i;\r\n\r\n if (isString(eventType) && eventType.search(' ') !== -1){\r\n eventType = eventType.trim().split(/ +/);\r\n }\r\n\r\n if (isArray(eventType)){\r\n for (i = 0; i < eventType.length; i++){\r\n this.off(eventType[i], listener, useCapture);\r\n }\r\n\r\n return this;\r\n }\r\n\r\n if (isObject(eventType)){\r\n for (var prop in eventType){\r\n this.off(prop, eventType[prop], listener);\r\n }\r\n\r\n return this;\r\n }\r\n\r\n var eventList,\r\n index = -1;\r\n\r\n // convert to boolean\r\n useCapture = useCapture ? true : false;\r\n\r\n if (eventType === 'wheel'){\r\n eventType = wheelEvent;\r\n }\r\n\r\n // if it is an action event type\r\n if (contains(eventTypes, eventType)){\r\n eventList = this._iEvents[eventType];\r\n\r\n if (eventList && (index = indexOf(eventList, listener)) !== -1){\r\n this._iEvents[eventType].splice(index, 1);\r\n }\r\n }\r\n // delegated event\r\n else if (this.selector){\r\n var delegated = delegatedEvents[eventType],\r\n matchFound = false;\r\n\r\n if (!delegated){ return this; }\r\n\r\n // count from last index of delegated to 0\r\n for (index = delegated.selectors.length - 1; index >= 0; index--){\r\n // look for matching selector and context Node\r\n if (delegated.selectors[index] === this.selector\r\n && delegated.contexts[index] === this._context){\r\n var listeners = delegated.listeners[index];\r\n\r\n // each item of the listeners array is an array: [function, useCaptureFlag]\r\n for (i = listeners.length - 1; i >= 0; i--){\r\n var fn = listeners[i][0],\r\n useCap = listeners[i][1];\r\n\r\n // check if the listener functions and useCapture flags match\r\n if (fn === listener && useCap === useCapture){\r\n // remove the listener from the array of listeners\r\n listeners.splice(i, 1);\r\n\r\n // if all listeners for this interactable have been removed\r\n // remove the interactable from the delegated arrays\r\n if (!listeners.length){\r\n delegated.selectors.splice(index, 1);\r\n delegated.contexts.splice(index, 1);\r\n delegated.listeners.splice(index, 1);\r\n\r\n // remove delegate function from context\r\n events.remove(this._context, eventType, delegateListener);\r\n events.remove(this._context, eventType, delegateUseCapture, true);\r\n\r\n // remove the arrays if they are empty\r\n if (!delegated.selectors.length){\r\n delegatedEvents[eventType] = null;\r\n }\r\n }\r\n\r\n // only remove one listener\r\n matchFound = true;\r\n break;\r\n }\r\n }\r\n\r\n if (matchFound){ break; }\r\n }\r\n }\r\n }\r\n // remove listener from this Interatable's element\r\n else {\r\n events.remove(this._element, eventType, listener, useCapture);\r\n }\r\n\r\n return this;\r\n },\r\n\r\n /* \\\r\n * Interactable.set\r\n [ method ]\r\n *\r\n * Reset the options of this Interactable\r\n - options (object) The new settings to apply\r\n = (object) This Interactable\r\n \\*/\r\n set: function(options){\r\n if (!isObject(options)){\r\n options = {};\r\n }\r\n\r\n this.options = extend({}, defaultOptions.base);\r\n\r\n var i,\r\n actions = ['drag', 'drop', 'resize', 'gesture'],\r\n methods = ['draggable', 'dropzone', 'resizable', 'gesturable'],\r\n perActions = extend(extend({}, defaultOptions.perAction), options[action] || {});\r\n\r\n for (i = 0; i < actions.length; i++){\r\n var action = actions[i];\r\n\r\n this.options[action] = extend({}, defaultOptions[action]);\r\n\r\n this.setPerAction(action, perActions);\r\n\r\n this[methods[i]](options[action]);\r\n }\r\n\r\n var settings = [\r\n 'accept', 'actionChecker', 'allowFrom', 'deltaSource',\r\n 'dropChecker', 'ignoreFrom', 'origin', 'preventDefault',\r\n 'rectChecker', 'styleCursor'\r\n ];\r\n\r\n for (i = 0, len = settings.length; i < len; i++){\r\n var setting = settings[i];\r\n\r\n this.options[setting] = defaultOptions.base[setting];\r\n\r\n if (setting in options){\r\n this[setting](options[setting]);\r\n }\r\n }\r\n\r\n return this;\r\n },\r\n\r\n /* \\\r\n * Interactable.unset\r\n [ method ]\r\n *\r\n * Remove this interactable from the list of interactables and remove\r\n * it's drag, drop, resize and gesture capabilities\r\n *\r\n = (object) @interact\r\n \\*/\r\n unset: function(){\r\n events.remove(this._element, 'all');\r\n\r\n if (!isString(this.selector)){\r\n events.remove(this, 'all');\r\n if (this.options.styleCursor){\r\n this._element.style.cursor = '';\r\n }\r\n }\r\n else {\r\n // remove delegated events\r\n for (var type in delegatedEvents){\r\n var delegated = delegatedEvents[type];\r\n\r\n for (var i = 0; i < delegated.selectors.length; i++){\r\n if (delegated.selectors[i] === this.selector\r\n && delegated.contexts[i] === this._context){\r\n delegated.selectors.splice(i, 1);\r\n delegated.contexts.splice(i, 1);\r\n delegated.listeners.splice(i, 1);\r\n\r\n // remove the arrays if they are empty\r\n if (!delegated.selectors.length){\r\n delegatedEvents[type] = null;\r\n }\r\n }\r\n\r\n events.remove(this._context, type, delegateListener);\r\n events.remove(this._context, type, delegateUseCapture, true);\r\n\r\n break;\r\n }\r\n }\r\n }\r\n\r\n this.dropzone(false);\r\n\r\n interactables.splice(indexOf(interactables, this), 1);\r\n\r\n return interact;\r\n }\r\n };\r\n\r\n function warnOnce(method, message){\r\n var warned = false;\r\n\r\n return function(){\r\n if (!warned){\r\n window.console.warn(message);\r\n warned = true;\r\n }\r\n\r\n return method.apply(this, arguments);\r\n };\r\n }\r\n\r\n Interactable.prototype.snap = warnOnce(Interactable.prototype.snap,\r\n 'Interactable#snap is deprecated. See the new documentation for snapping at http://interactjs.io/docs/snapping');\r\n Interactable.prototype.restrict = warnOnce(Interactable.prototype.restrict,\r\n 'Interactable#restrict is deprecated. See the new documentation for resticting at http://interactjs.io/docs/restriction');\r\n Interactable.prototype.inertia = warnOnce(Interactable.prototype.inertia,\r\n 'Interactable#inertia is deprecated. See the new documentation for inertia at http://interactjs.io/docs/inertia');\r\n Interactable.prototype.autoScroll = warnOnce(Interactable.prototype.autoScroll,\r\n 'Interactable#autoScroll is deprecated. See the new documentation for autoScroll at http://interactjs.io/docs/#autoscroll');\r\n Interactable.prototype.squareResize = warnOnce(Interactable.prototype.squareResize,\r\n 'Interactable#squareResize is deprecated. See http://interactjs.io/docs/#resize-square');\r\n\r\n Interactable.prototype.accept = warnOnce(Interactable.prototype.accept,\r\n 'Interactable#accept is deprecated. use Interactable#dropzone({ accept: target }) instead');\r\n Interactable.prototype.dropChecker = warnOnce(Interactable.prototype.dropChecker,\r\n 'Interactable#dropChecker is deprecated. use Interactable#dropzone({ dropChecker: checkerFunction }) instead');\r\n Interactable.prototype.context = warnOnce(Interactable.prototype.context,\r\n 'Interactable#context as a method is deprecated. It will soon be a DOM Node instead');\r\n\r\n /* \\\r\n * interact.isSet\r\n [ method ]\r\n *\r\n * Check if an element has been set\r\n - element (Element) The Element being searched for\r\n = (boolean) Indicates if the element or CSS selector was previously passed to interact\r\n \\*/\r\n interact.isSet = function(element, options){\r\n return interactables.indexOfElement(element, options && options.context) !== -1;\r\n };\r\n\r\n /* \\\r\n * interact.on\r\n [ method ]\r\n *\r\n * Adds a global listener for an InteractEvent or adds a DOM event to\r\n * `document`\r\n *\r\n - type (string | array | object) The types of events to listen for\r\n - listener (function) The function to be called on the given event(s)\r\n - useCapture (boolean) #optional useCapture flag for addEventListener\r\n = (object) interact\r\n \\*/\r\n interact.on = function(type, listener, useCapture){\r\n if (isString(type) && type.search(' ') !== -1){\r\n type = type.trim().split(/ +/);\r\n }\r\n\r\n if (isArray(type)){\r\n for (var i = 0; i < type.length; i++){\r\n interact.on(type[i], listener, useCapture);\r\n }\r\n\r\n return interact;\r\n }\r\n\r\n if (isObject(type)){\r\n for (var prop in type){\r\n interact.on(prop, type[prop], listener);\r\n }\r\n\r\n return interact;\r\n }\r\n\r\n // if it is an InteractEvent type, add listener to globalEvents\r\n if (contains(eventTypes, type)){\r\n // if this type of event was never bound\r\n if (!globalEvents[type]){\r\n globalEvents[type] = [listener];\r\n }\r\n else {\r\n globalEvents[type].push(listener);\r\n }\r\n }\r\n // If non InteractEvent type, addEventListener to document\r\n else {\r\n events.add(document, type, listener, useCapture);\r\n }\r\n\r\n return interact;\r\n };\r\n\r\n /* \\\r\n * interact.off\r\n [ method ]\r\n *\r\n * Removes a global InteractEvent listener or DOM event from `document`\r\n *\r\n - type (string | array | object) The types of events that were listened for\r\n - listener (function) The listener function to be removed\r\n - useCapture (boolean) #optional useCapture flag for removeEventListener\r\n = (object) interact\r\n \\*/\r\n interact.off = function(type, listener, useCapture){\r\n if (isString(type) && type.search(' ') !== -1){\r\n type = type.trim().split(/ +/);\r\n }\r\n\r\n if (isArray(type)){\r\n for (var i = 0; i < type.length; i++){\r\n interact.off(type[i], listener, useCapture);\r\n }\r\n\r\n return interact;\r\n }\r\n\r\n if (isObject(type)){\r\n for (var prop in type){\r\n interact.off(prop, type[prop], listener);\r\n }\r\n\r\n return interact;\r\n }\r\n\r\n if (!contains(eventTypes, type)){\r\n events.remove(document, type, listener, useCapture);\r\n }\r\n else {\r\n var index;\r\n\r\n if (type in globalEvents\r\n && (index = indexOf(globalEvents[type], listener)) !== -1){\r\n globalEvents[type].splice(index, 1);\r\n }\r\n }\r\n\r\n return interact;\r\n };\r\n\r\n /* \\\r\n * interact.enableDragging\r\n [ method ]\r\n *\r\n * Deprecated.\r\n *\r\n * Returns or sets whether dragging is enabled for any Interactables\r\n *\r\n - newValue (boolean) #optional `true` to allow the action; `false` to disable action for all Interactables\r\n = (boolean | object) The current setting or interact\r\n \\*/\r\n interact.enableDragging = warnOnce(function(newValue){\r\n if (newValue !== null && newValue !== undefined){\r\n actionIsEnabled.drag = newValue;\r\n\r\n return interact;\r\n }\r\n return actionIsEnabled.drag;\r\n }, 'interact.enableDragging is deprecated and will soon be removed.');\r\n\r\n /* \\\r\n * interact.enableResizing\r\n [ method ]\r\n *\r\n * Deprecated.\r\n *\r\n * Returns or sets whether resizing is enabled for any Interactables\r\n *\r\n - newValue (boolean) #optional `true` to allow the action; `false` to disable action for all Interactables\r\n = (boolean | object) The current setting or interact\r\n \\*/\r\n interact.enableResizing = warnOnce(function(newValue){\r\n if (newValue !== null && newValue !== undefined){\r\n actionIsEnabled.resize = newValue;\r\n\r\n return interact;\r\n }\r\n return actionIsEnabled.resize;\r\n }, 'interact.enableResizing is deprecated and will soon be removed.');\r\n\r\n /* \\\r\n * interact.enableGesturing\r\n [ method ]\r\n *\r\n * Deprecated.\r\n *\r\n * Returns or sets whether gesturing is enabled for any Interactables\r\n *\r\n - newValue (boolean) #optional `true` to allow the action; `false` to disable action for all Interactables\r\n = (boolean | object) The current setting or interact\r\n \\*/\r\n interact.enableGesturing = warnOnce(function(newValue){\r\n if (newValue !== null && newValue !== undefined){\r\n actionIsEnabled.gesture = newValue;\r\n\r\n return interact;\r\n }\r\n return actionIsEnabled.gesture;\r\n }, 'interact.enableGesturing is deprecated and will soon be removed.');\r\n\r\n interact.eventTypes = eventTypes;\r\n\r\n /* \\\r\n * interact.debug\r\n [ method ]\r\n *\r\n * Returns debugging data\r\n = (object) An object with properties that outline the current state and expose internal functions and variables\r\n \\*/\r\n interact.debug = function(){\r\n var interaction = interactions[0] || new Interaction();\r\n\r\n return {\r\n interactions: interactions,\r\n target: interaction.target,\r\n dragging: interaction.dragging,\r\n resizing: interaction.resizing,\r\n gesturing: interaction.gesturing,\r\n prepared: interaction.prepared,\r\n matches: interaction.matches,\r\n matchElements: interaction.matchElements,\r\n\r\n prevCoords: interaction.prevCoords,\r\n startCoords: interaction.startCoords,\r\n\r\n pointerIds: interaction.pointerIds,\r\n pointers: interaction.pointers,\r\n addPointer: listeners.addPointer,\r\n removePointer: listeners.removePointer,\r\n recordPointer: listeners.recordPointer,\r\n\r\n snap: interaction.snapStatus,\r\n restrict: interaction.restrictStatus,\r\n inertia: interaction.inertiaStatus,\r\n\r\n downTime: interaction.downTimes[0],\r\n downEvent: interaction.downEvent,\r\n downPointer: interaction.downPointer,\r\n prevEvent: interaction.prevEvent,\r\n\r\n Interactable: Interactable,\r\n interactables: interactables,\r\n pointerIsDown: interaction.pointerIsDown,\r\n defaultOptions: defaultOptions,\r\n defaultActionChecker: defaultActionChecker,\r\n\r\n actionCursors: actionCursors,\r\n dragMove: listeners.dragMove,\r\n resizeMove: listeners.resizeMove,\r\n gestureMove: listeners.gestureMove,\r\n pointerUp: listeners.pointerUp,\r\n pointerDown: listeners.pointerDown,\r\n pointerMove: listeners.pointerMove,\r\n pointerHover: listeners.pointerHover,\r\n\r\n eventTypes: eventTypes,\r\n\r\n events: events,\r\n globalEvents: globalEvents,\r\n delegatedEvents: delegatedEvents,\r\n\r\n prefixedPropREs: prefixedPropREs\r\n };\r\n };\r\n\r\n // expose the functions used to calculate multi-touch properties\r\n interact.getPointerAverage = pointerAverage;\r\n interact.getTouchBBox = touchBBox;\r\n interact.getTouchDistance = touchDistance;\r\n interact.getTouchAngle = touchAngle;\r\n\r\n interact.getElementRect = getElementRect;\r\n interact.getElementClientRect = getElementClientRect;\r\n interact.matchesSelector = matchesSelector;\r\n interact.closest = closest;\r\n\r\n /* \\\r\n * interact.margin\r\n [ method ]\r\n *\r\n * Deprecated. Use `interact(target).resizable({ margin: number });` instead.\r\n * Returns or sets the margin for autocheck resizing used in\r\n * @Interactable.getAction. That is the distance from the bottom and right\r\n * edges of an element clicking in which will start resizing\r\n *\r\n - newValue (number) #optional\r\n = (number | interact) The current margin value or interact\r\n \\*/\r\n interact.margin = warnOnce(function(newvalue){\r\n if (isNumber(newvalue)){\r\n margin = newvalue;\r\n\r\n return interact;\r\n }\r\n return margin;\r\n },\r\n 'interact.margin is deprecated. Use interact(target).resizable({ margin: number }); instead.');\r\n\r\n /* \\\r\n * interact.supportsTouch\r\n [ method ]\r\n *\r\n = (boolean) Whether or not the browser supports touch input\r\n \\*/\r\n interact.supportsTouch = function(){\r\n return supportsTouch;\r\n };\r\n\r\n /* \\\r\n * interact.supportsPointerEvent\r\n [ method ]\r\n *\r\n = (boolean) Whether or not the browser supports PointerEvents\r\n \\*/\r\n interact.supportsPointerEvent = function(){\r\n return supportsPointerEvent;\r\n };\r\n\r\n /* \\\r\n * interact.stop\r\n [ method ]\r\n *\r\n * Cancels all interactions (end events are not fired)\r\n *\r\n - event (Event) An event on which to call preventDefault()\r\n = (object) interact\r\n \\*/\r\n interact.stop = function(event){\r\n for (var i = interactions.length - 1; i >= 0; i--){\r\n interactions[i].stop(event);\r\n }\r\n\r\n return interact;\r\n };\r\n\r\n /* \\\r\n * interact.dynamicDrop\r\n [ method ]\r\n *\r\n * Returns or sets whether the dimensions of dropzone elements are\r\n * calculated on every dragmove or only on dragstart for the default\r\n * dropChecker\r\n *\r\n - newValue (boolean) #optional True to check on each move. False to check only before start\r\n = (boolean | interact) The current setting or interact\r\n \\*/\r\n interact.dynamicDrop = function(newValue){\r\n if (isBool(newValue)){\r\n // if (dragging && dynamicDrop !== newValue && !newValue) {\r\n // calcRects(dropzones);\r\n // }\r\n\r\n dynamicDrop = newValue;\r\n\r\n return interact;\r\n }\r\n return dynamicDrop;\r\n };\r\n\r\n /* \\\r\n * interact.pointerMoveTolerance\r\n [ method ]\r\n * Returns or sets the distance the pointer must be moved before an action\r\n * sequence occurs. This also affects tolerance for tap events.\r\n *\r\n - newValue (number) #optional The movement from the start position must be greater than this value\r\n = (number | Interactable) The current setting or interact\r\n \\*/\r\n interact.pointerMoveTolerance = function(newValue){\r\n if (isNumber(newValue)){\r\n pointerMoveTolerance = newValue;\r\n\r\n return this;\r\n }\r\n\r\n return pointerMoveTolerance;\r\n };\r\n\r\n /* \\\r\n * interact.maxInteractions\r\n [ method ]\r\n **\r\n * Returns or sets the maximum number of concurrent interactions allowed.\r\n * By default only 1 interaction is allowed at a time (for backwards\r\n * compatibility). To allow multiple interactions on the same Interactables\r\n * and elements, you need to enable it in the draggable, resizable and\r\n * gesturable `'max'` and `'maxPerElement'` options.\r\n **\r\n - newValue (number) #optional Any number. newValue <= 0 means no interactions.\r\n \\*/\r\n interact.maxInteractions = function(newValue){\r\n if (isNumber(newValue)){\r\n maxInteractions = newValue;\r\n\r\n return this;\r\n }\r\n\r\n return maxInteractions;\r\n };\r\n\r\n interact.createSnapGrid = function(grid){\r\n return function(x, y){\r\n var offsetX = 0,\r\n offsetY = 0;\r\n\r\n if (isObject(grid.offset)){\r\n offsetX = grid.offset.x;\r\n offsetY = grid.offset.y;\r\n }\r\n\r\n var gridx = Math.round((x - offsetX) / grid.x),\r\n gridy = Math.round((y - offsetY) / grid.y),\r\n\r\n newX = gridx * grid.x + offsetX,\r\n newY = gridy * grid.y + offsetY;\r\n\r\n return {\r\n x: newX,\r\n y: newY,\r\n range: grid.range\r\n };\r\n };\r\n };\r\n\r\n function endAllInteractions(event){\r\n for (var i = 0; i < interactions.length; i++){\r\n interactions[i].pointerEnd(event, event);\r\n }\r\n }\r\n\r\n function listenToDocument(doc){\r\n if (contains(documents, doc)){ return; }\r\n\r\n var win = doc.defaultView || doc.parentWindow;\r\n\r\n // add delegate event listener\r\n for (var eventType in delegatedEvents){\r\n events.add(doc, eventType, delegateListener);\r\n events.add(doc, eventType, delegateUseCapture, true);\r\n }\r\n\r\n if (supportsPointerEvent){\r\n if (PointerEvent === win.MSPointerEvent){\r\n pEventTypes = {\r\n up: 'MSPointerUp', down: 'MSPointerDown', over: 'mouseover',\r\n out: 'mouseout', move: 'MSPointerMove', cancel: 'MSPointerCancel' };\r\n }\r\n else {\r\n pEventTypes = {\r\n up: 'pointerup', down: 'pointerdown', over: 'pointerover',\r\n out: 'pointerout', move: 'pointermove', cancel: 'pointercancel' };\r\n }\r\n\r\n events.add(doc, pEventTypes.down, listeners.selectorDown);\r\n events.add(doc, pEventTypes.move, listeners.pointerMove);\r\n events.add(doc, pEventTypes.over, listeners.pointerOver);\r\n events.add(doc, pEventTypes.out, listeners.pointerOut);\r\n events.add(doc, pEventTypes.up, listeners.pointerUp);\r\n events.add(doc, pEventTypes.cancel, listeners.pointerCancel);\r\n\r\n // autoscroll\r\n events.add(doc, pEventTypes.move, listeners.autoScrollMove);\r\n }\r\n else {\r\n events.add(doc, 'mousedown', listeners.selectorDown);\r\n events.add(doc, 'mousemove', listeners.pointerMove);\r\n events.add(doc, 'mouseup', listeners.pointerUp);\r\n events.add(doc, 'mouseover', listeners.pointerOver);\r\n events.add(doc, 'mouseout', listeners.pointerOut);\r\n\r\n events.add(doc, 'touchstart', listeners.selectorDown);\r\n events.add(doc, 'touchmove', listeners.pointerMove);\r\n events.add(doc, 'touchend', listeners.pointerUp);\r\n events.add(doc, 'touchcancel', listeners.pointerCancel);\r\n\r\n // autoscroll\r\n events.add(doc, 'mousemove', listeners.autoScrollMove);\r\n events.add(doc, 'touchmove', listeners.autoScrollMove);\r\n }\r\n\r\n events.add(win, 'blur', endAllInteractions);\r\n\r\n try {\r\n if (win.frameElement){\r\n var parentDoc = win.frameElement.ownerDocument,\r\n parentWindow = parentDoc.defaultView;\r\n\r\n events.add(parentDoc, 'mouseup', listeners.pointerEnd);\r\n events.add(parentDoc, 'touchend', listeners.pointerEnd);\r\n events.add(parentDoc, 'touchcancel', listeners.pointerEnd);\r\n events.add(parentDoc, 'pointerup', listeners.pointerEnd);\r\n events.add(parentDoc, 'MSPointerUp', listeners.pointerEnd);\r\n events.add(parentWindow, 'blur', endAllInteractions);\r\n }\r\n }\r\n catch (error){\r\n interact.windowParentError = error;\r\n }\r\n\r\n // prevent native HTML5 drag on interact.js target elements\r\n events.add(doc, 'dragstart', function(event){\r\n for (var i = 0; i < interactions.length; i++){\r\n var interaction = interactions[i];\r\n\r\n if (interaction.element\r\n && (interaction.element === event.target\r\n || nodeContains(interaction.element, event.target))){\r\n interaction.checkAndPreventDefault(event, interaction.target, interaction.element);\r\n return;\r\n }\r\n }\r\n });\r\n\r\n if (events.useAttachEvent){\r\n // For IE's lack of Event#preventDefault\r\n events.add(doc, 'selectstart', function(event){\r\n var interaction = interactions[0];\r\n\r\n if (interaction.currentAction()){\r\n interaction.checkAndPreventDefault(event);\r\n }\r\n });\r\n\r\n // For IE's bad dblclick event sequence\r\n events.add(doc, 'dblclick', doOnInteractions('ie8Dblclick'));\r\n }\r\n\r\n documents.push(doc);\r\n }\r\n\r\n listenToDocument(document);\r\n\r\n function indexOf(array, target){\r\n for (var i = 0, len = array.length; i < len; i++){\r\n if (array[i] === target){\r\n return i;\r\n }\r\n }\r\n\r\n return -1;\r\n }\r\n\r\n function contains(array, target){\r\n return indexOf(array, target) !== -1;\r\n }\r\n\r\n function matchesSelector(element, selector, nodeList){\r\n if (ie8MatchesSelector){\r\n return ie8MatchesSelector(element, selector, nodeList);\r\n }\r\n\r\n // remove /deep/ from selectors if shadowDOM polyfill is used\r\n if (window !== realWindow){\r\n selector = selector.replace(/\\/deep\\//g, ' ');\r\n }\r\n\r\n return element[prefixedMatchesSelector](selector);\r\n }\r\n\r\n function matchesUpTo(element, selector, limit){\r\n while (isElement(element)){\r\n if (matchesSelector(element, selector)){\r\n return true;\r\n }\r\n\r\n element = parentElement(element);\r\n\r\n if (element === limit){\r\n return matchesSelector(element, selector);\r\n }\r\n }\r\n\r\n return false;\r\n }\r\n\r\n // For IE8's lack of an Element#matchesSelector\r\n // taken from http://tanalin.com/en/blog/2012/12/matches-selector-ie8/ and modified\r\n if (!(prefixedMatchesSelector in Element.prototype) || !isFunction(Element.prototype[prefixedMatchesSelector])){\r\n ie8MatchesSelector = function(element, selector, elems){\r\n elems = elems || element.parentNode.querySelectorAll(selector);\r\n\r\n for (var i = 0, len = elems.length; i < len; i++){\r\n if (elems[i] === element){\r\n return true;\r\n }\r\n }\r\n\r\n return false;\r\n };\r\n }\r\n\r\n // requestAnimationFrame polyfill\r\n (function(){\r\n var lastTime = 0,\r\n vendors = ['ms', 'moz', 'webkit', 'o'];\r\n\r\n for (var x = 0; x < vendors.length && !realWindow.requestAnimationFrame; ++x){\r\n reqFrame = realWindow[vendors[x] + 'RequestAnimationFrame'];\r\n cancelFrame = realWindow[vendors[x] + 'CancelAnimationFrame'] || realWindow[vendors[x] + 'CancelRequestAnimationFrame'];\r\n }\r\n\r\n if (!reqFrame){\r\n reqFrame = function(callback){\r\n var currTime = new Date().getTime(),\r\n timeToCall = Math.max(0, 16 - (currTime - lastTime)),\r\n id = setTimeout(function(){ callback(currTime + timeToCall); },\r\n timeToCall);\r\n lastTime = currTime + timeToCall;\r\n return id;\r\n };\r\n }\r\n\r\n if (!cancelFrame){\r\n cancelFrame = function(id){\r\n clearTimeout(id);\r\n };\r\n }\r\n }());\r\n\r\n /* global exports: true, module, define */\r\n\r\n // http://documentcloud.github.io/underscore/docs/underscore.html#section-11\r\n if (typeof exports !== 'undefined'){\r\n if (typeof module !== 'undefined' && module.exports){\r\n exports = module.exports = interact;\r\n }\r\n exports.interact = interact;\r\n }\r\n // AMD\r\n else if (typeof define === 'function' && define.amd){\r\n define('interact', function(){\r\n return interact;\r\n });\r\n }\r\n else {\r\n realWindow.interact = interact;\r\n }\r\n}(typeof window === 'undefined' ? undefined : window));\r\n\n\n\n// WEBPACK FOOTER //\n// ../src/interact.js","export AutoTooltips from './slick.autotooltips';\r\nexport CellCopyManager from './slick.cellcopymanager';\r\nexport CellRangeDecorator from './slick.cellrangedecorator';\r\nexport CellRangeSelector from './slick.cellrangeselector';\r\nexport CellSelectionModel from './slick.cellselectionmodel';\r\nexport CheckboxSelectColumn from './slick.checkboxselectcolumn';\r\nexport HeaderButtons from './slick.headerbuttons';\r\nexport HeaderMenu from './slick.headermenu';\r\nexport RowMoveManager from './slick.rowmovemanager';\r\nexport RowSelectionModel from './slick.rowselectionmodel';\r\n\n\n\n// WEBPACK FOOTER //\n// ../plugins/index.js","import AutoTooltips from './slick.autotooltips';\r\nexport default AutoTooltips;\r\n\n\n\n// WEBPACK FOOTER //\n// ../plugins/slick.autotooltips/index.js","import $ from 'jquery';\r\n\r\nexport default AutoTooltips;\r\n\r\n /**\r\n * AutoTooltips plugin to show/hide tooltips when columns are too narrow to fit content.\r\n * @constructor\r\n * @param {boolean} [options.enableForCells=true] - Enable tooltip for grid cells\r\n * @param {boolean} [options.enableForHeaderCells=false] - Enable tooltip for header cells\r\n * @param {number} [options.maxToolTipLength=null] - The maximum length for a tooltip\r\n */\r\nfunction AutoTooltips(options){\r\n let _grid;\r\n const _self = this;\r\n const _defaults = {\r\n enableForCells: true,\r\n enableForHeaderCells: false,\r\n maxToolTipLength: null\r\n };\r\n\r\n /**\r\n * Initialize plugin.\r\n */\r\n function init(grid){\r\n options = Object.assign({}, _defaults, options);\r\n _grid = grid;\r\n if (options.enableForCells) _grid.onMouseEnter.subscribe(handleMouseEnter);\r\n if (options.enableForHeaderCells) _grid.onHeaderMouseEnter.subscribe(handleHeaderMouseEnter);\r\n }\r\n\r\n /**\r\n * Destroy plugin.\r\n */\r\n function destroy(){\r\n if (options.enableForCells) _grid.onMouseEnter.unsubscribe(handleMouseEnter);\r\n if (options.enableForHeaderCells) _grid.onHeaderMouseEnter.unsubscribe(handleHeaderMouseEnter);\r\n }\r\n\r\n /**\r\n * Handle mouse entering grid cell to add/remove tooltip.\r\n * @param {jQuery.Event} e - The event\r\n */\r\n function handleMouseEnter(e){\r\n const cell = _grid.getCellFromEvent(e);\r\n if (cell){\r\n let $node = $(_grid.getCellNode(cell.row, cell.cell));\r\n let text;\r\n if ($node.innerWidth() < $node[0].scrollWidth){\r\n text = $.trim($node.text());\r\n if (options.maxToolTipLength && text.length > options.maxToolTipLength){\r\n text = text.substr(0, options.maxToolTipLength - 3) + '...';\r\n }\r\n } else {\r\n text = '';\r\n }\r\n $node.attr('title', text);\r\n }\r\n }\r\n\r\n /**\r\n * Handle mouse entering header cell to add/remove tooltip.\r\n * @param {jQuery.Event} e - The event\r\n * @param {object} args.column - The column definition\r\n */\r\n function handleHeaderMouseEnter(e, args){\r\n const column = args.column,\r\n $node = $(e.target).closest('.slick-header-column');\r\n if (column && !column.toolTip){\r\n $node.attr('title', ($node.innerWidth() < $node[0].scrollWidth) ? column.name : '');\r\n }\r\n }\r\n\r\n // Public API\r\n Object.assign(this, {\r\n init,\r\n destroy\r\n });\r\n}\r\n\n\n\n// WEBPACK FOOTER //\n// ../plugins/slick.autotooltips/slick.autotooltips.js","import CellCopyManager from './slick.cellcopymanager';\r\nexport default CellCopyManager;\r\n\n\n\n// WEBPACK FOOTER //\n// ../plugins/slick.cellcopymanager/index.js","import Slick from '../../src/slick.core';\r\nconst { keyCode } = Slick;\r\n\r\nexport default CellCopyManager;\r\n\r\nfunction CellCopyManager(){\r\n var _grid;\r\n var _self = this;\r\n var _copiedRanges;\r\n\r\n function init(grid){\r\n _grid = grid;\r\n _grid.onKeyDown.subscribe(handleKeyDown);\r\n }\r\n\r\n function destroy(){\r\n _grid.onKeyDown.unsubscribe(handleKeyDown);\r\n }\r\n\r\n function handleKeyDown(e, args){\r\n var ranges;\r\n if (!_grid.getEditorLock().isActive()){\r\n if (e.which == keyCode.ESCAPE){\r\n if (_copiedRanges){\r\n e.preventDefault();\r\n clearCopySelection();\r\n _self.onCopyCancelled.notify({ranges: _copiedRanges});\r\n _copiedRanges = null;\r\n }\r\n }\r\n\r\n if (e.which == 67 && (e.ctrlKey || e.metaKey)){\r\n ranges = _grid.getSelectionModel().getSelectedRanges();\r\n if (ranges.length != 0){\r\n e.preventDefault();\r\n _copiedRanges = ranges;\r\n markCopySelection(ranges);\r\n _self.onCopyCells.notify({ranges: ranges});\r\n }\r\n }\r\n\r\n if (e.which == 86 && (e.ctrlKey || e.metaKey)){\r\n if (_copiedRanges){\r\n e.preventDefault();\r\n clearCopySelection();\r\n ranges = _grid.getSelectionModel().getSelectedRanges();\r\n _self.onPasteCells.notify({from: _copiedRanges, to: ranges});\r\n _copiedRanges = null;\r\n }\r\n }\r\n }\r\n }\r\n\r\n function markCopySelection(ranges){\r\n var columns = _grid.getColumns();\r\n var hash = {};\r\n for (var i = 0; i < ranges.length; i++){\r\n for (var j = ranges[i].fromRow; j <= ranges[i].toRow; j++){\r\n hash[j] = {};\r\n for (var k = ranges[i].fromCell; k <= ranges[i].toCell; k++){\r\n hash[j][columns[k].id] = 'copied';\r\n }\r\n }\r\n }\r\n _grid.setCellCssStyles('copy-manager', hash);\r\n }\r\n\r\n function clearCopySelection(){\r\n _grid.removeCellCssStyles('copy-manager');\r\n }\r\n\r\n Object.assign(this, {\r\n init,\r\n destroy,\r\n clearCopySelection,\r\n\r\n onCopyCells: new Slick.Event(),\r\n onCopyCancelled: new Slick.Event(),\r\n onPasteCells: new Slick.Event()\r\n });\r\n}\r\n\n\n\n// WEBPACK FOOTER //\n// ../plugins/slick.cellcopymanager/slick.cellcopymanager.js","import CellRangeDecorator from './slick.cellrangedecorator';\r\nexport default CellRangeDecorator;\r\n\n\n\n// WEBPACK FOOTER //\n// ../plugins/slick.cellrangedecorator/index.js","import CellRangeDecorator from './slick.cellrangeselector';\r\nexport default CellRangeDecorator;\r\n\n\n\n// WEBPACK FOOTER //\n// ../plugins/slick.cellrangeselector/index.js","import CellSelectionModel from './slick.cellselectionmodel';\r\nexport default CellSelectionModel;\r\n\n\n\n// WEBPACK FOOTER //\n// ../plugins/slick.cellselectionmodel/index.js","import Slick from '../../src/slick.core';\r\nimport CellRangeSelector from '../slick.cellrangeselector/slick.cellrangeselector';\r\n\r\nexport default CellSelectionModel;\r\n\r\nfunction CellSelectionModel(options = {\r\n selectActiveCell: true\r\n}){\r\n let _grid;\r\n let _canvas;\r\n let _ranges = [];\r\n const _self = this;\r\n const _selector = new CellRangeSelector({\r\n selectionCss: {\r\n border: '2px solid black'\r\n }\r\n });\r\n let _options;\r\n const _defaults = {\r\n selectActiveCell: true\r\n };\r\n\r\n function init(grid){\r\n _options = Object.assign({}, options);\r\n _grid = grid;\r\n _canvas = _grid.getCanvasNode();\r\n _grid.onActiveCellChanged.subscribe(handleActiveCellChange);\r\n _grid.onKeyDown.subscribe(handleKeyDown);\r\n grid.registerPlugin(_selector);\r\n _selector.onCellRangeSelected.subscribe(handleCellRangeSelected);\r\n _selector.onBeforeCellRangeSelected.subscribe(handleBeforeCellRangeSelected);\r\n }\r\n\r\n function destroy(){\r\n _grid.onActiveCellChanged.unsubscribe(handleActiveCellChange);\r\n _grid.onKeyDown.unsubscribe(handleKeyDown);\r\n _selector.onCellRangeSelected.unsubscribe(handleCellRangeSelected);\r\n _selector.onBeforeCellRangeSelected.unsubscribe(handleBeforeCellRangeSelected);\r\n _grid.unregisterPlugin(_selector);\r\n }\r\n\r\n function removeInvalidRanges(ranges){\r\n const result = [];\r\n\r\n for (let i = 0; i < ranges.length; i++){\r\n const r = ranges[i];\r\n if (_grid.canCellBeSelected(r.fromRow, r.fromCell) && _grid.canCellBeSelected(r.toRow, r.toCell)){\r\n result.push(r);\r\n }\r\n }\r\n\r\n return result;\r\n }\r\n\r\n function setSelectedRanges(ranges){\r\n // simle check for: empty selection didn't change, prevent firing onSelectedRangesChanged\r\n if ((!_ranges || _ranges.length === 0) && (!ranges || ranges.length === 0)){\r\n return;\r\n }\r\n\r\n _ranges = removeInvalidRanges(ranges);\r\n _self.onSelectedRangesChanged.notify(_ranges);\r\n }\r\n\r\n function getSelectedRanges(){\r\n return _ranges;\r\n }\r\n\r\n function handleBeforeCellRangeSelected(e, args){\r\n if (_grid.getEditorLock().isActive()){\r\n e.stopPropagation();\r\n return false;\r\n }\r\n }\r\n\r\n function handleCellRangeSelected(e, args){\r\n setSelectedRanges([args.range]);\r\n }\r\n\r\n function handleActiveCellChange(e, args){\r\n if (_options.selectActiveCell && args.row != null && args.cell != null){\r\n setSelectedRanges([new Slick.Range(args.row, args.cell)]);\r\n }\r\n }\r\n\r\n function handleKeyDown(e){\r\n /** *\r\n * Кey codes\r\n * 37 left\r\n * 38 up\r\n * 39 right\r\n * 40 down\r\n */\r\n let ranges, last;\r\n const active = _grid.getActiveCell();\r\n\r\n if (active && e.shiftKey && !e.ctrlKey && !e.altKey &&\r\n (e.which == 37 || e.which == 39 || e.which == 38 || e.which == 40)){\r\n ranges = getSelectedRanges();\r\n if (!ranges.length)\r\n ranges.push(new Slick.Range(active.row, active.cell));\r\n\r\n // keyboard can work with last range only\r\n last = ranges.pop();\r\n\r\n // can't handle selection out of active cell\r\n if (!last.contains(active.row, active.cell))\r\n last = new Slick.Range(active.row, active.cell);\r\n\r\n let dRow = last.toRow - last.fromRow,\r\n dCell = last.toCell - last.fromCell,\r\n // walking direction\r\n dirRow = active.row == last.fromRow ? 1 : -1,\r\n dirCell = active.cell == last.fromCell ? 1 : -1;\r\n\r\n if (e.which == 37){\r\n dCell -= dirCell;\r\n } else if (e.which == 39){\r\n dCell += dirCell;\r\n } else if (e.which == 38){\r\n dRow -= dirRow;\r\n } else if (e.which == 40){\r\n dRow += dirRow;\r\n }\r\n\r\n // define new selection range\r\n const new_last = new Slick.Range(active.row, active.cell, active.row + dirRow * dRow, active.cell + dirCell * dCell);\r\n if (removeInvalidRanges([new_last]).length){\r\n ranges.push(new_last);\r\n const viewRow = dirRow > 0 ? new_last.toRow : new_last.fromRow;\r\n const viewCell = dirCell > 0 ? new_last.toCell : new_last.fromCell;\r\n _grid.scrollRowIntoView(viewRow);\r\n _grid.scrollCellIntoView(viewRow, viewCell);\r\n }\r\n else\r\n ranges.push(last);\r\n\r\n setSelectedRanges(ranges);\r\n\r\n e.preventDefault();\r\n e.stopPropagation();\r\n }\r\n }\r\n\r\n Object.assign(this, {\r\n getSelectedRanges,\r\n setSelectedRanges,\r\n\r\n init,\r\n destroy,\r\n\r\n onSelectedRangesChanged: new Slick.Event()\r\n });\r\n}\r\n\n\n\n// WEBPACK FOOTER //\n// ../plugins/slick.cellselectionmodel/slick.cellselectionmodel.js","import CheckboxSelectColumn from './slick.checkboxselectcolumn';\r\nexport default CheckboxSelectColumn;\r\n\n\n\n// WEBPACK FOOTER //\n// ../plugins/slick.checkboxselectcolumn/index.js","import $ from 'jquery';\r\nimport Slick from '../../src/slick.core';\r\n\r\nexport default CheckboxSelectColumn;\r\n\r\nfunction CheckboxSelectColumn(options){\r\n let _grid;\r\n const _self = this;\r\n const _handler = new Slick.EventHandler();\r\n let _selectedRowsLookup = {};\r\n const _defaults = {\r\n columnId: '_checkbox_selector',\r\n cssClass: null,\r\n toolTip: 'Select/Deselect All',\r\n width: 30\r\n };\r\n\r\n const _options = $.extend(true, {}, _defaults, options);\r\n\r\n function init(grid){\r\n _grid = grid;\r\n _handler\r\n .subscribe(_grid.onSelectedRowsChanged, handleSelectedRowsChanged)\r\n .subscribe(_grid.onClick, handleClick)\r\n .subscribe(_grid.onHeaderClick, handleHeaderClick)\r\n .subscribe(_grid.onKeyDown, handleKeyDown);\r\n }\r\n\r\n function destroy(){\r\n _handler.unsubscribeAll();\r\n }\r\n\r\n function handleSelectedRowsChanged(e, args){\r\n let selectedRows = _grid.getSelectedRows();\r\n let lookup = {}, row, i;\r\n for (i = 0; i < selectedRows.length; i++){\r\n row = selectedRows[i];\r\n lookup[row] = true;\r\n if (lookup[row] !== _selectedRowsLookup[row]){\r\n _grid.invalidateRow(row);\r\n delete _selectedRowsLookup[row];\r\n }\r\n }\r\n for (i in _selectedRowsLookup){\r\n _grid.invalidateRow(i);\r\n }\r\n _selectedRowsLookup = lookup;\r\n _grid.render();\r\n\r\n if (selectedRows.length && selectedRows.length == _grid.getDataLength()){\r\n _grid.updateColumnHeader(_options.columnId, \"\", _options.toolTip);\r\n } else {\r\n _grid.updateColumnHeader(_options.columnId, \"\", _options.toolTip);\r\n }\r\n }\r\n\r\n function handleKeyDown(e, args){\r\n if (e.which == 32){\r\n if (_grid.getColumns()[args.cell].id === _options.columnId){\r\n // if editing, try to commit\r\n if (!_grid.getEditorLock().isActive() || _grid.getEditorLock().commitCurrentEdit()){\r\n toggleRowSelection(args.row);\r\n }\r\n e.preventDefault();\r\n e.stopImmediatePropagation();\r\n }\r\n }\r\n }\r\n\r\n function handleClick(e, args){\r\n // clicking on a row select checkbox\r\n if (_grid.getColumns()[args.cell].id === _options.columnId && $(e.target).is(':checkbox')){\r\n // if editing, try to commit\r\n if (_grid.getEditorLock().isActive() && !_grid.getEditorLock().commitCurrentEdit()){\r\n e.preventDefault();\r\n e.stopImmediatePropagation();\r\n return;\r\n }\r\n\r\n toggleRowSelection(args.row);\r\n e.stopPropagation();\r\n e.stopImmediatePropagation();\r\n }\r\n }\r\n\r\n function toggleRowSelection(row){\r\n if (_selectedRowsLookup[row]){\r\n _grid.setSelectedRows($.grep(_grid.getSelectedRows(), function(n){\r\n return n != row;\r\n }));\r\n } else {\r\n _grid.setSelectedRows(_grid.getSelectedRows().concat(row));\r\n }\r\n }\r\n\r\n function handleHeaderClick(e, args){\r\n if (args.column.id == _options.columnId && $(e.target).is(':checkbox')){\r\n // if editing, try to commit\r\n if (_grid.getEditorLock().isActive() && !_grid.getEditorLock().commitCurrentEdit()){\r\n e.preventDefault();\r\n e.stopImmediatePropagation();\r\n return;\r\n }\r\n\r\n if ($(e.target).is(':checked')){\r\n const rows = [];\r\n for (let i = 0; i < _grid.getDataLength(); i++){\r\n rows.push(i);\r\n }\r\n _grid.setSelectedRows(rows);\r\n } else {\r\n _grid.setSelectedRows([]);\r\n }\r\n e.stopPropagation();\r\n e.stopImmediatePropagation();\r\n }\r\n }\r\n\r\n function getColumnDefinition(){\r\n return {\r\n id: _options.columnId,\r\n name: \"\",\r\n toolTip: _options.toolTip,\r\n field: 'sel',\r\n width: _options.width,\r\n resizable: false,\r\n sortable: false,\r\n cssClass: _options.cssClass,\r\n formatter: checkboxSelectionFormatter\r\n };\r\n }\r\n\r\n function checkboxSelectionFormatter(row, cell, value, columnDef, dataContext){\r\n if (dataContext){\r\n return _selectedRowsLookup[row]\r\n ? \"\"\r\n : \"\";\r\n }\r\n return null;\r\n }\r\n\r\n Object.assign(this, {\r\n init,\r\n destroy,\r\n\r\n getColumnDefinition\r\n });\r\n}\r\n\n\n\n// WEBPACK FOOTER //\n// ../plugins/slick.checkboxselectcolumn/slick.checkboxselectcolumn.js","import HeaderButtons from './slick.headerbuttons';\r\nexport default HeaderButtons;\r\n\n\n\n// WEBPACK FOOTER //\n// ../plugins/slick.headerbuttons/index.js","import $ from 'jquery';\r\nimport Slick from '../../src/slick.core';\r\n\r\nexport default HeaderButtons;\r\n/** *\r\n * A plugin to add custom buttons to column headers.\r\n *\r\n * USAGE:\r\n *\r\n * Add the plugin .js & .css files and register it with the grid.\r\n *\r\n * To specify a custom button in a column header, extend the column definition like so:\r\n *\r\n * var columns = [\r\n * {\r\n * id: 'myColumn',\r\n * name: 'My column',\r\n *\r\n * // This is the relevant part\r\n * header: {\r\n * buttons: [\r\n * {\r\n * // button options\r\n * },\r\n * {\r\n * // button options\r\n * }\r\n * ]\r\n * }\r\n * }\r\n * ];\r\n *\r\n * Available button options:\r\n * cssClass: CSS class to add to the button.\r\n * image: Relative button image path.\r\n * tooltip: Button tooltip.\r\n * showOnHover: Only show the button on hover.\r\n * handler: Button click handler.\r\n * command: A command identifier to be passed to the onCommand event handlers.\r\n *\r\n * The plugin exposes the following events:\r\n * onCommand: Fired on button click for buttons with 'command' specified.\r\n * Event args:\r\n * grid: Reference to the grid.\r\n * column: Column definition.\r\n * command: Button command identified.\r\n * button: Button options. Note that you can change the button options in your\r\n * event handler, and the column header will be automatically updated to\r\n * reflect them. This is useful if you want to implement something like a\r\n * toggle button.\r\n *\r\n *\r\n * @param options {Object} Options:\r\n * buttonCssClass: a CSS class to use for buttons (default 'slick-header-button')\r\n * @class Slick.Plugins.HeaderButtons\r\n * @constructor\r\n */\r\nfunction HeaderButtons(options){\r\n var _grid;\r\n var _self = this;\r\n var _handler = new Slick.EventHandler();\r\n var _defaults = {\r\n buttonCssClass: 'slick-header-button'\r\n };\r\n\r\n function init(grid){\r\n options = Object.assign({}, _defaults, options);\r\n _grid = grid;\r\n _handler\r\n .subscribe(_grid.onHeaderCellRendered, handleHeaderCellRendered)\r\n .subscribe(_grid.onBeforeHeaderCellDestroy, handleBeforeHeaderCellDestroy);\r\n\r\n // Force the grid to re-render the header now that the events are hooked up.\r\n _grid.setColumns(_grid.getColumns());\r\n }\r\n\r\n function destroy(){\r\n _handler.unsubscribeAll();\r\n }\r\n\r\n function handleHeaderCellRendered(e, args){\r\n var column = args.column;\r\n\r\n if (column.header && column.header.buttons){\r\n // Append buttons in reverse order since they are floated to the right.\r\n var i = column.header.buttons.length;\r\n while (i--){\r\n var button = column.header.buttons[i];\r\n var btn = $('')\r\n .addClass(options.buttonCssClass)\r\n .data('column', column)\r\n .data('button', button);\r\n\r\n if (button.showOnHover){\r\n btn.addClass('slick-header-button-hidden');\r\n }\r\n\r\n if (button.image){\r\n btn.css('backgroundImage', 'url(' + button.image + ')');\r\n }\r\n\r\n if (button.cssClass){\r\n btn.addClass(button.cssClass);\r\n }\r\n\r\n if (button.tooltip){\r\n btn.attr('title', button.tooltip);\r\n }\r\n\r\n if (button.command){\r\n btn.data('command', button.command);\r\n }\r\n\r\n if (button.handler){\r\n btn.bind('click', button.handler);\r\n }\r\n\r\n btn\r\n .bind('click', handleButtonClick)\r\n .appendTo(args.node);\r\n args.node.classList.add('has-buttons');\r\n }\r\n }\r\n }\r\n\r\n function handleBeforeHeaderCellDestroy(e, args){\r\n var column = args.column;\r\n\r\n if (column.header && column.header.buttons){\r\n // Removing buttons via jQuery will also clean up any event handlers and data.\r\n // NOTE: If you attach event handlers directly or using a different framework,\r\n // you must also clean them up here to avoid memory leaks.\r\n $(args.node).find(`.${options.buttonCssClass}`).remove();\r\n }\r\n }\r\n\r\n function handleButtonClick(e){\r\n var command = $(this).data('command');\r\n var columnDef = $(this).data('column');\r\n var button = $(this).data('button');\r\n\r\n if (command != null){\r\n _self.onCommand.notify({\r\n 'grid': _grid,\r\n 'column': columnDef,\r\n 'command': command,\r\n 'button': button\r\n }, e, _self);\r\n\r\n // Update the header in case the user updated the button definition in the handler.\r\n _grid.updateColumnHeader(columnDef.id);\r\n }\r\n\r\n // Stop propagation so that it doesn't register as a header click event.\r\n e.preventDefault();\r\n e.stopPropagation();\r\n }\r\n\r\n Object.assign(this, {\r\n init,\r\n destroy,\r\n\r\n 'onCommand': new Slick.Event()\r\n });\r\n}\r\n\n\n\n// WEBPACK FOOTER //\n// ../plugins/slick.headerbuttons/slick.headerbuttons.js","import HeaderMenu from './slick.headermenu';\r\nexport default HeaderMenu;\r\n\n\n\n// WEBPACK FOOTER //\n// ../plugins/slick.headermenu/index.js","import $ from 'jquery';\r\nimport Slick from '../../src/slick.core';\r\n\r\n// import './slick.headermenu.css';\r\n\r\nexport default HeaderMenu;\r\n\r\n/** *\r\n * A plugin to add drop-down menus to column headers.\r\n *\r\n * USAGE:\r\n *\r\n * Add the plugin .js & .css files and register it with the grid.\r\n *\r\n * To specify a menu in a column header, extend the column definition like so:\r\n *\r\n * const columns = [\r\n * {\r\n * id: 'myColumn',\r\n * name: 'My column',\r\n *\r\n * // This is the relevant part\r\n * header: {\r\n * menu: {\r\n * items: [\r\n * {\r\n * // menu item options\r\n * },\r\n * {\r\n * // menu item options\r\n * }\r\n * ]\r\n * }\r\n * }\r\n * }\r\n * ];\r\n *\r\n *\r\n * Available menu options:\r\n * tooltip: Menu button tooltip.\r\n *\r\n *\r\n * Available menu item options:\r\n * title: Menu item text.\r\n * disabled: Whether the item is disabled.\r\n * tooltip: Item tooltip.\r\n * command: A command identifier to be passed to the onCommand event handlers.\r\n * iconCssClass: A CSS class to be added to the menu item icon.\r\n * iconImage: A url to the icon image.\r\n *\r\n *\r\n * The plugin exposes the following events:\r\n * onBeforeMenuShow: Fired before the menu is shown. You can customize the menu or dismiss it by returning false.\r\n * Event args:\r\n * grid: Reference to the grid.\r\n * column: Column definition.\r\n * menu: Menu options. Note that you can change the menu items here.\r\n *\r\n * onCommand: Fired on menu item click for buttons with 'command' specified.\r\n * Event args:\r\n * grid: Reference to the grid.\r\n * column: Column definition.\r\n * command: Button command identified.\r\n * button: Button options. Note that you can change the button options in your\r\n * event handler, and the column header will be automatically updated to\r\n * reflect them. This is useful if you want to implement something like a\r\n * toggle button.\r\n *\r\n *\r\n * @param options {Object} Options:\r\n * buttonCssClass: an extra CSS class to add to the menu button\r\n * buttonImage: a url to the menu button image (default '../images/down.gif')\r\n * @class Slick.Plugins.HeaderButtons\r\n * @constructor\r\n */\r\nfunction HeaderMenu(options){\r\n let _grid;\r\n const _self = this;\r\n const _handler = new Slick.EventHandler();\r\n const _defaults = {\r\n buttonCssClass: null,\r\n buttonImage: null\r\n };\r\n\r\n let $menu;\r\n let $activeHeaderColumn;\r\n\r\n function init(grid){\r\n options = Object.assign({}, _defaults, options);\r\n _grid = grid;\r\n _handler\r\n .subscribe(_grid.onHeaderCellRendered, handleHeaderCellRendered)\r\n .subscribe(_grid.onBeforeHeaderCellDestroy, handleBeforeHeaderCellDestroy);\r\n\r\n // Force the grid to re-render the header now that the events are hooked up.\r\n _grid.setColumns(_grid.getColumns());\r\n\r\n // Hide the menu on outside click.\r\n $(document.body).bind('mousedown', handleBodyMouseDown);\r\n }\r\n\r\n function destroy(){\r\n _handler.unsubscribeAll();\r\n $(document.body).unbind('mousedown', handleBodyMouseDown);\r\n }\r\n\r\n function handleBodyMouseDown(e){\r\n if ($menu && $menu[0] != e.target && !$.contains($menu[0], e.target)){\r\n hideMenu();\r\n }\r\n }\r\n\r\n function hideMenu(){\r\n if ($menu){\r\n $menu.remove();\r\n $menu = null;\r\n $activeHeaderColumn\r\n .removeClass('slick-header-column-active');\r\n }\r\n }\r\n\r\n function handleHeaderCellRendered(e, args){\r\n const column = args.column;\r\n const menu = column.header && column.header.menu;\r\n\r\n if (menu){\r\n const $el = $('')\r\n .addClass('slick-header-menubutton')\r\n .data('column', column)\r\n .data('menu', menu);\r\n\r\n if (options.buttonCssClass){\r\n $el.addClass(options.buttonCssClass);\r\n }\r\n\r\n if (options.buttonImage){\r\n $el.css('background-image', 'url(' + options.buttonImage + ')');\r\n }\r\n\r\n if (menu.tooltip){\r\n $el.attr('title', menu.tooltip);\r\n }\r\n\r\n $el\r\n .bind('click', showMenu)\r\n .appendTo(args.node);\r\n }\r\n }\r\n\r\n function handleBeforeHeaderCellDestroy(e, args){\r\n const column = args.column;\r\n\r\n if (column.header && column.header.menu){\r\n $(args.node).find('.slick-header-menubutton').remove();\r\n }\r\n }\r\n\r\n function showMenu(e){\r\n const $menuButton = $(this);\r\n const menu = $menuButton.data('menu');\r\n const columnDef = $menuButton.data('column');\r\n\r\n // Let the user modify the menu or cancel altogether,\r\n // or provide alternative menu implementation.\r\n if (_self.onBeforeMenuShow.notify({\r\n 'grid': _grid,\r\n 'column': columnDef,\r\n 'menu': menu\r\n }, e, _self) == false){\r\n return;\r\n }\r\n\r\n if (!$menu){\r\n $menu = $(\"\")\r\n .appendTo(_grid.getContainerNode());\r\n }\r\n $menu.empty();\r\n\r\n // Construct the menu items.\r\n for (let i = 0; i < menu.items.length; i++){\r\n const item = menu.items[i];\r\n\r\n const $li = $(\"\")\r\n .data('command', item.command || '')\r\n .data('column', columnDef)\r\n .data('item', item)\r\n .bind('click', handleMenuItemClick)\r\n .appendTo($menu);\r\n\r\n if (item.disabled){\r\n $li.addClass('slick-header-menuitem-disabled');\r\n }\r\n\r\n if (item.tooltip){\r\n $li.attr('title', item.tooltip);\r\n }\r\n\r\n const $icon = $(\"\")\r\n .appendTo($li);\r\n\r\n if (item.iconCssClass){\r\n $icon.addClass(item.iconCssClass);\r\n }\r\n\r\n if (item.iconImage){\r\n $icon.css('background-image', 'url(' + item.iconImage + ')');\r\n }\r\n\r\n $(\"\")\r\n .text(item.title)\r\n .appendTo($li);\r\n }\r\n\r\n // Position the menu.\r\n $menu\r\n .offset({ top: $(this).offset().top + $(this).height(), left: $(this).offset().left });\r\n\r\n // Mark the header as active to keep the highlighting.\r\n $activeHeaderColumn = $menuButton.closest('.slick-header-column');\r\n $activeHeaderColumn\r\n .addClass('slick-header-column-active');\r\n\r\n // Stop propagation so that it doesn't register as a header click event.\r\n e.preventDefault();\r\n e.stopPropagation();\r\n }\r\n\r\n function handleMenuItemClick(e){\r\n const command = $(this).data('command');\r\n const columnDef = $(this).data('column');\r\n const item = $(this).data('item');\r\n\r\n if (item.disabled){\r\n return;\r\n }\r\n\r\n hideMenu();\r\n\r\n if (command != null && command != ''){\r\n _self.onCommand.notify({\r\n 'grid': _grid,\r\n 'column': columnDef,\r\n 'command': command,\r\n 'item': item\r\n }, e, _self);\r\n }\r\n\r\n // Stop propagation so that it doesn't register as a header click event.\r\n e.preventDefault();\r\n e.stopPropagation();\r\n }\r\n\r\n Object.assign(this, {\r\n init,\r\n destroy,\r\n\r\n 'onBeforeMenuShow': new Slick.Event(),\r\n 'onCommand': new Slick.Event()\r\n });\r\n}\r\n\n\n\n// WEBPACK FOOTER //\n// ../plugins/slick.headermenu/slick.headermenu.js","import RowMoveManager from './slick.rowmovemanager';\r\nexport default RowMoveManager;\r\n\n\n\n// WEBPACK FOOTER //\n// ../plugins/slick.rowmovemanager/index.js","import Slick from '../../src/slick.core';\r\n\r\nexport default RowMoveManager;\r\n\r\nfunction RowMoveManager(options){\r\n let _grid;\r\n let _canvas;\r\n let _dragging;\r\n const _self = this;\r\n const _handler = new Slick.EventHandler();\r\n const _defaults = {\r\n cancelEditOnDrag: false\r\n };\r\n\r\n function init(grid){\r\n options = Object.assign({}, _defaults, options);\r\n _grid = grid;\r\n _canvas = _grid.getCanvasNode();\r\n _handler\r\n .subscribe(_grid.onDragInit, handleDragInit)\r\n .subscribe(_grid.onDragStart, handleDragStart)\r\n .subscribe(_grid.onDrag, handleDrag)\r\n .subscribe(_grid.onDragEnd, handleDragEnd);\r\n }\r\n\r\n function destroy(){\r\n _handler.unsubscribeAll();\r\n }\r\n\r\n function handleDragInit(e, dd){\r\n // prevent the grid from cancelling drag'n'drop by default\r\n e.stopImmediatePropagation();\r\n }\r\n\r\n function handleDragStart(e, dd){\r\n const cell = _grid.getCellFromEvent(e);\r\n\r\n if (options.cancelEditOnDrag && _grid.getEditorLock().isActive()){\r\n _grid.getEditorLock().cancelCurrentEdit();\r\n }\r\n\r\n if (_grid.getEditorLock().isActive() || !/move|selectAndMove/.test(_grid.getColumns()[cell.cell].behavior)){\r\n return false;\r\n }\r\n\r\n _dragging = true;\r\n e.stopImmediatePropagation();\r\n\r\n let selectedRows = _grid.getSelectedRows();\r\n\r\n if (selectedRows.length == 0 || $.inArray(cell.row, selectedRows) == -1){\r\n selectedRows = [cell.row];\r\n _grid.setSelectedRows(selectedRows);\r\n }\r\n\r\n const rowHeight = _grid.getOptions().rowHeight;\r\n\r\n dd.selectedRows = selectedRows;\r\n\r\n dd.selectionProxy = $(\"\")\r\n .css('position', 'absolute')\r\n .css('zIndex', '99999')\r\n .css('width', $(_canvas).innerWidth())\r\n .css('height', rowHeight * selectedRows.length)\r\n .appendTo(_canvas);\r\n\r\n dd.guide = $(\"\")\r\n .css('position', 'absolute')\r\n .css('zIndex', '99998')\r\n .css('width', $(_canvas).innerWidth())\r\n .css('top', -1000)\r\n .appendTo(_canvas);\r\n\r\n dd.insertBefore = -1;\r\n }\r\n\r\n function handleDrag(e, dd){\r\n if (!_dragging){\r\n return;\r\n }\r\n\r\n e.stopImmediatePropagation();\r\n\r\n const top = e.pageY - $(_canvas).offset().top;\r\n dd.selectionProxy.css('top', top - 5);\r\n\r\n const insertBefore = Math.max(0, Math.min(Math.round(top / _grid.getOptions().rowHeight), _grid.getDataLength()));\r\n if (insertBefore !== dd.insertBefore){\r\n const eventData = {\r\n 'rows': dd.selectedRows,\r\n 'insertBefore': insertBefore\r\n };\r\n\r\n if (_self.onBeforeMoveRows.notify(eventData) === false){\r\n dd.guide.css('top', -1000);\r\n dd.canMove = false;\r\n } else {\r\n dd.guide.css('top', insertBefore * _grid.getOptions().rowHeight);\r\n dd.canMove = true;\r\n }\r\n\r\n dd.insertBefore = insertBefore;\r\n }\r\n }\r\n\r\n function handleDragEnd(e, dd){\r\n if (!_dragging){\r\n return;\r\n }\r\n _dragging = false;\r\n e.stopImmediatePropagation();\r\n\r\n dd.guide.remove();\r\n dd.selectionProxy.remove();\r\n\r\n if (dd.canMove){\r\n const eventData = {\r\n 'rows': dd.selectedRows,\r\n 'insertBefore': dd.insertBefore\r\n };\r\n // TODO: _grid.remapCellCssClasses ?\r\n _self.onMoveRows.notify(eventData);\r\n }\r\n }\r\n\r\n Object.assign(this, {\r\n 'onBeforeMoveRows': new Slick.Event(),\r\n 'onMoveRows': new Slick.Event(),\r\n init,\r\n destroy\r\n });\r\n}\r\n\n\n\n// WEBPACK FOOTER //\n// ../plugins/slick.rowmovemanager/slick.rowmovemanager.js","import RowSelectionModel from './slick.rowselectionmodel';\r\nexport default RowSelectionModel;\r\n\n\n\n// WEBPACK FOOTER //\n// ../plugins/slick.rowselectionmodel/index.js","import $ from 'jquery';\r\nimport Slick from '../../src/slick.core';\r\n\r\nexport default RowSelectionModel;\r\n\r\nfunction RowSelectionModel(options){\r\n let _grid;\r\n let _ranges = [];\r\n const _self = this;\r\n const _handler = new Slick.EventHandler();\r\n let _inHandler;\r\n let _options;\r\n const _defaults = {\r\n selectActiveRow: true\r\n };\r\n\r\n function init(grid){\r\n _options = Object.assign({}, _defaults, options);\r\n _grid = grid;\r\n _handler.subscribe(_grid.onActiveCellChanged,\r\n wrapHandler(handleActiveCellChange));\r\n _handler.subscribe(_grid.onKeyDown,\r\n wrapHandler(handleKeyDown));\r\n _handler.subscribe(_grid.onClick,\r\n wrapHandler(handleClick));\r\n }\r\n\r\n function destroy(){\r\n _handler.unsubscribeAll();\r\n }\r\n\r\n function wrapHandler(handler){\r\n return function(){\r\n if (!_inHandler){\r\n _inHandler = true;\r\n handler.apply(this, arguments);\r\n _inHandler = false;\r\n }\r\n };\r\n }\r\n\r\n function rangesToRows(ranges){\r\n const rows = [];\r\n for (let i = 0; i < ranges.length; i++){\r\n for (let j = ranges[i].fromRow; j <= ranges[i].toRow; j++){\r\n rows.push(j);\r\n }\r\n }\r\n return rows;\r\n }\r\n\r\n function rowsToRanges(rows){\r\n const ranges = [];\r\n const lastCell = _grid.getColumns().length - 1;\r\n for (let i = 0; i < rows.length; i++){\r\n ranges.push(new Slick.Range(rows[i], 0, rows[i], lastCell));\r\n }\r\n return ranges;\r\n }\r\n\r\n function getRowsRange(from, to){\r\n let i;\r\n const rows = [];\r\n for (i = from; i <= to; i++){\r\n rows.push(i);\r\n }\r\n for (i = to; i < from; i++){\r\n rows.push(i);\r\n }\r\n return rows;\r\n }\r\n\r\n function getSelectedRows(){\r\n return rangesToRows(_ranges);\r\n }\r\n\r\n function setSelectedRows(rows){\r\n setSelectedRanges(rowsToRanges(rows));\r\n }\r\n\r\n function setSelectedRanges(ranges){\r\n // simle check for: empty selection didn't change, prevent firing onSelectedRangesChanged\r\n if ((!_ranges || _ranges.length === 0) && (!ranges || ranges.length === 0)){\r\n return;\r\n }\r\n _ranges = ranges;\r\n _self.onSelectedRangesChanged.notify(_ranges);\r\n }\r\n\r\n function getSelectedRanges(){\r\n return _ranges;\r\n }\r\n\r\n function handleActiveCellChange(e, data){\r\n if (_options.selectActiveRow && data.row != null){\r\n setSelectedRanges([new Slick.Range(data.row, 0, data.row, _grid.getColumns().length - 1)]);\r\n }\r\n }\r\n\r\n function handleKeyDown(e){\r\n const activeRow = _grid.getActiveCell();\r\n if (activeRow && e.shiftKey && !e.ctrlKey && !e.altKey && !e.metaKey && (e.which == 38 || e.which == 40)){\r\n let selectedRows = getSelectedRows();\r\n selectedRows.sort(function(x, y){\r\n return x - y;\r\n });\r\n\r\n if (!selectedRows.length){\r\n selectedRows = [activeRow.row];\r\n }\r\n\r\n let top = selectedRows[0];\r\n let bottom = selectedRows[selectedRows.length - 1];\r\n let active;\r\n\r\n if (e.which == 40){\r\n active = activeRow.row < bottom || top == bottom ? ++bottom : ++top;\r\n } else {\r\n active = activeRow.row < bottom ? --bottom : --top;\r\n }\r\n\r\n if (active >= 0 && active < _grid.getDataLength()){\r\n _grid.scrollRowIntoView(active);\r\n _ranges = rowsToRanges(getRowsRange(top, bottom));\r\n setSelectedRanges(_ranges);\r\n }\r\n\r\n e.preventDefault();\r\n e.stopPropagation();\r\n }\r\n }\r\n\r\n function handleClick(e){\r\n const cell = _grid.getCellFromEvent(e);\r\n if (!cell || !_grid.canCellBeActive(cell.row, cell.cell)){\r\n return false;\r\n }\r\n\r\n if (!_grid.getOptions().multiSelect || (\r\n !e.ctrlKey && !e.shiftKey && !e.metaKey)){\r\n return false;\r\n }\r\n\r\n let selection = rangesToRows(_ranges);\r\n const idx = $.inArray(cell.row, selection);\r\n\r\n if (idx === -1 && (e.ctrlKey || e.metaKey)){\r\n selection.push(cell.row);\r\n _grid.setActiveCell(cell.row, cell.cell);\r\n } else if (idx !== -1 && (e.ctrlKey || e.metaKey)){\r\n selection = $.grep(selection, function(o, i){\r\n return (o !== cell.row);\r\n });\r\n _grid.setActiveCell(cell.row, cell.cell);\r\n } else if (selection.length && e.shiftKey){\r\n const last = selection.pop();\r\n const from = Math.min(cell.row, last);\r\n const to = Math.max(cell.row, last);\r\n selection = [];\r\n for (let i = from; i <= to; i++){\r\n if (i !== last){\r\n selection.push(i);\r\n }\r\n }\r\n selection.push(last);\r\n _grid.setActiveCell(cell.row, cell.cell);\r\n }\r\n\r\n _ranges = rowsToRanges(selection);\r\n setSelectedRanges(_ranges);\r\n e.stopImmediatePropagation();\r\n\r\n return true;\r\n }\r\n\r\n Object.assign(this, {\r\n getSelectedRows,\r\n setSelectedRows,\r\n\r\n getSelectedRanges,\r\n setSelectedRanges,\r\n\r\n init,\r\n destroy,\r\n\r\n 'onSelectedRangesChanged': new Slick.Event()\r\n });\r\n}\r\n\n\n\n// WEBPACK FOOTER //\n// ../plugins/slick.rowselectionmodel/slick.rowselectionmodel.js","import Slick from './slick.core';\r\nimport Editors from './slick.editors';\r\nimport Data from './slick.dataview';\r\nimport Grid from './slick.grid';\r\nimport FrozenGrid from './slick-frozen.grid';\r\nimport Formatters from './slick.formatters';\r\nimport * as Plugins from '../plugins';\r\n\r\nexport {\r\n Slick,\r\n Editors,\r\n Formatters,\r\n Data,\r\n Grid,\r\n FrozenGrid,\r\n Plugins\r\n}\r\n\n\n\n// WEBPACK FOOTER //\n// ../src/index.js","/**\r\n * @license\r\n * (c) 2009-2013 Michael Leibman\r\n * michael{dot}leibman{at}gmail{dot}com\r\n * http://github.com/mleibman/slickgrid\r\n *\r\n * Distributed under MIT license.\r\n * All rights reserved.\r\n *\r\n * SlickGrid v2.2\r\n *\r\n * NOTES:\r\n * Cell/row DOM manipulations are done directly bypassing jQuery's DOM manipulation methods.\r\n * This increases the speed dramatically, but can only be done safely because there are no event handlers\r\n * or data associated with any cell/row DOM nodes. Cell editors must make sure they implement .destroy()\r\n * and do proper cleanup.\r\n */\r\n\r\nimport $ from 'jquery';\r\nimport interact from './interact.js';\r\n\r\nimport Slick from './slick.core';\r\n\r\n// Slick.Grid globals pretense\r\nSlick.FrozenGrid = SlickGrid;\r\n\r\nexport default SlickGrid;\r\n\r\n// shared across all grids on the page\r\nvar scrollbarDimensions;\r\nvar maxSupportedCssHeight; // browser's breaking point\r\n\r\n//////////////////////////////////////////////////////////////////////////////////////////////\r\n// SlickGrid class implementation (available as Slick.Grid)\r\n\r\n/**\r\n * Creates a new instance of the grid.\r\n * @class SlickGrid\r\n * @constructor\r\n * @param {Node} container Container node to create the grid in.\r\n * @param {Array,Object} data An array of objects for databinding.\r\n * @param {Array} columns An array of column definitions.\r\n * @param {Object} options Grid options.\r\n **/\r\nfunction SlickGrid(container, data, columns, options){\r\n // settings\r\n var defaults = {\r\n explicitInitialization: false,\r\n rowHeight: 25,\r\n defaultColumnWidth: 80,\r\n enableAddRow: false,\r\n leaveSpaceForNewRows: false,\r\n editable: false,\r\n autoEdit: true,\r\n enableCellNavigation: true,\r\n enableColumnReorder: true,\r\n asyncEditorLoading: false,\r\n asyncEditorLoadDelay: 100,\r\n forceFitColumns: false,\r\n enableAsyncPostRender: false,\r\n asyncPostRenderDelay: 50,\r\n autoHeight: false,\r\n editorLock: Slick.GlobalEditorLock,\r\n showHeaderRow: false,\r\n headerRowHeight: 25,\r\n showFooterRow: false,\r\n footerRowHeight: 25,\r\n showTopPanel: false,\r\n topPanelHeight: 25,\r\n formatterFactory: null,\r\n editorFactory: null,\r\n cellFlashingCssClass: \"flashing\",\r\n selectedCellCssClass: \"selected\",\r\n multiSelect: true,\r\n enableTextSelectionOnCells: false,\r\n dataItemColumnValueExtractor: null,\r\n frozenBottom: false,\r\n frozenColumn: -1,\r\n frozenRow: -1,\r\n fullWidthRows: false,\r\n multiColumnSort: false,\r\n defaultFormatter: defaultFormatter,\r\n forceSyncScrolling: false,\r\n addNewRowCssClass: \"new-row\"\r\n };\r\n\r\n var columnDefaults = {\r\n name: \"\",\r\n resizable: true,\r\n sortable: false,\r\n minWidth: 30,\r\n rerenderOnResize: false,\r\n headerCssClass: null,\r\n defaultSortAsc: true,\r\n focusable: true,\r\n selectable: true\r\n };\r\n\r\n // scroller\r\n var th; // virtual height\r\n var h; // real scrollable height\r\n var ph; // page height\r\n var n; // number of pages\r\n var cj; // \"jumpiness\" coefficient\r\n\r\n var page = 0; // current page\r\n var offset = 0; // current page offset\r\n var vScrollDir = 1;\r\n\r\n // private\r\n var initialized = false;\r\n var $container;\r\n var uid = \"slickgrid_\" + Math.round(1000000 * Math.random());\r\n var self = this;\r\n var $focusSink, $focusSink2;\r\n var $groupHeaders = $();\r\n var $headerScroller;\r\n var $headers;\r\n var $headerRow, $headerRowScroller, $headerRowSpacerL, $headerRowSpacerR;\r\n var $footerRow, $footerRowScroller, $footerRowSpacerL, $footerRowSpacerR;\r\n var $topPanelScroller;\r\n var $topPanel;\r\n var $viewport;\r\n var $canvas;\r\n var $style;\r\n var $boundAncestors;\r\n var treeColumns;\r\n var stylesheet, columnCssRulesL, columnCssRulesR;\r\n var viewportH, viewportW;\r\n var canvasWidth, canvasWidthL, canvasWidthR;\r\n var headersWidth, headersWidthL, headersWidthR;\r\n var viewportHasHScroll, viewportHasVScroll;\r\n var headerColumnWidthDiff = 0,\r\n headerColumnHeightDiff = 0, // border+padding\r\n cellWidthDiff = 0,\r\n cellHeightDiff = 0;\r\n var absoluteColumnMinWidth;\r\n var hasFrozenRows = false;\r\n var frozenRowsHeight = 0;\r\n var actualFrozenRow = -1;\r\n var paneTopH = 0;\r\n var paneBottomH = 0;\r\n var viewportTopH = 0;\r\n var viewportBottomH = 0;\r\n var topPanelH = 0;\r\n var headerRowH = 0;\r\n var footerRowH = 0;\r\n\r\n var tabbingDirection = 1;\r\n var $activeCanvasNode;\r\n var $activeViewportNode;\r\n var activePosX;\r\n var activeRow, activeCell;\r\n var activeCellNode = null;\r\n var currentEditor = null;\r\n var serializedEditorValue;\r\n var editController;\r\n\r\n var rowsCache = {};\r\n var renderedRows = 0;\r\n var numVisibleRows = 0;\r\n var prevScrollTop = 0;\r\n var scrollTop = 0;\r\n var lastRenderedScrollTop = 0;\r\n var lastRenderedScrollLeft = 0;\r\n var prevScrollLeft = 0;\r\n var scrollLeft = 0;\r\n\r\n var selectionModel;\r\n var selectedRows = [];\r\n\r\n var plugins = [];\r\n var cellCssClasses = {};\r\n\r\n var columnsById = {};\r\n var sortColumns = [];\r\n var columnPosLeft = [];\r\n var columnPosRight = [];\r\n\r\n // async call handles\r\n var h_editorLoader = null;\r\n var h_render = null;\r\n var h_postrender = null;\r\n var postProcessedRows = {};\r\n var postProcessToRow = null;\r\n var postProcessFromRow = null;\r\n\r\n // perf counters\r\n var counter_rows_rendered = 0;\r\n var counter_rows_removed = 0;\r\n\r\n // These two variables work around a bug with inertial scrolling in Webkit/Blink on Mac.\r\n // See http://crbug.com/312427.\r\n var rowNodeFromLastMouseWheelEvent; // this node must not be deleted while inertial scrolling\r\n var zombieRowNodeFromLastMouseWheelEvent; // node that was hidden instead of getting deleted\r\n\r\n var $paneHeaderL;\r\n var $paneHeaderR;\r\n var $paneTopL;\r\n var $paneTopR;\r\n var $paneBottomL;\r\n var $paneBottomR;\r\n\r\n var $headerScrollerL;\r\n var $headerScrollerR;\r\n\r\n var $headerL;\r\n var $headerR;\r\n\r\n var $groupHeadersL;\r\n var $groupHeadersR;\r\n\r\n var $headerRowScrollerL;\r\n var $headerRowScrollerR;\r\n\r\n var $footerRowScrollerL;\r\n var $footerRowScrollerR;\r\n\r\n var $headerRowL;\r\n var $headerRowR;\r\n\r\n var $footerRowL;\r\n var $footerRowR;\r\n\r\n var $topPanelScrollerL;\r\n var $topPanelScrollerR;\r\n\r\n var $topPanelL;\r\n var $topPanelR;\r\n\r\n var $viewportTopL;\r\n var $viewportTopR;\r\n var $viewportBottomL;\r\n var $viewportBottomR;\r\n\r\n var $canvasTopL;\r\n var $canvasTopR;\r\n var $canvasBottomL;\r\n var $canvasBottomR;\r\n\r\n var $viewportScrollContainerX;\r\n var $viewportScrollContainerY;\r\n var $headerScrollContainer;\r\n var $headerRowScrollContainer;\r\n var $footerRowScrollContainer;\r\n\r\n //////////////////////////////////////////////////////////////////////////////////////////////\r\n // Initialization\r\n\r\n function init(){\r\n $container = $(container);\r\n if ($container.length < 1){\r\n throw new Error(\"SlickGrid requires a valid container, \" + container + \" does not exist in the DOM.\");\r\n }\r\n\r\n // calculate these only once and share between grid instances\r\n maxSupportedCssHeight = maxSupportedCssHeight || getMaxSupportedCssHeight();\r\n scrollbarDimensions = scrollbarDimensions || measureScrollbar();\r\n\r\n options = $.extend({}, defaults, options);\r\n validateAndEnforceOptions();\r\n columnDefaults.width = options.defaultColumnWidth;\r\n\r\n treeColumns = new Slick.TreeColumns(columns);\r\n columns = treeColumns.extractColumns();\r\n\r\n columnsById = {};\r\n for (var i = 0; i < columns.length; i++){\r\n var m = columns[i] = $.extend({}, columnDefaults, columns[i]);\r\n columnsById[m.id] = i;\r\n if (m.minWidth && m.width < m.minWidth){\r\n m.width = m.minWidth;\r\n }\r\n if (m.maxWidth && m.width > m.maxWidth){\r\n m.width = m.maxWidth;\r\n }\r\n }\r\n\r\n editController = {\r\n \"commitCurrentEdit\": commitCurrentEdit,\r\n \"cancelCurrentEdit\": cancelCurrentEdit\r\n };\r\n\r\n $container.empty()\r\n .css(\"overflow\", \"hidden\")\r\n .css(\"outline\", 0)\r\n .addClass(uid)\r\n .addClass(\"ui-widget\");\r\n\r\n // set up a positioning container if needed\r\n if (!/relative|absolute|fixed/.test($container.css(\"position\"))){\r\n $container.css(\"position\", \"relative\");\r\n }\r\n\r\n $focusSink = $(\"\").appendTo($container);\r\n\r\n // Containers used for scrolling frozen columns and rows\r\n $paneHeaderL = $(\"\").appendTo($container);\r\n $paneHeaderR = $(\"\").appendTo($container);\r\n $paneTopL = $(\"\").appendTo($container);\r\n $paneTopR = $(\"\").appendTo($container);\r\n $paneBottomL = $(\"\").appendTo($container);\r\n $paneBottomR = $(\"\").appendTo($container);\r\n\r\n // Append the header scroller containers\r\n $headerScrollerL = $(\"\").appendTo($paneHeaderL);\r\n $headerScrollerR = $(\"\").appendTo($paneHeaderR);\r\n\r\n // Cache the header scroller containers\r\n $headerScroller = $().add($headerScrollerL).add($headerScrollerR);\r\n\r\n if (treeColumns.hasDepth()){\r\n $groupHeadersL = [], $groupHeadersR = [];\r\n for (var index = 0; index < treeColumns.getDepth() - 1; index++){\r\n $groupHeadersL[index] = $(\"\").appendTo($headerScrollerL);\r\n $groupHeadersR[index] = $(\"\").appendTo($headerScrollerR);\r\n }\r\n\r\n $groupHeaders = $().add($groupHeadersL).add($groupHeadersR);\r\n }\r\n\r\n // Append the columnn containers to the headers\r\n $headerL = $(\"\").appendTo($headerScrollerL);\r\n $headerR = $(\"\").appendTo($headerScrollerR);\r\n\r\n // Cache the header columns\r\n $headers = $().add($headerL).add($headerR);\r\n\r\n $headerRowScrollerL = $(\"\").appendTo($paneTopL);\r\n $headerRowScrollerR = $(\"\").appendTo($paneTopR);\r\n\r\n $headerRowScroller = $().add($headerRowScrollerL).add($headerRowScrollerR);\r\n\r\n $headerRowSpacerL = $(\"\")\r\n .css(\"width\", getCanvasWidth() + scrollbarDimensions.width + \"px\")\r\n .appendTo($headerRowScrollerL);\r\n $headerRowSpacerR = $(\"\")\r\n .css(\"width\", getCanvasWidth() + scrollbarDimensions.width + \"px\")\r\n .appendTo($headerRowScrollerR);\r\n\r\n $headerRowL = $(\"\").appendTo($headerRowScrollerL);\r\n $headerRowR = $(\"\").appendTo($headerRowScrollerR);\r\n\r\n $headerRow = $().add($headerRowL).add($headerRowR);\r\n\r\n // Append the top panel scroller\r\n $topPanelScrollerL = $(\"\").appendTo($paneTopL);\r\n $topPanelScrollerR = $(\"\").appendTo($paneTopR);\r\n\r\n $topPanelScroller = $().add($topPanelScrollerL).add($topPanelScrollerR);\r\n\r\n // Append the top panel\r\n $topPanelL = $(\"\").appendTo($topPanelScrollerL);\r\n $topPanelR = $(\"\").appendTo($topPanelScrollerR);\r\n\r\n $topPanel = $().add($topPanelL).add($topPanelR);\r\n\r\n if (!options.showTopPanel){\r\n $topPanelScroller.hide();\r\n }\r\n\r\n if (!options.showHeaderRow){\r\n $headerRowScroller.hide();\r\n }\r\n\r\n // Append the viewport containers\r\n $viewportTopL = $(\"\").appendTo($paneTopL);\r\n $viewportTopR = $(\"\").appendTo($paneTopR);\r\n $viewportBottomL = $(\"\").appendTo($paneBottomL);\r\n $viewportBottomR = $(\"\").appendTo($paneBottomR);\r\n\r\n // Cache the viewports\r\n $viewport = $().add($viewportTopL).add($viewportTopR).add($viewportBottomL).add($viewportBottomR);\r\n\r\n // Default the active viewport to the top left\r\n $activeViewportNode = $viewportTopL;\r\n\r\n // Append the canvas containers\r\n $canvasTopL = $(\"\").appendTo($viewportTopL);\r\n $canvasTopR = $(\"\").appendTo($viewportTopR);\r\n $canvasBottomL = $(\"\").appendTo($viewportBottomL);\r\n $canvasBottomR = $(\"\").appendTo($viewportBottomR);\r\n\r\n // Cache the canvases\r\n $canvas = $().add($canvasTopL).add($canvasTopR).add($canvasBottomL).add($canvasBottomR);\r\n\r\n // Default the active canvas to the top left\r\n $activeCanvasNode = $canvasTopL;\r\n\r\n // footer Row\r\n $footerRowScrollerR = $(\"\").appendTo($paneTopR);\r\n $footerRowScrollerL = $(\"\").appendTo($paneTopL);\r\n\r\n $footerRowScroller = $().add($footerRowScrollerL).add($footerRowScrollerR);\r\n\r\n $footerRowSpacerL = $(\"\")\r\n .css(\"width\", getCanvasWidth() + scrollbarDimensions.width + \"px\")\r\n .appendTo($footerRowScrollerL);\r\n $footerRowSpacerR = $(\"\")\r\n .css(\"width\", getCanvasWidth() + scrollbarDimensions.width + \"px\")\r\n .appendTo($footerRowScrollerR);\r\n\r\n $footerRowL = $(\"\").appendTo($footerRowScrollerL);\r\n $footerRowR = $(\"\").appendTo($footerRowScrollerR);\r\n\r\n $footerRow = $().add($footerRowL).add($footerRowR);\r\n\r\n if (!options.showFooterRow){\r\n $footerRowScroller.hide();\r\n }\r\n\r\n $focusSink2 = $focusSink.clone().appendTo($container);\r\n\r\n if (!options.explicitInitialization){\r\n finishInitialization();\r\n }\r\n }\r\n\r\n function finishInitialization(){\r\n if (!initialized){\r\n initialized = true;\r\n\r\n getViewportWidth();\r\n getViewportHeight();\r\n\r\n // header columns and cells may have different padding/border skewing width calculations (box-sizing, hello?)\r\n // calculate the diff so we can set consistent sizes\r\n measureCellPaddingAndBorder();\r\n\r\n // for usability reasons, all text selection in SlickGrid is disabled\r\n // with the exception of input and textarea elements (selection must\r\n // be enabled there so that editors work as expected); note that\r\n // selection in grid cells (grid body) is already unavailable in\r\n // all browsers except IE\r\n disableSelection($headers); // disable all text selection in header (including input and textarea)\r\n\r\n if (!options.enableTextSelectionOnCells){\r\n // disable text selection in grid cells except in input and textarea elements\r\n // (this is IE-specific, because selectstart event will only fire in IE)\r\n $viewport.bind(\"selectstart.ui\", function(event){\r\n return $(event.target).is(\"input,textarea\");\r\n });\r\n }\r\n\r\n setFrozenOptions();\r\n setPaneVisibility();\r\n setScroller();\r\n setOverflow();\r\n\r\n updateColumnCaches();\r\n createColumnHeaders();\r\n createColumnGroupHeaders();\r\n createColumnFooter();\r\n setupColumnSort();\r\n createCssRules();\r\n resizeCanvas();\r\n bindAncestorScrollEvents();\r\n\r\n $container.bind(\"resize.slickgrid\", resizeCanvas);\r\n $viewport.on(\"scroll\", handleScroll);\r\n\r\n if ($.fn.mousewheel && (options.frozenColumn > -1 || hasFrozenRows)){\r\n $viewport.on(\"mousewheel\", handleMouseWheel);\r\n }\r\n\r\n $headerScroller.bind(\"contextmenu\", handleHeaderContextMenu)\r\n .bind(\"click\", handleHeaderClick)\r\n .delegate(\".slick-header-column\", \"mouseenter\", handleHeaderMouseEnter)\r\n .delegate(\".slick-header-column\", \"mouseleave\", handleHeaderMouseLeave);\r\n $headerRowScroller.bind(\"scroll\", handleHeaderRowScroll);\r\n\r\n $footerRowScroller.bind(\"scroll\", handleFooterRowScroll);\r\n\r\n $focusSink.add($focusSink2)\r\n .bind(\"keydown\", handleKeyDown);\r\n $canvas.bind(\"keydown\", handleKeyDown)\r\n .bind(\"click\", handleClick)\r\n .bind(\"dblclick\", handleDblClick)\r\n .bind(\"contextmenu\", handleContextMenu)\r\n .delegate(\".slick-cell\", \"mouseenter\", handleMouseEnter)\r\n .delegate(\".slick-cell\", \"mouseleave\", handleMouseLeave);\r\n\r\n // legacy support for drag events\r\n interact($canvas[0]).allowFrom('div.slick-cell').draggable({\r\n onmove: handleDrag,\r\n onstart: handleDragStart,\r\n onend: handleDragEnd\r\n }).styleCursor(false);\r\n\r\n // Work around http://crbug.com/312427.\r\n if (navigator.userAgent.toLowerCase().match(/webkit/) && navigator.userAgent.toLowerCase().match(/macintosh/)){\r\n $canvas.on(\"mousewheel\", handleMouseWheel);\r\n }\r\n }\r\n }\r\n\r\n function hasFrozenColumns(){\r\n return options.frozenColumn > -1;\r\n }\r\n\r\n function registerPlugin(plugin){\r\n plugins.unshift(plugin);\r\n plugin.init(self);\r\n }\r\n\r\n function unregisterPlugin(plugin){\r\n for (var i = plugins.length; i >= 0; i--){\r\n if (plugins[i] === plugin){\r\n if (plugins[i].destroy){\r\n plugins[i].destroy();\r\n }\r\n plugins.splice(i, 1);\r\n break;\r\n }\r\n }\r\n }\r\n\r\n function setSelectionModel(model){\r\n if (selectionModel){\r\n selectionModel.onSelectedRangesChanged.unsubscribe(handleSelectedRangesChanged);\r\n if (selectionModel.destroy){\r\n selectionModel.destroy();\r\n }\r\n }\r\n\r\n selectionModel = model;\r\n if (selectionModel){\r\n selectionModel.init(self);\r\n selectionModel.onSelectedRangesChanged.subscribe(handleSelectedRangesChanged);\r\n }\r\n }\r\n\r\n function getSelectionModel(){\r\n return selectionModel;\r\n }\r\n\r\n function getCanvasNode(){\r\n return $canvas[0];\r\n }\r\n\r\n function getActiveCanvasNode(element){\r\n setActiveCanvasNode(element);\r\n\r\n return $activeCanvasNode[0];\r\n }\r\n\r\n function getCanvases(){\r\n return $canvas;\r\n }\r\n\r\n function setActiveCanvasNode(element){\r\n if (element){\r\n $activeCanvasNode = $(element.target).closest('.grid-canvas');\r\n }\r\n }\r\n\r\n function getViewportNode(){\r\n return $viewport[0];\r\n }\r\n\r\n function getActiveViewportNode(element){\r\n setActiveViewPortNode(element);\r\n\r\n return $activeViewportNode[0];\r\n }\r\n\r\n function setActiveViewportNode(element){\r\n if (element){\r\n $activeViewportNode = $(element.target).closest('.slick-viewport');\r\n }\r\n }\r\n\r\n function measureScrollbar(){\r\n var $c = $(\"\").appendTo(document.body);\r\n var dim = {\r\n width: $c.width() - $c[0].clientWidth,\r\n height: $c.height() - $c[0].clientHeight\r\n };\r\n $c.remove();\r\n return dim;\r\n }\r\n\r\n function getHeadersWidth(){\r\n headersWidth = headersWidthL = headersWidthR = 0;\r\n\r\n for (var i = 0, ii = columns.length; i < ii; i++){\r\n var width = columns[i].width;\r\n\r\n if ((options.frozenColumn) > -1 && (i > options.frozenColumn)){\r\n headersWidthR += width;\r\n } else {\r\n headersWidthL += width;\r\n }\r\n }\r\n\r\n if (hasFrozenColumns()){\r\n headersWidthL = headersWidthL + 1000;\r\n\r\n headersWidthR = Math.max(headersWidthR, viewportW) + headersWidthL;\r\n headersWidthR += scrollbarDimensions.width;\r\n } else {\r\n headersWidthL += scrollbarDimensions.width;\r\n headersWidthL = Math.max(headersWidthL, viewportW) + 1000;\r\n }\r\n\r\n headersWidth = headersWidthL + headersWidthR;\r\n }\r\n\r\n function getHeadersWidthL(){\r\n headersWidthL = 0;\r\n\r\n columns.forEach(function(column, i){\r\n if (!((options.frozenColumn) > -1 && (i > options.frozenColumn))) headersWidthL += column.width;\r\n });\r\n\r\n if (hasFrozenColumns()){\r\n headersWidthL += 1000;\r\n } else {\r\n headersWidthL += scrollbarDimensions.width;\r\n headersWidthL = Math.max(headersWidthL, viewportW) + 1000;\r\n }\r\n\r\n return headersWidthL;\r\n }\r\n\r\n function getHeadersWidthR(){\r\n headersWidthR = 0;\r\n\r\n columns.forEach(function(column, i){\r\n if ((options.frozenColumn) > -1 && (i > options.frozenColumn)) headersWidthR += column.width;\r\n });\r\n\r\n if (hasFrozenColumns()){\r\n headersWidthR = Math.max(headersWidthR, viewportW) + getHeadersWidthL();\r\n headersWidthR += scrollbarDimensions.width;\r\n }\r\n\r\n return headersWidthR;\r\n }\r\n\r\n function getCanvasWidth(){\r\n var availableWidth = viewportHasVScroll ? viewportW - scrollbarDimensions.width : viewportW;\r\n\r\n var i = columns.length;\r\n\r\n canvasWidthL = canvasWidthR = 0;\r\n\r\n while (i--){\r\n if (hasFrozenColumns() && (i > options.frozenColumn)){\r\n canvasWidthR += columns[i].width;\r\n } else {\r\n canvasWidthL += columns[i].width;\r\n }\r\n }\r\n\r\n var totalRowWidth = canvasWidthL + canvasWidthR;\r\n\r\n return options.fullWidthRows ? Math.max(totalRowWidth, availableWidth) : totalRowWidth;\r\n }\r\n\r\n function updateCanvasWidth(forceColumnWidthsUpdate){\r\n var oldCanvasWidth = canvasWidth;\r\n var oldCanvasWidthL = canvasWidthL;\r\n var oldCanvasWidthR = canvasWidthR;\r\n var widthChanged;\r\n canvasWidth = getCanvasWidth();\r\n\r\n widthChanged = canvasWidth !== oldCanvasWidth || canvasWidthL !== oldCanvasWidthL || canvasWidthR !== oldCanvasWidthR;\r\n\r\n if (widthChanged || hasFrozenColumns() || hasFrozenRows){\r\n $canvasTopL.width(canvasWidthL);\r\n\r\n getHeadersWidth();\r\n\r\n $headerL.width(headersWidthL);\r\n $headerR.width(headersWidthR);\r\n\r\n if (hasFrozenColumns()){\r\n $canvasTopR.width(canvasWidthR);\r\n\r\n $paneHeaderL.width(canvasWidthL);\r\n $paneHeaderR.css('left', canvasWidthL);\r\n $paneHeaderR.css('width', viewportW - canvasWidthL);\r\n\r\n $paneTopL.width(canvasWidthL);\r\n $paneTopR.css('left', canvasWidthL);\r\n $paneTopR.css('width', viewportW - canvasWidthL);\r\n\r\n $headerRowScrollerL.width(canvasWidthL);\r\n $headerRowScrollerR.width(viewportW - canvasWidthL);\r\n\r\n $headerRowL.width(canvasWidthL);\r\n $headerRowR.width(canvasWidthR);\r\n\r\n $footerRowScrollerL.width(canvasWidthL);\r\n $footerRowScrollerR.width(viewportW - canvasWidthL);\r\n\r\n $footerRowL.width(canvasWidthL);\r\n $footerRowR.width(canvasWidthR);\r\n\r\n $viewportTopL.width(canvasWidthL);\r\n $viewportTopR.width(viewportW - canvasWidthL);\r\n\r\n if (hasFrozenRows){\r\n $paneBottomL.width(canvasWidthL);\r\n $paneBottomR.css('left', canvasWidthL);\r\n\r\n $viewportBottomL.width(canvasWidthL);\r\n $viewportBottomR.width(viewportW - canvasWidthL);\r\n\r\n $canvasBottomL.width(canvasWidthL);\r\n $canvasBottomR.width(canvasWidthR);\r\n }\r\n } else {\r\n $paneHeaderL.width('100%');\r\n\r\n $paneTopL.width('100%');\r\n\r\n $headerRowScrollerL.width('100%');\r\n\r\n $headerRowL.width(canvasWidth);\r\n\r\n $footerRowScrollerL.width('100%');\r\n\r\n $footerRowL.width(canvasWidth);\r\n\r\n $viewportTopL.width('100%');\r\n\r\n if (hasFrozenRows){\r\n $viewportBottomL.width('100%');\r\n $canvasBottomL.width(canvasWidthL);\r\n }\r\n }\r\n\r\n viewportHasHScroll = (canvasWidth > viewportW - scrollbarDimensions.width);\r\n }\r\n\r\n $headerRowSpacerL.width(canvasWidth + (viewportHasVScroll ? scrollbarDimensions.width : 0));\r\n $headerRowSpacerR.width(canvasWidth + (viewportHasVScroll ? scrollbarDimensions.width : 0));\r\n\r\n $footerRowSpacerL.width(canvasWidth + (viewportHasVScroll ? scrollbarDimensions.width : 0));\r\n $footerRowSpacerR.width(canvasWidth + (viewportHasVScroll ? scrollbarDimensions.width : 0));\r\n\r\n if (widthChanged || forceColumnWidthsUpdate){\r\n applyColumnWidths();\r\n }\r\n }\r\n\r\n function disableSelection($target){\r\n if ($target && $target.jquery){\r\n $target.attr(\"unselectable\", \"on\")\r\n .css(\"MozUserSelect\", \"none\")\r\n .bind(\"selectstart.ui\", function(){\r\n return false;\r\n }); // from jquery:ui.core.js 1.7.2\r\n }\r\n }\r\n\r\n function getMaxSupportedCssHeight(){\r\n var supportedHeight = 1000000;\r\n // FF reports the height back but still renders blank after ~6M px\r\n var testUpTo = navigator.userAgent.toLowerCase().match(/firefox/) ? 6000000 : 1000000000;\r\n var div = $(\"\").appendTo(document.body);\r\n\r\n while (true){\r\n var test = supportedHeight * 2;\r\n div.css(\"height\", test);\r\n if (test > testUpTo || div.height() !== test){\r\n break;\r\n } else {\r\n supportedHeight = test;\r\n }\r\n }\r\n\r\n div.remove();\r\n return supportedHeight;\r\n }\r\n\r\n // TODO: this is static. need to handle page mutation.\r\n function bindAncestorScrollEvents(){\r\n var elem = (hasFrozenRows && !options.frozenBottom) ? $canvasBottomL[0] : $canvasTopL[0];\r\n while ((elem = elem.parentNode) != document.body && elem != null){\r\n // bind to scroll containers only\r\n if (elem == $viewportTopL[0] || elem.scrollWidth != elem.clientWidth || elem.scrollHeight != elem.clientHeight){\r\n var $elem = $(elem);\r\n if (!$boundAncestors){\r\n $boundAncestors = $elem;\r\n } else {\r\n $boundAncestors = $boundAncestors.add($elem);\r\n }\r\n $elem.bind(\"scroll.\" + uid, handleActiveCellPositionChange);\r\n }\r\n }\r\n }\r\n\r\n function unbindAncestorScrollEvents(){\r\n if (!$boundAncestors){\r\n return;\r\n }\r\n $boundAncestors.unbind(\"scroll.\" + uid);\r\n $boundAncestors = null;\r\n }\r\n\r\n function updateColumnHeader(columnId, title, toolTip){\r\n if (!initialized){\r\n return;\r\n }\r\n var idx = getColumnIndex(columnId);\r\n if (idx == null){\r\n return;\r\n }\r\n\r\n var columnDef = columns[idx];\r\n var $header = $headers.children().eq(idx);\r\n if ($header){\r\n if (title !== undefined){\r\n columns[idx].name = title;\r\n }\r\n if (toolTip !== undefined){\r\n columns[idx].toolTip = toolTip;\r\n }\r\n\r\n trigger(self.onBeforeHeaderCellDestroy, {\r\n \"node\": $header[0],\r\n \"column\": columnDef\r\n });\r\n\r\n $header.attr(\"title\", toolTip || \"\")\r\n .children().eq(0).html(title);\r\n\r\n trigger(self.onHeaderCellRendered, {\r\n \"node\": $header[0],\r\n \"column\": columnDef\r\n });\r\n }\r\n }\r\n\r\n function getHeaderRow(){\r\n return hasFrozenColumns() ? $headerRow : $headerRow[0];\r\n }\r\n\r\n function getHeaderRowColumn(columnId){\r\n var idx = getColumnIndex(columnId);\r\n\r\n var $headerRowTarget;\r\n\r\n if (hasFrozenColumns()){\r\n if (idx <= options.frozenColumn){\r\n $headerRowTarget = $headerRowL;\r\n } else {\r\n $headerRowTarget = $headerRowR;\r\n\r\n idx -= options.frozenColumn + 1;\r\n }\r\n } else {\r\n $headerRowTarget = $headerRowL;\r\n }\r\n\r\n var $header = $headerRowTarget.children().eq(idx);\r\n return $header && $header[0];\r\n }\r\n\r\n function getFooterRow(){\r\n return hasFrozenColumns() ? $footerRow : $footerRow[0];\r\n }\r\n\r\n function getFooterRowColumn(columnId){\r\n var idx = getColumnIndex(columnId);\r\n\r\n var $footerRowTarget;\r\n\r\n if (hasFrozenColumns()){\r\n if (idx <= options.frozenColumn){\r\n $footerRowTarget = $footerRowL;\r\n } else {\r\n $footerRowTarget = $footerRowR;\r\n\r\n idx -= options.frozenColumn + 1;\r\n }\r\n } else {\r\n $footerRowTarget = $footerRowL;\r\n }\r\n\r\n var $footer = $footerRowTarget.children().eq(idx);\r\n return $footer && $footer[0];\r\n }\r\n\r\n function createColumnFooter(){\r\n $footerRow.find(\".slick-footerrow-column\")\r\n .each(function(){\r\n var columnDef = $(this).data(\"column\");\r\n if (columnDef){\r\n trigger(self.onBeforeFooterRowCellDestroy, {\r\n \"node\": this,\r\n \"column\": columnDef\r\n });\r\n }\r\n });\r\n\r\n $footerRowL.empty();\r\n $footerRowR.empty();\r\n\r\n for (var i = 0; i < columns.length; i++){\r\n var m = columns[i];\r\n\r\n var footerRowCell = $(\"\")\r\n .data(\"column\", m)\r\n .addClass(hasFrozenColumns() && i <= options.frozenColumn ? 'frozen' : '')\r\n .appendTo(hasFrozenColumns() && (i > options.frozenColumn) ? $footerRowR : $footerRowL);\r\n\r\n trigger(self.onFooterRowCellRendered, {\r\n \"node\": footerRowCell[0],\r\n \"column\": m\r\n });\r\n }\r\n }\r\n\r\n function createColumnGroupHeaders(){\r\n var columnsLength = 0;\r\n var frozenColumnsValid = false;\r\n\r\n if (!treeColumns.hasDepth()) return;\r\n\r\n for (var index = 0; index < $groupHeadersL.length; index++){\r\n\r\n $groupHeadersL[index].empty();\r\n $groupHeadersR[index].empty();\r\n\r\n var groupColumns = treeColumns.getColumnsInDepth(index);\r\n\r\n for (var indexGroup in groupColumns){\r\n var m = groupColumns[indexGroup];\r\n\r\n columnsLength += m.extractColumns().length;\r\n\r\n if (hasFrozenColumns() && index == 0 && (columnsLength - 1) === options.frozenColumn) frozenColumnsValid = true;\r\n\r\n $(\"\")\r\n .html(\"\" + m.name + \"\")\r\n .attr(\"id\", \"\" + uid + m.id)\r\n .attr(\"title\", m.toolTip || \"\")\r\n .data(\"column\", m)\r\n .addClass(m.headerCssClass || \"\")\r\n .addClass(hasFrozenColumns() && (columnsLength - 1) <= options.frozenColumn ? 'frozen' : '')\r\n .appendTo(hasFrozenColumns() && (columnsLength - 1) > options.frozenColumn ? $groupHeadersR[index] : $groupHeadersL[index]);\r\n }\r\n\r\n if (hasFrozenColumns() && index == 0 && !frozenColumnsValid){\r\n $groupHeadersL[index].empty();\r\n $groupHeadersR[index].empty();\r\n alert(\"All columns of group should to be grouped!\");\r\n break;\r\n }\r\n }\r\n\r\n applyColumnGroupHeaderWidths();\r\n }\r\n\r\n function createColumnHeaders(){\r\n function onMouseEnter(){\r\n $(this).addClass(\"ui-state-hover\");\r\n }\r\n\r\n function onMouseLeave(){\r\n $(this).removeClass(\"ui-state-hover\");\r\n }\r\n\r\n $headers.find(\".slick-header-column\")\r\n .each(function(){\r\n var columnDef = $(this).data(\"column\");\r\n if (columnDef){\r\n trigger(self.onBeforeHeaderCellDestroy, {\r\n \"node\": this,\r\n \"column\": columnDef\r\n });\r\n }\r\n });\r\n\r\n $headerL.empty();\r\n $headerR.empty();\r\n\r\n getHeadersWidth();\r\n\r\n $headerL.width(headersWidthL);\r\n $headerR.width(headersWidthR);\r\n\r\n $headerRow.find(\".slick-headerrow-column\")\r\n .each(function(){\r\n var columnDef = $(this).data(\"column\");\r\n if (columnDef){\r\n trigger(self.onBeforeHeaderRowCellDestroy, {\r\n \"node\": this,\r\n \"column\": columnDef\r\n });\r\n }\r\n });\r\n\r\n $headerRowL.empty();\r\n $headerRowR.empty();\r\n\r\n for (var i = 0; i < columns.length; i++){\r\n var m = columns[i];\r\n\r\n var $headerTarget = hasFrozenColumns() ? ((i <= options.frozenColumn) ? $headerL : $headerR) : $headerL;\r\n var $headerRowTarget = hasFrozenColumns() ? ((i <= options.frozenColumn) ? $headerRowL : $headerRowR) : $headerRowL;\r\n\r\n var header = $(\"\")\r\n .html(\"\" + m.name + \"\")\r\n .width(m.width - headerColumnWidthDiff)\r\n .attr(\"id\", \"\" + uid + m.id)\r\n .attr(\"title\", m.toolTip || \"\")\r\n .data(\"column\", m)\r\n .addClass(m.headerCssClass || \"\")\r\n .addClass(hasFrozenColumns() && i <= options.frozenColumn ? 'frozen' : '')\r\n .appendTo($headerTarget);\r\n\r\n if (options.enableColumnReorder || m.sortable){\r\n header.on('mouseenter', onMouseEnter)\r\n .on('mouseleave', onMouseLeave);\r\n }\r\n\r\n if (m.sortable){\r\n header.addClass(\"slick-header-sortable\");\r\n header.append(\"\");\r\n }\r\n\r\n trigger(self.onHeaderCellRendered, {\r\n \"node\": header[0],\r\n \"column\": m\r\n });\r\n\r\n if (options.showHeaderRow){\r\n var headerRowCell = $(\"\")\r\n .data(\"column\", m)\r\n .appendTo($headerRowTarget);\r\n\r\n trigger(self.onHeaderRowCellRendered, {\r\n \"node\": headerRowCell[0],\r\n \"column\": m\r\n });\r\n }\r\n }\r\n\r\n setSortColumns(sortColumns);\r\n setupColumnResize();\r\n if (options.enableColumnReorder){\r\n setupColumnReorder();\r\n }\r\n }\r\n\r\n function setupColumnSort(){\r\n $headers.click(function(e){\r\n // temporary workaround for a bug in jQuery 1.7.1 (http://bugs.jquery.com/ticket/11328)\r\n e.metaKey = e.metaKey || e.ctrlKey;\r\n\r\n if ($(e.target).hasClass(\"slick-resizable-handle\")){\r\n return;\r\n }\r\n\r\n var $col = $(e.target).closest(\".slick-header-column\");\r\n if (!$col.length){\r\n return;\r\n }\r\n\r\n var column = $col.data(\"column\");\r\n if (column.sortable){\r\n if (!getEditorLock().commitCurrentEdit()){\r\n return;\r\n }\r\n\r\n var sortOpts = null;\r\n var i = 0;\r\n for (; i < sortColumns.length; i++){\r\n if (sortColumns[i].columnId == column.id){\r\n sortOpts = sortColumns[i];\r\n sortOpts.sortAsc = !sortOpts.sortAsc;\r\n break;\r\n }\r\n }\r\n\r\n if (e.metaKey && options.multiColumnSort){\r\n if (sortOpts){\r\n sortColumns.splice(i, 1);\r\n }\r\n } else {\r\n if ((!e.shiftKey && !e.metaKey) || !options.multiColumnSort){\r\n sortColumns = [];\r\n }\r\n\r\n if (!sortOpts){\r\n sortOpts = {\r\n columnId: column.id,\r\n sortAsc: column.defaultSortAsc\r\n };\r\n sortColumns.push(sortOpts);\r\n } else if (sortColumns.length == 0){\r\n sortColumns.push(sortOpts);\r\n }\r\n }\r\n\r\n setSortColumns(sortColumns);\r\n\r\n if (!options.multiColumnSort){\r\n trigger(self.onSort, {\r\n multiColumnSort: false,\r\n sortCol: column,\r\n sortAsc: sortOpts.sortAsc\r\n }, e);\r\n } else {\r\n trigger(self.onSort, {\r\n multiColumnSort: true,\r\n sortCols: $.map(sortColumns, function(col){\r\n return {\r\n sortCol: columns[getColumnIndex(col.columnId)],\r\n sortAsc: col.sortAsc\r\n };\r\n })\r\n }, e);\r\n }\r\n }\r\n });\r\n }\r\n\r\n function currentPositionInHeader(id){\r\n var currentPosition = 0;\r\n $headers.find('.slick-header-column').each(function(i){\r\n if (this.id == id){\r\n currentPosition = i;\r\n return false;\r\n }\r\n });\r\n\r\n return currentPosition;\r\n }\r\n\r\n function limitPositionInGroup(idColumn){\r\n var groupColumnOfPreviousPosition,\r\n startLimit = 0,\r\n endLimit = 0;\r\n\r\n treeColumns.getColumnsInDepth($groupHeadersL.length - 1)\r\n .some(function(groupColumn){\r\n startLimit = endLimit;\r\n endLimit += groupColumn.columns.length;\r\n\r\n groupColumn.columns.some(function(column){\r\n\r\n if (column.id === idColumn) groupColumnOfPreviousPosition = groupColumn;\r\n\r\n return groupColumnOfPreviousPosition;\r\n });\r\n\r\n return groupColumnOfPreviousPosition;\r\n });\r\n\r\n endLimit--;\r\n\r\n return {\r\n start: startLimit,\r\n end: endLimit,\r\n group: groupColumnOfPreviousPosition\r\n }\r\n }\r\n\r\n function remove(arr, elem){\r\n var index = arr.lastIndexOf(elem);\r\n if (index > -1){\r\n arr.splice(index, 1);\r\n remove(arr, elem);\r\n }\r\n }\r\n\r\n function columnPositionValidInGroup($item){\r\n var currentPosition = currentPositionInHeader($item[0].id);\r\n var limit = limitPositionInGroup($item.data('column').id);\r\n var positionValid = limit.start <= currentPosition && currentPosition <= limit.end;\r\n\r\n return {\r\n limit: limit,\r\n valid: positionValid,\r\n message: positionValid ? '' : 'Column \"'.concat($item.text(), '\" can be reordered only within the \"', limit.group.name, '\" group!')\r\n };\r\n }\r\n\r\n function setupColumnReorder(){\r\n let x = 0;\r\n let delta = 0;\r\n let placeholder = document.createElement('div');\r\n\r\n placeholder.className = 'interact-placeholder';\r\n\r\n interact('.slick-header-column')\r\n .ignoreFrom('.slick-resizable-handle')\r\n .draggable({\r\n inertia: true,\r\n // keep the element within the area of it's parent\r\n restrict: {\r\n restriction: 'parent',\r\n endOnly: true,\r\n elementRect: {top: 0, left: 0, bottom: 0, right: 0}\r\n },\r\n // enable autoScroll\r\n autoScroll: true,\r\n axis: 'x',\r\n onstart: event => {\r\n x = 0;\r\n delta = event.target.offsetWidth;\r\n\r\n // get old order\r\n $headers.find('.slick-header-column').each(function(index){\r\n $(this).data('index', index);\r\n });\r\n\r\n placeholder.style.height = event.target.offsetHeight + 'px';\r\n placeholder.style.width = delta + 'px';\r\n\r\n $(event.target).after(placeholder).css({\r\n position: 'absolute',\r\n zIndex: 1000,\r\n marginLeft: $(event.target).position().left - 1000\r\n });\r\n },\r\n\r\n onmove: event => {\r\n x += event.dx;\r\n event.target.style.transform = `translate3d(${x}px, -3px, 100px)`;\r\n // event.target.style.marginLeft = x + 'px';\r\n },\r\n\r\n onend: event => {\r\n x = 0;\r\n delta = 0;\r\n\r\n if (treeColumns.hasDepth()) {\r\n var validPositionInGroup = columnPositionValidInGroup($(event.target));\r\n var limit = validPositionInGroup.limit;\r\n\r\n var cancel = !validPositionInGroup.valid;\r\n\r\n if (cancel)\r\n alert(validPositionInGroup.message);\r\n }\r\n\r\n placeholder.parentNode.removeChild(placeholder);\r\n\r\n if (cancel){\r\n event.target.style.transform = 'none';\r\n setColumns(getColumns());\r\n return;\r\n }\r\n\r\n $(event.target).css({\r\n position: 'relative',\r\n zIndex: '',\r\n marginLeft: 0,\r\n transform: 'none'\r\n });\r\n\r\n const newColumns = [];\r\n $headers.find('.slick-header-column').each(function(index){\r\n newColumns.push(columns[$(this).data('index')]);\r\n $(this).removeData('index');\r\n });\r\n\r\n setColumns(newColumns);\r\n\r\n trigger(self.onColumnsReordered, { impactedColumns : getImpactedColumns( limit ), grid: self });\r\n setupColumnResize();\r\n }\r\n })\r\n .dropzone({\r\n accept: '.slick-header-column',\r\n\r\n ondragenter: event => {\r\n event.target.classList.add('interact-drop-active');\r\n event.relatedTarget.classList.add('interact-can-drop');\r\n },\r\n\r\n ondragleave: event => {\r\n event.target.classList.remove('interact-drop-active');\r\n event.relatedTarget.classList.remove('interact-can-drop');\r\n },\r\n\r\n ondrop: event => {\r\n event.target.classList.remove('interact-drop-active');\r\n event.relatedTarget.classList.remove('interact-can-drop');\r\n $(event.target)[x > 0 ? 'after' : 'before'](event.relatedTarget);\r\n }\r\n }).styleCursor(false);\r\n }\r\n\r\n function getImpactedColumns(limit){\r\n var impactedColumns = [];\r\n\r\n if (limit != undefined){\r\n\r\n for (var i = limit.start; i <= limit.end; i++){\r\n impactedColumns.push(columns[i]);\r\n }\r\n } else {\r\n\r\n impactedColumns = columns;\r\n }\r\n\r\n return impactedColumns;\r\n }\r\n\r\n function setupColumnResize(){\r\n var $col, j, c, pageX, columnElements, minPageX, maxPageX, firstResizable, lastResizable;\r\n columnElements = $headers.children();\r\n columnElements.find('.slick-resizable-handle').remove();\r\n columnElements.each(function(i, e){\r\n if (columns[i].resizable){\r\n if (firstResizable === undefined){\r\n firstResizable = i;\r\n }\r\n lastResizable = i;\r\n }\r\n });\r\n if (firstResizable === undefined){\r\n return;\r\n }\r\n columnElements.each(function(i, element){\r\n if (i < firstResizable || (options.forceFitColumns && i >= lastResizable)){\r\n return;\r\n }\r\n $col = $(element);\r\n\r\n const $handle = $(\"\");\r\n $handle.appendTo(element);\r\n\r\n if ($col.data('resizable'))\r\n return;\r\n\r\n const activeColumn = columns[i];\r\n if (activeColumn.resizable){\r\n $col.data('resizable', true);\r\n interact(element).resizable({\r\n preserveAspectRatio: false,\r\n edges: { left: true, right: true, bottom: false, top: false }\r\n }).on('resizestart', function(event){\r\n if (!getEditorLock().commitCurrentEdit()){\r\n return false;\r\n }\r\n activeColumn.previousWidth = event.rect.width;\r\n event.target.classList.add('slick-header-column-active');\r\n }).on('resizemove', function(event){\r\n let x = event.dx;\r\n let width = activeColumn.width += x;\r\n\r\n if (activeColumn.minWidth > 0 && activeColumn.minWidth > width)\r\n width = activeColumn.minWidth;\r\n else if (activeColumn.maxWidth > 0 && activeColumn.maxWidth < width)\r\n width = activeColumn.maxWidth;\r\n\r\n activeColumn.width = width;\r\n\r\n if (options.forceFitColumns){\r\n autosizeColumns();\r\n }\r\n applyColumnHeaderWidths();\r\n if (options.syncColumnCellResize){\r\n applyColumnWidths();\r\n }\r\n }).on('resizeend', function(event){\r\n event.target.classList.remove('slick-header-column-active');\r\n if (treeColumns.hasDepth())\r\n createColumnGroupHeaders();\r\n\r\n invalidateAllRows();\r\n updateCanvasWidth(true);\r\n render();\r\n trigger(self.onColumnsResized, {grid: self});\r\n });\r\n }\r\n });\r\n }\r\n\r\n function getVBoxDelta($el){\r\n var p = [\"borderTopWidth\", \"borderBottomWidth\", \"paddingTop\", \"paddingBottom\"];\r\n var delta = 0;\r\n $.each(p, function(n, val){\r\n delta += parseFloat($el.css(val)) || 0;\r\n });\r\n return delta;\r\n }\r\n\r\n function setFrozenOptions(){\r\n options.frozenColumn = (options.frozenColumn >= 0 && options.frozenColumn < columns.length) ? parseInt(options.frozenColumn) : -1;\r\n\r\n options.frozenRow = (options.frozenRow >= 0 && options.frozenRow < numVisibleRows) ? parseInt(options.frozenRow) : -1;\r\n\r\n if (options.frozenRow > -1){\r\n hasFrozenRows = true;\r\n frozenRowsHeight = (options.frozenRow) * options.rowHeight;\r\n\r\n var dataLength = getDataLength() || this.data.length;\r\n\r\n actualFrozenRow = (options.frozenBottom) ? (dataLength - options.frozenRow) : options.frozenRow;\r\n } else {\r\n hasFrozenRows = false;\r\n }\r\n }\r\n\r\n function setPaneVisibility(){\r\n if (hasFrozenColumns()){\r\n $paneHeaderR.show();\r\n $paneTopR.show();\r\n\r\n if (hasFrozenRows){\r\n $paneBottomL.show();\r\n $paneBottomR.show();\r\n } else {\r\n $paneBottomR.hide();\r\n $paneBottomL.hide();\r\n }\r\n } else {\r\n $paneHeaderR.hide();\r\n $paneTopR.hide();\r\n $paneBottomR.hide();\r\n\r\n if (hasFrozenRows){\r\n $paneBottomL.show();\r\n } else {\r\n $paneBottomR.hide();\r\n $paneBottomL.hide();\r\n }\r\n }\r\n }\r\n\r\n function setOverflow(){\r\n $viewportTopL.css({\r\n 'overflow-x': (hasFrozenColumns()) ? (hasFrozenRows ? 'hidden' : 'scroll') : (hasFrozenRows ? 'hidden' : 'auto'),\r\n 'overflow-y': (hasFrozenColumns()) ? (hasFrozenRows ? 'hidden' : 'hidden') : (hasFrozenRows ? 'scroll' : 'auto')\r\n });\r\n\r\n $viewportTopR.css({\r\n 'overflow-x': (hasFrozenColumns()) ? (hasFrozenRows ? 'hidden' : 'scroll') : (hasFrozenRows ? 'hidden' : 'auto'),\r\n 'overflow-y': (hasFrozenColumns()) ? (hasFrozenRows ? 'scroll' : 'auto') : (hasFrozenRows ? 'scroll' : 'auto')\r\n });\r\n\r\n $viewportBottomL.css({\r\n 'overflow-x': (hasFrozenColumns()) ? (hasFrozenRows ? 'scroll' : 'auto') : (hasFrozenRows ? 'auto' : 'auto'),\r\n 'overflow-y': (hasFrozenColumns()) ? (hasFrozenRows ? 'hidden' : 'hidden') : (hasFrozenRows ? 'scroll' : 'auto')\r\n });\r\n\r\n $viewportBottomR.css({\r\n 'overflow-x': (hasFrozenColumns()) ? (hasFrozenRows ? 'scroll' : 'auto') : (hasFrozenRows ? 'auto' : 'auto'),\r\n 'overflow-y': (hasFrozenColumns()) ? (hasFrozenRows ? 'auto' : 'auto') : (hasFrozenRows ? 'auto' : 'auto')\r\n });\r\n }\r\n\r\n function setScroller(){\r\n if (hasFrozenColumns()){\r\n $headerScrollContainer = $headerScrollerR;\r\n $headerRowScrollContainer = $headerRowScrollerR;\r\n $footerRowScrollContainer = $footerRowScrollerR\r\n\r\n if (hasFrozenRows){\r\n if (options.frozenBottom){\r\n $viewportScrollContainerX = $viewportBottomR;\r\n $viewportScrollContainerY = $viewportTopR;\r\n } else {\r\n $viewportScrollContainerX = $viewportScrollContainerY = $viewportBottomR;\r\n }\r\n } else {\r\n $viewportScrollContainerX = $viewportScrollContainerY = $viewportTopR;\r\n }\r\n } else {\r\n $headerScrollContainer = $headerScrollerL;\r\n $headerRowScrollContainer = $headerRowScrollerL;\r\n $footerRowScrollContainer = $footerRowScrollerL;\r\n\r\n if (hasFrozenRows){\r\n if (options.frozenBottom){\r\n $viewportScrollContainerX = $viewportBottomL;\r\n $viewportScrollContainerY = $viewportTopL;\r\n } else {\r\n $viewportScrollContainerX = $viewportScrollContainerY = $viewportBottomL;\r\n }\r\n } else {\r\n $viewportScrollContainerX = $viewportScrollContainerY = $viewportTopL;\r\n }\r\n }\r\n }\r\n\r\n function measureCellPaddingAndBorder(){\r\n var el;\r\n var h = [\"borderLeftWidth\", \"borderRightWidth\", \"paddingLeft\", \"paddingRight\"];\r\n var v = [\"borderTopWidth\", \"borderBottomWidth\", \"paddingTop\", \"paddingBottom\"];\r\n\r\n el = $(\"
\").appendTo(r);\r\n cellWidthDiff = cellHeightDiff = 0;\r\n if (el.css(\"box-sizing\") != \"border-box\" && el.css(\"-moz-box-sizing\") != \"border-box\" && el.css(\"-webkit-box-sizing\") != \"border-box\"){\r\n $.each(h, function(n, val){\r\n cellWidthDiff += parseFloat(el.css(val)) || 0;\r\n });\r\n $.each(v, function(n, val){\r\n cellHeightDiff += parseFloat(el.css(val)) || 0;\r\n });\r\n }\r\n r.remove();\r\n\r\n absoluteColumnMinWidth = Math.max(headerColumnWidthDiff, cellWidthDiff);\r\n }\r\n\r\n function createCssRules(){\r\n $style = $(\"\").appendTo($(\"head\"));\r\n var rowHeight = (options.rowHeight - cellHeightDiff);\r\n var rules = [\".\" + uid + \" .slick-group-header-column { left: 1000px; }\", \".\" + uid + \" .slick-header-column { left: 1000px; }\", \".\" + uid + \" .slick-top-panel { height:\" + options.topPanelHeight + \"px; }\", \".\" + uid + \" .slick-headerrow-columns { height:\" + options.headerRowHeight + \"px; }\", \".\" + uid + \" .slick-cell { height:\" + rowHeight + \"px; }\", \".\" + uid + \" .slick-row { height:\" + options.rowHeight + \"px; }\", \".\" + uid + \" .slick-footerrow-columns { height:\" + options.footerRowHeight + \"px; }\"];\r\n\r\n for (var i = 0; i < columns.length; i++){\r\n rules.push(\".\" + uid + \" .l\" + i + \" { }\");\r\n rules.push(\".\" + uid + \" .r\" + i + \" { }\");\r\n }\r\n\r\n if ($style[0].styleSheet){ // IE\r\n $style[0].styleSheet.cssText = rules.join(\" \");\r\n } else {\r\n $style[0].appendChild(document.createTextNode(rules.join(\" \")));\r\n }\r\n }\r\n\r\n function getColumnCssRules(idx){\r\n if (!stylesheet){\r\n var sheets = document.styleSheets;\r\n for (var i = 0; i < sheets.length; i++){\r\n if ((sheets[i].ownerNode || sheets[i].owningElement) == $style[0]){\r\n stylesheet = sheets[i];\r\n break;\r\n }\r\n }\r\n\r\n if (!stylesheet){\r\n throw new Error(\"Cannot find stylesheet.\");\r\n }\r\n\r\n // find and cache column CSS rules\r\n columnCssRulesL = [];\r\n columnCssRulesR = [];\r\n var cssRules = (stylesheet.cssRules || stylesheet.rules);\r\n var matches, columnIdx;\r\n for (var i = 0; i < cssRules.length; i++){\r\n var selector = cssRules[i].selectorText;\r\n if (matches = /\\.l\\d+/.exec(selector)){\r\n columnIdx = parseInt(matches[0].substr(2, matches[0].length - 2), 10);\r\n columnCssRulesL[columnIdx] = cssRules[i];\r\n } else if (matches = /\\.r\\d+/.exec(selector)){\r\n columnIdx = parseInt(matches[0].substr(2, matches[0].length - 2), 10);\r\n columnCssRulesR[columnIdx] = cssRules[i];\r\n }\r\n }\r\n }\r\n\r\n return {\r\n \"left\": columnCssRulesL[idx],\r\n \"right\": columnCssRulesR[idx]\r\n };\r\n }\r\n\r\n function removeCssRules(){\r\n $style.remove();\r\n stylesheet = null;\r\n }\r\n\r\n function destroy(){\r\n getEditorLock().cancelCurrentEdit();\r\n\r\n trigger(self.onBeforeDestroy, {});\r\n\r\n var i = plugins.length;\r\n while (i--){\r\n unregisterPlugin(plugins[i]);\r\n }\r\n\r\n unbindAncestorScrollEvents();\r\n $container.unbind(\".slickgrid\");\r\n removeCssRules();\r\n\r\n $container.empty().removeClass(uid);\r\n }\r\n\r\n //////////////////////////////////////////////////////////////////////////////////////////////\r\n // General\r\n\r\n function trigger(evt, args, e){\r\n e = e || new Slick.EventData();\r\n args = args || {};\r\n args.grid = self;\r\n return evt.notify(args, e, self);\r\n }\r\n\r\n function getEditorLock(){\r\n return options.editorLock;\r\n }\r\n\r\n function getEditController(){\r\n return editController;\r\n }\r\n\r\n function getColumnIndex(id){\r\n return columnsById[id];\r\n }\r\n\r\n function autosizeColumns(){\r\n var i, c,\r\n widths = [],\r\n shrinkLeeway = 0,\r\n total = 0,\r\n prevTotal,\r\n availWidth = viewportHasVScroll ? viewportW - scrollbarDimensions.width : viewportW;\r\n\r\n for (i = 0; i < columns.length; i++){\r\n c = columns[i];\r\n widths.push(c.width);\r\n total += c.width;\r\n if (c.resizable){\r\n shrinkLeeway += c.width - Math.max(c.minWidth, absoluteColumnMinWidth);\r\n }\r\n }\r\n\r\n // shrink\r\n prevTotal = total;\r\n while (total > availWidth && shrinkLeeway){\r\n var shrinkProportion = (total - availWidth) / shrinkLeeway;\r\n for (i = 0; i < columns.length && total > availWidth; i++){\r\n c = columns[i];\r\n var width = widths[i];\r\n if (!c.resizable || width <= c.minWidth || width <= absoluteColumnMinWidth){\r\n continue;\r\n }\r\n var absMinWidth = Math.max(c.minWidth, absoluteColumnMinWidth);\r\n var shrinkSize = Math.floor(shrinkProportion * (width - absMinWidth)) || 1;\r\n shrinkSize = Math.min(shrinkSize, width - absMinWidth);\r\n total -= shrinkSize;\r\n shrinkLeeway -= shrinkSize;\r\n widths[i] -= shrinkSize;\r\n }\r\n if (prevTotal <= total){ // avoid infinite loop\r\n break;\r\n }\r\n prevTotal = total;\r\n }\r\n\r\n // grow\r\n prevTotal = total;\r\n while (total < availWidth){\r\n var growProportion = availWidth / total;\r\n for (i = 0; i < columns.length && total < availWidth; i++){\r\n c = columns[i];\r\n var currentWidth = widths[i];\r\n var growSize;\r\n\r\n if (!c.resizable || c.maxWidth <= currentWidth){\r\n growSize = 0;\r\n } else {\r\n growSize = Math.min(Math.floor(growProportion * currentWidth) - currentWidth, (c.maxWidth - currentWidth) || 1000000) || 1;\r\n }\r\n total += growSize;\r\n widths[i] += growSize;\r\n }\r\n if (prevTotal >= total){ // avoid infinite loop\r\n break;\r\n }\r\n prevTotal = total;\r\n }\r\n\r\n var reRender = false;\r\n for (i = 0; i < columns.length; i++){\r\n if (columns[i].rerenderOnResize && columns[i].width != widths[i]){\r\n reRender = true;\r\n }\r\n columns[i].width = widths[i];\r\n }\r\n\r\n applyColumnHeaderWidths();\r\n applyColumnGroupHeaderWidths();\r\n updateCanvasWidth(true);\r\n if (reRender){\r\n invalidateAllRows();\r\n render();\r\n }\r\n }\r\n\r\n function applyColumnGroupHeaderWidths(){\r\n if (!treeColumns.hasDepth()) return;\r\n\r\n for (var depth = $groupHeadersL.length - 1; depth >= 0; depth--){\r\n\r\n var groupColumns = treeColumns.getColumnsInDepth(depth);\r\n\r\n $().add($groupHeadersL[depth]).add($groupHeadersR[depth]).each(function(i){\r\n var $groupHeader = $(this),\r\n currentColumnIndex = 0;\r\n\r\n $groupHeader.width(i == 0 ? getHeadersWidthL() : getHeadersWidthR());\r\n\r\n $groupHeader.children().each(function(){\r\n var $groupHeaderColumn = $(this);\r\n\r\n var m = $(this).data('column');\r\n\r\n m.width = 0;\r\n\r\n m.columns.forEach(function(){\r\n var $headerColumn = $groupHeader.next().children(':eq(' + (currentColumnIndex++) + ')');\r\n m.width += $headerColumn.outerWidth();\r\n })\r\n\r\n $groupHeaderColumn.width(m.width - headerColumnWidthDiff);\r\n\r\n });\r\n\r\n })\r\n\r\n }\r\n }\r\n\r\n function applyColumnHeaderWidths(){\r\n if (!initialized){\r\n return;\r\n }\r\n var h;\r\n for (var i = 0, headers = $headers.children(), ii = headers.length; i < ii; i++){\r\n h = $(headers[i]);\r\n if (h.width() !== columns[i].width - headerColumnWidthDiff){\r\n h.width(columns[i].width - headerColumnWidthDiff);\r\n }\r\n }\r\n\r\n updateColumnCaches();\r\n }\r\n\r\n function applyColumnWidths(){\r\n var x = 0,\r\n w, rule;\r\n for (var i = 0; i < columns.length; i++){\r\n w = columns[i].width;\r\n\r\n rule = getColumnCssRules(i);\r\n rule.left.style.left = x + \"px\";\r\n rule.right.style.right = (((options.frozenColumn != -1 && i > options.frozenColumn) ? canvasWidthR : canvasWidthL) - x - w) + \"px\";\r\n\r\n // If this column is frozen, reset the css left value since the\r\n // column starts in a new viewport.\r\n if (options.frozenColumn == i){\r\n x = 0;\r\n } else {\r\n x += columns[i].width;\r\n }\r\n }\r\n }\r\n\r\n function setSortColumn(columnId, ascending){\r\n setSortColumns([{\r\n columnId: columnId,\r\n sortAsc: ascending\r\n }]);\r\n }\r\n\r\n function setSortColumns(cols){\r\n sortColumns = cols;\r\n\r\n var headerColumnEls = $headers.children();\r\n headerColumnEls.removeClass(\"slick-header-column-sorted\")\r\n .find(\".slick-sort-indicator\")\r\n .removeClass(\"slick-sort-indicator-asc slick-sort-indicator-desc\");\r\n\r\n $.each(sortColumns, function(i, col){\r\n if (col.sortAsc == null){\r\n col.sortAsc = true;\r\n }\r\n var columnIndex = getColumnIndex(col.columnId);\r\n if (columnIndex != null){\r\n headerColumnEls.eq(columnIndex)\r\n .addClass(\"slick-header-column-sorted\")\r\n .find(\".slick-sort-indicator\")\r\n .addClass(col.sortAsc ? \"slick-sort-indicator-asc\" : \"slick-sort-indicator-desc\");\r\n }\r\n });\r\n }\r\n\r\n function getSortColumns(){\r\n return sortColumns;\r\n }\r\n\r\n function handleSelectedRangesChanged(e, ranges){\r\n selectedRows = [];\r\n var hash = {};\r\n for (var i = 0; i < ranges.length; i++){\r\n for (var j = ranges[i].fromRow; j <= ranges[i].toRow; j++){\r\n if (!hash[j]){ // prevent duplicates\r\n selectedRows.push(j);\r\n hash[j] = {};\r\n }\r\n for (var k = ranges[i].fromCell; k <= ranges[i].toCell; k++){\r\n if (canCellBeSelected(j, k)){\r\n hash[j][columns[k].id] = options.selectedCellCssClass;\r\n }\r\n }\r\n }\r\n }\r\n\r\n setCellCssStyles(options.selectedCellCssClass, hash);\r\n\r\n trigger(self.onSelectedRowsChanged, {\r\n rows: getSelectedRows()\r\n }, e);\r\n }\r\n\r\n function getColumns(){\r\n return columns;\r\n }\r\n\r\n function updateColumnCaches(){\r\n // Pre-calculate cell boundaries.\r\n columnPosLeft = [];\r\n columnPosRight = [];\r\n var x = 0;\r\n for (var i = 0, ii = columns.length; i < ii; i++){\r\n columnPosLeft[i] = x;\r\n columnPosRight[i] = x + columns[i].width;\r\n\r\n if (options.frozenColumn == i){\r\n x = 0;\r\n } else {\r\n x += columns[i].width;\r\n }\r\n }\r\n }\r\n\r\n function setColumns(columnDefinitions){\r\n var _treeColumns = new Slick.TreeColumns(columnDefinitions);\r\n if (_treeColumns.hasDepth()){\r\n treeColumns = _treeColumns;\r\n columns = treeColumns.extractColumns();\r\n } else {\r\n columns = columnDefinitions;\r\n }\r\n\r\n columnsById = {};\r\n for (var i = 0; i < columns.length; i++){\r\n var m = columns[i] = $.extend({}, columnDefaults, columns[i]);\r\n columnsById[m.id] = i;\r\n if (m.minWidth && m.width < m.minWidth){\r\n m.width = m.minWidth;\r\n }\r\n if (m.maxWidth && m.width > m.maxWidth){\r\n m.width = m.maxWidth;\r\n }\r\n }\r\n\r\n updateColumnCaches();\r\n\r\n if (initialized){\r\n setPaneVisibility();\r\n setOverflow();\r\n\r\n invalidateAllRows();\r\n createColumnHeaders();\r\n createColumnGroupHeaders();\r\n createColumnFooter();\r\n removeCssRules();\r\n createCssRules();\r\n resizeCanvas();\r\n updateCanvasWidth();\r\n applyColumnWidths();\r\n handleScroll();\r\n }\r\n }\r\n\r\n function getOptions(){\r\n return options;\r\n }\r\n\r\n function setOptions(args){\r\n if (!getEditorLock().commitCurrentEdit()){\r\n return;\r\n }\r\n\r\n makeActiveCellNormal();\r\n\r\n if (options.enableAddRow !== args.enableAddRow){\r\n invalidateRow(getDataLength());\r\n }\r\n\r\n options = $.extend(options, args);\r\n validateAndEnforceOptions();\r\n\r\n setFrozenOptions();\r\n setScroller();\r\n zombieRowNodeFromLastMouseWheelEvent = null;\r\n\r\n setColumns(treeColumns.extractColumns());\r\n render();\r\n }\r\n\r\n function validateAndEnforceOptions(){\r\n if (options.autoHeight){\r\n options.leaveSpaceForNewRows = false;\r\n }\r\n }\r\n\r\n function setData(newData, scrollToTop){\r\n data = newData;\r\n invalidateAllRows();\r\n updateRowCount();\r\n if (scrollToTop){\r\n scrollTo(0);\r\n }\r\n }\r\n\r\n function getData(){\r\n return data;\r\n }\r\n\r\n function getDataLength(){\r\n if (data.getLength){\r\n return data.getLength();\r\n } else {\r\n return data.length;\r\n }\r\n }\r\n\r\n function getDataLengthIncludingAddNew(){\r\n return getDataLength() + (options.enableAddRow ? 1 : 0);\r\n }\r\n\r\n function getDataItem(i){\r\n if (data.getItem){\r\n return data.getItem(i);\r\n } else {\r\n return data[i];\r\n }\r\n }\r\n\r\n function getTopPanel(){\r\n return $topPanel[0];\r\n }\r\n\r\n function setTopPanelVisibility(visible){\r\n if (options.showTopPanel != visible){\r\n options.showTopPanel = visible;\r\n if (visible){\r\n $topPanelScroller.slideDown(\"fast\", resizeCanvas);\r\n } else {\r\n $topPanelScroller.slideUp(\"fast\", resizeCanvas);\r\n }\r\n }\r\n }\r\n\r\n function setHeaderRowVisibility(visible){\r\n if (options.showHeaderRow != visible){\r\n options.showHeaderRow = visible;\r\n if (visible){\r\n $headerRowScroller.slideDown(\"fast\", resizeCanvas);\r\n } else {\r\n $headerRowScroller.slideUp(\"fast\", resizeCanvas);\r\n }\r\n }\r\n }\r\n\r\n function setFooterRowVisibility(visible){\r\n if (options.showFooterRow != visible){\r\n options.showFooterRow = visible;\r\n if (visible){\r\n $footerRowScroller.fadeIn(\"fast\", resizeCanvas);\r\n } else {\r\n $footerRowScroller.slideDown(\"fast\", resizeCanvas);\r\n }\r\n }\r\n }\r\n\r\n function getContainerNode(){\r\n return $container.get(0);\r\n }\r\n\r\n //////////////////////////////////////////////////////////////////////////////////////////////\r\n // Rendering / Scrolling\r\n\r\n function getRowTop(row){\r\n return options.rowHeight * row - offset;\r\n }\r\n\r\n function getRowFromPosition(y){\r\n return Math.floor((y + offset) / options.rowHeight);\r\n }\r\n\r\n function scrollTo(y){\r\n y = Math.max(y, 0);\r\n y = Math.min(y, th - $viewportScrollContainerY.height() + ((viewportHasHScroll || hasFrozenColumns()) ? scrollbarDimensions.height : 0));\r\n\r\n var oldOffset = offset;\r\n\r\n page = Math.min(n - 1, Math.floor(y / ph));\r\n offset = Math.round(page * cj);\r\n var newScrollTop = y - offset;\r\n\r\n if (offset != oldOffset){\r\n var range = getVisibleRange(newScrollTop);\r\n cleanupRows(range);\r\n updateRowPositions();\r\n }\r\n\r\n if (prevScrollTop != newScrollTop){\r\n vScrollDir = (prevScrollTop + oldOffset < newScrollTop + offset) ? 1 : -1;\r\n\r\n lastRenderedScrollTop = (scrollTop = prevScrollTop = newScrollTop);\r\n\r\n if (hasFrozenColumns()){\r\n $viewportTopL[0].scrollTop = newScrollTop;\r\n }\r\n\r\n if (hasFrozenRows){\r\n $viewportBottomL[0].scrollTop = $viewportBottomR[0].scrollTop = newScrollTop;\r\n }\r\n\r\n $viewportScrollContainerY[0].scrollTop = newScrollTop;\r\n\r\n trigger(self.onViewportChanged, {});\r\n }\r\n }\r\n\r\n function defaultFormatter(row, cell, value, columnDef, dataContext){\r\n if (value == null){\r\n return \"\";\r\n } else {\r\n return (value + \"\").replace(/&/g, \"&\").replace(//g, \">\");\r\n }\r\n }\r\n\r\n function getFormatter(row, column){\r\n var rowMetadata = data.getItemMetadata && data.getItemMetadata(row);\r\n\r\n // look up by id, then index\r\n var columnOverrides = rowMetadata && rowMetadata.columns && (rowMetadata.columns[column.id] || rowMetadata.columns[getColumnIndex(column.id)]);\r\n\r\n return (columnOverrides && columnOverrides.formatter) || (rowMetadata && rowMetadata.formatter) || column.formatter || (options.formatterFactory && options.formatterFactory.getFormatter(column)) || options.defaultFormatter;\r\n }\r\n\r\n function callFormatter(row, cell, value, m, item){\r\n\r\n var result;\r\n\r\n // pass metadata to formatter\r\n var metadata = data.getItemMetadata && data.getItemMetadata(row);\r\n metadata = metadata && metadata.columns;\r\n\r\n if (metadata){\r\n var columnData = metadata[m.id] || metadata[cell];\r\n result = getFormatter(row, m)(row, cell, value, m, item, columnData);\r\n } else {\r\n result = getFormatter(row, m)(row, cell, value, m, item);\r\n }\r\n\r\n return result;\r\n }\r\n\r\n function getEditor(row, cell){\r\n var column = columns[cell];\r\n var rowMetadata = data.getItemMetadata && data.getItemMetadata(row);\r\n var columnMetadata = rowMetadata && rowMetadata.columns;\r\n\r\n if (columnMetadata && columnMetadata[column.id] && columnMetadata[column.id].editor !== undefined){\r\n return columnMetadata[column.id].editor;\r\n }\r\n if (columnMetadata && columnMetadata[cell] && columnMetadata[cell].editor !== undefined){\r\n return columnMetadata[cell].editor;\r\n }\r\n\r\n return column.editor || (options.editorFactory && options.editorFactory.getEditor(column));\r\n }\r\n\r\n function getDataItemValueForColumn(item, columnDef){\r\n if (options.dataItemColumnValueExtractor){\r\n return options.dataItemColumnValueExtractor(item, columnDef);\r\n }\r\n return item[columnDef.field];\r\n }\r\n\r\n function appendRowHtml(stringArrayL, stringArrayR, row, range, dataLength){\r\n var d = getDataItem(row);\r\n var dataLoading = row < dataLength && !d;\r\n var rowCss = \"slick-row\" + (hasFrozenRows && row < options.frozenRow ? ' frozen' : '') + (dataLoading ? \" loading\" : \"\") + (row === activeRow ? \" active\" : \"\") + (row % 2 == 1 ? \" odd\" : \" even\");\r\n\r\n if (!d){\r\n rowCss += \" \" + options.addNewRowCssClass;\r\n }\r\n\r\n var metadata = data.getItemMetadata && data.getItemMetadata(row);\r\n\r\n if (metadata && metadata.cssClasses){\r\n rowCss += \" \" + metadata.cssClasses;\r\n }\r\n\r\n var frozenRowOffset = getFrozenRowOffset(row);\r\n\r\n var rowHtml = \"
\";\r\n\r\n stringArrayL.push(rowHtml);\r\n\r\n if (hasFrozenColumns()){\r\n stringArrayR.push(rowHtml);\r\n }\r\n\r\n var colspan, m;\r\n for (var i = 0, ii = columns.length; i < ii; i++){\r\n m = columns[i];\r\n colspan = 1;\r\n if (metadata && metadata.columns){\r\n var columnData = metadata.columns[m.id] || metadata.columns[i];\r\n colspan = (columnData && columnData.colspan) || 1;\r\n if (colspan === \"*\"){\r\n colspan = ii - i;\r\n }\r\n }\r\n\r\n // Do not render cells outside of the viewport.\r\n if (columnPosRight[Math.min(ii - 1, i + colspan - 1)] > range.leftPx){\r\n if (columnPosLeft[i] > range.rightPx){\r\n // All columns to the right are outside the range.\r\n break;\r\n }\r\n\r\n if (hasFrozenColumns() && (i > options.frozenColumn)){\r\n appendCellHtml(stringArrayR, row, i, colspan, d);\r\n } else {\r\n appendCellHtml(stringArrayL, row, i, colspan, d);\r\n }\r\n } else if (hasFrozenColumns() && (i <= options.frozenColumn)){\r\n appendCellHtml(stringArrayL, row, i, colspan, d);\r\n }\r\n\r\n if (colspan > 1){\r\n i += (colspan - 1);\r\n }\r\n }\r\n\r\n stringArrayL.push(\"
\");\r\n\r\n if (hasFrozenColumns()){\r\n stringArrayR.push(\"
\");\r\n }\r\n }\r\n\r\n function appendCellHtml(stringArray, row, cell, colspan, item){\r\n var m = columns[cell];\r\n var cellCss = \"slick-cell l\" + cell + \" r\" + Math.min(columns.length - 1, cell + colspan - 1) + (m.cssClass ? \" \" + m.cssClass : \"\");\r\n\r\n if (hasFrozenColumns() && cell <= options.frozenColumn) cellCss += ' frozen';\r\n\r\n if (row === activeRow && cell === activeCell) cellCss += \" active\";\r\n\r\n // TODO: merge them together in the setter\r\n for (var key in cellCssClasses){\r\n if (cellCssClasses[key][row] && cellCssClasses[key][row][m.id]){\r\n cellCss += (\" \" + cellCssClasses[key][row][m.id]);\r\n }\r\n }\r\n\r\n stringArray.push(\"
\");\r\n\r\n // if there is a corresponding row (if not, this is the Add New row or this data hasn't been loaded yet)\r\n if (item){\r\n var value = getDataItemValueForColumn(item, m);\r\n stringArray.push(callFormatter(row, cell, value, m, item));\r\n }\r\n\r\n stringArray.push(\"
\");\r\n\r\n rowsCache[row].cellRenderQueue.push(cell);\r\n rowsCache[row].cellColSpans[cell] = colspan;\r\n }\r\n\r\n function cleanupRows(rangeToKeep){\r\n for (var i in rowsCache){\r\n var removeFrozenRow = true;\r\n\r\n if (hasFrozenRows && ((options.frozenBottom && i >= actualFrozenRow) // Frozen bottom rows\r\n ||\r\n (!options.frozenBottom && i <= actualFrozenRow) // Frozen top rows\r\n )){\r\n removeFrozenRow = false;\r\n }\r\n\r\n if (((i = parseInt(i, 10)) !== activeRow) && (i < rangeToKeep.top || i > rangeToKeep.bottom) && (removeFrozenRow)){\r\n removeRowFromCache(i);\r\n }\r\n }\r\n }\r\n\r\n function invalidate(){\r\n updateRowCount();\r\n invalidateAllRows();\r\n render();\r\n }\r\n\r\n function invalidateAllRows(){\r\n if (currentEditor){\r\n makeActiveCellNormal();\r\n }\r\n for (var row in rowsCache){\r\n removeRowFromCache(row);\r\n }\r\n }\r\n\r\n function removeRowFromCache(row){\r\n var cacheEntry = rowsCache[row];\r\n if (!cacheEntry){\r\n return;\r\n }\r\n\r\n if (rowNodeFromLastMouseWheelEvent == cacheEntry.rowNode[0] || (hasFrozenColumns() && rowNodeFromLastMouseWheelEvent == cacheEntry.rowNode[1])){\r\n\r\n cacheEntry.rowNode.hide();\r\n\r\n zombieRowNodeFromLastMouseWheelEvent = cacheEntry.rowNode;\r\n } else {\r\n\r\n cacheEntry.rowNode.each(function(){\r\n this.parentElement.removeChild(this);\r\n });\r\n\r\n }\r\n\r\n delete rowsCache[row];\r\n delete postProcessedRows[row];\r\n renderedRows--;\r\n counter_rows_removed++;\r\n }\r\n\r\n function invalidateRows(rows){\r\n var i, rl;\r\n if (!rows || !rows.length){\r\n return;\r\n }\r\n vScrollDir = 0;\r\n for (i = 0, rl = rows.length; i < rl; i++){\r\n if (currentEditor && activeRow === rows[i]){\r\n makeActiveCellNormal();\r\n }\r\n if (rowsCache[rows[i]]){\r\n removeRowFromCache(rows[i]);\r\n }\r\n }\r\n }\r\n\r\n function invalidateRow(row){\r\n invalidateRows([row]);\r\n }\r\n\r\n function updateCell(row, cell){\r\n var cellNode = getCellNode(row, cell);\r\n if (!cellNode){\r\n return;\r\n }\r\n\r\n var m = columns[cell],\r\n d = getDataItem(row);\r\n if (currentEditor && activeRow === row && activeCell === cell){\r\n currentEditor.loadValue(d);\r\n } else {\r\n cellNode.innerHTML = d ? callFormatter(row, cell, getDataItemValueForColumn(d, m), m, d) : \"\";\r\n invalidatePostProcessingResults(row);\r\n }\r\n }\r\n\r\n function updateRow(row){\r\n var cacheEntry = rowsCache[row];\r\n if (!cacheEntry){\r\n return;\r\n }\r\n\r\n ensureCellNodesInRowsCache(row);\r\n\r\n var d = getDataItem(row);\r\n\r\n for (var columnIdx in cacheEntry.cellNodesByColumnIdx){\r\n if (!cacheEntry.cellNodesByColumnIdx.hasOwnProperty(columnIdx)){\r\n continue;\r\n }\r\n\r\n columnIdx = columnIdx | 0;\r\n var m = columns[columnIdx],\r\n node = cacheEntry.cellNodesByColumnIdx[columnIdx][0];\r\n\r\n if (row === activeRow && columnIdx === activeCell && currentEditor){\r\n currentEditor.loadValue(d);\r\n } else if (d){\r\n node.innerHTML = callFormatter(row, columnIdx, getDataItemValueForColumn(d, m), m, d);\r\n } else {\r\n node.innerHTML = \"\";\r\n }\r\n }\r\n\r\n invalidatePostProcessingResults(row);\r\n }\r\n\r\n function getViewportHeight(){\r\n if (options.autoHeight){\r\n viewportH = options.rowHeight * getDataLengthIncludingAddNew() + ((options.frozenColumn == -1) ? $headers.outerHeight() : 0);\r\n } else {\r\n topPanelH = (options.showTopPanel) ? options.topPanelHeight + getVBoxDelta($topPanelScroller) : 0;\r\n\r\n headerRowH = (options.showHeaderRow) ? options.headerRowHeight + getVBoxDelta($headerRowScroller) : 0;\r\n\r\n footerRowH = (options.showFooterRow) ? options.footerRowHeight + getVBoxDelta($footerRowScroller) : 0;\r\n\r\n viewportH = parseFloat($.css($container[0], \"height\", true)) - parseFloat($.css($container[0], \"paddingTop\", true)) - parseFloat($.css($container[0], \"paddingBottom\", true)) - parseFloat($.css($headerScroller[0], \"height\")) - getVBoxDelta($headerScroller) - topPanelH - headerRowH - footerRowH;\r\n }\r\n\r\n numVisibleRows = Math.ceil(viewportH / options.rowHeight);\r\n }\r\n\r\n function getViewportWidth(){\r\n viewportW = parseFloat($.css($container[0], \"width\", true));\r\n }\r\n\r\n function resizeCanvas(){\r\n if (!initialized){\r\n return;\r\n }\r\n\r\n paneTopH = 0\r\n paneBottomH = 0\r\n viewportTopH = 0\r\n viewportBottomH = 0;\r\n\r\n getViewportWidth();\r\n getViewportHeight();\r\n\r\n // Account for Frozen Rows\r\n if (hasFrozenRows){\r\n if (options.frozenBottom){\r\n paneTopH = viewportH - frozenRowsHeight - scrollbarDimensions.height;\r\n\r\n paneBottomH = frozenRowsHeight + scrollbarDimensions.height;\r\n } else {\r\n paneTopH = frozenRowsHeight;\r\n paneBottomH = viewportH - frozenRowsHeight;\r\n }\r\n } else {\r\n paneTopH = viewportH;\r\n }\r\n\r\n // The top pane includes the top panel and the header row\r\n paneTopH += topPanelH + headerRowH + footerRowH;\r\n\r\n if (hasFrozenColumns() && options.autoHeight){\r\n paneTopH += scrollbarDimensions.height;\r\n }\r\n\r\n // The top viewport does not contain the top panel or header row\r\n viewportTopH = paneTopH - topPanelH - headerRowH - footerRowH;\r\n\r\n if (options.autoHeight){\r\n if (hasFrozenColumns()){\r\n $container.height(\r\n paneTopH + parseFloat($.css($headerScrollerL[0], \"height\")));\r\n }\r\n\r\n $paneTopL.css('position', 'relative');\r\n }\r\n\r\n $paneTopL.css({\r\n 'top': $paneHeaderL.height(),\r\n 'height': paneTopH\r\n });\r\n\r\n var paneBottomTop = $paneTopL.position().top + paneTopH;\r\n\r\n $viewportTopL.height(viewportTopH);\r\n\r\n if (hasFrozenColumns()){\r\n $paneTopR.css({\r\n 'top': $paneHeaderL.height(),\r\n 'height': paneTopH\r\n });\r\n\r\n $viewportTopR.height(viewportTopH);\r\n\r\n if (hasFrozenRows){\r\n $paneBottomL.css({\r\n 'top': paneBottomTop,\r\n 'height': paneBottomH\r\n });\r\n\r\n $paneBottomR.css({\r\n 'top': paneBottomTop,\r\n 'height': paneBottomH\r\n });\r\n\r\n $viewportBottomR.height(paneBottomH);\r\n }\r\n } else {\r\n if (hasFrozenRows){\r\n $paneBottomL.css({\r\n 'width': '100%',\r\n 'height': paneBottomH\r\n });\r\n\r\n $paneBottomL.css('top', paneBottomTop);\r\n }\r\n }\r\n\r\n if (hasFrozenRows){\r\n $viewportBottomL.height(paneBottomH);\r\n\r\n if (options.frozenBottom){\r\n $canvasBottomL.height(frozenRowsHeight);\r\n\r\n if (hasFrozenColumns()){\r\n $canvasBottomR.height(frozenRowsHeight);\r\n }\r\n } else {\r\n $canvasTopL.height(frozenRowsHeight);\r\n\r\n if (hasFrozenColumns()){\r\n $canvasTopR.height(frozenRowsHeight);\r\n }\r\n }\r\n } else {\r\n $viewportTopR.height(viewportTopH);\r\n }\r\n\r\n if (options.forceFitColumns){\r\n autosizeColumns();\r\n }\r\n\r\n updateRowCount();\r\n handleScroll();\r\n // Since the width has changed, force the render() to reevaluate virtually rendered cells.\r\n lastRenderedScrollLeft = -1;\r\n render();\r\n }\r\n\r\n function updateRowCount(){\r\n if (!initialized){\r\n return;\r\n }\r\n\r\n var dataLengthIncludingAddNew = getDataLengthIncludingAddNew();\r\n var numberOfRows = 0;\r\n var oldH = (hasFrozenRows && !options.frozenBottom) ? $canvasBottomL.height() : $canvasTopL.height();\r\n\r\n if (hasFrozenRows){\r\n var numberOfRows = getDataLength() - options.frozenRow;\r\n } else {\r\n var numberOfRows = dataLengthIncludingAddNew + (options.leaveSpaceForNewRows ? numVisibleRows - 1 : 0);\r\n }\r\n\r\n var tempViewportH = $viewportScrollContainerY.height();\r\n var oldViewportHasVScroll = viewportHasVScroll;\r\n // with autoHeight, we do not need to accommodate the vertical scroll bar\r\n viewportHasVScroll = !options.autoHeight && (numberOfRows * options.rowHeight > tempViewportH);\r\n\r\n makeActiveCellNormal();\r\n\r\n // remove the rows that are now outside of the data range\r\n // this helps avoid redundant calls to .removeRow() when the size of the data decreased by thousands of rows\r\n var l = dataLengthIncludingAddNew - 1;\r\n for (var i in rowsCache){\r\n if (i >= l){\r\n removeRowFromCache(i);\r\n }\r\n }\r\n\r\n th = Math.max(options.rowHeight * numberOfRows, tempViewportH - scrollbarDimensions.height);\r\n\r\n if (activeCellNode && activeRow > l){\r\n resetActiveCell();\r\n }\r\n\r\n if (th < maxSupportedCssHeight){\r\n // just one page\r\n h = ph = th;\r\n n = 1;\r\n cj = 0;\r\n } else {\r\n // break into pages\r\n h = maxSupportedCssHeight;\r\n ph = h / 100;\r\n n = Math.floor(th / ph);\r\n cj = (th - h) / (n - 1);\r\n }\r\n\r\n if (h !== oldH){\r\n if (hasFrozenRows && !options.frozenBottom){\r\n $canvasBottomL.css(\"height\", h);\r\n\r\n if (hasFrozenColumns()){\r\n $canvasBottomR.css(\"height\", h);\r\n }\r\n } else {\r\n $canvasTopL.css(\"height\", h);\r\n $canvasTopR.css(\"height\", h);\r\n }\r\n\r\n scrollTop = $viewportScrollContainerY[0].scrollTop;\r\n }\r\n\r\n var oldScrollTopInRange = (scrollTop + offset <= th - tempViewportH);\r\n\r\n if (th == 0 || scrollTop == 0){\r\n page = offset = 0;\r\n } else if (oldScrollTopInRange){\r\n // maintain virtual position\r\n scrollTo(scrollTop + offset);\r\n } else {\r\n // scroll to bottom\r\n scrollTo(th - tempViewportH);\r\n }\r\n\r\n if (h != oldH && options.autoHeight){\r\n resizeCanvas();\r\n }\r\n\r\n if (options.forceFitColumns && oldViewportHasVScroll != viewportHasVScroll){\r\n autosizeColumns();\r\n }\r\n updateCanvasWidth(false);\r\n }\r\n\r\n function getVisibleRange(viewportTop, viewportLeft){\r\n if (viewportTop == null){\r\n viewportTop = scrollTop;\r\n }\r\n if (viewportLeft == null){\r\n viewportLeft = scrollLeft;\r\n }\r\n\r\n return {\r\n top: getRowFromPosition(viewportTop),\r\n bottom: getRowFromPosition(viewportTop + viewportH) + 1,\r\n leftPx: viewportLeft,\r\n rightPx: viewportLeft + viewportW\r\n };\r\n }\r\n\r\n function getRenderedRange(viewportTop, viewportLeft){\r\n var range = getVisibleRange(viewportTop, viewportLeft);\r\n var buffer = Math.round(viewportH / options.rowHeight);\r\n var minBuffer = 3;\r\n\r\n if (vScrollDir == -1){\r\n range.top -= buffer;\r\n range.bottom += minBuffer;\r\n } else if (vScrollDir == 1){\r\n range.top -= minBuffer;\r\n range.bottom += buffer;\r\n } else {\r\n range.top -= minBuffer;\r\n range.bottom += minBuffer;\r\n }\r\n\r\n range.top = Math.max(0, range.top);\r\n range.bottom = Math.min(getDataLengthIncludingAddNew() - 1, range.bottom);\r\n\r\n range.leftPx -= viewportW;\r\n range.rightPx += viewportW;\r\n\r\n range.leftPx = Math.max(0, range.leftPx);\r\n range.rightPx = Math.min(canvasWidth, range.rightPx);\r\n\r\n return range;\r\n }\r\n\r\n function ensureCellNodesInRowsCache(row){\r\n var cacheEntry = rowsCache[row];\r\n if (cacheEntry){\r\n if (cacheEntry.cellRenderQueue.length){\r\n var $lastNode = cacheEntry.rowNode.children().last();\r\n while (cacheEntry.cellRenderQueue.length){\r\n var columnIdx = cacheEntry.cellRenderQueue.pop();\r\n\r\n cacheEntry.cellNodesByColumnIdx[columnIdx] = $lastNode;\r\n $lastNode = $lastNode.prev();\r\n\r\n // Hack to retrieve the frozen columns because\r\n if ($lastNode.length == 0){\r\n $lastNode = $(cacheEntry.rowNode[0]).children().last();\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n function cleanUpCells(range, row){\r\n // Ignore frozen rows\r\n if (hasFrozenRows && ((options.frozenBottom && row > actualFrozenRow) // Frozen bottom rows\r\n ||\r\n (row <= actualFrozenRow) // Frozen top rows\r\n )){\r\n return;\r\n }\r\n\r\n var totalCellsRemoved = 0;\r\n var cacheEntry = rowsCache[row];\r\n\r\n // Remove cells outside the range.\r\n var cellsToRemove = [];\r\n for (var i in cacheEntry.cellNodesByColumnIdx){\r\n // I really hate it when people mess with Array.prototype.\r\n if (!cacheEntry.cellNodesByColumnIdx.hasOwnProperty(i)){\r\n continue;\r\n }\r\n\r\n // This is a string, so it needs to be cast back to a number.\r\n i = i | 0;\r\n\r\n // Ignore frozen columns\r\n if (i <= options.frozenColumn){\r\n continue;\r\n }\r\n\r\n var colspan = cacheEntry.cellColSpans[i];\r\n if (columnPosLeft[i] > range.rightPx || columnPosRight[Math.min(columns.length - 1, i + colspan - 1)] < range.leftPx){\r\n if (!(row == activeRow && i == activeCell)){\r\n cellsToRemove.push(i);\r\n }\r\n }\r\n }\r\n\r\n var cellToRemove;\r\n while ((cellToRemove = cellsToRemove.pop()) != null){\r\n cacheEntry.cellNodesByColumnIdx[cellToRemove][0].parentElement.removeChild(cacheEntry.cellNodesByColumnIdx[cellToRemove][0]);\r\n delete cacheEntry.cellColSpans[cellToRemove];\r\n delete cacheEntry.cellNodesByColumnIdx[cellToRemove];\r\n if (postProcessedRows[row]){\r\n delete postProcessedRows[row][cellToRemove];\r\n }\r\n totalCellsRemoved++;\r\n }\r\n }\r\n\r\n function cleanUpAndRenderCells(range){\r\n var cacheEntry;\r\n var stringArray = [];\r\n var processedRows = [];\r\n var cellsAdded;\r\n var totalCellsAdded = 0;\r\n var colspan;\r\n\r\n for (var row = range.top, btm = range.bottom; row <= btm; row++){\r\n cacheEntry = rowsCache[row];\r\n if (!cacheEntry){\r\n continue;\r\n }\r\n\r\n // cellRenderQueue populated in renderRows() needs to be cleared first\r\n ensureCellNodesInRowsCache(row);\r\n\r\n cleanUpCells(range, row);\r\n\r\n // Render missing cells.\r\n cellsAdded = 0;\r\n\r\n var metadata = data.getItemMetadata && data.getItemMetadata(row);\r\n metadata = metadata && metadata.columns;\r\n\r\n var d = getDataItem(row);\r\n\r\n // TODO: shorten this loop (index? heuristics? binary search?)\r\n for (var i = 0, ii = columns.length; i < ii; i++){\r\n // Cells to the right are outside the range.\r\n if (columnPosLeft[i] > range.rightPx){\r\n break;\r\n }\r\n\r\n // Already rendered.\r\n if ((colspan = cacheEntry.cellColSpans[i]) != null){\r\n i += (colspan > 1 ? colspan - 1 : 0);\r\n continue;\r\n }\r\n\r\n colspan = 1;\r\n if (metadata){\r\n var columnData = metadata[columns[i].id] || metadata[i];\r\n colspan = (columnData && columnData.colspan) || 1;\r\n if (colspan === \"*\"){\r\n colspan = ii - i;\r\n }\r\n }\r\n\r\n if (columnPosRight[Math.min(ii - 1, i + colspan - 1)] > range.leftPx){\r\n appendCellHtml(stringArray, row, i, colspan, d);\r\n cellsAdded++;\r\n }\r\n\r\n i += (colspan > 1 ? colspan - 1 : 0);\r\n }\r\n\r\n if (cellsAdded){\r\n totalCellsAdded += cellsAdded;\r\n processedRows.push(row);\r\n }\r\n }\r\n\r\n if (!stringArray.length){\r\n return;\r\n }\r\n\r\n var x = document.createElement(\"div\");\r\n x.innerHTML = stringArray.join(\"\");\r\n\r\n var processedRow;\r\n var $node;\r\n while ((processedRow = processedRows.pop()) != null){\r\n cacheEntry = rowsCache[processedRow];\r\n var columnIdx;\r\n while ((columnIdx = cacheEntry.cellRenderQueue.pop()) != null){\r\n $node = $(x).children().last();\r\n\r\n if (hasFrozenColumns() && (columnIdx > options.frozenColumn)){\r\n $(cacheEntry.rowNode[1]).append($node);\r\n } else {\r\n $(cacheEntry.rowNode[0]).append($node);\r\n }\r\n\r\n cacheEntry.cellNodesByColumnIdx[columnIdx] = $node;\r\n }\r\n }\r\n }\r\n\r\n function renderRows(range){\r\n var stringArrayL = [],\r\n stringArrayR = [],\r\n rows = [],\r\n needToReselectCell = false,\r\n dataLength = getDataLength();\r\n\r\n for (var i = range.top, ii = range.bottom; i <= ii; i++){\r\n if (rowsCache[i] || (hasFrozenRows && options.frozenBottom && i == getDataLength())){\r\n continue;\r\n }\r\n renderedRows++;\r\n rows.push(i);\r\n\r\n // Create an entry right away so that appendRowHtml() can\r\n // start populatating it.\r\n rowsCache[i] = {\r\n \"rowNode\": null,\r\n\r\n // ColSpans of rendered cells (by column idx).\r\n // Can also be used for checking whether a cell has been rendered.\r\n \"cellColSpans\": [],\r\n\r\n // Cell nodes (by column idx). Lazy-populated by ensureCellNodesInRowsCache().\r\n \"cellNodesByColumnIdx\": [],\r\n\r\n // Column indices of cell nodes that have been rendered, but not yet indexed in\r\n // cellNodesByColumnIdx. These are in the same order as cell nodes added at the\r\n // end of the row.\r\n \"cellRenderQueue\": []\r\n };\r\n\r\n appendRowHtml(stringArrayL, stringArrayR, i, range, dataLength);\r\n if (activeCellNode && activeRow === i){\r\n needToReselectCell = true;\r\n }\r\n counter_rows_rendered++;\r\n }\r\n\r\n if (!rows.length){\r\n return;\r\n }\r\n\r\n var x = document.createElement(\"div\"),\r\n xRight = document.createElement(\"div\");\r\n\r\n x.innerHTML = stringArrayL.join(\"\");\r\n xRight.innerHTML = stringArrayR.join(\"\");\r\n\r\n for (var i = 0, ii = rows.length; i < ii; i++){\r\n if ((hasFrozenRows) && (rows[i] >= actualFrozenRow)){\r\n if (hasFrozenColumns()){\r\n rowsCache[rows[i]].rowNode = $()\r\n .add($(x.firstChild).appendTo($canvasBottomL))\r\n .add($(xRight.firstChild).appendTo($canvasBottomR));\r\n } else {\r\n rowsCache[rows[i]].rowNode = $()\r\n .add($(x.firstChild).appendTo($canvasBottomL));\r\n }\r\n } else if (hasFrozenColumns()){\r\n rowsCache[rows[i]].rowNode = $()\r\n .add($(x.firstChild).appendTo($canvasTopL))\r\n .add($(xRight.firstChild).appendTo($canvasTopR));\r\n } else {\r\n rowsCache[rows[i]].rowNode = $()\r\n .add($(x.firstChild).appendTo($canvasTopL));\r\n }\r\n }\r\n\r\n if (needToReselectCell){\r\n activeCellNode = getCellNode(activeRow, activeCell);\r\n }\r\n }\r\n\r\n function startPostProcessing(){\r\n if (!options.enableAsyncPostRender){\r\n return;\r\n }\r\n clearTimeout(h_postrender);\r\n h_postrender = setTimeout(asyncPostProcessRows, options.asyncPostRenderDelay);\r\n }\r\n\r\n function invalidatePostProcessingResults(row){\r\n delete postProcessedRows[row];\r\n postProcessFromRow = Math.min(postProcessFromRow, row);\r\n postProcessToRow = Math.max(postProcessToRow, row);\r\n startPostProcessing();\r\n }\r\n\r\n function updateRowPositions(){\r\n for (var row in rowsCache){\r\n rowsCache[row].rowNode.css('top', getRowTop(row) + \"px\");\r\n }\r\n }\r\n\r\n function render(){\r\n if (!initialized){\r\n return;\r\n }\r\n var visible = getVisibleRange();\r\n var rendered = getRenderedRange();\r\n\r\n // remove rows no longer in the viewport\r\n cleanupRows(rendered);\r\n\r\n // add new rows & missing cells in existing rows\r\n if (lastRenderedScrollLeft != scrollLeft){\r\n\r\n if (hasFrozenRows){\r\n\r\n var renderedFrozenRows = $.extend(true, {}, rendered);\r\n\r\n if (options.frozenBottom){\r\n\r\n renderedFrozenRows.top = actualFrozenRow;\r\n renderedFrozenRows.bottom = getDataLength();\r\n } else {\r\n\r\n renderedFrozenRows.top = 0;\r\n renderedFrozenRows.bottom = options.frozenRow;\r\n }\r\n\r\n cleanUpAndRenderCells(renderedFrozenRows);\r\n }\r\n\r\n cleanUpAndRenderCells(rendered);\r\n }\r\n\r\n // render missing rows\r\n renderRows(rendered);\r\n\r\n // Render frozen rows\r\n if (hasFrozenRows){\r\n if (options.frozenBottom){\r\n renderRows({\r\n top: actualFrozenRow,\r\n bottom: getDataLength() - 1,\r\n leftPx: rendered.leftPx,\r\n rightPx: rendered.rightPx\r\n });\r\n } else {\r\n renderRows({\r\n top: 0,\r\n bottom: options.frozenRow - 1,\r\n leftPx: rendered.leftPx,\r\n rightPx: rendered.rightPx\r\n });\r\n }\r\n }\r\n\r\n postProcessFromRow = visible.top;\r\n postProcessToRow = Math.min(getDataLengthIncludingAddNew() - 1, visible.bottom);\r\n startPostProcessing();\r\n\r\n lastRenderedScrollTop = scrollTop;\r\n lastRenderedScrollLeft = scrollLeft;\r\n h_render = null;\r\n }\r\n\r\n function handleHeaderRowScroll(){\r\n var scrollLeft = $headerRowScrollContainer[0].scrollLeft;\r\n if (scrollLeft != $viewportScrollContainerX[0].scrollLeft){\r\n $viewportScrollContainerX[0].scrollLeft = scrollLeft;\r\n }\r\n }\r\n\r\n function handleFooterRowScroll(){\r\n var scrollLeft = $footerRowScrollContainer[0].scrollLeft;\r\n if (scrollLeft != $viewportScrollContainerX[0].scrollLeft){\r\n $viewportScrollContainerX[0].scrollLeft = scrollLeft;\r\n }\r\n }\r\n\r\n function handleMouseWheel(e, delta, deltaX, deltaY){\r\n var $rowNode = $(e.target).closest(\".slick-row\");\r\n var rowNode = $rowNode[0];\r\n\r\n if (rowNode != rowNodeFromLastMouseWheelEvent){\r\n\r\n var $gridCanvas = $rowNode.parents('.grid-canvas');\r\n var left = $gridCanvas.hasClass('grid-canvas-left');\r\n\r\n if (zombieRowNodeFromLastMouseWheelEvent && zombieRowNodeFromLastMouseWheelEvent[left ? 0 : 1] != rowNode){\r\n var zombieRow = zombieRowNodeFromLastMouseWheelEvent[left || zombieRowNodeFromLastMouseWheelEvent.length == 1 ? 0 : 1];\r\n zombieRow.parentElement.removeChild(zombieRow);\r\n\r\n zombieRowNodeFromLastMouseWheelEvent = null;\r\n }\r\n\r\n rowNodeFromLastMouseWheelEvent = rowNode;\r\n }\r\n\r\n scrollTop = Math.max(0, $viewportScrollContainerY[0].scrollTop - (deltaY * options.rowHeight));\r\n scrollLeft = $viewportScrollContainerX[0].scrollLeft + (deltaX * 10);\r\n var handled = _handleScroll(true);\r\n if (handled) e.preventDefault();\r\n }\r\n\r\n function handleScroll(){\r\n scrollTop = $viewportScrollContainerY[0].scrollTop;\r\n scrollLeft = $viewportScrollContainerX[0].scrollLeft;\r\n return _handleScroll(false);\r\n }\r\n\r\n function _handleScroll(isMouseWheel){\r\n var maxScrollDistanceY = $viewportScrollContainerY[0].scrollHeight - $viewportScrollContainerY[0].clientHeight;\r\n var maxScrollDistanceX = $viewportScrollContainerY[0].scrollWidth - $viewportScrollContainerY[0].clientWidth;\r\n var hasFrozenCols = hasFrozenColumns();\r\n\r\n // Ceiling the max scroll values\r\n if (scrollTop > maxScrollDistanceY){\r\n scrollTop = maxScrollDistanceY;\r\n }\r\n if (scrollLeft > maxScrollDistanceX){\r\n scrollLeft = maxScrollDistanceX;\r\n }\r\n\r\n var vScrollDist = Math.abs(scrollTop - prevScrollTop);\r\n var hScrollDist = Math.abs(scrollLeft - prevScrollLeft);\r\n\r\n if (hScrollDist){\r\n prevScrollLeft = scrollLeft;\r\n\r\n $viewportScrollContainerX[0].scrollLeft = scrollLeft;\r\n $headerScrollContainer[0].scrollLeft = scrollLeft;\r\n $topPanelScroller[0].scrollLeft = scrollLeft;\r\n $headerRowScrollContainer[0].scrollLeft = scrollLeft;\r\n $footerRowScrollContainer[0].scrollLeft = scrollLeft;\r\n\r\n if (hasFrozenCols){\r\n if (hasFrozenRows){\r\n $viewportTopR[0].scrollLeft = scrollLeft;\r\n }\r\n } else {\r\n if (hasFrozenRows){\r\n $viewportTopL[0].scrollLeft = scrollLeft;\r\n }\r\n }\r\n }\r\n\r\n if (vScrollDist){\r\n vScrollDir = prevScrollTop < scrollTop ? 1 : -1;\r\n prevScrollTop = scrollTop;\r\n\r\n if (isMouseWheel){\r\n $viewportScrollContainerY[0].scrollTop = scrollTop;\r\n }\r\n\r\n if (hasFrozenCols){\r\n if (hasFrozenRows && !options.frozenBottom){\r\n $viewportBottomL[0].scrollTop = scrollTop;\r\n } else {\r\n $viewportTopL[0].scrollTop = scrollTop;\r\n }\r\n }\r\n\r\n // switch virtual pages if needed\r\n if (vScrollDist < viewportH){\r\n scrollTo(scrollTop + offset);\r\n } else {\r\n var oldOffset = offset;\r\n if (h == viewportH){\r\n page = 0;\r\n } else {\r\n page = Math.min(n - 1, Math.floor(scrollTop * ((th - viewportH) / (h - viewportH)) * (1 / ph)));\r\n }\r\n offset = Math.round(page * cj);\r\n if (oldOffset != offset){\r\n invalidateAllRows();\r\n }\r\n }\r\n }\r\n\r\n if (hScrollDist || vScrollDist){\r\n if (h_render){\r\n clearTimeout(h_render);\r\n }\r\n\r\n if (Math.abs(lastRenderedScrollTop - scrollTop) > 20 || Math.abs(lastRenderedScrollLeft - scrollLeft) > 20){\r\n if (options.forceSyncScrolling || (\r\n Math.abs(lastRenderedScrollTop - scrollTop) < viewportH && Math.abs(lastRenderedScrollLeft - scrollLeft) < viewportW)){\r\n render();\r\n } else {\r\n h_render = setTimeout(render, 50);\r\n }\r\n\r\n trigger(self.onViewportChanged, {});\r\n }\r\n }\r\n\r\n trigger(self.onScroll, {\r\n scrollLeft: scrollLeft,\r\n scrollTop: scrollTop\r\n });\r\n\r\n if (hScrollDist || vScrollDist) return true;\r\n return false;\r\n }\r\n\r\n function asyncPostProcessRows(){\r\n var dataLength = getDataLength();\r\n while (postProcessFromRow <= postProcessToRow){\r\n var row = (vScrollDir >= 0) ? postProcessFromRow++ : postProcessToRow--;\r\n var cacheEntry = rowsCache[row];\r\n if (!cacheEntry || row >= dataLength){\r\n continue;\r\n }\r\n\r\n if (!postProcessedRows[row]){\r\n postProcessedRows[row] = {};\r\n }\r\n\r\n ensureCellNodesInRowsCache(row);\r\n for (var columnIdx in cacheEntry.cellNodesByColumnIdx){\r\n if (!cacheEntry.cellNodesByColumnIdx.hasOwnProperty(columnIdx)){\r\n continue;\r\n }\r\n\r\n columnIdx = columnIdx | 0;\r\n\r\n var m = columns[columnIdx];\r\n if (m.asyncPostRender && !postProcessedRows[row][columnIdx]){\r\n var node = cacheEntry.cellNodesByColumnIdx[columnIdx];\r\n if (node){\r\n m.asyncPostRender(node, row, getDataItem(row), m);\r\n }\r\n postProcessedRows[row][columnIdx] = true;\r\n }\r\n }\r\n\r\n h_postrender = setTimeout(asyncPostProcessRows, options.asyncPostRenderDelay);\r\n return;\r\n }\r\n }\r\n\r\n function updateCellCssStylesOnRenderedRows(addedHash, removedHash){\r\n var node, columnId, addedRowHash, removedRowHash;\r\n for (var row in rowsCache){\r\n removedRowHash = removedHash && removedHash[row];\r\n addedRowHash = addedHash && addedHash[row];\r\n\r\n if (removedRowHash){\r\n for (columnId in removedRowHash){\r\n if (!addedRowHash || removedRowHash[columnId] != addedRowHash[columnId]){\r\n node = getCellNode(row, getColumnIndex(columnId));\r\n if (node){\r\n $(node).removeClass(removedRowHash[columnId]);\r\n }\r\n }\r\n }\r\n }\r\n\r\n if (addedRowHash){\r\n for (columnId in addedRowHash){\r\n if (!removedRowHash || removedRowHash[columnId] != addedRowHash[columnId]){\r\n node = getCellNode(row, getColumnIndex(columnId));\r\n if (node){\r\n $(node).addClass(addedRowHash[columnId]);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n function addCellCssStyles(key, hash){\r\n if (cellCssClasses[key]){\r\n throw \"addCellCssStyles: cell CSS hash with key '\" + key + \"' already exists.\";\r\n }\r\n\r\n cellCssClasses[key] = hash;\r\n updateCellCssStylesOnRenderedRows(hash, null);\r\n\r\n trigger(self.onCellCssStylesChanged, {\r\n \"key\": key,\r\n \"hash\": hash\r\n });\r\n }\r\n\r\n function removeCellCssStyles(key){\r\n if (!cellCssClasses[key]){\r\n return;\r\n }\r\n\r\n updateCellCssStylesOnRenderedRows(null, cellCssClasses[key]);\r\n delete cellCssClasses[key];\r\n\r\n trigger(self.onCellCssStylesChanged, {\r\n \"key\": key,\r\n \"hash\": null\r\n });\r\n }\r\n\r\n function setCellCssStyles(key, hash){\r\n var prevHash = cellCssClasses[key];\r\n\r\n cellCssClasses[key] = hash;\r\n updateCellCssStylesOnRenderedRows(hash, prevHash);\r\n\r\n trigger(self.onCellCssStylesChanged, {\r\n \"key\": key,\r\n \"hash\": hash\r\n });\r\n }\r\n\r\n function getCellCssStyles(key){\r\n return cellCssClasses[key];\r\n }\r\n\r\n function flashCell(row, cell, speed){\r\n speed = speed || 100;\r\n if (rowsCache[row]){\r\n var $cell = $(getCellNode(row, cell));\r\n\r\n function toggleCellClass(times){\r\n if (!times){\r\n return;\r\n }\r\n setTimeout(function(){\r\n $cell.queue(function(){\r\n $cell.toggleClass(options.cellFlashingCssClass).dequeue();\r\n toggleCellClass(times - 1);\r\n });\r\n },\r\n speed);\r\n }\r\n\r\n toggleCellClass(4);\r\n }\r\n }\r\n\r\n //////////////////////////////////////////////////////////////////////////////////////////////\r\n // Interactivity\r\n\r\n function handleDragInit(e, dd){\r\n var cell = getCellFromEvent(e);\r\n if (!cell || !cellExists(cell.row, cell.cell)){\r\n return false;\r\n }\r\n\r\n var retval = trigger(self.onDragInit, dd, e);\r\n if (e.isImmediatePropagationStopped()){\r\n return retval;\r\n }\r\n\r\n // if nobody claims to be handling drag'n'drop by stopping immediate propagation,\r\n // cancel out of it\r\n return false;\r\n }\r\n\r\n function handleDragStart(interactEvent){\r\n var event = $.Event(interactEvent.originalEvent.type, interactEvent.originalEvent);\r\n var cell = getCellFromEvent(event);\r\n if (!cell || !cellExists(cell.row, cell.cell)){\r\n return false;\r\n }\r\n\r\n var retval = trigger(self.onDragStart, interactEvent, event);\r\n if (event.isImmediatePropagationStopped()){\r\n return retval;\r\n }\r\n\r\n return false;\r\n }\r\n\r\n function handleDrag(interactEvent){\r\n var event = $.Event(interactEvent.originalEvent.type, interactEvent.originalEvent);\r\n return trigger(self.onDrag, interactEvent, event);\r\n }\r\n\r\n function handleDragEnd(interactEvent){\r\n trigger(self.onDragEnd, interactEvent, $.Event('mousedown'));\r\n }\r\n\r\n function handleKeyDown(e){\r\n trigger(self.onKeyDown, {\r\n row: activeRow,\r\n cell: activeCell\r\n }, e);\r\n var handled = e.isImmediatePropagationStopped();\r\n\r\n if (!handled){\r\n if (!e.shiftKey && !e.altKey && !e.ctrlKey){\r\n if (e.which == 27){\r\n if (!getEditorLock().isActive()){\r\n return; // no editing mode to cancel, allow bubbling and default processing (exit without cancelling the event)\r\n }\r\n cancelEditAndSetFocus();\r\n } else if (e.which == 34){\r\n navigatePageDown();\r\n handled = true;\r\n } else if (e.which == 33){\r\n navigatePageUp();\r\n handled = true;\r\n } else if (e.which == 37){\r\n handled = navigateLeft();\r\n } else if (e.which == 39){\r\n handled = navigateRight();\r\n } else if (e.which == 38){\r\n handled = navigateUp();\r\n } else if (e.which == 40){\r\n handled = navigateDown();\r\n } else if (e.which == 9){\r\n handled = navigateNext();\r\n } else if (e.which == 13){\r\n if (options.editable){\r\n if (currentEditor){\r\n // adding new row\r\n if (activeRow === getDataLength()){\r\n navigateDown();\r\n } else {\r\n commitEditAndSetFocus();\r\n }\r\n } else {\r\n if (getEditorLock().commitCurrentEdit()){\r\n makeActiveCellEditable();\r\n }\r\n }\r\n }\r\n handled = true;\r\n }\r\n } else if (e.which == 9 && e.shiftKey && !e.ctrlKey && !e.altKey){\r\n handled = navigatePrev();\r\n }\r\n }\r\n\r\n if (handled){\r\n // the event has been handled so don't let parent element (bubbling/propagation) or browser (default) handle it\r\n e.stopPropagation();\r\n e.preventDefault();\r\n try {\r\n e.originalEvent.keyCode = 0; // prevent default behaviour for special keys in IE browsers (F3, F5, etc.)\r\n }\r\n // ignore exceptions - setting the original event's keycode throws access denied exception for \"Ctrl\"\r\n // (hitting control key only, nothing else), \"Shift\" (maybe others)\r\n catch (error) {\r\n }\r\n }\r\n }\r\n\r\n function handleClick(e){\r\n if (!currentEditor){\r\n // if this click resulted in some cell child node getting focus,\r\n // don't steal it back - keyboard events will still bubble up\r\n // IE9+ seems to default DIVs to tabIndex=0 instead of -1, so check for cell clicks directly.\r\n if (e.target != document.activeElement || $(e.target).hasClass(\"slick-cell\")){\r\n setFocus();\r\n }\r\n }\r\n\r\n var cell = getCellFromEvent(e);\r\n if (!cell || (currentEditor !== null && activeRow == cell.row && activeCell == cell.cell)){\r\n return;\r\n }\r\n\r\n trigger(self.onClick, {\r\n row: cell.row,\r\n cell: cell.cell\r\n }, e);\r\n if (e.isImmediatePropagationStopped()){\r\n return;\r\n }\r\n\r\n if ((activeCell != cell.cell || activeRow != cell.row) && canCellBeActive(cell.row, cell.cell)){\r\n if (!getEditorLock().isActive() || getEditorLock().commitCurrentEdit()){\r\n\r\n scrollRowIntoView(cell.row, false);\r\n setActiveCellInternal(getCellNode(cell.row, cell.cell));\r\n }\r\n }\r\n }\r\n\r\n function handleContextMenu(e){\r\n var $cell = $(e.target).closest(\".slick-cell\", $canvas);\r\n if ($cell.length === 0){\r\n return;\r\n }\r\n\r\n // are we editing this cell?\r\n if (activeCellNode === $cell[0] && currentEditor !== null){\r\n return;\r\n }\r\n\r\n trigger(self.onContextMenu, {}, e);\r\n }\r\n\r\n function handleDblClick(e){\r\n var cell = getCellFromEvent(e);\r\n if (!cell || (currentEditor !== null && activeRow == cell.row && activeCell == cell.cell)){\r\n return;\r\n }\r\n\r\n trigger(self.onDblClick, {\r\n row: cell.row,\r\n cell: cell.cell\r\n }, e);\r\n if (e.isImmediatePropagationStopped()){\r\n return;\r\n }\r\n\r\n if (options.editable){\r\n gotoCell(cell.row, cell.cell, true);\r\n }\r\n }\r\n\r\n function handleHeaderMouseEnter(e){\r\n trigger(self.onHeaderMouseEnter, {\r\n \"column\": $(this).data(\"column\")\r\n }, e);\r\n }\r\n\r\n function handleHeaderMouseLeave(e){\r\n trigger(self.onHeaderMouseLeave, {\r\n \"column\": $(this).data(\"column\")\r\n }, e);\r\n }\r\n\r\n function handleHeaderContextMenu(e){\r\n var $header = $(e.target).closest(\".slick-header-column\", \".slick-header-columns\");\r\n var column = $header && $header.data(\"column\");\r\n trigger(self.onHeaderContextMenu, {\r\n column: column\r\n }, e);\r\n }\r\n\r\n function handleHeaderClick(e){\r\n var $header = $(e.target).closest(\".slick-header-column\", \".slick-header-columns\");\r\n var column = $header && $header.data(\"column\");\r\n if (column){\r\n trigger(self.onHeaderClick, {\r\n column: column\r\n }, e);\r\n }\r\n }\r\n\r\n function handleMouseEnter(e){\r\n trigger(self.onMouseEnter, {}, e);\r\n }\r\n\r\n function handleMouseLeave(e){\r\n trigger(self.onMouseLeave, {}, e);\r\n }\r\n\r\n function cellExists(row, cell){\r\n return !(row < 0 || row >= getDataLength() || cell < 0 || cell >= columns.length);\r\n }\r\n\r\n function getCellFromPoint(x, y){\r\n var row = getRowFromPosition(y);\r\n var cell = 0;\r\n\r\n var w = 0;\r\n for (var i = 0; i < columns.length && w < x; i++){\r\n w += columns[i].width;\r\n cell++;\r\n }\r\n\r\n if (cell < 0){\r\n cell = 0;\r\n }\r\n\r\n return {\r\n row: row,\r\n cell: cell - 1\r\n };\r\n }\r\n\r\n function getCellFromNode(cellNode){\r\n // read column number from .l CSS class\r\n var cls = /l\\d+/.exec(cellNode.className);\r\n if (!cls){\r\n throw \"getCellFromNode: cannot get cell - \" + cellNode.className;\r\n }\r\n return parseInt(cls[0].substr(1, cls[0].length - 1), 10);\r\n }\r\n\r\n function getRowFromNode(rowNode){\r\n for (var row in rowsCache)\r\n for (var i in rowsCache[row].rowNode)\r\n if (rowsCache[row].rowNode[i] === rowNode) return row | 0;\r\n\r\n return null;\r\n }\r\n\r\n function getFrozenRowOffset(row){\r\n var offset = (hasFrozenRows) ? (options.frozenBottom) ? (row >= actualFrozenRow) ? (h < viewportTopH) ? (actualFrozenRow * options.rowHeight) : h : 0 : (row >= actualFrozenRow) ? frozenRowsHeight : 0 : 0;\r\n\r\n return offset;\r\n }\r\n\r\n function getCellFromEvent(e){\r\n var row, cell;\r\n var $cell = $(e.target).closest(\".slick-cell\", $canvas);\r\n if (!$cell.length){\r\n return null;\r\n }\r\n\r\n row = getRowFromNode($cell[0].parentNode);\r\n\r\n if (hasFrozenRows){\r\n\r\n var c = $cell.parents('.grid-canvas').offset();\r\n\r\n var rowOffset = 0;\r\n var isBottom = $cell.parents('.grid-canvas-bottom').length;\r\n\r\n if (isBottom){\r\n rowOffset = (options.frozenBottom) ? $canvasTopL.height() : frozenRowsHeight;\r\n }\r\n\r\n row = getCellFromPoint(e.clientX - c.left, e.clientY - c.top + rowOffset + $(document).scrollTop()).row;\r\n }\r\n\r\n cell = getCellFromNode($cell[0]);\r\n\r\n if (row == null || cell == null){\r\n return null;\r\n } else {\r\n return {\r\n \"row\": row,\r\n \"cell\": cell\r\n };\r\n }\r\n }\r\n\r\n function getCellNodeBox(row, cell){\r\n if (!cellExists(row, cell)){\r\n return null;\r\n }\r\n\r\n var frozenRowOffset = getFrozenRowOffset(row);\r\n\r\n var y1 = getRowTop(row) - frozenRowOffset;\r\n var y2 = y1 + options.rowHeight - 1;\r\n var x1 = 0;\r\n for (var i = 0; i < cell; i++){\r\n x1 += columns[i].width;\r\n\r\n if (options.frozenColumn == i){\r\n x1 = 0;\r\n }\r\n }\r\n var x2 = x1 + columns[cell].width;\r\n\r\n return {\r\n top: y1,\r\n left: x1,\r\n bottom: y2,\r\n right: x2\r\n };\r\n }\r\n\r\n //////////////////////////////////////////////////////////////////////////////////////////////\r\n // Cell switching\r\n\r\n function resetActiveCell(){\r\n setActiveCellInternal(null, false);\r\n }\r\n\r\n function setFocus(){\r\n if (tabbingDirection == -1){\r\n $focusSink[0].focus();\r\n } else {\r\n $focusSink2[0].focus();\r\n }\r\n }\r\n\r\n function scrollCellIntoView(row, cell, doPaging){\r\n // Don't scroll to frozen cells\r\n if (cell <= options.frozenColumn){\r\n return;\r\n }\r\n\r\n if (row < actualFrozenRow){\r\n scrollRowIntoView(row, doPaging);\r\n }\r\n\r\n var colspan = getColspan(row, cell);\r\n var left = columnPosLeft[cell],\r\n right = columnPosRight[cell + (colspan > 1 ? colspan - 1 : 0)],\r\n scrollRight = scrollLeft + $viewportScrollContainerX.width();\r\n\r\n if (left < scrollLeft){\r\n $viewportScrollContainerX.scrollLeft(left);\r\n handleScroll();\r\n render();\r\n } else if (right > scrollRight){\r\n $viewportScrollContainerX.scrollLeft(Math.min(left, right - $viewportScrollContainerX[0].clientWidth));\r\n handleScroll();\r\n render();\r\n }\r\n }\r\n\r\n function setActiveCellInternal(newCell, opt_editMode){\r\n if (activeCellNode !== null){\r\n makeActiveCellNormal();\r\n $(activeCellNode).removeClass(\"active\");\r\n if (rowsCache[activeRow]){\r\n $(rowsCache[activeRow].rowNode).removeClass(\"active\");\r\n }\r\n }\r\n\r\n var activeCellChanged = (activeCellNode !== newCell);\r\n activeCellNode = newCell;\r\n\r\n if (activeCellNode != null){\r\n var $activeCellNode = $(activeCellNode);\r\n var $activeCellOffset = $activeCellNode.offset();\r\n\r\n var rowOffset = Math.floor($activeCellNode.parents('.grid-canvas').offset().top);\r\n var isBottom = $activeCellNode.parents('.grid-canvas-bottom').length;\r\n\r\n if (hasFrozenRows && isBottom){\r\n rowOffset -= (options.frozenBottom) ? $canvasTopL.height() : frozenRowsHeight;\r\n }\r\n\r\n var cell = getCellFromPoint($activeCellOffset.left, Math.ceil($activeCellOffset.top) - rowOffset);\r\n\r\n activeRow = cell.row;\r\n activeCell = activePosX = activeCell = activePosX = getCellFromNode(activeCellNode[0]);\r\n\r\n $activeCellNode.addClass(\"active\");\r\n if (rowsCache[activeRow]){\r\n $(rowsCache[activeRow].rowNode).addClass('active');\r\n }\r\n\r\n if (opt_editMode == null){\r\n opt_editMode = (activeRow == getDataLength()) || options.autoEdit;\r\n }\r\n\r\n if (options.editable && opt_editMode && isCellPotentiallyEditable(activeRow, activeCell)){\r\n clearTimeout(h_editorLoader);\r\n\r\n if (options.asyncEditorLoading){\r\n h_editorLoader = setTimeout(function(){\r\n makeActiveCellEditable();\r\n }, options.asyncEditorLoadDelay);\r\n } else {\r\n makeActiveCellEditable();\r\n }\r\n }\r\n } else {\r\n activeRow = activeCell = null;\r\n }\r\n\r\n if (activeCellChanged){\r\n setTimeout(scrollActiveCellIntoView, 50);\r\n trigger(self.onActiveCellChanged, getActiveCell());\r\n }\r\n }\r\n\r\n function clearTextSelection(){\r\n if (document.selection && document.selection.empty){\r\n try {\r\n //IE fails here if selected element is not in dom\r\n document.selection.empty();\r\n } catch (e) {\r\n }\r\n } else if (window.getSelection){\r\n var sel = window.getSelection();\r\n if (sel && sel.removeAllRanges){\r\n sel.removeAllRanges();\r\n }\r\n }\r\n }\r\n\r\n function isCellPotentiallyEditable(row, cell){\r\n var dataLength = getDataLength();\r\n // is the data for this row loaded?\r\n if (row < dataLength && !getDataItem(row)){\r\n return false;\r\n }\r\n\r\n // are we in the Add New row? can we create new from this cell?\r\n if (columns[cell].cannotTriggerInsert && row >= dataLength){\r\n return false;\r\n }\r\n\r\n // does this cell have an editor?\r\n if (!getEditor(row, cell)){\r\n return false;\r\n }\r\n\r\n return true;\r\n }\r\n\r\n function makeActiveCellNormal(){\r\n if (!currentEditor){\r\n return;\r\n }\r\n trigger(self.onBeforeCellEditorDestroy, {\r\n editor: currentEditor\r\n });\r\n currentEditor.destroy();\r\n currentEditor = null;\r\n\r\n if (activeCellNode){\r\n var d = getDataItem(activeRow);\r\n $(activeCellNode).removeClass(\"editable invalid\");\r\n if (d){\r\n var column = columns[activeCell];\r\n activeCellNode[0].innerHTML = callFormatter(activeRow, activeCell, getDataItemValueForColumn(d, column), column, d);\r\n invalidatePostProcessingResults(activeRow);\r\n }\r\n }\r\n\r\n // if there previously was text selected on a page (such as selected text in the edit cell just removed),\r\n // IE can't set focus to anything else correctly\r\n if (navigator.userAgent.toLowerCase().match(/msie/)){\r\n clearTextSelection();\r\n }\r\n\r\n getEditorLock().deactivate(editController);\r\n }\r\n\r\n function makeActiveCellEditable(editor){\r\n if (!activeCellNode){\r\n return;\r\n }\r\n if (!options.editable){\r\n throw \"Grid : makeActiveCellEditable : should never get called when options.editable is false\";\r\n }\r\n\r\n // cancel pending async call if there is one\r\n clearTimeout(h_editorLoader);\r\n\r\n if (!isCellPotentiallyEditable(activeRow, activeCell)){\r\n return;\r\n }\r\n\r\n var columnDef = columns[activeCell];\r\n var item = getDataItem(activeRow);\r\n\r\n if (trigger(self.onBeforeEditCell, {\r\n row: activeRow,\r\n cell: activeCell,\r\n item: item,\r\n column: columnDef\r\n }) === false){\r\n setFocus();\r\n return;\r\n }\r\n\r\n getEditorLock().activate(editController);\r\n $(activeCellNode).addClass(\"editable\");\r\n\r\n // don't clear the cell if a custom editor is passed through\r\n if (!editor){\r\n activeCellNode[0].innerHTML = \"\";\r\n }\r\n\r\n currentEditor = new (editor || getEditor(activeRow, activeCell))({\r\n grid: self,\r\n gridPosition: absBox($container[0]),\r\n position: absBox(activeCellNode[0]),\r\n container: activeCellNode,\r\n column: columnDef,\r\n item: item || {},\r\n commitChanges: commitEditAndSetFocus,\r\n cancelChanges: cancelEditAndSetFocus\r\n });\r\n\r\n if (item){\r\n currentEditor.loadValue(item);\r\n }\r\n\r\n serializedEditorValue = currentEditor.serializeValue();\r\n\r\n if (currentEditor.position){\r\n handleActiveCellPositionChange();\r\n }\r\n }\r\n\r\n function commitEditAndSetFocus(){\r\n // if the commit fails, it would do so due to a validation error\r\n // if so, do not steal the focus from the editor\r\n if (getEditorLock().commitCurrentEdit()){\r\n setFocus();\r\n if (options.autoEdit){\r\n navigateDown();\r\n }\r\n }\r\n }\r\n\r\n function cancelEditAndSetFocus(){\r\n if (getEditorLock().cancelCurrentEdit()){\r\n setFocus();\r\n }\r\n }\r\n\r\n function absBox(elem){\r\n var box = {\r\n top: elem.offsetTop,\r\n left: elem.offsetLeft,\r\n bottom: 0,\r\n right: 0,\r\n width: $(elem).outerWidth(),\r\n height: $(elem).outerHeight(),\r\n visible: true\r\n };\r\n box.bottom = box.top + box.height;\r\n box.right = box.left + box.width;\r\n\r\n // walk up the tree\r\n var offsetParent = elem.offsetParent;\r\n while ((elem = elem.parentNode) != document.body){\r\n if (box.visible && elem.scrollHeight != elem.offsetHeight && $(elem).css(\"overflowY\") != \"visible\"){\r\n box.visible = box.bottom > elem.scrollTop && box.top < elem.scrollTop + elem.clientHeight;\r\n }\r\n\r\n if (box.visible && elem.scrollWidth != elem.offsetWidth && $(elem).css(\"overflowX\") != \"visible\"){\r\n box.visible = box.right > elem.scrollLeft && box.left < elem.scrollLeft + elem.clientWidth;\r\n }\r\n\r\n box.left -= elem.scrollLeft;\r\n box.top -= elem.scrollTop;\r\n\r\n if (elem === offsetParent){\r\n box.left += elem.offsetLeft;\r\n box.top += elem.offsetTop;\r\n offsetParent = elem.offsetParent;\r\n }\r\n\r\n box.bottom = box.top + box.height;\r\n box.right = box.left + box.width;\r\n }\r\n\r\n return box;\r\n }\r\n\r\n function getActiveCellPosition(){\r\n return absBox(activeCellNode[0]);\r\n }\r\n\r\n function getGridPosition(){\r\n return absBox($container[0])\r\n }\r\n\r\n function handleActiveCellPositionChange(){\r\n if (!activeCellNode){\r\n return;\r\n }\r\n\r\n trigger(self.onActiveCellPositionChanged, {});\r\n\r\n if (currentEditor){\r\n var cellBox = getActiveCellPosition();\r\n if (currentEditor.show && currentEditor.hide){\r\n if (!cellBox.visible){\r\n currentEditor.hide();\r\n } else {\r\n currentEditor.show();\r\n }\r\n }\r\n\r\n if (currentEditor.position){\r\n currentEditor.position(cellBox);\r\n }\r\n }\r\n }\r\n\r\n function getCellEditor(){\r\n return currentEditor;\r\n }\r\n\r\n function getActiveCell(){\r\n if (!activeCellNode){\r\n return null;\r\n } else {\r\n return {\r\n row: activeRow,\r\n cell: activeCell\r\n };\r\n }\r\n }\r\n\r\n function getActiveCellNode(){\r\n return activeCellNode;\r\n }\r\n\r\n function scrollActiveCellIntoView(){\r\n if (activeRow != null && activeCell != null){\r\n scrollCellIntoView(activeRow, activeCell);\r\n }\r\n }\r\n\r\n function scrollRowIntoView(row, doPaging){\r\n\r\n if (!hasFrozenRows || (!options.frozenBottom && row > actualFrozenRow - 1) || (options.frozenBottom && row < actualFrozenRow - 1)){\r\n\r\n var viewportScrollH = $viewportScrollContainerY.height();\r\n\r\n var rowAtTop = row * options.rowHeight;\r\n var rowAtBottom = (row + 1) * options.rowHeight - viewportScrollH + (viewportHasHScroll ? scrollbarDimensions.height : 0);\r\n\r\n // need to page down?\r\n if ((row + 1) * options.rowHeight > scrollTop + viewportScrollH + offset){\r\n scrollTo(doPaging ? rowAtTop : rowAtBottom);\r\n render();\r\n }\r\n // or page up?\r\n else if (row * options.rowHeight < scrollTop + offset){\r\n scrollTo(doPaging ? rowAtBottom : rowAtTop);\r\n render();\r\n }\r\n }\r\n }\r\n\r\n function scrollRowToTop(row){\r\n scrollTo(row * options.rowHeight);\r\n render();\r\n }\r\n\r\n function scrollPage(dir){\r\n var deltaRows = dir * numVisibleRows;\r\n scrollTo((getRowFromPosition(scrollTop) + deltaRows) * options.rowHeight);\r\n render();\r\n\r\n if (options.enableCellNavigation && activeRow != null){\r\n var row = activeRow + deltaRows;\r\n var dataLengthIncludingAddNew = getDataLengthIncludingAddNew();\r\n if (row >= dataLengthIncludingAddNew){\r\n row = dataLengthIncludingAddNew - 1;\r\n }\r\n if (row < 0){\r\n row = 0;\r\n }\r\n\r\n var cell = 0,\r\n prevCell = null;\r\n var prevActivePosX = activePosX;\r\n while (cell <= activePosX){\r\n if (canCellBeActive(row, cell)){\r\n prevCell = cell;\r\n }\r\n cell += getColspan(row, cell);\r\n }\r\n\r\n if (prevCell !== null){\r\n setActiveCellInternal(getCellNode(row, prevCell));\r\n activePosX = prevActivePosX;\r\n } else {\r\n resetActiveCell();\r\n }\r\n }\r\n }\r\n\r\n function navigatePageDown(){\r\n scrollPage(1);\r\n }\r\n\r\n function navigatePageUp(){\r\n scrollPage(-1);\r\n }\r\n\r\n function getColspan(row, cell){\r\n var metadata = data.getItemMetadata && data.getItemMetadata(row);\r\n if (!metadata || !metadata.columns){\r\n return 1;\r\n }\r\n\r\n var columnData = columns[cell] && (metadata.columns[columns[cell].id] || metadata.columns[cell]);\r\n var colspan = (columnData && columnData.colspan);\r\n if (colspan === \"*\"){\r\n colspan = columns.length - cell;\r\n } else {\r\n colspan = colspan || 1;\r\n }\r\n\r\n return colspan;\r\n }\r\n\r\n function findFirstFocusableCell(row){\r\n var cell = 0;\r\n while (cell < columns.length){\r\n if (canCellBeActive(row, cell)){\r\n return cell;\r\n }\r\n cell += getColspan(row, cell);\r\n }\r\n return null;\r\n }\r\n\r\n function findLastFocusableCell(row){\r\n var cell = 0;\r\n var lastFocusableCell = null;\r\n while (cell < columns.length){\r\n if (canCellBeActive(row, cell)){\r\n lastFocusableCell = cell;\r\n }\r\n cell += getColspan(row, cell);\r\n }\r\n return lastFocusableCell;\r\n }\r\n\r\n function gotoRight(row, cell, posX){\r\n if (cell >= columns.length){\r\n return null;\r\n }\r\n\r\n do {\r\n cell += getColspan(row, cell);\r\n }\r\n while (cell < columns.length && !canCellBeActive(row, cell));\r\n\r\n if (cell < columns.length){\r\n return {\r\n \"row\": row,\r\n \"cell\": cell,\r\n \"posX\": cell\r\n };\r\n }\r\n return null;\r\n }\r\n\r\n function gotoLeft(row, cell, posX){\r\n if (cell <= 0){\r\n return null;\r\n }\r\n\r\n var firstFocusableCell = findFirstFocusableCell(row);\r\n if (firstFocusableCell === null || firstFocusableCell >= cell){\r\n return null;\r\n }\r\n\r\n var prev = {\r\n \"row\": row,\r\n \"cell\": firstFocusableCell,\r\n \"posX\": firstFocusableCell\r\n };\r\n var pos;\r\n while (true){\r\n pos = gotoRight(prev.row, prev.cell, prev.posX);\r\n if (!pos){\r\n return null;\r\n }\r\n if (pos.cell >= cell){\r\n return prev;\r\n }\r\n prev = pos;\r\n }\r\n }\r\n\r\n function gotoDown(row, cell, posX){\r\n var prevCell;\r\n var dataLengthIncludingAddNew = getDataLengthIncludingAddNew();\r\n while (true){\r\n if (++row >= dataLengthIncludingAddNew){\r\n return null;\r\n }\r\n\r\n prevCell = cell = 0;\r\n while (cell <= posX){\r\n prevCell = cell;\r\n cell += getColspan(row, cell);\r\n }\r\n\r\n if (canCellBeActive(row, prevCell)){\r\n return {\r\n \"row\": row,\r\n \"cell\": prevCell,\r\n \"posX\": posX\r\n };\r\n }\r\n }\r\n }\r\n\r\n function gotoUp(row, cell, posX){\r\n var prevCell;\r\n while (true){\r\n if (--row < 0){\r\n return null;\r\n }\r\n\r\n prevCell = cell = 0;\r\n while (cell <= posX){\r\n prevCell = cell;\r\n cell += getColspan(row, cell);\r\n }\r\n\r\n if (canCellBeActive(row, prevCell)){\r\n return {\r\n \"row\": row,\r\n \"cell\": prevCell,\r\n \"posX\": posX\r\n };\r\n }\r\n }\r\n }\r\n\r\n function gotoNext(row, cell, posX){\r\n if (row == null && cell == null){\r\n row = cell = posX = 0;\r\n if (canCellBeActive(row, cell)){\r\n return {\r\n \"row\": row,\r\n \"cell\": cell,\r\n \"posX\": cell\r\n };\r\n }\r\n }\r\n\r\n var pos = gotoRight(row, cell, posX);\r\n if (pos){\r\n return pos;\r\n }\r\n\r\n var firstFocusableCell = null;\r\n var dataLengthIncludingAddNew = getDataLengthIncludingAddNew();\r\n while (++row < dataLengthIncludingAddNew){\r\n firstFocusableCell = findFirstFocusableCell(row);\r\n if (firstFocusableCell !== null){\r\n return {\r\n \"row\": row,\r\n \"cell\": firstFocusableCell,\r\n \"posX\": firstFocusableCell\r\n };\r\n }\r\n }\r\n return null;\r\n }\r\n\r\n function gotoPrev(row, cell, posX){\r\n if (row == null && cell == null){\r\n row = getDataLengthIncludingAddNew() - 1;\r\n cell = posX = columns.length - 1;\r\n if (canCellBeActive(row, cell)){\r\n return {\r\n \"row\": row,\r\n \"cell\": cell,\r\n \"posX\": cell\r\n };\r\n }\r\n }\r\n\r\n var pos;\r\n var lastSelectableCell;\r\n while (!pos){\r\n pos = gotoLeft(row, cell, posX);\r\n if (pos){\r\n break;\r\n }\r\n if (--row < 0){\r\n return null;\r\n }\r\n\r\n cell = 0;\r\n lastSelectableCell = findLastFocusableCell(row);\r\n if (lastSelectableCell !== null){\r\n pos = {\r\n \"row\": row,\r\n \"cell\": lastSelectableCell,\r\n \"posX\": lastSelectableCell\r\n };\r\n }\r\n }\r\n return pos;\r\n }\r\n\r\n function navigateRight(){\r\n return navigate(\"right\");\r\n }\r\n\r\n function navigateLeft(){\r\n return navigate(\"left\");\r\n }\r\n\r\n function navigateDown(){\r\n return navigate(\"down\");\r\n }\r\n\r\n function navigateUp(){\r\n return navigate(\"up\");\r\n }\r\n\r\n function navigateNext(){\r\n return navigate(\"next\");\r\n }\r\n\r\n function navigatePrev(){\r\n return navigate(\"prev\");\r\n }\r\n\r\n /**\r\n * @param {string} dir Navigation direction.\r\n * @return {boolean} Whether navigation resulted in a change of active cell.\r\n */\r\n function navigate(dir){\r\n if (!options.enableCellNavigation){\r\n return false;\r\n }\r\n\r\n if (!activeCellNode && dir != \"prev\" && dir != \"next\"){\r\n return false;\r\n }\r\n\r\n if (!getEditorLock().commitCurrentEdit()){\r\n return true;\r\n }\r\n setFocus();\r\n\r\n var tabbingDirections = {\r\n \"up\": -1,\r\n \"down\": 1,\r\n \"left\": -1,\r\n \"right\": 1,\r\n \"prev\": -1,\r\n \"next\": 1\r\n };\r\n tabbingDirection = tabbingDirections[dir];\r\n\r\n var stepFunctions = {\r\n \"up\": gotoUp,\r\n \"down\": gotoDown,\r\n \"left\": gotoLeft,\r\n \"right\": gotoRight,\r\n \"prev\": gotoPrev,\r\n \"next\": gotoNext\r\n };\r\n var stepFn = stepFunctions[dir];\r\n var pos = stepFn(activeRow, activeCell, activePosX);\r\n if (pos){\r\n if (hasFrozenRows && options.frozenBottom & pos.row == getDataLength()){\r\n return;\r\n }\r\n\r\n var isAddNewRow = (pos.row == getDataLength());\r\n\r\n if ((!options.frozenBottom && pos.row >= actualFrozenRow) || (options.frozenBottom && pos.row < actualFrozenRow)){\r\n scrollCellIntoView(pos.row, pos.cell, !isAddNewRow);\r\n }\r\n\r\n setActiveCellInternal(getCellNode(pos.row, pos.cell))\r\n activePosX = pos.posX;\r\n return true;\r\n } else {\r\n setActiveCellInternal(getCellNode(activeRow, activeCell));\r\n return false;\r\n }\r\n }\r\n\r\n function getCellNode(row, cell){\r\n if (rowsCache[row]){\r\n ensureCellNodesInRowsCache(row);\r\n return rowsCache[row].cellNodesByColumnIdx[cell];\r\n }\r\n return null;\r\n }\r\n\r\n function setActiveCell(row, cell){\r\n if (!initialized){\r\n return;\r\n }\r\n if (row > getDataLength() || row < 0 || cell >= columns.length || cell < 0){\r\n return;\r\n }\r\n\r\n if (!options.enableCellNavigation){\r\n return;\r\n }\r\n\r\n scrollCellIntoView(row, cell, false);\r\n setActiveCellInternal(getCellNode(row, cell), false);\r\n }\r\n\r\n function canCellBeActive(row, cell){\r\n if (!options.enableCellNavigation || row >= getDataLengthIncludingAddNew() || row < 0 || cell >= columns.length || cell < 0){\r\n return false;\r\n }\r\n\r\n var rowMetadata = data.getItemMetadata && data.getItemMetadata(row);\r\n if (rowMetadata && typeof rowMetadata.focusable === \"boolean\"){\r\n return rowMetadata.focusable;\r\n }\r\n\r\n var columnMetadata = rowMetadata && rowMetadata.columns;\r\n if (columnMetadata && columns[cell] && columnMetadata[columns[cell].id] && typeof columnMetadata[columns[cell].id].focusable === \"boolean\"){\r\n return columnMetadata[columns[cell].id].focusable;\r\n }\r\n if (columnMetadata && columnMetadata[cell] && typeof columnMetadata[cell].focusable === \"boolean\"){\r\n return columnMetadata[cell].focusable;\r\n }\r\n\r\n return columns[cell] && columns[cell].focusable;\r\n }\r\n\r\n function canCellBeSelected(row, cell){\r\n if (row >= getDataLength() || row < 0 || cell >= columns.length || cell < 0){\r\n return false;\r\n }\r\n\r\n var rowMetadata = data.getItemMetadata && data.getItemMetadata(row);\r\n if (rowMetadata && typeof rowMetadata.selectable === \"boolean\"){\r\n return rowMetadata.selectable;\r\n }\r\n\r\n var columnMetadata = rowMetadata && rowMetadata.columns && (rowMetadata.columns[columns[cell].id] || rowMetadata.columns[cell]);\r\n if (columnMetadata && typeof columnMetadata.selectable === \"boolean\"){\r\n return columnMetadata.selectable;\r\n }\r\n\r\n return columns[cell].selectable;\r\n }\r\n\r\n function gotoCell(row, cell, forceEdit){\r\n if (!initialized){\r\n return;\r\n }\r\n if (!canCellBeActive(row, cell)){\r\n return;\r\n }\r\n\r\n if (!getEditorLock().commitCurrentEdit()){\r\n return;\r\n }\r\n\r\n scrollCellIntoView(row, cell, false);\r\n\r\n var newCell = getCellNode(row, cell);\r\n\r\n // if selecting the 'add new' row, start editing right away\r\n setActiveCellInternal(newCell, forceEdit || (row === getDataLength()) || options.autoEdit);\r\n\r\n // if no editor was created, set the focus back on the grid\r\n if (!currentEditor){\r\n setFocus();\r\n }\r\n }\r\n\r\n //////////////////////////////////////////////////////////////////////////////////////////////\r\n // IEditor implementation for the editor lock\r\n\r\n function commitCurrentEdit(){\r\n var item = getDataItem(activeRow);\r\n var column = columns[activeCell];\r\n\r\n if (currentEditor){\r\n if (currentEditor.isValueChanged()){\r\n var validationResults = currentEditor.validate();\r\n\r\n if (validationResults.valid){\r\n if (activeRow < getDataLength()){\r\n var editCommand = {\r\n row: activeRow,\r\n cell: activeCell,\r\n editor: currentEditor,\r\n serializedValue: currentEditor.serializeValue(),\r\n prevSerializedValue: serializedEditorValue,\r\n execute: function(){\r\n this.editor.applyValue(item, this.serializedValue);\r\n updateRow(this.row);\r\n trigger(self.onCellChange, {\r\n row: activeRow,\r\n cell: activeCell,\r\n item: item\r\n });\r\n },\r\n undo: function(){\r\n this.editor.applyValue(item, this.prevSerializedValue);\r\n updateRow(this.row);\r\n trigger(self.onCellChange, {\r\n row: activeRow,\r\n cell: activeCell,\r\n item: item\r\n });\r\n }\r\n };\r\n\r\n if (options.editCommandHandler){\r\n makeActiveCellNormal();\r\n options.editCommandHandler(item, column, editCommand);\r\n } else {\r\n editCommand.execute();\r\n makeActiveCellNormal();\r\n }\r\n\r\n } else {\r\n var newItem = {};\r\n currentEditor.applyValue(newItem, currentEditor.serializeValue());\r\n makeActiveCellNormal();\r\n trigger(self.onAddNewRow, {\r\n item: newItem,\r\n column: column\r\n });\r\n }\r\n\r\n // check whether the lock has been re-acquired by event handlers\r\n return !getEditorLock().isActive();\r\n } else {\r\n // Re-add the CSS class to trigger transitions, if any.\r\n $(activeCellNode).removeClass(\"invalid\");\r\n $(activeCellNode).width(); // force layout\r\n $(activeCellNode).addClass(\"invalid\");\r\n\r\n trigger(self.onValidationError, {\r\n editor: currentEditor,\r\n cellNode: activeCellNode,\r\n validationResults: validationResults,\r\n row: activeRow,\r\n cell: activeCell,\r\n column: column\r\n });\r\n\r\n currentEditor.focus();\r\n return false;\r\n }\r\n }\r\n\r\n makeActiveCellNormal();\r\n }\r\n return true;\r\n }\r\n\r\n function cancelCurrentEdit(){\r\n makeActiveCellNormal();\r\n return true;\r\n }\r\n\r\n function rowsToRanges(rows){\r\n var ranges = [];\r\n var lastCell = columns.length - 1;\r\n for (var i = 0; i < rows.length; i++){\r\n ranges.push(new Slick.Range(rows[i], 0, rows[i], lastCell));\r\n }\r\n return ranges;\r\n }\r\n\r\n function getSelectedRows(){\r\n if (!selectionModel){\r\n throw \"Selection model is not set\";\r\n }\r\n return selectedRows;\r\n }\r\n\r\n function setSelectedRows(rows){\r\n if (!selectionModel){\r\n throw \"Selection model is not set\";\r\n }\r\n selectionModel.setSelectedRanges(rowsToRanges(rows));\r\n }\r\n\r\n //////////////////////////////////////////////////////////////////////////////////////////////\r\n // Debug\r\n\r\n this.debug = function(){\r\n var s = \"\";\r\n\r\n s += (\"\\n\" + \"counter_rows_rendered: \" + counter_rows_rendered);\r\n s += (\"\\n\" + \"counter_rows_removed: \" + counter_rows_removed);\r\n s += (\"\\n\" + \"renderedRows: \" + renderedRows);\r\n s += (\"\\n\" + \"numVisibleRows: \" + numVisibleRows);\r\n s += (\"\\n\" + \"maxSupportedCssHeight: \" + maxSupportedCssHeight);\r\n s += (\"\\n\" + \"n(umber of pages): \" + n);\r\n s += (\"\\n\" + \"(current) page: \" + page);\r\n s += (\"\\n\" + \"page height (ph): \" + ph);\r\n s += (\"\\n\" + \"vScrollDir: \" + vScrollDir);\r\n\r\n alert(s);\r\n };\r\n\r\n // a debug helper to be able to access private members\r\n this.eval = function(expr){\r\n return eval(expr);\r\n };\r\n\r\n //////////////////////////////////////////////////////////////////////////////////////////////\r\n // Public API\r\n\r\n $.extend(this, {\r\n \"slickGridVersion\": \"2.1\",\r\n\r\n // Events\r\n \"onScroll\": new Slick.Event(),\r\n \"onSort\": new Slick.Event(),\r\n \"onHeaderMouseEnter\": new Slick.Event(),\r\n \"onHeaderMouseLeave\": new Slick.Event(),\r\n \"onHeaderContextMenu\": new Slick.Event(),\r\n \"onHeaderClick\": new Slick.Event(),\r\n \"onHeaderCellRendered\": new Slick.Event(),\r\n \"onBeforeHeaderCellDestroy\": new Slick.Event(),\r\n \"onHeaderRowCellRendered\": new Slick.Event(),\r\n \"onFooterRowCellRendered\": new Slick.Event(),\r\n \"onBeforeHeaderRowCellDestroy\": new Slick.Event(),\r\n \"onBeforeFooterRowCellDestroy\": new Slick.Event(),\r\n \"onMouseEnter\": new Slick.Event(),\r\n \"onMouseLeave\": new Slick.Event(),\r\n \"onClick\": new Slick.Event(),\r\n \"onDblClick\": new Slick.Event(),\r\n \"onContextMenu\": new Slick.Event(),\r\n \"onKeyDown\": new Slick.Event(),\r\n \"onAddNewRow\": new Slick.Event(),\r\n \"onValidationError\": new Slick.Event(),\r\n \"onViewportChanged\": new Slick.Event(),\r\n \"onColumnsReordered\": new Slick.Event(),\r\n \"onColumnsResized\": new Slick.Event(),\r\n \"onCellChange\": new Slick.Event(),\r\n \"onBeforeEditCell\": new Slick.Event(),\r\n \"onBeforeCellEditorDestroy\": new Slick.Event(),\r\n \"onBeforeDestroy\": new Slick.Event(),\r\n \"onActiveCellChanged\": new Slick.Event(),\r\n \"onActiveCellPositionChanged\": new Slick.Event(),\r\n \"onDragInit\": new Slick.Event(),\r\n \"onDragStart\": new Slick.Event(),\r\n \"onDrag\": new Slick.Event(),\r\n \"onDragEnd\": new Slick.Event(),\r\n \"onSelectedRowsChanged\": new Slick.Event(),\r\n \"onCellCssStylesChanged\": new Slick.Event(),\r\n\r\n // Methods\r\n \"registerPlugin\": registerPlugin,\r\n \"unregisterPlugin\": unregisterPlugin,\r\n \"getColumns\": getColumns,\r\n \"setColumns\": setColumns,\r\n \"getColumnIndex\": getColumnIndex,\r\n \"updateColumnHeader\": updateColumnHeader,\r\n \"setSortColumn\": setSortColumn,\r\n \"setSortColumns\": setSortColumns,\r\n \"getSortColumns\": getSortColumns,\r\n \"autosizeColumns\": autosizeColumns,\r\n \"getOptions\": getOptions,\r\n \"setOptions\": setOptions,\r\n \"getData\": getData,\r\n \"getDataLength\": getDataLength,\r\n \"getDataItem\": getDataItem,\r\n \"setData\": setData,\r\n \"getSelectionModel\": getSelectionModel,\r\n \"setSelectionModel\": setSelectionModel,\r\n \"getSelectedRows\": getSelectedRows,\r\n \"setSelectedRows\": setSelectedRows,\r\n \"getContainerNode\": getContainerNode,\r\n\r\n \"render\": render,\r\n \"invalidate\": invalidate,\r\n \"invalidateRow\": invalidateRow,\r\n \"invalidateRows\": invalidateRows,\r\n \"invalidateAllRows\": invalidateAllRows,\r\n \"updateCell\": updateCell,\r\n \"updateRow\": updateRow,\r\n \"getViewport\": getVisibleRange,\r\n \"getRenderedRange\": getRenderedRange,\r\n \"resizeCanvas\": resizeCanvas,\r\n \"updateRowCount\": updateRowCount,\r\n \"scrollRowIntoView\": scrollRowIntoView,\r\n \"scrollRowToTop\": scrollRowToTop,\r\n \"scrollCellIntoView\": scrollCellIntoView,\r\n \"getCanvasNode\": getCanvasNode,\r\n \"getCanvases\": getCanvases,\r\n \"getActiveCanvasNode\": getActiveCanvasNode,\r\n \"setActiveCanvasNode\": setActiveCanvasNode,\r\n \"getViewportNode\": getViewportNode,\r\n \"getActiveViewportNode\": getActiveViewportNode,\r\n \"setActiveViewportNode\": setActiveViewportNode,\r\n \"focus\": setFocus,\r\n\r\n \"getCellFromPoint\": getCellFromPoint,\r\n \"getCellFromEvent\": getCellFromEvent,\r\n \"getActiveCell\": getActiveCell,\r\n \"setActiveCell\": setActiveCell,\r\n \"getActiveCellNode\": getActiveCellNode,\r\n \"getActiveCellPosition\": getActiveCellPosition,\r\n \"resetActiveCell\": resetActiveCell,\r\n \"editActiveCell\": makeActiveCellEditable,\r\n \"getCellEditor\": getCellEditor,\r\n \"getCellNode\": getCellNode,\r\n \"getCellNodeBox\": getCellNodeBox,\r\n \"canCellBeSelected\": canCellBeSelected,\r\n \"canCellBeActive\": canCellBeActive,\r\n \"navigatePrev\": navigatePrev,\r\n \"navigateNext\": navigateNext,\r\n \"navigateUp\": navigateUp,\r\n \"navigateDown\": navigateDown,\r\n \"navigateLeft\": navigateLeft,\r\n \"navigateRight\": navigateRight,\r\n \"navigatePageUp\": navigatePageUp,\r\n \"navigatePageDown\": navigatePageDown,\r\n \"gotoCell\": gotoCell,\r\n \"getTopPanel\": getTopPanel,\r\n \"setTopPanelVisibility\": setTopPanelVisibility,\r\n \"setHeaderRowVisibility\": setHeaderRowVisibility,\r\n \"getHeaderRow\": getHeaderRow,\r\n \"getHeaderRowColumn\": getHeaderRowColumn,\r\n \"setFooterRowVisibility\": setFooterRowVisibility,\r\n \"getFooterRow\": getFooterRow,\r\n \"getFooterRowColumn\": getFooterRowColumn,\r\n \"getGridPosition\": getGridPosition,\r\n \"flashCell\": flashCell,\r\n \"addCellCssStyles\": addCellCssStyles,\r\n \"setCellCssStyles\": setCellCssStyles,\r\n \"removeCellCssStyles\": removeCellCssStyles,\r\n \"getCellCssStyles\": getCellCssStyles,\r\n \"getFrozenRowOffset\": getFrozenRowOffset,\r\n\r\n \"init\": finishInitialization,\r\n \"destroy\": destroy,\r\n\r\n // IEditor implementation\r\n \"getEditorLock\": getEditorLock,\r\n \"getEditController\": getEditController\r\n });\r\n\r\n init();\r\n}\r\n\n\n\n// WEBPACK FOOTER //\n// ../src/slick-frozen.grid.js","import Slick from './slick.core';\r\nimport $ from 'jquery';\r\nimport GroupMetaDataProvider from './slick.groupmetadataprovider';\r\n\r\nconst Aggregators = {\r\n Avg: AvgAggregator,\r\n Min: MinAggregator,\r\n Max: MaxAggregator,\r\n Sum: SumAggregator\r\n};\r\n\r\nconst Data = {\r\n DataView,\r\n GroupMetaDataProvider,\r\n Aggregators\r\n};\r\n\r\nexport default Data;\r\n\r\n/** *\r\n * A sample Model implementation.\r\n * Provides a filtered view of the underlying data.\r\n *\r\n * Relies on the data item having an \"id\" property uniquely identifying it.\r\n */\r\nfunction DataView(options){\r\n let self = this;\r\n\r\n let defaults = {\r\n groupItemMetadataProvider: null,\r\n inlineFilters: false\r\n };\r\n\r\n // private\r\n let idProperty = 'id'; // property holding a unique row id\r\n let items = []; // data by index\r\n let rows = []; // data by row\r\n let idxById = {}; // indexes by id\r\n let rowsById = null; // rows by id; lazy-calculated\r\n let filter = null; // filter function\r\n let updated = null; // updated item ids\r\n let suspend = false; // suspends the recalculation\r\n let sortAsc = true;\r\n let fastSortField;\r\n let sortComparer;\r\n let refreshHints = {};\r\n let prevRefreshHints = {};\r\n let filterArgs;\r\n let filteredItems = [];\r\n let compiledFilter;\r\n let compiledFilterWithCaching;\r\n let filterCache = [];\r\n\r\n // grouping\r\n let groupingInfoDefaults = {\r\n getter: null,\r\n formatter: null,\r\n comparer: function(a, b){\r\n return (a.value === b.value ? 0 :\r\n (a.value > b.value ? 1 : -1)\r\n );\r\n },\r\n predefinedValues: [],\r\n aggregators: [],\r\n aggregateEmpty: false,\r\n aggregateCollapsed: false,\r\n aggregateChildGroups: false,\r\n collapsed: false,\r\n displayTotalsRow: true,\r\n lazyTotalsCalculation: false\r\n };\r\n let groupingInfos = [];\r\n let groups = [];\r\n let toggledGroupsByLevel = [];\r\n let groupingDelimiter = ':|:';\r\n\r\n let pagesize = 0;\r\n let pagenum = 0;\r\n let totalRows = 0;\r\n\r\n // events\r\n let onRowCountChanged = new Slick.Event();\r\n let onRowsChanged = new Slick.Event();\r\n let onPagingInfoChanged = new Slick.Event();\r\n\r\n options = $.extend(true, {}, defaults, options);\r\n\r\n function beginUpdate(){\r\n suspend = true;\r\n }\r\n\r\n function endUpdate(){\r\n suspend = false;\r\n refresh();\r\n }\r\n\r\n function setRefreshHints(hints){\r\n refreshHints = hints;\r\n }\r\n\r\n function setFilterArgs(args){\r\n filterArgs = args;\r\n }\r\n\r\n function updateIdxById(startingIndex){\r\n startingIndex = startingIndex || 0;\r\n let id;\r\n for (let i = startingIndex, l = items.length; i < l; i++){\r\n id = items[i][idProperty];\r\n if (id === undefined){\r\n throw \"Each data element must implement a unique 'id' property\";\r\n }\r\n idxById[id] = i;\r\n }\r\n }\r\n\r\n function ensureIdUniqueness(){\r\n let id;\r\n for (let i = 0, l = items.length; i < l; i++){\r\n id = items[i][idProperty];\r\n if (id === undefined || idxById[id] !== i){\r\n throw \"Each data element must implement a unique 'id' property\";\r\n }\r\n }\r\n }\r\n\r\n function getItems(){\r\n return items;\r\n }\r\n\r\n function setItems(data, objectIdProperty){\r\n if (objectIdProperty !== undefined){\r\n idProperty = objectIdProperty;\r\n }\r\n items = filteredItems = data;\r\n idxById = {};\r\n updateIdxById();\r\n ensureIdUniqueness();\r\n refresh();\r\n }\r\n\r\n function setPagingOptions(args){\r\n if (args.pageSize != undefined){\r\n pagesize = args.pageSize;\r\n pagenum = pagesize ? Math.min(pagenum, Math.max(0, Math.ceil(totalRows / pagesize) - 1)) : 0;\r\n }\r\n\r\n if (args.pageNum != undefined){\r\n pagenum = Math.min(args.pageNum, Math.max(0, Math.ceil(totalRows / pagesize) - 1));\r\n }\r\n\r\n onPagingInfoChanged.notify(getPagingInfo(), null, self);\r\n\r\n refresh();\r\n }\r\n\r\n function getPagingInfo(){\r\n let totalPages = pagesize ? Math.max(1, Math.ceil(totalRows / pagesize)) : 1;\r\n return {pageSize: pagesize, pageNum: pagenum, totalRows: totalRows, totalPages: totalPages, dataView: self};\r\n }\r\n\r\n function sort(comparer, ascending){\r\n sortAsc = ascending;\r\n sortComparer = comparer;\r\n fastSortField = null;\r\n if (ascending === false){\r\n items.reverse();\r\n }\r\n items.sort(comparer);\r\n if (ascending === false){\r\n items.reverse();\r\n }\r\n idxById = {};\r\n updateIdxById();\r\n refresh();\r\n }\r\n\r\n /** *\r\n * Provides a workaround for the extremely slow sorting in IE.\r\n * Does a [lexicographic] sort on a give column by temporarily overriding Object.prototype.toString\r\n * to return the value of that field and then doing a native Array.sort().\r\n */\r\n function fastSort(field, ascending){\r\n sortAsc = ascending;\r\n fastSortField = field;\r\n sortComparer = null;\r\n let oldToString = Object.prototype.toString;\r\n Object.prototype.toString = (typeof field == 'function') ? field : function(){\r\n return this[field];\r\n };\r\n // an extra reversal for descending sort keeps the sort stable\r\n // (assuming a stable native sort implementation, which isn't true in some cases)\r\n if (ascending === false){\r\n items.reverse();\r\n }\r\n items.sort();\r\n Object.prototype.toString = oldToString;\r\n if (ascending === false){\r\n items.reverse();\r\n }\r\n idxById = {};\r\n updateIdxById();\r\n refresh();\r\n }\r\n\r\n function reSort(){\r\n if (sortComparer){\r\n sort(sortComparer, sortAsc);\r\n } else if (fastSortField){\r\n fastSort(fastSortField, sortAsc);\r\n }\r\n }\r\n\r\n function setFilter(filterFn){\r\n filter = filterFn;\r\n if (options.inlineFilters){\r\n compiledFilter = compileFilter();\r\n compiledFilterWithCaching = compileFilterWithCaching();\r\n }\r\n refresh();\r\n }\r\n\r\n function getGrouping(){\r\n return groupingInfos;\r\n }\r\n\r\n function setGrouping(groupingInfo){\r\n if (!options.groupItemMetadataProvider){\r\n options.groupItemMetadataProvider = new Data.GroupItemMetadataProvider();\r\n }\r\n\r\n groups = [];\r\n toggledGroupsByLevel = [];\r\n groupingInfo = groupingInfo || [];\r\n groupingInfos = (groupingInfo instanceof Array) ? groupingInfo : [groupingInfo];\r\n\r\n for (let i = 0; i < groupingInfos.length; i++){\r\n let gi = groupingInfos[i] = $.extend(true, {}, groupingInfoDefaults, groupingInfos[i]);\r\n gi.getterIsAFn = typeof gi.getter === 'function';\r\n\r\n // pre-compile accumulator loops\r\n gi.compiledAccumulators = [];\r\n let idx = gi.aggregators.length;\r\n while (idx--){\r\n gi.compiledAccumulators[idx] = compileAccumulatorLoop(gi.aggregators[idx]);\r\n }\r\n\r\n toggledGroupsByLevel[i] = {};\r\n }\r\n\r\n refresh();\r\n }\r\n\r\n /**\r\n * @deprecated Please use {@link setGrouping}.\r\n */\r\n function groupBy(valueGetter, valueFormatter, sortComparer){\r\n if (valueGetter == null){\r\n setGrouping([]);\r\n return;\r\n }\r\n\r\n setGrouping({\r\n getter: valueGetter,\r\n formatter: valueFormatter,\r\n comparer: sortComparer\r\n });\r\n }\r\n\r\n /**\r\n * @deprecated Please use {@link setGrouping}.\r\n */\r\n function setAggregators(groupAggregators, includeCollapsed){\r\n if (!groupingInfos.length){\r\n throw new Error('At least one grouping must be specified before calling setAggregators().');\r\n }\r\n\r\n groupingInfos[0].aggregators = groupAggregators;\r\n groupingInfos[0].aggregateCollapsed = includeCollapsed;\r\n\r\n setGrouping(groupingInfos);\r\n }\r\n\r\n function getItemByIdx(i){\r\n return items[i];\r\n }\r\n\r\n function getIdxById(id){\r\n return idxById[id];\r\n }\r\n\r\n function ensureRowsByIdCache(){\r\n if (!rowsById){\r\n rowsById = {};\r\n for (let i = 0, l = rows.length; i < l; i++){\r\n rowsById[rows[i][idProperty]] = i;\r\n }\r\n }\r\n }\r\n\r\n function getRowById(id){\r\n ensureRowsByIdCache();\r\n return rowsById[id];\r\n }\r\n\r\n function getItemById(id){\r\n return items[idxById[id]];\r\n }\r\n\r\n function mapIdsToRows(idArray){\r\n let rows = [];\r\n ensureRowsByIdCache();\r\n for (let i = 0, l = idArray.length; i < l; i++){\r\n let row = rowsById[idArray[i]];\r\n if (row != null){\r\n rows[rows.length] = row;\r\n }\r\n }\r\n return rows;\r\n }\r\n\r\n function mapRowsToIds(rowArray){\r\n let ids = [];\r\n for (let i = 0, l = rowArray.length; i < l; i++){\r\n if (rowArray[i] < rows.length){\r\n ids[ids.length] = rows[rowArray[i]][idProperty];\r\n }\r\n }\r\n return ids;\r\n }\r\n\r\n function updateItem(id, item){\r\n if (idxById[id] === undefined || id !== item[idProperty]){\r\n throw 'Invalid or non-matching id';\r\n }\r\n items[idxById[id]] = item;\r\n if (!updated){\r\n updated = {};\r\n }\r\n updated[id] = true;\r\n refresh();\r\n }\r\n\r\n function insertItem(insertBefore, item){\r\n items.splice(insertBefore, 0, item);\r\n updateIdxById(insertBefore);\r\n refresh();\r\n }\r\n\r\n function addItem(item){\r\n items.push(item);\r\n updateIdxById(items.length - 1);\r\n refresh();\r\n }\r\n\r\n function deleteItem(id){\r\n let idx = idxById[id];\r\n if (idx === undefined){\r\n throw 'Invalid id';\r\n }\r\n delete idxById[id];\r\n items.splice(idx, 1);\r\n updateIdxById(idx);\r\n refresh();\r\n }\r\n\r\n function getLength(){\r\n return rows.length;\r\n }\r\n\r\n function getItem(i){\r\n let item = rows[i];\r\n\r\n // if this is a group row, make sure totals are calculated and update the title\r\n if (item && item.__group && item.totals && !item.totals.initialized){\r\n let gi = groupingInfos[item.level];\r\n if (!gi.displayTotalsRow){\r\n calculateTotals(item.totals);\r\n item.title = gi.formatter ? gi.formatter(item) : item.value;\r\n }\r\n }\r\n // if this is a totals row, make sure it's calculated\r\n else if (item && item.__groupTotals && !item.initialized){\r\n calculateTotals(item);\r\n }\r\n\r\n return item;\r\n }\r\n\r\n function getItemMetadata(i){\r\n let item = rows[i];\r\n if (item === undefined){\r\n return null;\r\n }\r\n\r\n // overrides for grouping rows\r\n if (item.__group){\r\n return options.groupItemMetadataProvider.getGroupRowMetadata(item);\r\n }\r\n\r\n // overrides for totals rows\r\n if (item.__groupTotals){\r\n return options.groupItemMetadataProvider.getTotalsRowMetadata(item);\r\n }\r\n\r\n return null;\r\n }\r\n\r\n function expandCollapseAllGroups(level, collapse){\r\n if (level == null){\r\n for (let i = 0; i < groupingInfos.length; i++){\r\n toggledGroupsByLevel[i] = {};\r\n groupingInfos[i].collapsed = collapse;\r\n }\r\n } else {\r\n toggledGroupsByLevel[level] = {};\r\n groupingInfos[level].collapsed = collapse;\r\n }\r\n refresh();\r\n }\r\n\r\n /**\r\n * @param level {Number} Optional level to collapse. If not specified, applies to all levels.\r\n */\r\n function collapseAllGroups(level){\r\n expandCollapseAllGroups(level, true);\r\n }\r\n\r\n /**\r\n * @param level {Number} Optional level to expand. If not specified, applies to all levels.\r\n */\r\n function expandAllGroups(level){\r\n expandCollapseAllGroups(level, false);\r\n }\r\n\r\n function expandCollapseGroup(level, groupingKey, collapse){\r\n toggledGroupsByLevel[level][groupingKey] = groupingInfos[level].collapsed ^ collapse;\r\n refresh();\r\n }\r\n\r\n /**\r\n * @param letArgs Either a Slick.Group's \"groupingKey\" property, or a\r\n * letiable argument list of grouping values denoting a unique path to the row. For\r\n * example, calling collapseGroup('high', '10%') will collapse the '10%' subgroup of\r\n * the 'high' group.\r\n */\r\n function collapseGroup(letArgs){\r\n let args = Array.prototype.slice.call(arguments);\r\n let arg0 = args[0];\r\n if (args.length == 1 && arg0.indexOf(groupingDelimiter) != -1){\r\n expandCollapseGroup(arg0.split(groupingDelimiter).length - 1, arg0, true);\r\n } else {\r\n expandCollapseGroup(args.length - 1, args.join(groupingDelimiter), true);\r\n }\r\n }\r\n\r\n /**\r\n * @param letArgs Either a Slick.Group's \"groupingKey\" property, or a\r\n * letiable argument list of grouping values denoting a unique path to the row. For\r\n * example, calling expandGroup('high', '10%') will expand the '10%' subgroup of\r\n * the 'high' group.\r\n */\r\n function expandGroup(letArgs){\r\n let args = Array.prototype.slice.call(arguments);\r\n let arg0 = args[0];\r\n if (args.length == 1 && arg0.indexOf(groupingDelimiter) != -1){\r\n expandCollapseGroup(arg0.split(groupingDelimiter).length - 1, arg0, false);\r\n } else {\r\n expandCollapseGroup(args.length - 1, args.join(groupingDelimiter), false);\r\n }\r\n }\r\n\r\n function getGroups(){\r\n return groups;\r\n }\r\n\r\n function extractGroups(rows, parentGroup){\r\n let group;\r\n let val;\r\n let groups = [];\r\n let groupsByVal = {};\r\n let r;\r\n let level = parentGroup ? parentGroup.level + 1 : 0;\r\n let gi = groupingInfos[level];\r\n\r\n for (let i = 0, l = gi.predefinedValues.length; i < l; i++){\r\n val = gi.predefinedValues[i];\r\n group = groupsByVal[val];\r\n if (!group){\r\n group = new Slick.Group();\r\n group.value = val;\r\n group.level = level;\r\n group.groupingKey = (parentGroup ? parentGroup.groupingKey + groupingDelimiter : '') + val;\r\n groups[groups.length] = group;\r\n groupsByVal[val] = group;\r\n }\r\n }\r\n\r\n for (let i = 0, l = rows.length; i < l; i++){\r\n r = rows[i];\r\n val = gi.getterIsAFn ? gi.getter(r) : r[gi.getter];\r\n group = groupsByVal[val];\r\n if (!group){\r\n group = new Slick.Group();\r\n group.value = val;\r\n group.level = level;\r\n group.groupingKey = (parentGroup ? parentGroup.groupingKey + groupingDelimiter : '') + val;\r\n groups[groups.length] = group;\r\n groupsByVal[val] = group;\r\n }\r\n\r\n group.rows[group.count++] = r;\r\n }\r\n\r\n if (level < groupingInfos.length - 1){\r\n for (let i = 0; i < groups.length; i++){\r\n group = groups[i];\r\n group.groups = extractGroups(group.rows, group);\r\n }\r\n }\r\n\r\n groups.sort(groupingInfos[level].comparer);\r\n\r\n return groups;\r\n }\r\n\r\n function calculateTotals(totals){\r\n let group = totals.group;\r\n let gi = groupingInfos[group.level];\r\n let isLeafLevel = (group.level == groupingInfos.length);\r\n let agg, idx = gi.aggregators.length;\r\n\r\n if (!isLeafLevel && gi.aggregateChildGroups){\r\n // make sure all the subgroups are calculated\r\n let i = group.groups.length;\r\n while (i--){\r\n if (!group.groups[i].totals.initialized){\r\n calculateTotals(group.groups[i].totals);\r\n }\r\n }\r\n }\r\n\r\n while (idx--){\r\n agg = gi.aggregators[idx];\r\n agg.init();\r\n if (!isLeafLevel && gi.aggregateChildGroups){\r\n gi.compiledAccumulators[idx].call(agg, group.groups);\r\n } else {\r\n gi.compiledAccumulators[idx].call(agg, group.rows);\r\n }\r\n agg.storeResult(totals);\r\n }\r\n totals.initialized = true;\r\n }\r\n\r\n function addGroupTotals(group){\r\n let gi = groupingInfos[group.level];\r\n let totals = new Slick.GroupTotals();\r\n totals.group = group;\r\n group.totals = totals;\r\n if (!gi.lazyTotalsCalculation){\r\n calculateTotals(totals);\r\n }\r\n }\r\n\r\n function addTotals(groups, level){\r\n level = level || 0;\r\n let gi = groupingInfos[level];\r\n let groupCollapsed = gi.collapsed;\r\n let toggledGroups = toggledGroupsByLevel[level];\r\n let idx = groups.length, g;\r\n while (idx--){\r\n g = groups[idx];\r\n\r\n if (g.collapsed && !gi.aggregateCollapsed){\r\n continue;\r\n }\r\n\r\n // Do a depth-first aggregation so that parent group aggregators can access subgroup totals.\r\n if (g.groups){\r\n addTotals(g.groups, level + 1);\r\n }\r\n\r\n if (gi.aggregators.length && (\r\n gi.aggregateEmpty || g.rows.length || (g.groups && g.groups.length))){\r\n addGroupTotals(g);\r\n }\r\n\r\n g.collapsed = groupCollapsed ^ toggledGroups[g.groupingKey];\r\n g.title = gi.formatter ? gi.formatter(g) : g.value;\r\n }\r\n }\r\n\r\n function flattenGroupedRows(groups, level){\r\n level = level || 0;\r\n let gi = groupingInfos[level];\r\n let groupedRows = [], rows, gl = 0, g;\r\n for (let i = 0, l = groups.length; i < l; i++){\r\n g = groups[i];\r\n groupedRows[gl++] = g;\r\n\r\n if (!g.collapsed){\r\n rows = g.groups ? flattenGroupedRows(g.groups, level + 1) : g.rows;\r\n for (let j = 0, jj = rows.length; j < jj; j++){\r\n groupedRows[gl++] = rows[j];\r\n }\r\n }\r\n\r\n if (g.totals && gi.displayTotalsRow && (!g.collapsed || gi.aggregateCollapsed)){\r\n groupedRows[gl++] = g.totals;\r\n }\r\n }\r\n return groupedRows;\r\n }\r\n\r\n function getFunctionInfo(fn){\r\n let fnRegex = /^function[^(]*\\(([^)]*)\\)\\s*{([\\s\\S]*)}$/;\r\n let matches = fn.toString().match(fnRegex);\r\n return {\r\n params: matches[1].split(','),\r\n body: matches[2]\r\n };\r\n }\r\n\r\n function compileAccumulatorLoop(aggregator){\r\n let accumulatorInfo = getFunctionInfo(aggregator.accumulate);\r\n let fn = new Function(\r\n '_items',\r\n 'for (let ' + accumulatorInfo.params[0] + ', _i=0, _il=_items.length; _i<_il; _i++) {' +\r\n accumulatorInfo.params[0] + ' = _items[_i]; ' +\r\n accumulatorInfo.body +\r\n '}'\r\n );\r\n fn.displayName = 'compiledAccumulatorLoop';\r\n return fn;\r\n }\r\n\r\n function compileFilter(){\r\n let filterInfo = getFunctionInfo(filter);\r\n\r\n let filterPath1 = '{ continue _coreloop; }$1';\r\n let filterPath2 = '{ _retval[_idx++] = $item$; continue _coreloop; }$1';\r\n // make some allowances for minification - there's only so far we can go with RegEx\r\n let filterBody = filterInfo.body\r\n .replace(/return false\\s*([;}]|\\}|$)/gi, filterPath1)\r\n .replace(/return!1([;}]|\\}|$)/gi, filterPath1)\r\n .replace(/return true\\s*([;}]|\\}|$)/gi, filterPath2)\r\n .replace(/return!0([;}]|\\}|$)/gi, filterPath2)\r\n .replace(/return ([^;}]+?)\\s*([;}]|$)/gi,\r\n '{ if ($1) { _retval[_idx++] = $item$; }; continue _coreloop; }$2');\r\n\r\n // This preserves the function template code after JS compression,\r\n // so that replace() commands still work as expected.\r\n let tpl = [\r\n // \"function(_items, _args) { \",\r\n 'let _retval = [], _idx = 0; ',\r\n 'let $item$, $args$ = _args; ',\r\n '_coreloop: ',\r\n 'for (let _i = 0, _il = _items.length; _i < _il; _i++) { ',\r\n '$item$ = _items[_i]; ',\r\n '$filter$; ',\r\n '} ',\r\n 'return _retval; '\r\n // \"}\"\r\n ].join('');\r\n tpl = tpl.replace(/\\$filter\\$/gi, filterBody);\r\n tpl = tpl.replace(/\\$item\\$/gi, filterInfo.params[0]);\r\n tpl = tpl.replace(/\\$args\\$/gi, filterInfo.params[1]);\r\n\r\n let fn = new Function('_items,_args', tpl);\r\n fn.displayName = 'compiledFilter';\r\n\r\n return fn;\r\n }\r\n\r\n function compileFilterWithCaching(){\r\n let filterInfo = getFunctionInfo(filter);\r\n\r\n let filterPath1 = '{ continue _coreloop; }$1';\r\n let filterPath2 = '{ _cache[_i] = true;_retval[_idx++] = $item$; continue _coreloop; }$1';\r\n // make some allowances for minification - there's only so far we can go with RegEx\r\n let filterBody = filterInfo.body\r\n .replace(/return false\\s*([;}]|\\}|$)/gi, filterPath1)\r\n .replace(/return!1([;}]|\\}|$)/gi, filterPath1)\r\n .replace(/return true\\s*([;}]|\\}|$)/gi, filterPath2)\r\n .replace(/return!0([;}]|\\}|$)/gi, filterPath2)\r\n .replace(/return ([^;}]+?)\\s*([;}]|$)/gi,\r\n '{ if ((_cache[_i] = $1)) { _retval[_idx++] = $item$; }; continue _coreloop; }$2');\r\n\r\n // This preserves the function template code after JS compression,\r\n // so that replace() commands still work as expected.\r\n let tpl = [\r\n // \"function(_items, _args, _cache) { \",\r\n 'let _retval = [], _idx = 0; ',\r\n 'let $item$, $args$ = _args; ',\r\n '_coreloop: ',\r\n 'for (let _i = 0, _il = _items.length; _i < _il; _i++) { ',\r\n '$item$ = _items[_i]; ',\r\n 'if (_cache[_i]) { ',\r\n '_retval[_idx++] = $item$; ',\r\n 'continue _coreloop; ',\r\n '} ',\r\n '$filter$; ',\r\n '} ',\r\n 'return _retval; '\r\n // \"}\"\r\n ].join('');\r\n tpl = tpl.replace(/\\$filter\\$/gi, filterBody);\r\n tpl = tpl.replace(/\\$item\\$/gi, filterInfo.params[0]);\r\n tpl = tpl.replace(/\\$args\\$/gi, filterInfo.params[1]);\r\n\r\n let fn = new Function('_items,_args,_cache', tpl);\r\n fn.displayName = 'compiledFilterWithCaching';\r\n return fn;\r\n }\r\n\r\n function uncompiledFilter(items, args){\r\n let retval = [], idx = 0;\r\n\r\n for (let i = 0, ii = items.length; i < ii; i++){\r\n if (filter(items[i], args)){\r\n retval[idx++] = items[i];\r\n }\r\n }\r\n\r\n return retval;\r\n }\r\n\r\n function uncompiledFilterWithCaching(items, args, cache){\r\n let retval = [], idx = 0, item;\r\n\r\n for (let i = 0, ii = items.length; i < ii; i++){\r\n item = items[i];\r\n if (cache[i]){\r\n retval[idx++] = item;\r\n } else if (filter(item, args)){\r\n retval[idx++] = item;\r\n cache[i] = true;\r\n }\r\n }\r\n\r\n return retval;\r\n }\r\n\r\n function getFilteredAndPagedItems(items){\r\n if (filter){\r\n let batchFilter = options.inlineFilters ? compiledFilter : uncompiledFilter;\r\n let batchFilterWithCaching = options.inlineFilters ? compiledFilterWithCaching : uncompiledFilterWithCaching;\r\n\r\n if (refreshHints.isFilterNarrowing){\r\n filteredItems = batchFilter(filteredItems, filterArgs);\r\n } else if (refreshHints.isFilterExpanding){\r\n filteredItems = batchFilterWithCaching(items, filterArgs, filterCache);\r\n } else if (!refreshHints.isFilterUnchanged){\r\n filteredItems = batchFilter(items, filterArgs);\r\n }\r\n } else {\r\n // special case: if not filtering and not paging, the resulting\r\n // rows collection needs to be a copy so that changes due to sort\r\n // can be caught\r\n filteredItems = pagesize ? items : items.concat();\r\n }\r\n\r\n // get the current page\r\n let paged;\r\n if (pagesize){\r\n if (filteredItems.length < pagenum * pagesize){\r\n pagenum = Math.floor(filteredItems.length / pagesize);\r\n }\r\n paged = filteredItems.slice(pagesize * pagenum, pagesize * pagenum + pagesize);\r\n } else {\r\n paged = filteredItems;\r\n }\r\n\r\n return {totalRows: filteredItems.length, rows: paged};\r\n }\r\n\r\n function getRowDiffs(rows, newRows){\r\n let item, r, eitherIsNonData, diff = [];\r\n let from = 0, to = newRows.length;\r\n\r\n if (refreshHints && refreshHints.ignoreDiffsBefore){\r\n from = Math.max(0,\r\n Math.min(newRows.length, refreshHints.ignoreDiffsBefore));\r\n }\r\n\r\n if (refreshHints && refreshHints.ignoreDiffsAfter){\r\n to = Math.min(newRows.length,\r\n Math.max(0, refreshHints.ignoreDiffsAfter));\r\n }\r\n\r\n for (let i = from, rl = rows.length; i < to; i++){\r\n if (i >= rl){\r\n diff[diff.length] = i;\r\n } else {\r\n item = newRows[i];\r\n r = rows[i];\r\n\r\n if ((groupingInfos.length && (eitherIsNonData = (item.__nonDataRow) || (r.__nonDataRow)) &&\r\n item.__group !== r.__group ||\r\n item.__group && !item.equals(r))\r\n || (eitherIsNonData &&\r\n // no good way to compare totals since they are arbitrary DTOs\r\n // deep object comparison is pretty expensive\r\n // always considering them 'dirty' seems easier for the time being\r\n (item.__groupTotals || r.__groupTotals))\r\n || item[idProperty] != r[idProperty]\r\n || (updated && updated[item[idProperty]])\r\n ){\r\n diff[diff.length] = i;\r\n }\r\n }\r\n }\r\n return diff;\r\n }\r\n\r\n function recalc(_items){\r\n rowsById = null;\r\n\r\n if (refreshHints.isFilterNarrowing != prevRefreshHints.isFilterNarrowing ||\r\n refreshHints.isFilterExpanding != prevRefreshHints.isFilterExpanding){\r\n filterCache = [];\r\n }\r\n\r\n let filteredItems = getFilteredAndPagedItems(_items);\r\n totalRows = filteredItems.totalRows;\r\n let newRows = filteredItems.rows;\r\n\r\n groups = [];\r\n if (groupingInfos.length){\r\n groups = extractGroups(newRows);\r\n if (groups.length){\r\n addTotals(groups);\r\n newRows = flattenGroupedRows(groups);\r\n }\r\n }\r\n\r\n let diff = getRowDiffs(rows, newRows);\r\n\r\n rows = newRows;\r\n\r\n return diff;\r\n }\r\n\r\n function refresh(){\r\n if (suspend){\r\n return;\r\n }\r\n\r\n let countBefore = rows.length;\r\n let totalRowsBefore = totalRows;\r\n\r\n let diff = recalc(items, filter); // pass as direct refs to avoid closure perf hit\r\n\r\n // if the current page is no longer valid, go to last page and recalc\r\n // we suffer a performance penalty here, but the main loop (recalc) remains highly optimized\r\n if (pagesize && totalRows < pagenum * pagesize){\r\n pagenum = Math.max(0, Math.ceil(totalRows / pagesize) - 1);\r\n diff = recalc(items, filter);\r\n }\r\n\r\n updated = null;\r\n prevRefreshHints = refreshHints;\r\n refreshHints = {};\r\n\r\n if (totalRowsBefore !== totalRows){\r\n onPagingInfoChanged.notify(getPagingInfo(), null, self);\r\n }\r\n if (countBefore !== rows.length){\r\n onRowCountChanged.notify({previous: countBefore, current: rows.length, dataView: self}, null, self);\r\n }\r\n if (diff.length > 0){\r\n onRowsChanged.notify({rows: diff, dataView: self}, null, self);\r\n }\r\n }\r\n\r\n /** *\r\n * Wires the grid and the DataView together to keep row selection tied to item ids.\r\n * This is useful since, without it, the grid only knows about rows, so if the items\r\n * move around, the same rows stay selected instead of the selection moving along\r\n * with the items.\r\n *\r\n * NOTE: This doesn't work with cell selection model.\r\n *\r\n * @param grid {Slick.Grid} The grid to sync selection with.\r\n * @param preserveHidden {Boolean} Whether to keep selected items that go out of the\r\n * view due to them getting filtered out.\r\n * @param preserveHiddenOnSelectionChange {Boolean} Whether to keep selected items\r\n * that are currently out of the view (see preserveHidden) as selected when selection\r\n * changes.\r\n * @return {Slick.Event} An event that notifies when an internal list of selected row ids\r\n * changes. This is useful since, in combination with the above two options, it allows\r\n * access to the full list selected row ids, and not just the ones visible to the grid.\r\n * @method syncGridSelection\r\n */\r\n function syncGridSelection(grid, preserveHidden, preserveHiddenOnSelectionChange){\r\n let self = this;\r\n let inHandler;\r\n let selectedRowIds = self.mapRowsToIds(grid.getSelectedRows());\r\n let onSelectedRowIdsChanged = new Slick.Event();\r\n\r\n function setSelectedRowIds(rowIds){\r\n if (selectedRowIds.join(',') == rowIds.join(',')){\r\n return;\r\n }\r\n\r\n selectedRowIds = rowIds;\r\n\r\n onSelectedRowIdsChanged.notify({\r\n 'grid': grid,\r\n 'ids': selectedRowIds,\r\n 'dataView': self\r\n }, new Slick.EventData(), self);\r\n }\r\n\r\n function update(){\r\n if (selectedRowIds.length > 0){\r\n inHandler = true;\r\n let selectedRows = self.mapIdsToRows(selectedRowIds);\r\n if (!preserveHidden){\r\n setSelectedRowIds(self.mapRowsToIds(selectedRows));\r\n }\r\n grid.setSelectedRows(selectedRows);\r\n inHandler = false;\r\n }\r\n }\r\n\r\n grid.onSelectedRowsChanged.subscribe(function(e, args){\r\n if (inHandler){\r\n return;\r\n }\r\n let newSelectedRowIds = self.mapRowsToIds(grid.getSelectedRows());\r\n if (!preserveHiddenOnSelectionChange || !grid.getOptions().multiSelect){\r\n setSelectedRowIds(newSelectedRowIds);\r\n } else {\r\n // keep the ones that are hidden\r\n let existing = $.grep(selectedRowIds, function(id){\r\n return self.getRowById(id) === undefined;\r\n });\r\n // add the newly selected ones\r\n setSelectedRowIds(existing.concat(newSelectedRowIds));\r\n }\r\n });\r\n\r\n this.onRowsChanged.subscribe(update);\r\n\r\n this.onRowCountChanged.subscribe(update);\r\n\r\n return onSelectedRowIdsChanged;\r\n }\r\n\r\n function syncGridCellCssStyles(grid, key){\r\n let hashById;\r\n let inHandler;\r\n\r\n // since this method can be called after the cell styles have been set,\r\n // get the existing ones right away\r\n storeCellCssStyles(grid.getCellCssStyles(key));\r\n\r\n function storeCellCssStyles(hash){\r\n hashById = {};\r\n for (let row in hash){\r\n let id = rows[row][idProperty];\r\n hashById[id] = hash[row];\r\n }\r\n }\r\n\r\n function update(){\r\n if (hashById){\r\n inHandler = true;\r\n ensureRowsByIdCache();\r\n let newHash = {};\r\n for (let id in hashById){\r\n let row = rowsById[id];\r\n if (row != undefined){\r\n newHash[row] = hashById[id];\r\n }\r\n }\r\n grid.setCellCssStyles(key, newHash);\r\n inHandler = false;\r\n }\r\n }\r\n\r\n grid.onCellCssStylesChanged.subscribe(function(e, args){\r\n if (inHandler){\r\n return;\r\n }\r\n if (key != args.key){\r\n return;\r\n }\r\n if (args.hash){\r\n storeCellCssStyles(args.hash);\r\n }\r\n });\r\n\r\n this.onRowsChanged.subscribe(update);\r\n\r\n this.onRowCountChanged.subscribe(update);\r\n }\r\n\r\n $.extend(this, {\r\n // methods\r\n 'beginUpdate': beginUpdate,\r\n 'endUpdate': endUpdate,\r\n 'setPagingOptions': setPagingOptions,\r\n 'getPagingInfo': getPagingInfo,\r\n 'getItems': getItems,\r\n 'setItems': setItems,\r\n 'setFilter': setFilter,\r\n 'sort': sort,\r\n 'fastSort': fastSort,\r\n 'reSort': reSort,\r\n 'setGrouping': setGrouping,\r\n 'getGrouping': getGrouping,\r\n 'groupBy': groupBy,\r\n 'setAggregators': setAggregators,\r\n 'collapseAllGroups': collapseAllGroups,\r\n 'expandAllGroups': expandAllGroups,\r\n 'collapseGroup': collapseGroup,\r\n 'expandGroup': expandGroup,\r\n 'getGroups': getGroups,\r\n 'getIdxById': getIdxById,\r\n 'getRowById': getRowById,\r\n 'getItemById': getItemById,\r\n 'getItemByIdx': getItemByIdx,\r\n 'mapRowsToIds': mapRowsToIds,\r\n 'mapIdsToRows': mapIdsToRows,\r\n 'setRefreshHints': setRefreshHints,\r\n 'setFilterArgs': setFilterArgs,\r\n 'refresh': refresh,\r\n 'updateItem': updateItem,\r\n 'insertItem': insertItem,\r\n 'addItem': addItem,\r\n 'deleteItem': deleteItem,\r\n 'syncGridSelection': syncGridSelection,\r\n 'syncGridCellCssStyles': syncGridCellCssStyles,\r\n\r\n // data provider methods\r\n 'getLength': getLength,\r\n 'getItem': getItem,\r\n 'getItemMetadata': getItemMetadata,\r\n\r\n // events\r\n 'onRowCountChanged': onRowCountChanged,\r\n 'onRowsChanged': onRowsChanged,\r\n 'onPagingInfoChanged': onPagingInfoChanged\r\n });\r\n}\r\n\r\nfunction AvgAggregator(field){\r\n this.field_ = field;\r\n\r\n this.init = function(){\r\n this.count_ = 0;\r\n this.nonNullCount_ = 0;\r\n this.sum_ = 0;\r\n };\r\n\r\n this.accumulate = function(item){\r\n let val = item[this.field_];\r\n this.count_++;\r\n if (val != null && val !== '' && !isNaN(val)){\r\n this.nonNullCount_++;\r\n this.sum_ += parseFloat(val);\r\n }\r\n };\r\n\r\n this.storeResult = function(groupTotals){\r\n if (!groupTotals.avg){\r\n groupTotals.avg = {};\r\n }\r\n if (this.nonNullCount_ != 0){\r\n groupTotals.avg[this.field_] = this.sum_ / this.nonNullCount_;\r\n }\r\n };\r\n}\r\n\r\nfunction MinAggregator(field){\r\n this.field_ = field;\r\n\r\n this.init = function(){\r\n this.min_ = null;\r\n };\r\n\r\n this.accumulate = function(item){\r\n let val = item[this.field_];\r\n if (val != null && val !== '' && !isNaN(val)){\r\n if (this.min_ == null || val < this.min_){\r\n this.min_ = val;\r\n }\r\n }\r\n };\r\n\r\n this.storeResult = function(groupTotals){\r\n if (!groupTotals.min){\r\n groupTotals.min = {};\r\n }\r\n groupTotals.min[this.field_] = this.min_;\r\n };\r\n}\r\n\r\nfunction MaxAggregator(field){\r\n this.field_ = field;\r\n\r\n this.init = function(){\r\n this.max_ = null;\r\n };\r\n\r\n this.accumulate = function(item){\r\n let val = item[this.field_];\r\n if (val != null && val !== '' && !isNaN(val)){\r\n if (this.max_ == null || val > this.max_){\r\n this.max_ = val;\r\n }\r\n }\r\n };\r\n\r\n this.storeResult = function(groupTotals){\r\n if (!groupTotals.max){\r\n groupTotals.max = {};\r\n }\r\n groupTotals.max[this.field_] = this.max_;\r\n };\r\n}\r\n\r\nfunction SumAggregator(field){\r\n this.field_ = field;\r\n\r\n this.init = function(){\r\n this.sum_ = null;\r\n };\r\n\r\n this.accumulate = function(item){\r\n let val = item[this.field_];\r\n if (val != null && val !== '' && !isNaN(val)){\r\n this.sum_ += parseFloat(val);\r\n }\r\n };\r\n\r\n this.storeResult = function(groupTotals){\r\n if (!groupTotals.sum){\r\n groupTotals.sum = {};\r\n }\r\n groupTotals.sum[this.field_] = this.sum_;\r\n };\r\n}\r\n\n\n\n// WEBPACK FOOTER //\n// ../src/slick.dataview.js","import Slick from './slick.core';\r\nimport flatpickr from 'flatpickr';\r\n//import 'flatpickr/dist/flatpickr.min.css';\r\nimport $ from 'jquery';\r\n\r\nconst { keyCode } = Slick;\r\n\r\n/** *\r\n * Contains basic SlickGrid editors.\r\n * @module Editors\r\n * @namespace Slick\r\n */\r\n\r\nconst Editors = {\r\n Text: TextEditor,\r\n Integer: IntegerEditor,\r\n Float: FloatEditor,\r\n Date: DateEditor,\r\n YesNoSelect: YesNoSelectEditor,\r\n Checkbox: CheckboxEditor,\r\n LongText: LongTextEditor\r\n};\r\n\r\nSlick.Editors = Editors;\r\nexport default Editors;\r\n\r\nfunction TextEditor(args){\r\n let $input;\r\n let defaultValue;\r\n\r\n this.init = function(){\r\n $input = $(\"\")\r\n .appendTo(args.container)\r\n .bind('keydown.nav', function(e){\r\n if (e.keyCode === keyCode.LEFT || e.keyCode === keyCode.RIGHT){\r\n e.stopImmediatePropagation();\r\n }\r\n })\r\n .focus()\r\n .select();\r\n };\r\n\r\n this.destroy = function(){\r\n $input.remove();\r\n };\r\n\r\n this.focus = function(){\r\n $input.focus();\r\n };\r\n\r\n this.getValue = function(){\r\n return $input.val();\r\n };\r\n\r\n this.setValue = function(val){\r\n $input.val(val);\r\n };\r\n\r\n this.loadValue = function(item){\r\n defaultValue = item[args.column.field] || '';\r\n $input.val(defaultValue);\r\n $input[0].defaultValue = defaultValue;\r\n $input.select();\r\n };\r\n\r\n this.serializeValue = function(){\r\n return $input.val();\r\n };\r\n\r\n this.applyValue = function(item, state){\r\n item[args.column.field] = state;\r\n };\r\n\r\n this.isValueChanged = function(){\r\n return (!($input.val() == '' && defaultValue == null)) && ($input.val() != defaultValue);\r\n };\r\n\r\n this.validate = function(){\r\n let valid = true;\r\n let msg = null;\r\n if (args.column.validator){\r\n let validationResults = args.column.validator($input.val(), args);\r\n valid = validationResults.valid;\r\n msg = validationResults.msg;\r\n }\r\n\r\n return {\r\n valid: true,\r\n msg: null\r\n };\r\n };\r\n\r\n this.init();\r\n}\r\n\r\nfunction IntegerEditor(args){\r\n let $input;\r\n let defaultValue;\r\n\r\n this.init = function(){\r\n $input = $(\"\");\r\n\r\n $input.bind('keydown.nav', function(e){\r\n if (e.keyCode === keyCode.LEFT || e.keyCode === keyCode.RIGHT){\r\n e.stopImmediatePropagation();\r\n }\r\n });\r\n\r\n $input.appendTo(args.container);\r\n $input.focus().select();\r\n };\r\n\r\n this.destroy = function(){\r\n $input.remove();\r\n };\r\n\r\n this.focus = function(){\r\n $input.focus();\r\n };\r\n\r\n this.loadValue = function(item){\r\n defaultValue = item[args.column.field];\r\n $input.val(defaultValue);\r\n $input[0].defaultValue = defaultValue;\r\n $input.select();\r\n };\r\n\r\n this.serializeValue = function(){\r\n return parseInt($input.val(), 10) || 0;\r\n };\r\n\r\n this.applyValue = function(item, state){\r\n item[args.column.field] = state;\r\n };\r\n\r\n this.isValueChanged = function(){\r\n return (!($input.val() == '' && defaultValue == null)) && ($input.val() != defaultValue);\r\n };\r\n\r\n this.validate = function(){\r\n if (isNaN($input.val())){\r\n return {\r\n valid: false,\r\n msg: 'Please enter a valid integer'\r\n };\r\n }\r\n\r\n if (args.column.validator){\r\n let validationResults = args.column.validator($input.val());\r\n if (!validationResults.valid){\r\n return validationResults;\r\n }\r\n }\r\n\r\n return {\r\n valid: true,\r\n msg: null\r\n };\r\n };\r\n\r\n this.init();\r\n}\r\n\r\nfunction FloatEditor(args){\r\n let $input;\r\n let defaultValue;\r\n let scope = this;\r\n\r\n this.init = function(){\r\n $input = $(\"\");\r\n\r\n $input.bind('keydown.nav', function(e){\r\n if (e.keyCode === keyCode.LEFT || e.keyCode === keyCode.RIGHT){\r\n e.stopImmediatePropagation();\r\n }\r\n });\r\n\r\n $input.appendTo(args.container);\r\n $input.focus().select();\r\n };\r\n\r\n this.destroy = function(){\r\n $input.remove();\r\n };\r\n\r\n this.focus = function(){\r\n $input.focus();\r\n };\r\n\r\n function getDecimalPlaces(){\r\n // returns the number of fixed decimal places or null\r\n let rtn = args.column.editorFixedDecimalPlaces;\r\n if (typeof rtn == 'undefined'){\r\n rtn = FloatEditor.DefaultDecimalPlaces;\r\n }\r\n return (!rtn && rtn !== 0 ? null : rtn);\r\n }\r\n\r\n this.loadValue = function(item){\r\n defaultValue = item[args.column.field];\r\n\r\n let decPlaces = getDecimalPlaces();\r\n if (decPlaces !== null\r\n && (defaultValue || defaultValue === 0)\r\n && defaultValue.toFixed){\r\n defaultValue = defaultValue.toFixed(decPlaces);\r\n }\r\n\r\n $input.val(defaultValue);\r\n $input[0].defaultValue = defaultValue;\r\n $input.select();\r\n };\r\n\r\n this.serializeValue = function(){\r\n let rtn = parseFloat($input.val()) || 0;\r\n\r\n let decPlaces = getDecimalPlaces();\r\n if (decPlaces !== null\r\n && (rtn || rtn === 0)\r\n && rtn.toFixed){\r\n rtn = parseFloat(rtn.toFixed(decPlaces));\r\n }\r\n\r\n return rtn;\r\n };\r\n\r\n this.applyValue = function(item, state){\r\n item[args.column.field] = state;\r\n };\r\n\r\n this.isValueChanged = function(){\r\n return (!($input.val() == '' && defaultValue == null)) && ($input.val() != defaultValue);\r\n };\r\n\r\n this.validate = function(){\r\n if (isNaN($input.val())){\r\n return {\r\n valid: false,\r\n msg: 'Please enter a valid number'\r\n };\r\n }\r\n\r\n if (args.column.validator){\r\n let validationResults = args.column.validator($input.val(), args);\r\n if (!validationResults.valid){\r\n return validationResults;\r\n }\r\n }\r\n\r\n return {\r\n valid: true,\r\n msg: null\r\n };\r\n };\r\n\r\n this.init();\r\n}\r\n\r\nFloatEditor.DefaultDecimalPlaces = null;\r\n\r\n/**\r\n * see https://chmln.github.io/flatpickr/#options - pass as column.options.date = {}\r\n * @param args\r\n * @constructor\r\n */\r\nfunction DateEditor(args){\r\n let $input,\r\n flatInstance,\r\n defaultDate,\r\n options = args.column.options && args.column.options.date ? args.column.options.date : {};\r\n\r\n this.init = function(){\r\n defaultDate = options.defaultDate = args.item[args.column.field];\r\n\r\n $input = $('');\r\n $input.appendTo(args.container);\r\n $input.focus().val(defaultDate).select();\r\n flatInstance = flatpickr($input[0], options);\r\n };\r\n\r\n this.destroy = function(){\r\n flatInstance.destroy();\r\n $input.remove();\r\n };\r\n\r\n this.show = function(){\r\n flatInstance.open();\r\n flatInstance.positionCalendar();\r\n };\r\n\r\n this.hide = function(){\r\n flatInstance.close();\r\n };\r\n\r\n this.position = function(position){\r\n //todo: fix how scrolling is affected\r\n flatInstance.positionCalendar();\r\n };\r\n\r\n this.focus = function(){\r\n $input.focus();\r\n };\r\n\r\n this.loadValue = function(item){\r\n defaultDate = item[args.column.field];\r\n $input.val(defaultDate);\r\n $input.select();\r\n };\r\n\r\n this.serializeValue = function(){\r\n return $input.val();\r\n };\r\n\r\n this.applyValue = function(item, state){\r\n item[args.column.field] = state;\r\n };\r\n\r\n this.isValueChanged = function(){\r\n return (!($input.val() == '' && defaultDate == null)) && ($input.val() != defaultDate);\r\n };\r\n\r\n this.validate = function(){\r\n if (args.column.validator){\r\n let validationResults = args.column.validator($input.val(), args);\r\n if (!validationResults.valid){\r\n return validationResults;\r\n }\r\n }\r\n\r\n return {\r\n valid: true,\r\n msg: null\r\n };\r\n };\r\n\r\n this.init();\r\n}\r\n\r\nfunction YesNoSelectEditor(args){\r\n let $select;\r\n let defaultValue;\r\n let scope = this;\r\n\r\n this.init = function(){\r\n $select = $(\"\");\r\n $select.appendTo(args.container);\r\n $select.focus();\r\n };\r\n\r\n this.destroy = function(){\r\n $select.remove();\r\n };\r\n\r\n this.focus = function(){\r\n $select.focus();\r\n };\r\n\r\n this.loadValue = function(item){\r\n $select.val((defaultValue = item[args.column.field]) ? 'yes' : 'no');\r\n $select.select();\r\n };\r\n\r\n this.serializeValue = function(){\r\n return ($select.val() == 'yes');\r\n };\r\n\r\n this.applyValue = function(item, state){\r\n item[args.column.field] = state;\r\n };\r\n\r\n this.isValueChanged = function(){\r\n return ($select.val() != defaultValue);\r\n };\r\n\r\n this.validate = function(){\r\n let valid = true;\r\n let msg = null;\r\n if (args.column.validator){\r\n let validationResults = args.column.validator($select.val(), args);\r\n valid = validationResults.valid;\r\n msg = validationResults.msg;\r\n }\r\n\r\n return {\r\n valid: true,\r\n msg: null\r\n };\r\n };\r\n\r\n this.init();\r\n}\r\n\r\nfunction CheckboxEditor(args){\r\n let $select;\r\n let defaultValue;\r\n let scope = this;\r\n\r\n this.init = function(){\r\n $select = $(\"\");\r\n $select.appendTo(args.container);\r\n $select.focus();\r\n };\r\n\r\n this.destroy = function(){\r\n $select.remove();\r\n };\r\n\r\n this.focus = function(){\r\n $select.focus();\r\n };\r\n\r\n this.loadValue = function(item){\r\n defaultValue = !!item[args.column.field];\r\n if (defaultValue){\r\n $select.prop('checked', true);\r\n } else {\r\n $select.prop('checked', false);\r\n }\r\n };\r\n\r\n this.serializeValue = function(){\r\n return $select.prop('checked');\r\n };\r\n\r\n this.applyValue = function(item, state){\r\n item[args.column.field] = state;\r\n };\r\n\r\n this.isValueChanged = function(){\r\n return (this.serializeValue() !== defaultValue);\r\n };\r\n\r\n this.validate = function(){\r\n let valid = true;\r\n let msg = null;\r\n if (args.column.validator){\r\n let validationResults = args.column.validator($select.val(), args);\r\n valid = validationResults.valid;\r\n msg = validationResults.msg;\r\n }\r\n\r\n return {\r\n valid: true,\r\n msg: null\r\n };\r\n };\r\n\r\n this.init();\r\n}\r\n\r\nfunction PercentCompleteEditor(args){\r\n console.error('PercentCompleteEditor is derecated');\r\n}\r\n\r\n/*\r\n * An example of a \"detached\" editor.\r\n * The UI is added onto document BODY and .position(), .show() and .hide() are implemented.\r\n * KeyDown events are also handled to provide handling for Tab, Shift-Tab, Esc and Ctrl-Enter.\r\n */\r\nfunction LongTextEditor(args){\r\n let $input, $wrapper;\r\n let defaultValue;\r\n let scope = this;\r\n\r\n this.init = function(){\r\n let $container = $('body');\r\n\r\n $wrapper = $(\"\").appendTo($container);\r\n $input = $(\"\").appendTo($wrapper);\r\n\r\n $(\"
\").appendTo($wrapper);\r\n\r\n $wrapper.find('button:first').bind('click', this.save);\r\n $wrapper.find('button:last').bind('click', this.cancel);\r\n $input.bind('keydown', this.handleKeyDown);\r\n\r\n scope.position(args.position);\r\n $input.focus().select();\r\n };\r\n\r\n this.handleKeyDown = function(e){\r\n if (e.which == keyCode.ENTER && e.ctrlKey){\r\n scope.save();\r\n } else if (e.which == keyCode.ESCAPE){\r\n e.preventDefault();\r\n scope.cancel();\r\n } else if (e.which == keyCode.TAB && e.shiftKey){\r\n e.preventDefault();\r\n args.grid.navigatePrev();\r\n } else if (e.which == keyCode.TAB){\r\n e.preventDefault();\r\n args.grid.navigateNext();\r\n }\r\n };\r\n\r\n this.save = function(){\r\n args.commitChanges();\r\n };\r\n\r\n this.cancel = function(){\r\n $input.val(defaultValue);\r\n args.cancelChanges();\r\n };\r\n\r\n this.hide = function(){\r\n $wrapper.hide();\r\n };\r\n\r\n this.show = function(){\r\n $wrapper.show();\r\n };\r\n\r\n this.position = function(position){\r\n $wrapper\r\n .css('top', position.top - 5)\r\n .css('left', position.left - 5);\r\n };\r\n\r\n this.destroy = function(){\r\n $wrapper.remove();\r\n };\r\n\r\n this.focus = function(){\r\n $input.focus();\r\n };\r\n\r\n this.loadValue = function(item){\r\n $input.val(defaultValue = item[args.column.field]);\r\n $input.select();\r\n };\r\n\r\n this.serializeValue = function(){\r\n return $input.val();\r\n };\r\n\r\n this.applyValue = function(item, state){\r\n item[args.column.field] = state;\r\n };\r\n\r\n this.isValueChanged = function(){\r\n return (!($input.val() == '' && defaultValue == null)) && ($input.val() != defaultValue);\r\n };\r\n\r\n this.validate = function(){\r\n let valid = true;\r\n let msg = null;\r\n if (args.column.validator){\r\n let validationResults = args.column.validator($select.val(), args);\r\n valid = validationResults.valid;\r\n msg = validationResults.msg;\r\n }\r\n\r\n return {\r\n valid: true,\r\n msg: null\r\n };\r\n };\r\n\r\n this.init();\r\n}\r\n\n\n\n// WEBPACK FOOTER //\n// ../src/slick.editors.js","function PercentCompleteFormatter(row, cell, value, columnDef, dataContext){\r\n if (value == null || value === ''){\r\n return '-';\r\n } else if (value < 50){\r\n return `${value}%`;\r\n } else {\r\n return `${value}%`;\r\n }\r\n}\r\n\r\nfunction PercentCompleteBarFormatter(row, cell, value, columnDef, dataContext){\r\n if (value == null || value === ''){\r\n return '';\r\n }\r\n\r\n let color;\r\n\r\n if (value < 30){\r\n color = 'red';\r\n } else if (value < 70){\r\n color = 'silver';\r\n } else {\r\n color = 'green';\r\n }\r\n\r\n return \"\";\r\n}\r\n\r\nfunction YesNoFormatter(row, cell, value, columnDef, dataContext){\r\n return value ? 'Yes' : 'No';\r\n}\r\n\r\nfunction CheckmarkFormatter(row, cell, value, columnDef, dataContext){\r\n return value ? '✔' : '';\r\n}\r\n\r\nexport default {\r\n PercentComplete: PercentCompleteFormatter,\r\n PercentCompleteBar: PercentCompleteBarFormatter,\r\n YesNo: YesNoFormatter,\r\n Checkmark: CheckmarkFormatter\r\n};\r\n\n\n\n// WEBPACK FOOTER //\n// ../src/slick.formatters.js","/**\r\n * @license\r\n * (c) 2009-2013 Michael Leibman\r\n * michael{dot}leibman{at}gmail{dot}com\r\n * http://github.com/mleibman/slickgrid\r\n *\r\n * Distributed under MIT license.\r\n * All rights reserved.\r\n *\r\n * SlickGrid v2.2\r\n *\r\n * NOTES:\r\n * Cell/row DOM manipulations are done directly bypassing jQuery's DOM manipulation methods.\r\n * This increases the speed dramatically, but can only be done safely because there are no event handlers\r\n * or data associated with any cell/row DOM nodes. Cell editors must make sure they implement .destroy()\r\n * and do proper cleanup.\r\n */\r\n\r\nimport $ from 'jquery';\r\nimport interact from './interact.js';\r\n\r\nimport Slick from './slick.core';\r\n\r\n// Slick.Grid globals pretense\r\nSlick.Grid = SlickGrid;\r\n\r\nexport default SlickGrid;\r\n\r\n// shared across all grids on the page\r\nvar scrollbarDimensions;\r\nvar maxSupportedCssHeight; // browser's breaking point\r\n\r\n// ////////////////////////////////////////////////////////////////////////////////////////////\r\n// SlickGrid class implementation (available as Slick.Grid)\r\n\r\n/**\r\n * Creates a new instance of the grid.\r\n * @class SlickGrid\r\n * @constructor\r\n * @param {Node} container Container node to create the grid in.\r\n * @param {Array,Object} data An array of objects for databinding.\r\n * @param {Array} columns An array of column definitions.\r\n * @param {Object} options Grid options.\r\n **/\r\nfunction SlickGrid(container, data, columns, options){\r\n // settings\r\n var defaults = {\r\n explicitInitialization: false,\r\n rowHeight: 25,\r\n defaultColumnWidth: 80,\r\n enableAddRow: false,\r\n leaveSpaceForNewRows: false,\r\n editable: false,\r\n autoEdit: true,\r\n enableCellNavigation: true,\r\n enableColumnReorder: true,\r\n asyncEditorLoading: false,\r\n asyncEditorLoadDelay: 100,\r\n forceFitColumns: false,\r\n enableAsyncPostRender: false,\r\n asyncPostRenderDelay: 50,\r\n enableAsyncPostRenderCleanup: false,\r\n asyncPostRenderCleanupDelay: 40,\r\n autoHeight: false,\r\n editorLock: Slick.GlobalEditorLock,\r\n showHeaderRow: false,\r\n headerRowHeight: 25,\r\n createFooterRow: false,\r\n showFooterRow: false,\r\n footerRowHeight: 25,\r\n showTopPanel: false,\r\n topPanelHeight: 25,\r\n formatterFactory: null,\r\n editorFactory: null,\r\n cellFlashingCssClass: 'flashing',\r\n selectedCellCssClass: 'selected',\r\n multiSelect: true,\r\n enableTextSelectionOnCells: false,\r\n dataItemColumnValueExtractor: null,\r\n fullWidthRows: false,\r\n multiColumnSort: false,\r\n defaultFormatter: defaultFormatter,\r\n forceSyncScrolling: false,\r\n addNewRowCssClass: 'new-row'\r\n };\r\n\r\n var columnDefaults = {\r\n name: '',\r\n resizable: true,\r\n sortable: false,\r\n minWidth: 30,\r\n rerenderOnResize: false,\r\n headerCssClass: null,\r\n defaultSortAsc: true,\r\n focusable: true,\r\n selectable: true\r\n };\r\n\r\n // scroller\r\n var th; // virtual height\r\n var h; // real scrollable height\r\n var ph; // page height\r\n var n; // number of pages\r\n var cj; // \"jumpiness\" coefficient\r\n\r\n var page = 0; // current page\r\n var offset = 0; // current page offset\r\n var vScrollDir = 1;\r\n\r\n // private\r\n var initialized = false;\r\n var $container;\r\n var uid = 'slickgrid_' + Math.round(1000000 * Math.random());\r\n var self = this;\r\n var $focusSink, $focusSink2;\r\n var $headerScroller;\r\n var $headers;\r\n var $headerRow, $headerRowScroller, $headerRowSpacer;\r\n var $footerRow, $footerRowScroller, $footerRowSpacer;\r\n var $topPanelScroller;\r\n var $topPanel;\r\n var $viewport;\r\n var $canvas;\r\n var $style;\r\n var $boundAncestors;\r\n var stylesheet, columnCssRulesL, columnCssRulesR;\r\n var viewportH, viewportW;\r\n var canvasWidth;\r\n var viewportHasHScroll, viewportHasVScroll;\r\n var headerColumnWidthDiff = 0, headerColumnHeightDiff = 0, // border+padding\r\n cellWidthDiff = 0, cellHeightDiff = 0, jQueryNewWidthBehaviour = false;\r\n var absoluteColumnMinWidth;\r\n\r\n var tabbingDirection = 1;\r\n var activePosX;\r\n var activeRow, activeCell;\r\n var activeCellNode = null;\r\n var currentEditor = null;\r\n var serializedEditorValue;\r\n var editController;\r\n\r\n var rowsCache = {};\r\n var renderedRows = 0;\r\n var numVisibleRows;\r\n var prevScrollTop = 0;\r\n var scrollTop = 0;\r\n var lastRenderedScrollTop = 0;\r\n var lastRenderedScrollLeft = 0;\r\n var prevScrollLeft = 0;\r\n var scrollLeft = 0;\r\n\r\n var selectionModel;\r\n var selectedRows = [];\r\n\r\n var plugins = [];\r\n var cellCssClasses = {};\r\n\r\n var columnsById = {};\r\n var sortColumns = [];\r\n var columnPosLeft = [];\r\n var columnPosRight = [];\r\n\r\n // async call handles\r\n var h_editorLoader = null;\r\n var h_render = null;\r\n var h_postrender = null;\r\n var h_postrenderCleanup = null;\r\n var postProcessedRows = {};\r\n var postProcessToRow = null;\r\n var postProcessFromRow = null;\r\n var postProcessedCleanupQueue = [];\r\n var postProcessgroupId = 0;\r\n\r\n // perf counters\r\n var counter_rows_rendered = 0;\r\n var counter_rows_removed = 0;\r\n\r\n // These two variables work around a bug with inertial scrolling in Webkit/Blink on Mac.\r\n // See http://crbug.com/312427.\r\n var rowNodeFromLastMouseWheelEvent; // this node must not be deleted while inertial scrolling\r\n var zombieRowNodeFromLastMouseWheelEvent; // node that was hidden instead of getting deleted\r\n var zombieRowCacheFromLastMouseWheelEvent; // row cache for above node\r\n var zombieRowPostProcessedFromLastMouseWheelEvent; // post processing references for above node\r\n\r\n // store css attributes if display:none is active in container or parent\r\n var cssShow = {position: 'absolute', visibility: 'hidden', display: 'block'};\r\n var $hiddenParents;\r\n var oldProps = [];\r\n\r\n // ////////////////////////////////////////////////////////////////////////////////////////////\r\n // Initialization\r\n\r\n function init(){\r\n $container = $(container);\r\n if ($container.length < 1){\r\n throw new Error('SlickGrid requires a valid container, ' + container + ' does not exist in the DOM.');\r\n }\r\n\r\n cacheCssForHiddenInit();\r\n\r\n // calculate these only once and share between grid instances\r\n maxSupportedCssHeight = maxSupportedCssHeight || getMaxSupportedCssHeight();\r\n scrollbarDimensions = scrollbarDimensions || measureScrollbar();\r\n\r\n options = $.extend({}, defaults, options);\r\n validateAndEnforceOptions();\r\n columnDefaults.width = options.defaultColumnWidth;\r\n\r\n columnsById = {};\r\n for (var i = 0; i < columns.length; i++){\r\n var m = columns[i] = $.extend({}, columnDefaults, columns[i]);\r\n columnsById[m.id] = i;\r\n if (m.minWidth && m.width < m.minWidth){\r\n m.width = m.minWidth;\r\n }\r\n if (m.maxWidth && m.width > m.maxWidth){\r\n m.width = m.maxWidth;\r\n }\r\n }\r\n\r\n editController = {\r\n 'commitCurrentEdit': commitCurrentEdit,\r\n 'cancelCurrentEdit': cancelCurrentEdit\r\n };\r\n\r\n $container\r\n .empty()\r\n .css('overflow', 'hidden')\r\n .css('outline', 0)\r\n .addClass(uid)\r\n .addClass('ui-widget');\r\n\r\n // set up a positioning container if needed\r\n if (!/relative|absolute|fixed/.test($container.css('position'))){\r\n $container.css('position', 'relative');\r\n }\r\n\r\n $focusSink = $(\"\").appendTo($container);\r\n\r\n $headerScroller = $(\"\").appendTo($container);\r\n $headers = $(\"\").appendTo($headerScroller);\r\n $headers.width(getHeadersWidth());\r\n\r\n $headerRowScroller = $(\"\").appendTo($container);\r\n $headerRow = $(\"\").appendTo($headerRowScroller);\r\n $headerRowSpacer = $(\"\")\r\n .css('width', getCanvasWidth() + scrollbarDimensions.width + 'px')\r\n .appendTo($headerRowScroller);\r\n\r\n $topPanelScroller = $(\"\").appendTo($container);\r\n $topPanel = $(\"\").appendTo($topPanelScroller);\r\n\r\n if (!options.showTopPanel){\r\n $topPanelScroller.hide();\r\n }\r\n\r\n if (!options.showHeaderRow){\r\n $headerRowScroller.hide();\r\n }\r\n\r\n $viewport = $(\"
\").appendTo($container);\r\n $viewport.css('overflow-y', options.autoHeight ? 'hidden' : 'auto');\r\n\r\n $canvas = $(\"\").appendTo($viewport);\r\n\r\n if (options.createFooterRow){\r\n $footerRowScroller = $(\"\").appendTo($container);\r\n $footerRow = $(\"\").appendTo($footerRowScroller);\r\n $footerRowSpacer = $(\"\")\r\n .css('width', getCanvasWidth() + scrollbarDimensions.width + 'px')\r\n .appendTo($footerRowScroller);\r\n\r\n if (!options.showFooterRow){\r\n $footerRowScroller.hide();\r\n }\r\n }\r\n\r\n $focusSink2 = $focusSink.clone().appendTo($container);\r\n\r\n if (!options.explicitInitialization){\r\n finishInitialization();\r\n }\r\n }\r\n\r\n function finishInitialization(){\r\n if (!initialized){\r\n initialized = true;\r\n\r\n viewportW = parseFloat($.css($container[0], 'width', true));\r\n\r\n // header columns and cells may have different padding/border skewing width calculations (box-sizing, hello?)\r\n // calculate the diff so we can set consistent sizes\r\n measureCellPaddingAndBorder();\r\n\r\n // for usability reasons, all text selection in SlickGrid is disabled\r\n // with the exception of input and textarea elements (selection must\r\n // be enabled there so that editors work as expected); note that\r\n // selection in grid cells (grid body) is already unavailable in\r\n // all browsers except IE\r\n disableSelection($headers); // disable all text selection in header (including input and textarea)\r\n\r\n if (!options.enableTextSelectionOnCells){\r\n // disable text selection in grid cells except in input and textarea elements\r\n // (this is IE-specific, because selectstart event will only fire in IE)\r\n $viewport.bind('selectstart.ui', function(event){\r\n return $(event.target).is('input,textarea');\r\n });\r\n }\r\n\r\n updateColumnCaches();\r\n createColumnHeaders();\r\n setupColumnSort();\r\n createCssRules();\r\n resizeCanvas();\r\n bindAncestorScrollEvents();\r\n\r\n $container\r\n .bind('resize.slickgrid', resizeCanvas);\r\n $viewport\r\n // .bind(\"click\", handleClick)\r\n .bind('scroll', handleScroll);\r\n $headerScroller\r\n .bind('contextmenu', handleHeaderContextMenu)\r\n .bind('click', handleHeaderClick)\r\n .delegate('.slick-header-column', 'mouseenter', handleHeaderMouseEnter)\r\n .delegate('.slick-header-column', 'mouseleave', handleHeaderMouseLeave);\r\n $headerRowScroller\r\n .bind('scroll', handleHeaderRowScroll);\r\n\r\n if (options.createFooterRow){\r\n $footerRowScroller\r\n .bind('scroll', handleFooterRowScroll);\r\n }\r\n\r\n $focusSink.add($focusSink2)\r\n .bind('keydown', handleKeyDown);\r\n $canvas\r\n .bind('keydown', handleKeyDown)\r\n .bind('click', handleClick)\r\n .bind('dblclick', handleDblClick)\r\n .bind('contextmenu', handleContextMenu)\r\n .delegate('.slick-cell', 'mouseenter', handleMouseEnter)\r\n .delegate('.slick-cell', 'mouseleave', handleMouseLeave);\r\n\r\n // legacy support for drag events\r\n interact($canvas[0]).allowFrom('div.slick-cell').draggable({\r\n onmove: handleDrag,\r\n onstart: handleDragStart,\r\n onend: handleDragEnd\r\n }).styleCursor(false);\r\n\r\n // Work around http://crbug.com/312427.\r\n if (navigator.userAgent.toLowerCase().match(/webkit/) &&\r\n navigator.userAgent.toLowerCase().match(/macintosh/)){\r\n $canvas.bind('mousewheel', handleMouseWheel);\r\n }\r\n restoreCssFromHiddenInit();\r\n }\r\n }\r\n\r\n function cacheCssForHiddenInit(){\r\n // handle display:none on container or container parents\r\n $hiddenParents = $container.parents().addBack().not(':visible');\r\n $hiddenParents.each(function(){\r\n var old = {};\r\n for (var name in cssShow){\r\n old[name] = this.style[name];\r\n this.style[name] = cssShow[name];\r\n }\r\n oldProps.push(old);\r\n });\r\n }\r\n\r\n function restoreCssFromHiddenInit(){\r\n // finish handle display:none on container or container parents\r\n // - put values back the way they were\r\n $hiddenParents.each(function(i){\r\n var old = oldProps[i];\r\n for (var name in cssShow){\r\n this.style[name] = old[name];\r\n }\r\n });\r\n }\r\n\r\n function registerPlugin(plugin){\r\n plugins.unshift(plugin);\r\n plugin.init(self);\r\n }\r\n\r\n function unregisterPlugin(plugin){\r\n for (var i = plugins.length; i >= 0; i--){\r\n if (plugins[i] === plugin){\r\n if (plugins[i].destroy){\r\n plugins[i].destroy();\r\n }\r\n plugins.splice(i, 1);\r\n break;\r\n }\r\n }\r\n }\r\n\r\n function setSelectionModel(model){\r\n if (selectionModel){\r\n selectionModel.onSelectedRangesChanged.unsubscribe(handleSelectedRangesChanged);\r\n if (selectionModel.destroy){\r\n selectionModel.destroy();\r\n }\r\n }\r\n\r\n selectionModel = model;\r\n if (selectionModel){\r\n selectionModel.init(self);\r\n selectionModel.onSelectedRangesChanged.subscribe(handleSelectedRangesChanged);\r\n }\r\n }\r\n\r\n function getSelectionModel(){\r\n return selectionModel;\r\n }\r\n\r\n function getCanvasNode(){\r\n return $canvas[0];\r\n }\r\n\r\n function measureScrollbar(){\r\n var $c = $(\"\").appendTo('body');\r\n var dim = {\r\n width: $c.width() - $c[0].clientWidth,\r\n height: $c.height() - $c[0].clientHeight\r\n };\r\n $c.remove();\r\n return dim;\r\n }\r\n\r\n function getHeadersWidth(){\r\n var headersWidth = 0;\r\n for (var i = 0, ii = columns.length; i < ii; i++){\r\n var width = columns[i].width;\r\n headersWidth += width;\r\n }\r\n headersWidth += scrollbarDimensions.width;\r\n return Math.max(headersWidth, viewportW) + 1000;\r\n }\r\n\r\n function getCanvasWidth(){\r\n var availableWidth = viewportHasVScroll ? viewportW - scrollbarDimensions.width : viewportW;\r\n var rowWidth = 0;\r\n var i = columns.length;\r\n while (i--){\r\n rowWidth += columns[i].width;\r\n }\r\n return options.fullWidthRows ? Math.max(rowWidth, availableWidth) : rowWidth;\r\n }\r\n\r\n function updateCanvasWidth(forceColumnWidthsUpdate){\r\n var oldCanvasWidth = canvasWidth;\r\n canvasWidth = getCanvasWidth();\r\n\r\n if (canvasWidth != oldCanvasWidth){\r\n $canvas.width(canvasWidth);\r\n $headerRow.width(canvasWidth);\r\n if (options.createFooterRow){\r\n $footerRow.width(canvasWidth);\r\n }\r\n $headers.width(getHeadersWidth());\r\n viewportHasHScroll = (canvasWidth > viewportW - scrollbarDimensions.width);\r\n }\r\n\r\n var w = canvasWidth + (viewportHasVScroll ? scrollbarDimensions.width : 0);\r\n $headerRowSpacer.width(w);\r\n if (options.createFooterRow){\r\n $footerRowSpacer.width(w);\r\n }\r\n\r\n if (canvasWidth != oldCanvasWidth || forceColumnWidthsUpdate){\r\n applyColumnWidths();\r\n }\r\n }\r\n\r\n function disableSelection($target){\r\n if ($target && $target.jquery){\r\n $target\r\n .attr('unselectable', 'on')\r\n .css('MozUserSelect', 'none')\r\n .bind('selectstart.ui', function(){\r\n return false;\r\n }); // from jquery:ui.core.js 1.7.2\r\n }\r\n }\r\n\r\n function getMaxSupportedCssHeight(){\r\n var supportedHeight = 1000000;\r\n // FF reports the height back but still renders blank after ~6M px\r\n var testUpTo = navigator.userAgent.toLowerCase().match(/firefox/) ? 6000000 : 1000000000;\r\n var div = $(\"\").appendTo(document.body);\r\n\r\n while (true){\r\n var test = supportedHeight * 2;\r\n div.css('height', test);\r\n if (test > testUpTo || div.height() !== test){\r\n break;\r\n } else {\r\n supportedHeight = test;\r\n }\r\n }\r\n\r\n div.remove();\r\n return supportedHeight;\r\n }\r\n\r\n // TODO: this is static. need to handle page mutation.\r\n function bindAncestorScrollEvents(){\r\n var elem = $canvas[0];\r\n while ((elem = elem.parentNode) != document.body && elem != null){\r\n // bind to scroll containers only\r\n if (elem == $viewport[0] || elem.scrollWidth != elem.clientWidth || elem.scrollHeight != elem.clientHeight){\r\n var $elem = $(elem);\r\n if (!$boundAncestors){\r\n $boundAncestors = $elem;\r\n } else {\r\n $boundAncestors = $boundAncestors.add($elem);\r\n }\r\n $elem.bind('scroll.' + uid, handleActiveCellPositionChange);\r\n }\r\n }\r\n }\r\n\r\n function unbindAncestorScrollEvents(){\r\n if (!$boundAncestors){\r\n return;\r\n }\r\n $boundAncestors.unbind('scroll.' + uid);\r\n $boundAncestors = null;\r\n }\r\n\r\n function updateColumnHeader(columnId, title, toolTip){\r\n if (!initialized){\r\n return;\r\n }\r\n var idx = getColumnIndex(columnId);\r\n if (idx == null){\r\n return;\r\n }\r\n\r\n var columnDef = columns[idx];\r\n var $header = $headers.children().eq(idx);\r\n if ($header){\r\n if (title !== undefined){\r\n columns[idx].name = title;\r\n }\r\n if (toolTip !== undefined){\r\n columns[idx].toolTip = toolTip;\r\n }\r\n\r\n trigger(self.onBeforeHeaderCellDestroy, {\r\n 'node': $header[0],\r\n 'column': columnDef,\r\n 'grid': self\r\n });\r\n\r\n $header\r\n .attr('title', toolTip || '')\r\n .children().eq(0).html(title);\r\n\r\n trigger(self.onHeaderCellRendered, {\r\n 'node': $header[0],\r\n 'column': columnDef,\r\n 'grid': self\r\n });\r\n }\r\n }\r\n\r\n function getHeaderRow(){\r\n return $headerRow[0];\r\n }\r\n\r\n function getFooterRow(){\r\n return $footerRow[0];\r\n }\r\n\r\n function getHeaderRowColumn(columnId){\r\n var idx = getColumnIndex(columnId);\r\n var $header = $headerRow.children().eq(idx);\r\n return $header && $header[0];\r\n }\r\n\r\n function getFooterRowColumn(columnId){\r\n var idx = getColumnIndex(columnId);\r\n var $footer = $footerRow.children().eq(idx);\r\n return $footer && $footer[0];\r\n }\r\n\r\n function createColumnHeaders(){\r\n function onMouseEnter(){\r\n $(this).addClass('ui-state-hover');\r\n }\r\n\r\n function onMouseLeave(){\r\n $(this).removeClass('ui-state-hover');\r\n }\r\n\r\n $headers.find('.slick-header-column')\r\n .each(function(){\r\n var columnDef = $(this).data('column');\r\n if (columnDef){\r\n trigger(self.onBeforeHeaderCellDestroy, {\r\n 'node': this,\r\n 'column': columnDef,\r\n 'grid': self\r\n });\r\n }\r\n });\r\n $headers.empty();\r\n $headers.width(getHeadersWidth());\r\n\r\n $headerRow.find('.slick-headerrow-column')\r\n .each(function(){\r\n var columnDef = $(this).data('column');\r\n if (columnDef){\r\n trigger(self.onBeforeHeaderRowCellDestroy, {\r\n 'node': this,\r\n 'column': columnDef,\r\n 'grid': self\r\n });\r\n }\r\n });\r\n $headerRow.empty();\r\n\r\n if (options.createFooterRow){\r\n $footerRow.find('.slick-footerrow-column')\r\n .each(function(){\r\n var columnDef = $(this).data('column');\r\n if (columnDef){\r\n trigger(self.onBeforeFooterRowCellDestroy, {\r\n 'node': this,\r\n 'column': columnDef\r\n });\r\n }\r\n });\r\n $footerRow.empty();\r\n }\r\n\r\n for (var i = 0; i < columns.length; i++){\r\n var m = columns[i];\r\n\r\n var header = $(\"\")\r\n .html(\"\" + m.name + '')\r\n .width(m.width - headerColumnWidthDiff)\r\n .attr('id', '' + uid + m.id)\r\n .attr('title', m.toolTip || '')\r\n .data('column', m)\r\n .addClass(m.headerCssClass || '')\r\n .appendTo($headers);\r\n\r\n if (options.enableColumnReorder || m.sortable){\r\n header\r\n .on('mouseenter', onMouseEnter)\r\n .on('mouseleave', onMouseLeave);\r\n }\r\n\r\n if (m.sortable){\r\n header.addClass('slick-header-sortable');\r\n header.append(\"\");\r\n }\r\n\r\n trigger(self.onHeaderCellRendered, {\r\n 'node': header[0],\r\n 'column': m,\r\n 'grid': self\r\n });\r\n\r\n if (options.showHeaderRow){\r\n var headerRowCell = $(\"\")\r\n .data('column', m)\r\n .appendTo($headerRow);\r\n\r\n trigger(self.onHeaderRowCellRendered, {\r\n 'node': headerRowCell[0],\r\n 'column': m,\r\n 'grid': self\r\n });\r\n }\r\n if (options.createFooterRow && options.showFooterRow){\r\n var footerRowCell = $(\"\")\r\n .data('column', m)\r\n .appendTo($footerRow);\r\n\r\n trigger(self.onFooterRowCellRendered, {\r\n 'node': footerRowCell[0],\r\n 'column': m\r\n });\r\n }\r\n }\r\n\r\n setSortColumns(sortColumns);\r\n setupColumnResize();\r\n if (options.enableColumnReorder){\r\n setupColumnReorder();\r\n }\r\n }\r\n\r\n function setupColumnSort(){\r\n $headers.click(function(e){\r\n // temporary workaround for a bug in jQuery 1.7.1 (http://bugs.jquery.com/ticket/11328)\r\n e.metaKey = e.metaKey || e.ctrlKey;\r\n\r\n if ($(e.target).hasClass('slick-resizable-handle')){\r\n return;\r\n }\r\n\r\n var $col = $(e.target).closest('.slick-header-column');\r\n if (!$col.length){\r\n return;\r\n }\r\n\r\n var column = $col.data('column');\r\n if (column.sortable){\r\n if (!getEditorLock().commitCurrentEdit()){\r\n return;\r\n }\r\n\r\n var sortOpts = null;\r\n var i = 0;\r\n for (; i < sortColumns.length; i++){\r\n if (sortColumns[i].columnId == column.id){\r\n sortOpts = sortColumns[i];\r\n sortOpts.sortAsc = !sortOpts.sortAsc;\r\n break;\r\n }\r\n }\r\n\r\n if (e.metaKey && options.multiColumnSort){\r\n if (sortOpts){\r\n sortColumns.splice(i, 1);\r\n }\r\n }\r\n else {\r\n if ((!e.shiftKey && !e.metaKey) || !options.multiColumnSort){\r\n sortColumns = [];\r\n }\r\n\r\n if (!sortOpts){\r\n sortOpts = {columnId: column.id, sortAsc: column.defaultSortAsc};\r\n sortColumns.push(sortOpts);\r\n } else if (sortColumns.length == 0){\r\n sortColumns.push(sortOpts);\r\n }\r\n }\r\n\r\n setSortColumns(sortColumns);\r\n\r\n if (!options.multiColumnSort){\r\n trigger(self.onSort, {\r\n multiColumnSort: false,\r\n sortCol: column,\r\n sortAsc: sortOpts.sortAsc,\r\n grid: self\r\n }, e);\r\n } else {\r\n trigger(self.onSort, {\r\n multiColumnSort: true,\r\n sortCols: $.map(sortColumns, function(col){\r\n return {sortCol: columns[getColumnIndex(col.columnId)], sortAsc: col.sortAsc};\r\n }),\r\n grid: self\r\n }, e);\r\n }\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Refactored to use interactjs\r\n */\r\n function setupColumnReorder(){\r\n let x = 0;\r\n let delta = 0;\r\n let placeholder = document.createElement('div');\r\n\r\n placeholder.className = 'interact-placeholder';\r\n\r\n interact('.slick-header-column')\r\n .ignoreFrom('.slick-resizable-handle')\r\n .draggable({\r\n inertia: true,\r\n // keep the element within the area of it's parent\r\n restrict: {\r\n restriction: 'parent',\r\n endOnly: true,\r\n elementRect: {top: 0, left: 0, bottom: 0, right: 0}\r\n },\r\n // enable autoScroll\r\n autoScroll: true,\r\n axis: 'x',\r\n onstart: event => {\r\n x = 0;\r\n delta = event.target.offsetWidth;\r\n\r\n // get old order\r\n $headers.find('.slick-header-column').each(function(index){\r\n $(this).data('index', index);\r\n });\r\n\r\n placeholder.style.height = event.target.offsetHeight + 'px';\r\n placeholder.style.width = delta + 'px';\r\n\r\n $(event.target).after(placeholder).css({\r\n position: 'absolute',\r\n zIndex: 1000,\r\n marginLeft: $(event.target).position().left\r\n });\r\n },\r\n\r\n onmove: event => {\r\n x += event.dx;\r\n event.target.style.transform = `translate3d(${x}px, -3px, 100px)`;\r\n // event.target.style.marginLeft = x + 'px';\r\n },\r\n\r\n onend: event => {\r\n x = 0;\r\n delta = 0;\r\n $(event.target).css({\r\n position: 'relative',\r\n zIndex: '',\r\n marginLeft: 0,\r\n transform: 'none'\r\n });\r\n\r\n placeholder.parentNode.removeChild(placeholder);\r\n const newColumns = [];\r\n\r\n $headers.find('.slick-header-column').each(function(index){\r\n newColumns.push(columns[$(this).data('index')]);\r\n $(this).removeData('index');\r\n });\r\n\r\n setColumns(newColumns);\r\n trigger(self.onColumnsReordered, {grid: self});\r\n setupColumnResize();\r\n }\r\n })\r\n .dropzone({\r\n accept: '.slick-header-column',\r\n\r\n ondragenter: event => {\r\n event.target.classList.add('interact-drop-active');\r\n event.relatedTarget.classList.add('interact-can-drop');\r\n },\r\n\r\n ondragleave: event => {\r\n event.target.classList.remove('interact-drop-active');\r\n event.relatedTarget.classList.remove('interact-can-drop');\r\n },\r\n\r\n ondrop: event => {\r\n event.target.classList.remove('interact-drop-active');\r\n event.relatedTarget.classList.remove('interact-can-drop');\r\n $(event.target)[x > 0 ? 'after' : 'before'](event.relatedTarget);\r\n }\r\n }).styleCursor(false);\r\n }\r\n\r\n function setupColumnResize(){\r\n var $col, j, c, pageX, columnElements, minPageX, maxPageX, firstResizable, lastResizable;\r\n columnElements = $headers.children();\r\n columnElements.find('.slick-resizable-handle').remove();\r\n columnElements.each(function(i, e){\r\n if (columns[i].resizable){\r\n if (firstResizable === undefined){\r\n firstResizable = i;\r\n }\r\n lastResizable = i;\r\n }\r\n });\r\n if (firstResizable === undefined){\r\n return;\r\n }\r\n columnElements.each(function(i, element){\r\n if (i < firstResizable || (options.forceFitColumns && i >= lastResizable)){\r\n return;\r\n }\r\n $col = $(element);\r\n\r\n const $handle = $(\"\");\r\n $handle.appendTo(element);\r\n\r\n if ($col.data('resizable'))\r\n return;\r\n\r\n const activeColumn = columns[i];\r\n if (activeColumn.resizable){\r\n $col.data('resizable', true);\r\n interact(element).resizable({\r\n preserveAspectRatio: false,\r\n edges: { left: true, right: true, bottom: false, top: false }\r\n }).on('resizestart', function(event){\r\n if (!getEditorLock().commitCurrentEdit()){\r\n return false;\r\n }\r\n activeColumn.previousWidth = event.rect.width;\r\n event.target.classList.add('slick-header-column-active');\r\n }).on('resizemove', function(event){\r\n let x = event.dx;\r\n let width = activeColumn.width += x;\r\n\r\n if (activeColumn.minWidth > 0 && activeColumn.minWidth > width)\r\n width = activeColumn.minWidth;\r\n else if (activeColumn.maxWidth > 0 && activeColumn.maxWidth < width)\r\n width = activeColumn.maxWidth;\r\n\r\n activeColumn.width = width;\r\n\r\n if (options.forceFitColumns){\r\n autosizeColumns();\r\n }\r\n applyColumnHeaderWidths();\r\n if (options.syncColumnCellResize){\r\n applyColumnWidths();\r\n }\r\n }).on('resizeend', function(event){\r\n event.target.classList.remove('slick-header-column-active');\r\n invalidateAllRows();\r\n updateCanvasWidth(true);\r\n render();\r\n trigger(self.onColumnsResized, {grid: self});\r\n });\r\n }\r\n });\r\n }\r\n\r\n function getVBoxDelta($el){\r\n var p = ['borderTopWidth', 'borderBottomWidth', 'paddingTop', 'paddingBottom'];\r\n var delta = 0;\r\n $.each(p, function(n, val){\r\n delta += parseFloat($el.css(val)) || 0;\r\n });\r\n return delta;\r\n }\r\n\r\n function measureCellPaddingAndBorder(){\r\n var el;\r\n var h = ['borderLeftWidth', 'borderRightWidth', 'paddingLeft', 'paddingRight'];\r\n var v = ['borderTopWidth', 'borderBottomWidth', 'paddingTop', 'paddingBottom'];\r\n\r\n // jquery prior to version 1.8 handles .width setter/getter as a direct css write/read\r\n // jquery 1.8 changed .width to read the true inner element width if box-sizing is set to border-box, and introduced a setter for .outerWidth\r\n // so for equivalent functionality, prior to 1.8 use .width, and after use .outerWidth\r\n var verArray = $.fn.jquery.split('.');\r\n jQueryNewWidthBehaviour = (verArray[0] == 1 && verArray[1] >= 8) || verArray[0] >= 2;\r\n\r\n el = $(\"
\").appendTo(r);\r\n cellWidthDiff = cellHeightDiff = 0;\r\n if (el.css('box-sizing') != 'border-box' && el.css('-moz-box-sizing') != 'border-box' && el.css('-webkit-box-sizing') != 'border-box'){\r\n $.each(h, function(n, val){\r\n cellWidthDiff += parseFloat(el.css(val)) || 0;\r\n });\r\n $.each(v, function(n, val){\r\n cellHeightDiff += parseFloat(el.css(val)) || 0;\r\n });\r\n }\r\n r.remove();\r\n\r\n absoluteColumnMinWidth = Math.max(headerColumnWidthDiff, cellWidthDiff);\r\n }\r\n\r\n function createCssRules() {\r\n $style = $(\"\").appendTo($(\"head\"));\r\n var rowHeight = (options.rowHeight - cellHeightDiff);\r\n if ($style[0].styleSheet) { // IE\r\n $style[0].styleSheet.cssText = \"\";\r\n } else {\r\n $style[0].appendChild(document.createTextNode(\"\"));\r\n }\r\n\r\n var sheet = $style[0].sheet;\r\n var index = 0;\r\n addCSSRule(sheet,\".\" + uid + \" .slick-header-column\", \"left: 0;\", index++);\r\n addCSSRule(sheet,\".\" + uid + \" .slick-top-panel\", \"height:\" + options.topPanelHeight + \"px;\", index++);\r\n addCSSRule(sheet,\".\" + uid + \" .slick-headerrow-columns\", \"height:\" + options.headerRowHeight + \"px;\", index++);\r\n addCSSRule(sheet,\".\" + uid + \" .slick-cell\", \"height:\" + rowHeight + \"px;\", index++);\r\n addCSSRule(sheet,\".\" + uid + \" .slick-row\", \"height:\" + options.rowHeight + \"px;\", index++);\r\n\r\n for (var i = 0; i < columns.length; i++) {\r\n addCSSRule(sheet,\".\" + uid + \" .l\" + i , \"\", index++);\r\n addCSSRule(sheet,\".\" + uid + \" .r\" + i, \"\", index++);\r\n }\r\n }\r\n\r\n function addCSSRule(sheet, selector, rules, index) {\r\n if(sheet.insertRule) {\r\n sheet.insertRule(selector + \"{\" + rules + \"}\", index);\r\n }\r\n else {\r\n sheet.addRule(selector, rules, index);\r\n }\r\n } \r\n\r\n function getColumnCssRules(idx){\r\n if (!stylesheet){\r\n var sheets = document.styleSheets;\r\n for (var i = 0; i < sheets.length; i++){\r\n if ((sheets[i].ownerNode || sheets[i].owningElement) == $style[0]){\r\n stylesheet = sheets[i];\r\n break;\r\n }\r\n }\r\n\r\n if (!stylesheet){\r\n throw new Error('Cannot find stylesheet.');\r\n }\r\n\r\n // find and cache column CSS rules\r\n columnCssRulesL = [];\r\n columnCssRulesR = [];\r\n var cssRules = (stylesheet.cssRules || stylesheet.rules);\r\n var matches, columnIdx;\r\n for (var i = 0; i < cssRules.length; i++){\r\n var selector = cssRules[i].selectorText;\r\n if (matches = /\\.l\\d+/.exec(selector)){\r\n columnIdx = parseInt(matches[0].substr(2, matches[0].length - 2), 10);\r\n columnCssRulesL[columnIdx] = cssRules[i];\r\n } else if (matches = /\\.r\\d+/.exec(selector)){\r\n columnIdx = parseInt(matches[0].substr(2, matches[0].length - 2), 10);\r\n columnCssRulesR[columnIdx] = cssRules[i];\r\n }\r\n }\r\n }\r\n\r\n return {\r\n 'left': columnCssRulesL[idx],\r\n 'right': columnCssRulesR[idx]\r\n };\r\n }\r\n\r\n function removeCssRules(){\r\n $style.remove();\r\n stylesheet = null;\r\n }\r\n\r\n function destroy(){\r\n getEditorLock().cancelCurrentEdit();\r\n\r\n trigger(self.onBeforeDestroy, {grid: self});\r\n\r\n var i = plugins.length;\r\n while (i--){\r\n unregisterPlugin(plugins[i]);\r\n }\r\n\r\n unbindAncestorScrollEvents();\r\n $container.unbind('.slickgrid');\r\n removeCssRules();\r\n\r\n $container.empty().removeClass(uid);\r\n }\r\n\r\n // ////////////////////////////////////////////////////////////////////////////////////////////\r\n // General\r\n\r\n function trigger(evt, args, e){\r\n e = e || new Slick.EventData();\r\n args = args || {};\r\n args.grid = self;\r\n return evt.notify(args, e, self);\r\n }\r\n\r\n function getEditorLock(){\r\n return options.editorLock;\r\n }\r\n\r\n function getEditController(){\r\n return editController;\r\n }\r\n\r\n function getColumnIndex(id){\r\n return columnsById[id];\r\n }\r\n\r\n function autosizeColumns(){\r\n var i, c,\r\n widths = [],\r\n shrinkLeeway = 0,\r\n total = 0,\r\n prevTotal,\r\n availWidth = viewportHasVScroll ? viewportW - scrollbarDimensions.width : viewportW;\r\n\r\n for (i = 0; i < columns.length; i++){\r\n c = columns[i];\r\n widths.push(c.width);\r\n total += c.width;\r\n if (c.resizable){\r\n shrinkLeeway += c.width - Math.max(c.minWidth, absoluteColumnMinWidth);\r\n }\r\n }\r\n\r\n // shrink\r\n prevTotal = total;\r\n while (total > availWidth && shrinkLeeway){\r\n var shrinkProportion = (total - availWidth) / shrinkLeeway;\r\n for (i = 0; i < columns.length && total > availWidth; i++){\r\n c = columns[i];\r\n var width = widths[i];\r\n if (!c.resizable || width <= c.minWidth || width <= absoluteColumnMinWidth){\r\n continue;\r\n }\r\n var absMinWidth = Math.max(c.minWidth, absoluteColumnMinWidth);\r\n var shrinkSize = Math.floor(shrinkProportion * (width - absMinWidth)) || 1;\r\n shrinkSize = Math.min(shrinkSize, width - absMinWidth);\r\n total -= shrinkSize;\r\n shrinkLeeway -= shrinkSize;\r\n widths[i] -= shrinkSize;\r\n }\r\n if (prevTotal <= total){ // avoid infinite loop\r\n break;\r\n }\r\n prevTotal = total;\r\n }\r\n\r\n // grow\r\n prevTotal = total;\r\n while (total < availWidth){\r\n var growProportion = availWidth / total;\r\n for (i = 0; i < columns.length && total < availWidth; i++){\r\n c = columns[i];\r\n var currentWidth = widths[i];\r\n var growSize;\r\n\r\n if (!c.resizable || c.maxWidth <= currentWidth){\r\n growSize = 0;\r\n } else {\r\n growSize = Math.min(Math.floor(growProportion * currentWidth) - currentWidth, (c.maxWidth - currentWidth) || 1000000) || 1;\r\n }\r\n total += growSize;\r\n widths[i] += (total <= availWidth ? growSize : 0);\r\n }\r\n if (prevTotal >= total){ // avoid infinite loop\r\n break;\r\n }\r\n prevTotal = total;\r\n }\r\n\r\n var reRender = false;\r\n for (i = 0; i < columns.length; i++){\r\n if (columns[i].rerenderOnResize && columns[i].width != widths[i]){\r\n reRender = true;\r\n }\r\n columns[i].width = widths[i];\r\n }\r\n\r\n applyColumnHeaderWidths();\r\n updateCanvasWidth(true);\r\n if (reRender){\r\n invalidateAllRows();\r\n render();\r\n }\r\n }\r\n\r\n function applyColumnHeaderWidths(){\r\n if (!initialized){\r\n return;\r\n }\r\n var h;\r\n for (var i = 0, headers = $headers.children('[id]'), ii = headers.length; i < ii; i++){\r\n h = $(headers[i]);\r\n if (jQueryNewWidthBehaviour){\r\n if (h.outerWidth() !== columns[i].width){\r\n h.outerWidth(columns[i].width);\r\n }\r\n } else {\r\n if (h.width() !== columns[i].width - headerColumnWidthDiff){\r\n h.width(columns[i].width - headerColumnWidthDiff);\r\n }\r\n }\r\n }\r\n\r\n updateColumnCaches();\r\n }\r\n\r\n function applyColumnWidths(){\r\n var x = 0, w, rule;\r\n for (var i = 0; i < columns.length; i++){\r\n w = columns[i].width;\r\n\r\n rule = getColumnCssRules(i);\r\n rule.left.style.left = x + 'px';\r\n rule.right.style.right = (canvasWidth - x - w) + 'px';\r\n\r\n x += columns[i].width;\r\n }\r\n }\r\n\r\n function setSortColumn(columnId, ascending){\r\n setSortColumns([{columnId: columnId, sortAsc: ascending}]);\r\n }\r\n\r\n function setSortColumns(cols){\r\n sortColumns = cols;\r\n\r\n var headerColumnEls = $headers.children();\r\n headerColumnEls\r\n .removeClass('slick-header-column-sorted')\r\n .find('.slick-sort-indicator')\r\n .removeClass('slick-sort-indicator-asc slick-sort-indicator-desc');\r\n\r\n $.each(sortColumns, function(i, col){\r\n if (col.sortAsc == null){\r\n col.sortAsc = true;\r\n }\r\n var columnIndex = getColumnIndex(col.columnId);\r\n if (columnIndex != null){\r\n headerColumnEls.eq(columnIndex)\r\n .addClass('slick-header-column-sorted')\r\n .find('.slick-sort-indicator')\r\n .addClass(col.sortAsc ? 'slick-sort-indicator-asc' : 'slick-sort-indicator-desc');\r\n }\r\n });\r\n }\r\n\r\n function getSortColumns(){\r\n return sortColumns;\r\n }\r\n\r\n function handleSelectedRangesChanged(e, ranges){\r\n selectedRows = [];\r\n var hash = {};\r\n for (var i = 0; i < ranges.length; i++){\r\n for (var j = ranges[i].fromRow; j <= ranges[i].toRow; j++){\r\n if (!hash[j]){ // prevent duplicates\r\n selectedRows.push(j);\r\n hash[j] = {};\r\n }\r\n for (var k = ranges[i].fromCell; k <= ranges[i].toCell; k++){\r\n if (canCellBeSelected(j, k)){\r\n hash[j][columns[k].id] = options.selectedCellCssClass;\r\n }\r\n }\r\n }\r\n }\r\n\r\n setCellCssStyles(options.selectedCellCssClass, hash);\r\n\r\n trigger(self.onSelectedRowsChanged, {rows: getSelectedRows(), grid: self}, e);\r\n }\r\n\r\n function getColumns(){\r\n return columns;\r\n }\r\n\r\n function updateColumnCaches(){\r\n // Pre-calculate cell boundaries.\r\n columnPosLeft = [];\r\n columnPosRight = [];\r\n var x = 0;\r\n for (var i = 0, ii = columns.length; i < ii; i++){\r\n columnPosLeft[i] = x;\r\n columnPosRight[i] = x + columns[i].width;\r\n x += columns[i].width;\r\n }\r\n }\r\n\r\n function setColumns(columnDefinitions){\r\n columns = columnDefinitions;\r\n\r\n columnsById = {};\r\n for (var i = 0; i < columns.length; i++){\r\n var m = columns[i] = $.extend({}, columnDefaults, columns[i]);\r\n columnsById[m.id] = i;\r\n if (m.minWidth && m.width < m.minWidth){\r\n m.width = m.minWidth;\r\n }\r\n if (m.maxWidth && m.width > m.maxWidth){\r\n m.width = m.maxWidth;\r\n }\r\n }\r\n\r\n updateColumnCaches();\r\n\r\n if (initialized){\r\n invalidateAllRows();\r\n createColumnHeaders();\r\n removeCssRules();\r\n createCssRules();\r\n resizeCanvas();\r\n applyColumnWidths();\r\n handleScroll();\r\n }\r\n }\r\n\r\n function getOptions(){\r\n return options;\r\n }\r\n\r\n function setOptions(args){\r\n if (!getEditorLock().commitCurrentEdit()){\r\n return;\r\n }\r\n\r\n makeActiveCellNormal();\r\n\r\n if (options.enableAddRow !== args.enableAddRow){\r\n invalidateRow(getDataLength());\r\n }\r\n\r\n options = $.extend(options, args);\r\n validateAndEnforceOptions();\r\n\r\n $viewport.css('overflow-y', options.autoHeight ? 'hidden' : 'auto');\r\n render();\r\n }\r\n\r\n function validateAndEnforceOptions(){\r\n if (options.autoHeight){\r\n options.leaveSpaceForNewRows = false;\r\n }\r\n }\r\n\r\n function setData(newData, scrollToTop){\r\n data = newData;\r\n invalidateAllRows();\r\n updateRowCount();\r\n if (scrollToTop){\r\n scrollTo(0);\r\n }\r\n }\r\n\r\n function getData(){\r\n return data;\r\n }\r\n\r\n function getDataLength(){\r\n if (data.getLength){\r\n return data.getLength();\r\n } else {\r\n return data.length;\r\n }\r\n }\r\n\r\n function getDataLengthIncludingAddNew(){\r\n return getDataLength() + (options.enableAddRow ? 1 : 0);\r\n }\r\n\r\n function getDataItem(i){\r\n if (data.getItem){\r\n return data.getItem(i);\r\n } else {\r\n return data[i];\r\n }\r\n }\r\n\r\n function getTopPanel(){\r\n return $topPanel[0];\r\n }\r\n\r\n function setTopPanelVisibility(visible){\r\n if (options.showTopPanel != visible){\r\n options.showTopPanel = visible;\r\n if (visible){\r\n $topPanelScroller.slideDown('fast', resizeCanvas);\r\n } else {\r\n $topPanelScroller.slideUp('fast', resizeCanvas);\r\n }\r\n }\r\n }\r\n\r\n function setHeaderRowVisibility(visible){\r\n if (options.showHeaderRow != visible){\r\n options.showHeaderRow = visible;\r\n if (visible){\r\n $headerRowScroller.slideDown('fast', resizeCanvas);\r\n } else {\r\n $headerRowScroller.slideUp('fast', resizeCanvas);\r\n }\r\n }\r\n }\r\n\r\n function setFooterRowVisibility(visible){\r\n if (options.showFooterRow != visible){\r\n options.showFooterRow = visible;\r\n if (visible){\r\n $footerRowScroller.slideDown('fast', resizeCanvas);\r\n } else {\r\n $footerRowScroller.slideUp('fast', resizeCanvas);\r\n }\r\n }\r\n }\r\n\r\n function getContainerNode(){\r\n return $container.get(0);\r\n }\r\n\r\n // ////////////////////////////////////////////////////////////////////////////////////////////\r\n // Rendering / Scrolling\r\n\r\n function getRowTop(row){\r\n return options.rowHeight * row - offset;\r\n }\r\n\r\n function getRowFromPosition(y){\r\n return Math.floor((y + offset) / options.rowHeight);\r\n }\r\n\r\n function scrollTo(y){\r\n y = Math.max(y, 0);\r\n y = Math.min(y, th - viewportH + (viewportHasHScroll ? scrollbarDimensions.height : 0));\r\n\r\n var oldOffset = offset;\r\n\r\n page = Math.min(n - 1, Math.floor(y / ph));\r\n offset = Math.round(page * cj);\r\n var newScrollTop = y - offset;\r\n\r\n if (offset != oldOffset){\r\n var range = getVisibleRange(newScrollTop);\r\n cleanupRows(range);\r\n updateRowPositions();\r\n }\r\n\r\n if (prevScrollTop != newScrollTop){\r\n vScrollDir = (prevScrollTop + oldOffset < newScrollTop + offset) ? 1 : -1;\r\n $viewport[0].scrollTop = (lastRenderedScrollTop = scrollTop = prevScrollTop = newScrollTop);\r\n\r\n trigger(self.onViewportChanged, {grid: self});\r\n }\r\n }\r\n\r\n function defaultFormatter(row, cell, value, columnDef, dataContext){\r\n if (value == null){\r\n return '';\r\n } else {\r\n return (value + '').replace(/&/g, '&').replace(//g, '>');\r\n }\r\n }\r\n\r\n function getFormatter(row, column){\r\n var rowMetadata = data.getItemMetadata && data.getItemMetadata(row);\r\n\r\n // look up by id, then index\r\n var columnOverrides = rowMetadata &&\r\n rowMetadata.columns &&\r\n (rowMetadata.columns[column.id] || rowMetadata.columns[getColumnIndex(column.id)]);\r\n\r\n return (columnOverrides && columnOverrides.formatter) ||\r\n (rowMetadata && rowMetadata.formatter) ||\r\n column.formatter ||\r\n (options.formatterFactory && options.formatterFactory.getFormatter(column)) ||\r\n options.defaultFormatter;\r\n }\r\n\r\n function getEditor(row, cell){\r\n var column = columns[cell];\r\n var rowMetadata = data.getItemMetadata && data.getItemMetadata(row);\r\n var columnMetadata = rowMetadata && rowMetadata.columns;\r\n\r\n if (columnMetadata && columnMetadata[column.id] && columnMetadata[column.id].editor !== undefined){\r\n return columnMetadata[column.id].editor;\r\n }\r\n if (columnMetadata && columnMetadata[cell] && columnMetadata[cell].editor !== undefined){\r\n return columnMetadata[cell].editor;\r\n }\r\n\r\n return column.editor || (options.editorFactory && options.editorFactory.getEditor(column));\r\n }\r\n\r\n function getDataItemValueForColumn(item, columnDef){\r\n if (options.dataItemColumnValueExtractor){\r\n return options.dataItemColumnValueExtractor(item, columnDef);\r\n }\r\n return item[columnDef.field];\r\n }\r\n\r\n function appendRowHtml(stringArray, row, range, dataLength){\r\n var d = getDataItem(row);\r\n var dataLoading = row < dataLength && !d;\r\n var rowCss = 'slick-row' +\r\n (dataLoading ? ' loading' : '') +\r\n (row === activeRow ? ' active' : '') +\r\n (row % 2 == 1 ? ' odd' : ' even');\r\n\r\n if (!d){\r\n rowCss += ' ' + options.addNewRowCssClass;\r\n }\r\n\r\n var metadata = data.getItemMetadata && data.getItemMetadata(row);\r\n\r\n if (metadata && metadata.cssClasses){\r\n rowCss += ' ' + metadata.cssClasses;\r\n }\r\n\r\n stringArray.push(\"
\");\r\n\r\n var colspan, m;\r\n for (var i = 0, ii = columns.length; i < ii; i++){\r\n m = columns[i];\r\n colspan = 1;\r\n if (metadata && metadata.columns){\r\n var columnData = metadata.columns[m.id] || metadata.columns[i];\r\n colspan = (columnData && columnData.colspan) || 1;\r\n if (colspan === '*'){\r\n colspan = ii - i;\r\n }\r\n }\r\n\r\n // Do not render cells outside of the viewport.\r\n if (columnPosRight[Math.min(ii - 1, i + colspan - 1)] > range.leftPx){\r\n if (columnPosLeft[i] > range.rightPx){\r\n // All columns to the right are outside the range.\r\n break;\r\n }\r\n\r\n appendCellHtml(stringArray, row, i, colspan, d);\r\n }\r\n\r\n if (colspan > 1){\r\n i += (colspan - 1);\r\n }\r\n }\r\n\r\n stringArray.push('
');\r\n }\r\n\r\n function appendCellHtml(stringArray, row, cell, colspan, item){\r\n // stringArray: stringBuilder containing the HTML parts\r\n // row, cell: row and column index\r\n // colspan: HTML colspan\r\n // item: grid data for row\r\n\r\n var m = columns[cell];\r\n var cellCss = 'slick-cell l' + cell + ' r' + Math.min(columns.length - 1, cell + colspan - 1) +\r\n (m.cssClass ? ' ' + m.cssClass : '');\r\n if (row === activeRow && cell === activeCell){\r\n cellCss += (' active');\r\n }\r\n\r\n // TODO: merge them together in the setter\r\n for (var key in cellCssClasses){\r\n if (cellCssClasses[key][row] && cellCssClasses[key][row][m.id]){\r\n cellCss += (' ' + cellCssClasses[key][row][m.id]);\r\n }\r\n }\r\n\r\n stringArray.push(\"
\");\r\n\r\n // if there is a corresponding row (if not, this is the Add New row or this data hasn't been loaded yet)\r\n if (item){\r\n var value = getDataItemValueForColumn(item, m);\r\n stringArray.push(getFormatter(row, m)(row, cell, value, m, item));\r\n }\r\n\r\n stringArray.push('
');\r\n\r\n rowsCache[row].cellRenderQueue.push(cell);\r\n rowsCache[row].cellColSpans[cell] = colspan;\r\n }\r\n\r\n function cleanupRows(rangeToKeep){\r\n for (var i in rowsCache){\r\n if (((i = parseInt(i, 10)) !== activeRow) && (i < rangeToKeep.top || i > rangeToKeep.bottom)){\r\n removeRowFromCache(i);\r\n }\r\n }\r\n if (options.enableAsyncPostRenderCleanup){\r\n startPostProcessingCleanup();\r\n }\r\n }\r\n\r\n function invalidate(){\r\n updateRowCount();\r\n invalidateAllRows();\r\n render();\r\n }\r\n\r\n function invalidateAllRows(){\r\n if (currentEditor){\r\n makeActiveCellNormal();\r\n }\r\n for (var row in rowsCache){\r\n removeRowFromCache(row);\r\n }\r\n if (options.enableAsyncPostRenderCleanup){\r\n startPostProcessingCleanup();\r\n }\r\n }\r\n\r\n function queuePostProcessedRowForCleanup(cacheEntry, postProcessedRow, rowIdx){\r\n postProcessgroupId++;\r\n\r\n // store and detach node for later async cleanup\r\n for (var columnIdx in postProcessedRow){\r\n if (postProcessedRow.hasOwnProperty(columnIdx)){\r\n postProcessedCleanupQueue.push({\r\n actionType: 'C',\r\n groupId: postProcessgroupId,\r\n node: cacheEntry.cellNodesByColumnIdx[columnIdx | 0],\r\n columnIdx: columnIdx | 0,\r\n rowIdx: rowIdx\r\n });\r\n }\r\n }\r\n postProcessedCleanupQueue.push({\r\n actionType: 'R',\r\n groupId: postProcessgroupId,\r\n node: cacheEntry.rowNode\r\n });\r\n $(cacheEntry.rowNode).detach();\r\n }\r\n\r\n function queuePostProcessedCellForCleanup(cellnode, columnIdx, rowIdx){\r\n postProcessedCleanupQueue.push({\r\n actionType: 'C',\r\n groupId: postProcessgroupId,\r\n node: cellnode,\r\n columnIdx: columnIdx,\r\n rowIdx: rowIdx\r\n });\r\n $(cellnode).detach();\r\n }\r\n\r\n function removeRowFromCache(row){\r\n var cacheEntry = rowsCache[row];\r\n if (!cacheEntry){\r\n return;\r\n }\r\n\r\n if (rowNodeFromLastMouseWheelEvent === cacheEntry.rowNode){\r\n cacheEntry.rowNode.style.display = 'none';\r\n zombieRowNodeFromLastMouseWheelEvent = rowNodeFromLastMouseWheelEvent;\r\n zombieRowCacheFromLastMouseWheelEvent = cacheEntry;\r\n zombieRowPostProcessedFromLastMouseWheelEvent = postProcessedRows[row];\r\n // ignore post processing cleanup in this case - it will be dealt with later\r\n } else {\r\n if (options.enableAsyncPostRenderCleanup && postProcessedRows[row]){\r\n queuePostProcessedRowForCleanup(cacheEntry, postProcessedRows[row], row);\r\n } else {\r\n $canvas[0].removeChild(cacheEntry.rowNode);\r\n }\r\n }\r\n\r\n delete rowsCache[row];\r\n delete postProcessedRows[row];\r\n renderedRows--;\r\n counter_rows_removed++;\r\n }\r\n\r\n function invalidateRows(rows){\r\n var i, rl;\r\n if (!rows || !rows.length){\r\n return;\r\n }\r\n vScrollDir = 0;\r\n for (i = 0, rl = rows.length; i < rl; i++){\r\n if (currentEditor && activeRow === rows[i]){\r\n makeActiveCellNormal();\r\n }\r\n if (rowsCache[rows[i]]){\r\n removeRowFromCache(rows[i]);\r\n }\r\n }\r\n if (options.enableAsyncPostRenderCleanup){\r\n startPostProcessingCleanup();\r\n }\r\n }\r\n\r\n function invalidateRow(row){\r\n invalidateRows([row]);\r\n }\r\n\r\n function updateCell(row, cell){\r\n var cellNode = getCellNode(row, cell);\r\n if (!cellNode){\r\n return;\r\n }\r\n\r\n var m = columns[cell], d = getDataItem(row);\r\n if (currentEditor && activeRow === row && activeCell === cell){\r\n currentEditor.loadValue(d);\r\n } else {\r\n cellNode.innerHTML = d ? getFormatter(row, m)(row, cell, getDataItemValueForColumn(d, m), m, d) : '';\r\n invalidatePostProcessingResults(row);\r\n }\r\n }\r\n\r\n function updateRow(row){\r\n var cacheEntry = rowsCache[row];\r\n if (!cacheEntry){\r\n return;\r\n }\r\n\r\n ensureCellNodesInRowsCache(row);\r\n\r\n var d = getDataItem(row);\r\n\r\n for (var columnIdx in cacheEntry.cellNodesByColumnIdx){\r\n if (!cacheEntry.cellNodesByColumnIdx.hasOwnProperty(columnIdx)){\r\n continue;\r\n }\r\n\r\n columnIdx = columnIdx | 0;\r\n var m = columns[columnIdx],\r\n node = cacheEntry.cellNodesByColumnIdx[columnIdx];\r\n\r\n if (row === activeRow && columnIdx === activeCell && currentEditor){\r\n currentEditor.loadValue(d);\r\n } else if (d){\r\n node.innerHTML = getFormatter(row, m)(row, columnIdx, getDataItemValueForColumn(d, m), m, d);\r\n } else {\r\n node.innerHTML = '';\r\n }\r\n }\r\n\r\n invalidatePostProcessingResults(row);\r\n }\r\n\r\n function getViewportHeight(){\r\n return parseFloat($.css($container[0], 'height', true)) -\r\n parseFloat($.css($container[0], 'paddingTop', true)) -\r\n parseFloat($.css($container[0], 'paddingBottom', true)) -\r\n parseFloat($.css($headerScroller[0], 'height')) - getVBoxDelta($headerScroller) -\r\n (options.showTopPanel ? options.topPanelHeight + getVBoxDelta($topPanelScroller) : 0) -\r\n (options.showHeaderRow ? options.headerRowHeight + getVBoxDelta($headerRowScroller) : 0) -\r\n (options.createFooterRow && options.showFooterRow ? options.footerRowHeight + getVBoxDelta($footerRowScroller) : 0);\r\n }\r\n\r\n function resizeCanvas(){\r\n if (!initialized){\r\n return;\r\n }\r\n if (options.autoHeight){\r\n viewportH = options.rowHeight * getDataLengthIncludingAddNew();\r\n } else {\r\n viewportH = getViewportHeight();\r\n }\r\n\r\n numVisibleRows = Math.ceil(viewportH / options.rowHeight);\r\n viewportW = parseFloat($.css($container[0], 'width', true));\r\n if (!options.autoHeight){\r\n $viewport.height(viewportH);\r\n }\r\n\r\n if (options.forceFitColumns){\r\n autosizeColumns();\r\n }\r\n\r\n updateRowCount();\r\n handleScroll();\r\n // Since the width has changed, force the render() to reevaluate virtually rendered cells.\r\n lastRenderedScrollLeft = -1;\r\n render();\r\n }\r\n\r\n function updateRowCount(){\r\n if (!initialized){\r\n return;\r\n }\r\n\r\n var dataLengthIncludingAddNew = getDataLengthIncludingAddNew();\r\n var numberOfRows = dataLengthIncludingAddNew +\r\n (options.leaveSpaceForNewRows ? numVisibleRows - 1 : 0);\r\n\r\n var oldViewportHasVScroll = viewportHasVScroll;\r\n // with autoHeight, we do not need to accommodate the vertical scroll bar\r\n viewportHasVScroll = !options.autoHeight && (numberOfRows * options.rowHeight > viewportH);\r\n viewportHasHScroll = (canvasWidth > viewportW - scrollbarDimensions.width);\r\n\r\n makeActiveCellNormal();\r\n\r\n // remove the rows that are now outside of the data range\r\n // this helps avoid redundant calls to .removeRow() when the size of the data decreased by thousands of rows\r\n var l = dataLengthIncludingAddNew - 1;\r\n for (var i in rowsCache){\r\n if (i > l){\r\n removeRowFromCache(i);\r\n }\r\n }\r\n if (options.enableAsyncPostRenderCleanup){\r\n startPostProcessingCleanup();\r\n }\r\n\r\n if (activeCellNode && activeRow > l){\r\n resetActiveCell();\r\n }\r\n\r\n var oldH = h;\r\n th = Math.max(options.rowHeight * numberOfRows, viewportH - scrollbarDimensions.height);\r\n if (th < maxSupportedCssHeight){\r\n // just one page\r\n h = ph = th;\r\n n = 1;\r\n cj = 0;\r\n } else {\r\n // break into pages\r\n h = maxSupportedCssHeight;\r\n ph = h / 100;\r\n n = Math.floor(th / ph);\r\n cj = (th - h) / (n - 1);\r\n }\r\n\r\n if (h !== oldH){\r\n $canvas.css('height', h);\r\n scrollTop = $viewport[0].scrollTop;\r\n }\r\n\r\n var oldScrollTopInRange = (scrollTop + offset <= th - viewportH);\r\n\r\n if (th == 0 || scrollTop == 0){\r\n page = offset = 0;\r\n } else if (oldScrollTopInRange){\r\n // maintain virtual position\r\n scrollTo(scrollTop + offset);\r\n } else {\r\n // scroll to bottom\r\n scrollTo(th - viewportH);\r\n }\r\n\r\n if (h != oldH && options.autoHeight){\r\n resizeCanvas();\r\n }\r\n\r\n if (options.forceFitColumns && oldViewportHasVScroll != viewportHasVScroll){\r\n autosizeColumns();\r\n }\r\n updateCanvasWidth(false);\r\n }\r\n\r\n function getVisibleRange(viewportTop, viewportLeft){\r\n if (viewportTop == null){\r\n viewportTop = scrollTop;\r\n }\r\n if (viewportLeft == null){\r\n viewportLeft = scrollLeft;\r\n }\r\n\r\n return {\r\n top: getRowFromPosition(viewportTop),\r\n bottom: getRowFromPosition(viewportTop + viewportH) + 1,\r\n leftPx: viewportLeft,\r\n rightPx: viewportLeft + viewportW\r\n };\r\n }\r\n\r\n function getRenderedRange(viewportTop, viewportLeft){\r\n var range = getVisibleRange(viewportTop, viewportLeft);\r\n var buffer = Math.round(viewportH / options.rowHeight);\r\n var minBuffer = 3;\r\n\r\n if (vScrollDir == -1){\r\n range.top -= buffer;\r\n range.bottom += minBuffer;\r\n } else if (vScrollDir == 1){\r\n range.top -= minBuffer;\r\n range.bottom += buffer;\r\n } else {\r\n range.top -= minBuffer;\r\n range.bottom += minBuffer;\r\n }\r\n\r\n range.top = Math.max(0, range.top);\r\n range.bottom = Math.min(getDataLengthIncludingAddNew() - 1, range.bottom);\r\n\r\n range.leftPx -= viewportW;\r\n range.rightPx += viewportW;\r\n\r\n range.leftPx = Math.max(0, range.leftPx);\r\n range.rightPx = Math.min(canvasWidth, range.rightPx);\r\n\r\n return range;\r\n }\r\n\r\n function ensureCellNodesInRowsCache(row){\r\n var cacheEntry = rowsCache[row];\r\n if (cacheEntry){\r\n if (cacheEntry.cellRenderQueue.length){\r\n var lastChild = cacheEntry.rowNode.lastChild;\r\n while (cacheEntry.cellRenderQueue.length){\r\n var columnIdx = cacheEntry.cellRenderQueue.pop();\r\n cacheEntry.cellNodesByColumnIdx[columnIdx] = lastChild;\r\n lastChild = lastChild.previousSibling;\r\n }\r\n }\r\n }\r\n }\r\n\r\n function cleanUpCells(range, row){\r\n var totalCellsRemoved = 0;\r\n var cacheEntry = rowsCache[row];\r\n\r\n // Remove cells outside the range.\r\n var cellsToRemove = [];\r\n for (var i in cacheEntry.cellNodesByColumnIdx){\r\n // I really hate it when people mess with Array.prototype.\r\n if (!cacheEntry.cellNodesByColumnIdx.hasOwnProperty(i)){\r\n continue;\r\n }\r\n\r\n // This is a string, so it needs to be cast back to a number.\r\n i = i | 0;\r\n\r\n var colspan = cacheEntry.cellColSpans[i];\r\n if (columnPosLeft[i] > range.rightPx ||\r\n columnPosRight[Math.min(columns.length - 1, i + colspan - 1)] < range.leftPx){\r\n if (!(row == activeRow && i == activeCell)){\r\n cellsToRemove.push(i);\r\n }\r\n }\r\n }\r\n\r\n var cellToRemove, node;\r\n postProcessgroupId++;\r\n while ((cellToRemove = cellsToRemove.pop()) != null){\r\n node = cacheEntry.cellNodesByColumnIdx[cellToRemove];\r\n if (options.enableAsyncPostRenderCleanup && postProcessedRows[row] && postProcessedRows[row][cellToRemove]){\r\n queuePostProcessedCellForCleanup(node, cellToRemove, row);\r\n } else {\r\n cacheEntry.rowNode.removeChild(node);\r\n }\r\n\r\n delete cacheEntry.cellColSpans[cellToRemove];\r\n delete cacheEntry.cellNodesByColumnIdx[cellToRemove];\r\n if (postProcessedRows[row]){\r\n delete postProcessedRows[row][cellToRemove];\r\n }\r\n totalCellsRemoved++;\r\n }\r\n }\r\n\r\n function cleanUpAndRenderCells(range){\r\n var cacheEntry;\r\n var stringArray = [];\r\n var processedRows = [];\r\n var cellsAdded;\r\n var totalCellsAdded = 0;\r\n var colspan;\r\n\r\n for (var row = range.top, btm = range.bottom; row <= btm; row++){\r\n cacheEntry = rowsCache[row];\r\n if (!cacheEntry){\r\n continue;\r\n }\r\n\r\n // cellRenderQueue populated in renderRows() needs to be cleared first\r\n ensureCellNodesInRowsCache(row);\r\n\r\n cleanUpCells(range, row);\r\n\r\n // Render missing cells.\r\n cellsAdded = 0;\r\n\r\n var metadata = data.getItemMetadata && data.getItemMetadata(row);\r\n metadata = metadata && metadata.columns;\r\n\r\n var d = getDataItem(row);\r\n\r\n // TODO: shorten this loop (index? heuristics? binary search?)\r\n for (var i = 0, ii = columns.length; i < ii; i++){\r\n // Cells to the right are outside the range.\r\n if (columnPosLeft[i] > range.rightPx){\r\n break;\r\n }\r\n\r\n // Already rendered.\r\n if ((colspan = cacheEntry.cellColSpans[i]) != null){\r\n i += (colspan > 1 ? colspan - 1 : 0);\r\n continue;\r\n }\r\n\r\n colspan = 1;\r\n if (metadata){\r\n var columnData = metadata[columns[i].id] || metadata[i];\r\n colspan = (columnData && columnData.colspan) || 1;\r\n if (colspan === '*'){\r\n colspan = ii - i;\r\n }\r\n }\r\n\r\n if (columnPosRight[Math.min(ii - 1, i + colspan - 1)] > range.leftPx){\r\n appendCellHtml(stringArray, row, i, colspan, d);\r\n cellsAdded++;\r\n }\r\n\r\n i += (colspan > 1 ? colspan - 1 : 0);\r\n }\r\n\r\n if (cellsAdded){\r\n totalCellsAdded += cellsAdded;\r\n processedRows.push(row);\r\n }\r\n }\r\n\r\n if (!stringArray.length){\r\n return;\r\n }\r\n\r\n var x = document.createElement('div');\r\n x.innerHTML = stringArray.join('');\r\n\r\n var processedRow;\r\n var node;\r\n while ((processedRow = processedRows.pop()) != null){\r\n cacheEntry = rowsCache[processedRow];\r\n var columnIdx;\r\n while ((columnIdx = cacheEntry.cellRenderQueue.pop()) != null){\r\n node = x.lastChild;\r\n cacheEntry.rowNode.appendChild(node);\r\n cacheEntry.cellNodesByColumnIdx[columnIdx] = node;\r\n }\r\n }\r\n }\r\n\r\n function renderRows(range){\r\n var parentNode = $canvas[0],\r\n stringArray = [],\r\n rows = [],\r\n needToReselectCell = false,\r\n dataLength = getDataLength();\r\n\r\n for (var i = range.top, ii = range.bottom; i <= ii; i++){\r\n if (rowsCache[i]){\r\n continue;\r\n }\r\n renderedRows++;\r\n rows.push(i);\r\n\r\n // Create an entry right away so that appendRowHtml() can\r\n // start populatating it.\r\n rowsCache[i] = {\r\n 'rowNode': null,\r\n\r\n // ColSpans of rendered cells (by column idx).\r\n // Can also be used for checking whether a cell has been rendered.\r\n 'cellColSpans': [],\r\n\r\n // Cell nodes (by column idx). Lazy-populated by ensureCellNodesInRowsCache().\r\n 'cellNodesByColumnIdx': [],\r\n\r\n // Column indices of cell nodes that have been rendered, but not yet indexed in\r\n // cellNodesByColumnIdx. These are in the same order as cell nodes added at the\r\n // end of the row.\r\n 'cellRenderQueue': []\r\n };\r\n\r\n appendRowHtml(stringArray, i, range, dataLength);\r\n if (activeCellNode && activeRow === i){\r\n needToReselectCell = true;\r\n }\r\n counter_rows_rendered++;\r\n }\r\n\r\n if (!rows.length){\r\n return;\r\n }\r\n\r\n var x = document.createElement('div');\r\n x.innerHTML = stringArray.join('');\r\n\r\n for (var i = 0, ii = rows.length; i < ii; i++){\r\n rowsCache[rows[i]].rowNode = parentNode.appendChild(x.firstChild);\r\n }\r\n\r\n if (needToReselectCell){\r\n activeCellNode = getCellNode(activeRow, activeCell);\r\n }\r\n }\r\n\r\n function startPostProcessing(){\r\n if (!options.enableAsyncPostRender){\r\n return;\r\n }\r\n clearTimeout(h_postrender);\r\n h_postrender = setTimeout(asyncPostProcessRows, options.asyncPostRenderDelay);\r\n }\r\n\r\n function startPostProcessingCleanup(){\r\n if (!options.enableAsyncPostRenderCleanup){\r\n return;\r\n }\r\n clearTimeout(h_postrenderCleanup);\r\n h_postrenderCleanup = setTimeout(asyncPostProcessCleanupRows, options.asyncPostRenderCleanupDelay);\r\n }\r\n\r\n function invalidatePostProcessingResults(row){\r\n // change status of columns to be re-rendered\r\n for (var columnIdx in postProcessedRows[row]){\r\n if (postProcessedRows[row].hasOwnProperty(columnIdx)){\r\n postProcessedRows[row][columnIdx] = 'C';\r\n }\r\n }\r\n postProcessFromRow = Math.min(postProcessFromRow, row);\r\n postProcessToRow = Math.max(postProcessToRow, row);\r\n startPostProcessing();\r\n }\r\n\r\n function updateRowPositions(){\r\n for (var row in rowsCache){\r\n rowsCache[row].rowNode.style.top = getRowTop(row) + 'px';\r\n }\r\n }\r\n\r\n function render(){\r\n if (!initialized){\r\n return;\r\n }\r\n var visible = getVisibleRange();\r\n var rendered = getRenderedRange();\r\n\r\n // remove rows no longer in the viewport\r\n cleanupRows(rendered);\r\n\r\n // add new rows & missing cells in existing rows\r\n if (lastRenderedScrollLeft != scrollLeft){\r\n cleanUpAndRenderCells(rendered);\r\n }\r\n\r\n // render missing rows\r\n renderRows(rendered);\r\n\r\n postProcessFromRow = visible.top;\r\n postProcessToRow = Math.min(getDataLengthIncludingAddNew() - 1, visible.bottom);\r\n startPostProcessing();\r\n\r\n lastRenderedScrollTop = scrollTop;\r\n lastRenderedScrollLeft = scrollLeft;\r\n h_render = null;\r\n }\r\n\r\n function handleHeaderRowScroll(){\r\n var scrollLeft = $headerRowScroller[0].scrollLeft;\r\n if (scrollLeft != $viewport[0].scrollLeft){\r\n $viewport[0].scrollLeft = scrollLeft;\r\n }\r\n }\r\n\r\n function handleFooterRowScroll(){\r\n var scrollLeft = $footerRowScroller[0].scrollLeft;\r\n if (scrollLeft != $viewport[0].scrollLeft){\r\n $viewport[0].scrollLeft = scrollLeft;\r\n }\r\n }\r\n\r\n function handleScroll(){\r\n scrollTop = $viewport[0].scrollTop;\r\n scrollLeft = $viewport[0].scrollLeft;\r\n var vScrollDist = Math.abs(scrollTop - prevScrollTop);\r\n var hScrollDist = Math.abs(scrollLeft - prevScrollLeft);\r\n\r\n if (hScrollDist){\r\n prevScrollLeft = scrollLeft;\r\n $headerScroller[0].scrollLeft = scrollLeft;\r\n $topPanelScroller[0].scrollLeft = scrollLeft;\r\n $headerRowScroller[0].scrollLeft = scrollLeft;\r\n if (options.createFooterRow){\r\n $footerRowScroller[0].scrollLeft = scrollLeft;\r\n }\r\n }\r\n\r\n if (vScrollDist){\r\n vScrollDir = prevScrollTop < scrollTop ? 1 : -1;\r\n prevScrollTop = scrollTop;\r\n\r\n // switch virtual pages if needed\r\n if (vScrollDist < viewportH){\r\n scrollTo(scrollTop + offset);\r\n } else {\r\n var oldOffset = offset;\r\n if (h == viewportH){\r\n page = 0;\r\n } else {\r\n page = Math.min(n - 1, Math.floor(scrollTop * ((th - viewportH) / (h - viewportH)) * (1 / ph)));\r\n }\r\n offset = Math.round(page * cj);\r\n if (oldOffset != offset){\r\n invalidateAllRows();\r\n }\r\n }\r\n }\r\n\r\n if (hScrollDist || vScrollDist){\r\n if (h_render){\r\n clearTimeout(h_render);\r\n }\r\n\r\n if (Math.abs(lastRenderedScrollTop - scrollTop) > 20 ||\r\n Math.abs(lastRenderedScrollLeft - scrollLeft) > 20){\r\n if (options.forceSyncScrolling || (\r\n Math.abs(lastRenderedScrollTop - scrollTop) < viewportH &&\r\n Math.abs(lastRenderedScrollLeft - scrollLeft) < viewportW)){\r\n render();\r\n } else {\r\n h_render = setTimeout(render, 50);\r\n }\r\n\r\n trigger(self.onViewportChanged, {grid: self});\r\n }\r\n }\r\n\r\n trigger(self.onScroll, {scrollLeft: scrollLeft, scrollTop: scrollTop, grid: self});\r\n }\r\n\r\n function asyncPostProcessRows(){\r\n var dataLength = getDataLength();\r\n while (postProcessFromRow <= postProcessToRow){\r\n var row = (vScrollDir >= 0) ? postProcessFromRow++ : postProcessToRow--;\r\n var cacheEntry = rowsCache[row];\r\n if (!cacheEntry || row >= dataLength){\r\n continue;\r\n }\r\n\r\n if (!postProcessedRows[row]){\r\n postProcessedRows[row] = {};\r\n }\r\n\r\n ensureCellNodesInRowsCache(row);\r\n for (var columnIdx in cacheEntry.cellNodesByColumnIdx){\r\n if (!cacheEntry.cellNodesByColumnIdx.hasOwnProperty(columnIdx)){\r\n continue;\r\n }\r\n\r\n columnIdx = columnIdx | 0;\r\n\r\n var m = columns[columnIdx];\r\n var processedStatus = postProcessedRows[row][columnIdx]; // C=cleanup and re-render, R=rendered\r\n if (m.asyncPostRender && processedStatus !== 'R'){\r\n var node = cacheEntry.cellNodesByColumnIdx[columnIdx];\r\n if (node){\r\n m.asyncPostRender(node, row, getDataItem(row), m, (processedStatus === 'C'));\r\n }\r\n postProcessedRows[row][columnIdx] = 'R';\r\n }\r\n }\r\n\r\n h_postrender = setTimeout(asyncPostProcessRows, options.asyncPostRenderDelay);\r\n return;\r\n }\r\n }\r\n\r\n function asyncPostProcessCleanupRows(){\r\n if (postProcessedCleanupQueue.length > 0){\r\n var groupId = postProcessedCleanupQueue[0].groupId;\r\n\r\n // loop through all queue members with this groupID\r\n while (postProcessedCleanupQueue.length > 0 && postProcessedCleanupQueue[0].groupId == groupId){\r\n var entry = postProcessedCleanupQueue.shift();\r\n if (entry.actionType == 'R'){\r\n $(entry.node).remove();\r\n }\r\n if (entry.actionType == 'C'){\r\n var column = columns[entry.columnIdx];\r\n if (column.asyncPostRenderCleanup && entry.node){\r\n // cleanup must also remove element\r\n column.asyncPostRenderCleanup(entry.node, entry.rowIdx, column);\r\n }\r\n }\r\n }\r\n\r\n // call this function again after the specified delay\r\n h_postrenderCleanup = setTimeout(asyncPostProcessCleanupRows, options.asyncPostRenderCleanupDelay);\r\n }\r\n }\r\n\r\n function updateCellCssStylesOnRenderedRows(addedHash, removedHash){\r\n var node, columnId, addedRowHash, removedRowHash;\r\n for (var row in rowsCache){\r\n removedRowHash = removedHash && removedHash[row];\r\n addedRowHash = addedHash && addedHash[row];\r\n\r\n if (removedRowHash){\r\n for (columnId in removedRowHash){\r\n if (!addedRowHash || removedRowHash[columnId] != addedRowHash[columnId]){\r\n node = getCellNode(row, getColumnIndex(columnId));\r\n if (node){\r\n $(node).removeClass(removedRowHash[columnId]);\r\n }\r\n }\r\n }\r\n }\r\n\r\n if (addedRowHash){\r\n for (columnId in addedRowHash){\r\n if (!removedRowHash || removedRowHash[columnId] != addedRowHash[columnId]){\r\n node = getCellNode(row, getColumnIndex(columnId));\r\n if (node){\r\n $(node).addClass(addedRowHash[columnId]);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n function addCellCssStyles(key, hash){\r\n if (cellCssClasses[key]){\r\n throw \"addCellCssStyles: cell CSS hash with key '\" + key + \"' already exists.\";\r\n }\r\n\r\n cellCssClasses[key] = hash;\r\n updateCellCssStylesOnRenderedRows(hash, null);\r\n\r\n trigger(self.onCellCssStylesChanged, {'key': key, 'hash': hash, 'grid': self});\r\n }\r\n\r\n function removeCellCssStyles(key){\r\n if (!cellCssClasses[key]){\r\n return;\r\n }\r\n\r\n updateCellCssStylesOnRenderedRows(null, cellCssClasses[key]);\r\n delete cellCssClasses[key];\r\n\r\n trigger(self.onCellCssStylesChanged, {'key': key, 'hash': null, 'grid': self});\r\n }\r\n\r\n function setCellCssStyles(key, hash){\r\n var prevHash = cellCssClasses[key];\r\n\r\n cellCssClasses[key] = hash;\r\n updateCellCssStylesOnRenderedRows(hash, prevHash);\r\n\r\n trigger(self.onCellCssStylesChanged, {'key': key, 'hash': hash, 'grid': self});\r\n }\r\n\r\n function getCellCssStyles(key){\r\n return cellCssClasses[key];\r\n }\r\n\r\n function flashCell(row, cell, speed){\r\n speed = speed || 100;\r\n if (rowsCache[row]){\r\n var $cell = $(getCellNode(row, cell));\r\n\r\n function toggleCellClass(times){\r\n if (!times){\r\n return;\r\n }\r\n setTimeout(function(){\r\n $cell.queue(function(){\r\n $cell.toggleClass(options.cellFlashingCssClass).dequeue();\r\n toggleCellClass(times - 1);\r\n });\r\n },\r\n speed);\r\n }\r\n\r\n toggleCellClass(4);\r\n }\r\n }\r\n\r\n // ////////////////////////////////////////////////////////////////////////////////////////////\r\n // Interactivity\r\n\r\n function handleMouseWheel(e){\r\n var rowNode = $(e.target).closest('.slick-row')[0];\r\n if (rowNode != rowNodeFromLastMouseWheelEvent){\r\n if (zombieRowNodeFromLastMouseWheelEvent && zombieRowNodeFromLastMouseWheelEvent != rowNode){\r\n if (options.enableAsyncPostRenderCleanup && zombieRowPostProcessedFromLastMouseWheelEvent){\r\n queuePostProcessedRowForCleanup(zombieRowCacheFromLastMouseWheelEvent,\r\n zombieRowPostProcessedFromLastMouseWheelEvent);\r\n } else {\r\n $canvas[0].removeChild(zombieRowNodeFromLastMouseWheelEvent);\r\n }\r\n zombieRowNodeFromLastMouseWheelEvent = null;\r\n zombieRowCacheFromLastMouseWheelEvent = null;\r\n zombieRowPostProcessedFromLastMouseWheelEvent = null;\r\n\r\n if (options.enableAsyncPostRenderCleanup){\r\n startPostProcessingCleanup();\r\n }\r\n }\r\n rowNodeFromLastMouseWheelEvent = rowNode;\r\n }\r\n }\r\n\r\n function handleDragStart(interactEvent){\r\n var event = $.Event(interactEvent.originalEvent.type, interactEvent.originalEvent);\r\n var cell = getCellFromEvent(event);\r\n if (!cell || !cellExists(cell.row, cell.cell)){\r\n return false;\r\n }\r\n\r\n var retval = trigger(self.onDragStart, interactEvent, event);\r\n if (event.isImmediatePropagationStopped()){\r\n return retval;\r\n }\r\n\r\n return false;\r\n }\r\n\r\n function handleDrag(interactEvent){\r\n var event = $.Event(interactEvent.originalEvent.type, interactEvent.originalEvent);\r\n return trigger(self.onDrag, interactEvent, event);\r\n }\r\n\r\n function handleDragEnd(interactEvent){\r\n trigger(self.onDragEnd, interactEvent, $.Event('mousedown'));\r\n }\r\n\r\n function handleKeyDown(e){\r\n trigger(self.onKeyDown, {row: activeRow, cell: activeCell, grid: self}, e);\r\n var handled = e.isImmediatePropagationStopped();\r\n var keyCode = Slick.keyCode;\r\n\r\n if (!handled){\r\n if (!e.shiftKey && !e.altKey && !e.ctrlKey){\r\n // editor may specify an array of keys to bubble\r\n if (options.editable && currentEditor && currentEditor.keyCaptureList){\r\n if (currentEditor.keyCaptureList.indexOf(e.which) > -1){\r\n return;\r\n }\r\n }\r\n if (e.which == keyCode.ESCAPE){\r\n if (!getEditorLock().isActive()){\r\n return; // no editing mode to cancel, allow bubbling and default processing (exit without cancelling the event)\r\n }\r\n cancelEditAndSetFocus();\r\n } else if (e.which == keyCode.PAGE_DOWN){\r\n navigatePageDown();\r\n handled = true;\r\n } else if (e.which == keyCode.PAGE_UP){\r\n navigatePageUp();\r\n handled = true;\r\n } else if (e.which == keyCode.LEFT){\r\n handled = navigateLeft();\r\n } else if (e.which == keyCode.RIGHT){\r\n handled = navigateRight();\r\n } else if (e.which == keyCode.UP){\r\n handled = navigateUp();\r\n } else if (e.which == keyCode.DOWN){\r\n handled = navigateDown();\r\n } else if (e.which == keyCode.TAB){\r\n handled = navigateNext();\r\n } else if (e.which == keyCode.ENTER){\r\n if (options.editable){\r\n if (currentEditor){\r\n // adding new row\r\n if (activeRow === getDataLength()){\r\n navigateDown();\r\n } else {\r\n commitEditAndSetFocus();\r\n }\r\n } else {\r\n if (getEditorLock().commitCurrentEdit()){\r\n makeActiveCellEditable();\r\n }\r\n }\r\n }\r\n handled = true;\r\n }\r\n } else if (e.which == keyCode.TAB && e.shiftKey && !e.ctrlKey && !e.altKey){\r\n handled = navigatePrev();\r\n }\r\n }\r\n\r\n if (handled){\r\n // the event has been handled so don't let parent element (bubbling/propagation) or browser (default) handle it\r\n e.stopPropagation();\r\n e.preventDefault();\r\n try {\r\n e.originalEvent.keyCode = 0; // prevent default behaviour for special keys in IE browsers (F3, F5, etc.)\r\n }\r\n // ignore exceptions - setting the original event's keycode throws access denied exception for \"Ctrl\"\r\n // (hitting control key only, nothing else), \"Shift\" (maybe others)\r\n catch (error){\r\n }\r\n }\r\n }\r\n\r\n function handleClick(e){\r\n if (!currentEditor){\r\n // if this click resulted in some cell child node getting focus,\r\n // don't steal it back - keyboard events will still bubble up\r\n // IE9+ seems to default DIVs to tabIndex=0 instead of -1, so check for cell clicks directly.\r\n if (e.target != document.activeElement || $(e.target).hasClass('slick-cell')){\r\n setFocus();\r\n }\r\n }\r\n\r\n var cell = getCellFromEvent(e);\r\n if (!cell || (currentEditor !== null && activeRow == cell.row && activeCell == cell.cell)){\r\n return;\r\n }\r\n\r\n trigger(self.onClick, {row: cell.row, cell: cell.cell, grid: self}, e);\r\n if (e.isImmediatePropagationStopped()){\r\n return;\r\n }\r\n\r\n if ((activeCell != cell.cell || activeRow != cell.row) && canCellBeActive(cell.row, cell.cell)){\r\n if (!getEditorLock().isActive() || getEditorLock().commitCurrentEdit()){\r\n scrollRowIntoView(cell.row, false);\r\n setActiveCellInternal(getCellNode(cell.row, cell.cell));\r\n }\r\n }\r\n }\r\n\r\n function handleContextMenu(e){\r\n var $cell = $(e.target).closest('.slick-cell', $canvas);\r\n if ($cell.length === 0){\r\n return;\r\n }\r\n\r\n // are we editing this cell?\r\n if (activeCellNode === $cell[0] && currentEditor !== null){\r\n return;\r\n }\r\n\r\n trigger(self.onContextMenu, {grid: self}, e);\r\n }\r\n\r\n function handleDblClick(e){\r\n var cell = getCellFromEvent(e);\r\n if (!cell || (currentEditor !== null && activeRow == cell.row && activeCell == cell.cell)){\r\n return;\r\n }\r\n\r\n trigger(self.onDblClick, {row: cell.row, cell: cell.cell, grid: self}, e);\r\n if (e.isImmediatePropagationStopped()){\r\n return;\r\n }\r\n\r\n if (options.editable){\r\n gotoCell(cell.row, cell.cell, true);\r\n }\r\n }\r\n\r\n function handleHeaderMouseEnter(e){\r\n trigger(self.onHeaderMouseEnter, {\r\n 'column': $(this).data('column'),\r\n 'grid': self\r\n }, e);\r\n }\r\n\r\n function handleHeaderMouseLeave(e){\r\n trigger(self.onHeaderMouseLeave, {\r\n 'column': $(this).data('column'),\r\n 'grid': self\r\n }, e);\r\n }\r\n\r\n function handleHeaderContextMenu(e){\r\n var $header = $(e.target).closest('.slick-header-column', '.slick-header-columns');\r\n var column = $header && $header.data('column');\r\n trigger(self.onHeaderContextMenu, {column: column, grid: self}, e);\r\n }\r\n\r\n function handleHeaderClick(e){\r\n var $header = $(e.target).closest('.slick-header-column', '.slick-header-columns');\r\n var column = $header && $header.data('column');\r\n if (column){\r\n trigger(self.onHeaderClick, {column: column, grid: self}, e);\r\n }\r\n }\r\n\r\n function handleMouseEnter(e){\r\n trigger(self.onMouseEnter, {grid: self}, e);\r\n }\r\n\r\n function handleMouseLeave(e){\r\n trigger(self.onMouseLeave, {grid: self}, e);\r\n }\r\n\r\n function cellExists(row, cell){\r\n return !(row < 0 || row >= getDataLength() || cell < 0 || cell >= columns.length);\r\n }\r\n\r\n function getCellFromPoint(x, y){\r\n var row = getRowFromPosition(y);\r\n var cell = 0;\r\n\r\n var w = 0;\r\n for (var i = 0; i < columns.length && w < x; i++){\r\n w += columns[i].width;\r\n cell++;\r\n }\r\n\r\n if (cell < 0){\r\n cell = 0;\r\n }\r\n\r\n return {row: row, cell: cell - 1};\r\n }\r\n\r\n function getCellFromNode(cellNode){\r\n // read column number from .l CSS class\r\n var cls = /l\\d+/.exec(cellNode.className);\r\n if (!cls){\r\n throw 'getCellFromNode: cannot get cell - ' + cellNode.className;\r\n }\r\n return parseInt(cls[0].substr(1, cls[0].length - 1), 10);\r\n }\r\n\r\n function getRowFromNode(rowNode){\r\n for (var row in rowsCache){\r\n if (rowsCache[row].rowNode === rowNode){\r\n return row | 0;\r\n }\r\n }\r\n\r\n return null;\r\n }\r\n\r\n function getCellFromEvent(e){\r\n var $cell = $(e.target).closest('.slick-cell', $canvas);\r\n if (!$cell.length){\r\n return null;\r\n }\r\n\r\n var row = getRowFromNode($cell[0].parentNode);\r\n var cell = getCellFromNode($cell[0]);\r\n\r\n if (row == null || cell == null){\r\n return null;\r\n } else {\r\n return {\r\n 'row': row,\r\n 'cell': cell\r\n };\r\n }\r\n }\r\n\r\n function getCellNodeBox(row, cell){\r\n if (!cellExists(row, cell)){\r\n return null;\r\n }\r\n\r\n var y1 = getRowTop(row);\r\n var y2 = y1 + options.rowHeight - 1;\r\n var x1 = 0;\r\n for (var i = 0; i < cell; i++){\r\n x1 += columns[i].width;\r\n }\r\n var x2 = x1 + columns[cell].width;\r\n\r\n return {\r\n top: y1,\r\n left: x1,\r\n bottom: y2,\r\n right: x2\r\n };\r\n }\r\n\r\n // ////////////////////////////////////////////////////////////////////////////////////////////\r\n // Cell switching\r\n\r\n function resetActiveCell(){\r\n setActiveCellInternal(null, false);\r\n }\r\n\r\n function setFocus(){\r\n if (tabbingDirection == -1){\r\n $focusSink[0].focus();\r\n } else {\r\n $focusSink2[0].focus();\r\n }\r\n }\r\n\r\n function scrollCellIntoView(row, cell, doPaging){\r\n scrollRowIntoView(row, doPaging);\r\n\r\n var colspan = getColspan(row, cell);\r\n var left = columnPosLeft[cell],\r\n right = columnPosRight[cell + (colspan > 1 ? colspan - 1 : 0)],\r\n scrollRight = scrollLeft + viewportW;\r\n\r\n if (left < scrollLeft){\r\n $viewport.scrollLeft(left);\r\n handleScroll();\r\n render();\r\n } else if (right > scrollRight){\r\n $viewport.scrollLeft(Math.min(left, right - $viewport[0].clientWidth));\r\n handleScroll();\r\n render();\r\n }\r\n }\r\n\r\n function setActiveCellInternal(newCell, opt_editMode){\r\n if (activeCellNode !== null){\r\n makeActiveCellNormal();\r\n $(activeCellNode).removeClass('active');\r\n if (rowsCache[activeRow]){\r\n $(rowsCache[activeRow].rowNode).removeClass('active');\r\n }\r\n }\r\n\r\n var activeCellChanged = (activeCellNode !== newCell);\r\n activeCellNode = newCell;\r\n\r\n if (activeCellNode != null){\r\n activeRow = getRowFromNode(activeCellNode.parentNode);\r\n activeCell = activePosX = getCellFromNode(activeCellNode);\r\n\r\n if (opt_editMode == null){\r\n opt_editMode = (activeRow == getDataLength()) || options.autoEdit;\r\n }\r\n\r\n $(activeCellNode).addClass('active');\r\n $(rowsCache[activeRow].rowNode).addClass('active');\r\n\r\n if (options.editable && opt_editMode && isCellPotentiallyEditable(activeRow, activeCell)){\r\n clearTimeout(h_editorLoader);\r\n\r\n if (options.asyncEditorLoading){\r\n h_editorLoader = setTimeout(function(){\r\n makeActiveCellEditable();\r\n }, options.asyncEditorLoadDelay);\r\n } else {\r\n makeActiveCellEditable();\r\n }\r\n }\r\n } else {\r\n activeRow = activeCell = null;\r\n }\r\n\r\n if (activeCellChanged){\r\n trigger(self.onActiveCellChanged, getActiveCell());\r\n }\r\n }\r\n\r\n function clearTextSelection(){\r\n if (document.selection && document.selection.empty){\r\n try {\r\n // IE fails here if selected element is not in dom\r\n document.selection.empty();\r\n } catch (e){\r\n }\r\n } else if (window.getSelection){\r\n var sel = window.getSelection();\r\n if (sel && sel.removeAllRanges){\r\n sel.removeAllRanges();\r\n }\r\n }\r\n }\r\n\r\n function isCellPotentiallyEditable(row, cell){\r\n var dataLength = getDataLength();\r\n // is the data for this row loaded?\r\n if (row < dataLength && !getDataItem(row)){\r\n return false;\r\n }\r\n\r\n // are we in the Add New row? can we create new from this cell?\r\n if (columns[cell].cannotTriggerInsert && row >= dataLength){\r\n return false;\r\n }\r\n\r\n // does this cell have an editor?\r\n if (!getEditor(row, cell)){\r\n return false;\r\n }\r\n\r\n return true;\r\n }\r\n\r\n function makeActiveCellNormal(){\r\n if (!currentEditor){\r\n return;\r\n }\r\n trigger(self.onBeforeCellEditorDestroy, {editor: currentEditor, grid: self});\r\n currentEditor.destroy();\r\n currentEditor = null;\r\n\r\n if (activeCellNode){\r\n var d = getDataItem(activeRow);\r\n $(activeCellNode).removeClass('editable invalid');\r\n if (d){\r\n var column = columns[activeCell];\r\n var formatter = getFormatter(activeRow, column);\r\n activeCellNode.innerHTML = formatter(activeRow, activeCell, getDataItemValueForColumn(d, column), column, d, self);\r\n invalidatePostProcessingResults(activeRow);\r\n }\r\n }\r\n\r\n // if there previously was text selected on a page (such as selected text in the edit cell just removed),\r\n // IE can't set focus to anything else correctly\r\n if (navigator.userAgent.toLowerCase().match(/msie/)){\r\n clearTextSelection();\r\n }\r\n\r\n getEditorLock().deactivate(editController);\r\n }\r\n\r\n function makeActiveCellEditable(editor){\r\n if (!activeCellNode){\r\n return;\r\n }\r\n if (!options.editable){\r\n throw 'Grid : makeActiveCellEditable : should never get called when options.editable is false';\r\n }\r\n\r\n // cancel pending async call if there is one\r\n clearTimeout(h_editorLoader);\r\n\r\n if (!isCellPotentiallyEditable(activeRow, activeCell)){\r\n return;\r\n }\r\n\r\n var columnDef = columns[activeCell];\r\n var item = getDataItem(activeRow);\r\n\r\n if (trigger(self.onBeforeEditCell, {\r\n row: activeRow,\r\n cell: activeCell,\r\n item: item,\r\n column: columnDef,\r\n grid: self\r\n }) === false){\r\n setFocus();\r\n return;\r\n }\r\n\r\n getEditorLock().activate(editController);\r\n $(activeCellNode).addClass('editable');\r\n\r\n var useEditor = editor || getEditor(activeRow, activeCell);\r\n\r\n // don't clear the cell if a custom editor is passed through\r\n if (!editor && !useEditor.suppressClearOnEdit){\r\n activeCellNode.innerHTML = '';\r\n }\r\n\r\n currentEditor = new useEditor({\r\n grid: self,\r\n gridPosition: absBox($container[0]),\r\n position: absBox(activeCellNode),\r\n container: activeCellNode,\r\n column: columnDef,\r\n item: item || {},\r\n commitChanges: commitEditAndSetFocus,\r\n cancelChanges: cancelEditAndSetFocus\r\n });\r\n\r\n if (item){\r\n currentEditor.loadValue(item);\r\n }\r\n\r\n serializedEditorValue = currentEditor.serializeValue();\r\n\r\n if (currentEditor.position){\r\n handleActiveCellPositionChange();\r\n }\r\n }\r\n\r\n function commitEditAndSetFocus(){\r\n // if the commit fails, it would do so due to a validation error\r\n // if so, do not steal the focus from the editor\r\n if (getEditorLock().commitCurrentEdit()){\r\n setFocus();\r\n if (options.autoEdit){\r\n navigateDown();\r\n }\r\n }\r\n }\r\n\r\n function cancelEditAndSetFocus(){\r\n if (getEditorLock().cancelCurrentEdit()){\r\n setFocus();\r\n }\r\n }\r\n\r\n function absBox(elem){\r\n var box = {\r\n top: elem.offsetTop,\r\n left: elem.offsetLeft,\r\n bottom: 0,\r\n right: 0,\r\n width: $(elem).outerWidth(),\r\n height: $(elem).outerHeight(),\r\n visible: true\r\n };\r\n box.bottom = box.top + box.height;\r\n box.right = box.left + box.width;\r\n\r\n // walk up the tree\r\n var offsetParent = elem.offsetParent;\r\n while ((elem = elem.parentNode) != document.body){\r\n if (elem == null) break;\r\n\r\n if (box.visible && elem.scrollHeight != elem.offsetHeight && $(elem).css('overflowY') != 'visible'){\r\n box.visible = box.bottom > elem.scrollTop && box.top < elem.scrollTop + elem.clientHeight;\r\n }\r\n\r\n if (box.visible && elem.scrollWidth != elem.offsetWidth && $(elem).css('overflowX') != 'visible'){\r\n box.visible = box.right > elem.scrollLeft && box.left < elem.scrollLeft + elem.clientWidth;\r\n }\r\n\r\n box.left -= elem.scrollLeft;\r\n box.top -= elem.scrollTop;\r\n\r\n if (elem === offsetParent){\r\n box.left += elem.offsetLeft;\r\n box.top += elem.offsetTop;\r\n offsetParent = elem.offsetParent;\r\n }\r\n\r\n box.bottom = box.top + box.height;\r\n box.right = box.left + box.width;\r\n }\r\n\r\n return box;\r\n }\r\n\r\n function getActiveCellPosition(){\r\n return absBox(activeCellNode);\r\n }\r\n\r\n function getGridPosition(){\r\n return absBox($container[0]);\r\n }\r\n\r\n function handleActiveCellPositionChange(){\r\n if (!activeCellNode){\r\n return;\r\n }\r\n\r\n trigger(self.onActiveCellPositionChanged, {grid: self});\r\n\r\n if (currentEditor){\r\n var cellBox = getActiveCellPosition();\r\n if (currentEditor.show && currentEditor.hide){\r\n if (!cellBox.visible){\r\n currentEditor.hide();\r\n } else {\r\n currentEditor.show();\r\n }\r\n }\r\n\r\n if (currentEditor.position){\r\n currentEditor.position(cellBox);\r\n }\r\n }\r\n }\r\n\r\n function getCellEditor(){\r\n return currentEditor;\r\n }\r\n\r\n function getActiveCell(){\r\n if (!activeCellNode){\r\n return null;\r\n } else {\r\n return {row: activeRow, cell: activeCell, grid: self};\r\n }\r\n }\r\n\r\n function getActiveCellNode(){\r\n return activeCellNode;\r\n }\r\n\r\n function scrollRowIntoView(row, doPaging){\r\n var rowAtTop = row * options.rowHeight;\r\n var rowAtBottom = (row + 1) * options.rowHeight - viewportH + (viewportHasHScroll ? scrollbarDimensions.height : 0);\r\n\r\n // need to page down?\r\n if ((row + 1) * options.rowHeight > scrollTop + viewportH + offset){\r\n scrollTo(doPaging ? rowAtTop : rowAtBottom);\r\n render();\r\n }\r\n // or page up?\r\n else if (row * options.rowHeight < scrollTop + offset){\r\n scrollTo(doPaging ? rowAtBottom : rowAtTop);\r\n render();\r\n }\r\n }\r\n\r\n function scrollRowToTop(row){\r\n scrollTo(row * options.rowHeight);\r\n render();\r\n }\r\n\r\n function scrollPage(dir){\r\n var deltaRows = dir * numVisibleRows;\r\n scrollTo((getRowFromPosition(scrollTop) + deltaRows) * options.rowHeight);\r\n render();\r\n\r\n if (options.enableCellNavigation && activeRow != null){\r\n var row = activeRow + deltaRows;\r\n var dataLengthIncludingAddNew = getDataLengthIncludingAddNew();\r\n if (row >= dataLengthIncludingAddNew){\r\n row = dataLengthIncludingAddNew - 1;\r\n }\r\n if (row < 0){\r\n row = 0;\r\n }\r\n\r\n var cell = 0, prevCell = null;\r\n var prevActivePosX = activePosX;\r\n while (cell <= activePosX){\r\n if (canCellBeActive(row, cell)){\r\n prevCell = cell;\r\n }\r\n cell += getColspan(row, cell);\r\n }\r\n\r\n if (prevCell !== null){\r\n setActiveCellInternal(getCellNode(row, prevCell));\r\n activePosX = prevActivePosX;\r\n } else {\r\n resetActiveCell();\r\n }\r\n }\r\n }\r\n\r\n function navigatePageDown(){\r\n scrollPage(1);\r\n }\r\n\r\n function navigatePageUp(){\r\n scrollPage(-1);\r\n }\r\n\r\n function getColspan(row, cell){\r\n var metadata = data.getItemMetadata && data.getItemMetadata(row);\r\n if (!metadata || !metadata.columns){\r\n return 1;\r\n }\r\n\r\n var columnData = metadata.columns[columns[cell].id] || metadata.columns[cell];\r\n var colspan = (columnData && columnData.colspan);\r\n if (colspan === '*'){\r\n colspan = columns.length - cell;\r\n } else {\r\n colspan = colspan || 1;\r\n }\r\n\r\n return colspan;\r\n }\r\n\r\n function findFirstFocusableCell(row){\r\n var cell = 0;\r\n while (cell < columns.length){\r\n if (canCellBeActive(row, cell)){\r\n return cell;\r\n }\r\n cell += getColspan(row, cell);\r\n }\r\n return null;\r\n }\r\n\r\n function findLastFocusableCell(row){\r\n var cell = 0;\r\n var lastFocusableCell = null;\r\n while (cell < columns.length){\r\n if (canCellBeActive(row, cell)){\r\n lastFocusableCell = cell;\r\n }\r\n cell += getColspan(row, cell);\r\n }\r\n return lastFocusableCell;\r\n }\r\n\r\n function gotoRight(row, cell, posX){\r\n if (cell >= columns.length){\r\n return null;\r\n }\r\n\r\n do {\r\n cell += getColspan(row, cell);\r\n }\r\n while (cell < columns.length && !canCellBeActive(row, cell));\r\n\r\n if (cell < columns.length){\r\n return {\r\n 'row': row,\r\n 'cell': cell,\r\n 'posX': cell\r\n };\r\n }\r\n return null;\r\n }\r\n\r\n function gotoLeft(row, cell, posX){\r\n if (cell <= 0){\r\n return null;\r\n }\r\n\r\n var firstFocusableCell = findFirstFocusableCell(row);\r\n if (firstFocusableCell === null || firstFocusableCell >= cell){\r\n return null;\r\n }\r\n\r\n var prev = {\r\n 'row': row,\r\n 'cell': firstFocusableCell,\r\n 'posX': firstFocusableCell\r\n };\r\n var pos;\r\n while (true){\r\n pos = gotoRight(prev.row, prev.cell, prev.posX);\r\n if (!pos){\r\n return null;\r\n }\r\n if (pos.cell >= cell){\r\n return prev;\r\n }\r\n prev = pos;\r\n }\r\n }\r\n\r\n function gotoDown(row, cell, posX){\r\n var prevCell;\r\n var dataLengthIncludingAddNew = getDataLengthIncludingAddNew();\r\n while (true){\r\n if (++row >= dataLengthIncludingAddNew){\r\n return null;\r\n }\r\n\r\n prevCell = cell = 0;\r\n while (cell <= posX){\r\n prevCell = cell;\r\n cell += getColspan(row, cell);\r\n }\r\n\r\n if (canCellBeActive(row, prevCell)){\r\n return {\r\n 'row': row,\r\n 'cell': prevCell,\r\n 'posX': posX\r\n };\r\n }\r\n }\r\n }\r\n\r\n function gotoUp(row, cell, posX){\r\n var prevCell;\r\n while (true){\r\n if (--row < 0){\r\n return null;\r\n }\r\n\r\n prevCell = cell = 0;\r\n while (cell <= posX){\r\n prevCell = cell;\r\n cell += getColspan(row, cell);\r\n }\r\n\r\n if (canCellBeActive(row, prevCell)){\r\n return {\r\n 'row': row,\r\n 'cell': prevCell,\r\n 'posX': posX\r\n };\r\n }\r\n }\r\n }\r\n\r\n function gotoNext(row, cell, posX){\r\n if (row == null && cell == null){\r\n row = cell = posX = 0;\r\n if (canCellBeActive(row, cell)){\r\n return {\r\n 'row': row,\r\n 'cell': cell,\r\n 'posX': cell\r\n };\r\n }\r\n }\r\n\r\n var pos = gotoRight(row, cell, posX);\r\n if (pos){\r\n return pos;\r\n }\r\n\r\n var firstFocusableCell = null;\r\n var dataLengthIncludingAddNew = getDataLengthIncludingAddNew();\r\n while (++row < dataLengthIncludingAddNew){\r\n firstFocusableCell = findFirstFocusableCell(row);\r\n if (firstFocusableCell !== null){\r\n return {\r\n 'row': row,\r\n 'cell': firstFocusableCell,\r\n 'posX': firstFocusableCell\r\n };\r\n }\r\n }\r\n return null;\r\n }\r\n\r\n function gotoPrev(row, cell, posX){\r\n if (row == null && cell == null){\r\n row = getDataLengthIncludingAddNew() - 1;\r\n cell = posX = columns.length - 1;\r\n if (canCellBeActive(row, cell)){\r\n return {\r\n 'row': row,\r\n 'cell': cell,\r\n 'posX': cell\r\n };\r\n }\r\n }\r\n\r\n var pos;\r\n var lastSelectableCell;\r\n while (!pos){\r\n pos = gotoLeft(row, cell, posX);\r\n if (pos){\r\n break;\r\n }\r\n if (--row < 0){\r\n return null;\r\n }\r\n\r\n cell = 0;\r\n lastSelectableCell = findLastFocusableCell(row);\r\n if (lastSelectableCell !== null){\r\n pos = {\r\n 'row': row,\r\n 'cell': lastSelectableCell,\r\n 'posX': lastSelectableCell\r\n };\r\n }\r\n }\r\n return pos;\r\n }\r\n\r\n function navigateRight(){\r\n return navigate('right');\r\n }\r\n\r\n function navigateLeft(){\r\n return navigate('left');\r\n }\r\n\r\n function navigateDown(){\r\n return navigate('down');\r\n }\r\n\r\n function navigateUp(){\r\n return navigate('up');\r\n }\r\n\r\n function navigateNext(){\r\n return navigate('next');\r\n }\r\n\r\n function navigatePrev(){\r\n return navigate('prev');\r\n }\r\n\r\n /**\r\n * @param {string} dir Navigation direction.\r\n * @return {boolean} Whether navigation resulted in a change of active cell.\r\n */\r\n function navigate(dir){\r\n if (!options.enableCellNavigation){\r\n return false;\r\n }\r\n\r\n if (!activeCellNode && dir != 'prev' && dir != 'next'){\r\n return false;\r\n }\r\n\r\n if (!getEditorLock().commitCurrentEdit()){\r\n return true;\r\n }\r\n setFocus();\r\n\r\n var tabbingDirections = {\r\n 'up': -1,\r\n 'down': 1,\r\n 'left': -1,\r\n 'right': 1,\r\n 'prev': -1,\r\n 'next': 1\r\n };\r\n tabbingDirection = tabbingDirections[dir];\r\n\r\n var stepFunctions = {\r\n 'up': gotoUp,\r\n 'down': gotoDown,\r\n 'left': gotoLeft,\r\n 'right': gotoRight,\r\n 'prev': gotoPrev,\r\n 'next': gotoNext\r\n };\r\n var stepFn = stepFunctions[dir];\r\n var pos = stepFn(activeRow, activeCell, activePosX);\r\n if (pos){\r\n var isAddNewRow = (pos.row == getDataLength());\r\n scrollCellIntoView(pos.row, pos.cell, !isAddNewRow);\r\n setActiveCellInternal(getCellNode(pos.row, pos.cell));\r\n activePosX = pos.posX;\r\n return true;\r\n } else {\r\n setActiveCellInternal(getCellNode(activeRow, activeCell));\r\n return false;\r\n }\r\n }\r\n\r\n function getCellNode(row, cell){\r\n if (rowsCache[row]){\r\n ensureCellNodesInRowsCache(row);\r\n return rowsCache[row].cellNodesByColumnIdx[cell];\r\n }\r\n return null;\r\n }\r\n\r\n function setActiveCell(row, cell){\r\n if (!initialized){\r\n return;\r\n }\r\n if (row > getDataLength() || row < 0 || cell >= columns.length || cell < 0){\r\n return;\r\n }\r\n\r\n if (!options.enableCellNavigation){\r\n return;\r\n }\r\n\r\n scrollCellIntoView(row, cell, false);\r\n setActiveCellInternal(getCellNode(row, cell), false);\r\n }\r\n\r\n function canCellBeActive(row, cell){\r\n if (!options.enableCellNavigation || row >= getDataLengthIncludingAddNew() ||\r\n row < 0 || cell >= columns.length || cell < 0){\r\n return false;\r\n }\r\n\r\n var rowMetadata = data.getItemMetadata && data.getItemMetadata(row);\r\n if (rowMetadata && typeof rowMetadata.focusable === 'boolean'){\r\n return rowMetadata.focusable;\r\n }\r\n\r\n var columnMetadata = rowMetadata && rowMetadata.columns;\r\n if (columnMetadata && columnMetadata[columns[cell].id] && typeof columnMetadata[columns[cell].id].focusable === 'boolean'){\r\n return columnMetadata[columns[cell].id].focusable;\r\n }\r\n if (columnMetadata && columnMetadata[cell] && typeof columnMetadata[cell].focusable === 'boolean'){\r\n return columnMetadata[cell].focusable;\r\n }\r\n\r\n return columns[cell].focusable;\r\n }\r\n\r\n function canCellBeSelected(row, cell){\r\n if (row >= getDataLength() || row < 0 || cell >= columns.length || cell < 0){\r\n return false;\r\n }\r\n\r\n var rowMetadata = data.getItemMetadata && data.getItemMetadata(row);\r\n if (rowMetadata && typeof rowMetadata.selectable === 'boolean'){\r\n return rowMetadata.selectable;\r\n }\r\n\r\n var columnMetadata = rowMetadata && rowMetadata.columns && (rowMetadata.columns[columns[cell].id] || rowMetadata.columns[cell]);\r\n if (columnMetadata && typeof columnMetadata.selectable === 'boolean'){\r\n return columnMetadata.selectable;\r\n }\r\n\r\n return columns[cell].selectable;\r\n }\r\n\r\n function gotoCell(row, cell, forceEdit){\r\n if (!initialized){\r\n return;\r\n }\r\n if (!canCellBeActive(row, cell)){\r\n return;\r\n }\r\n\r\n if (!getEditorLock().commitCurrentEdit()){\r\n return;\r\n }\r\n\r\n scrollCellIntoView(row, cell, false);\r\n\r\n var newCell = getCellNode(row, cell);\r\n\r\n // if selecting the 'add new' row, start editing right away\r\n setActiveCellInternal(newCell, forceEdit || (row === getDataLength()) || options.autoEdit);\r\n\r\n // if no editor was created, set the focus back on the grid\r\n if (!currentEditor){\r\n setFocus();\r\n }\r\n }\r\n\r\n // ////////////////////////////////////////////////////////////////////////////////////////////\r\n // IEditor implementation for the editor lock\r\n\r\n function commitCurrentEdit(){\r\n var item = getDataItem(activeRow);\r\n var column = columns[activeCell];\r\n\r\n if (currentEditor){\r\n if (currentEditor.isValueChanged()){\r\n var validationResults = currentEditor.validate();\r\n\r\n if (validationResults.valid){\r\n if (activeRow < getDataLength()){\r\n var editCommand = {\r\n row: activeRow,\r\n cell: activeCell,\r\n editor: currentEditor,\r\n serializedValue: currentEditor.serializeValue(),\r\n prevSerializedValue: serializedEditorValue,\r\n execute: function(){\r\n this.editor.applyValue(item, this.serializedValue);\r\n updateRow(this.row);\r\n trigger(self.onCellChange, {\r\n row: activeRow,\r\n cell: activeCell,\r\n item: item,\r\n grid: self\r\n });\r\n },\r\n undo: function(){\r\n this.editor.applyValue(item, this.prevSerializedValue);\r\n updateRow(this.row);\r\n trigger(self.onCellChange, {\r\n row: activeRow,\r\n cell: activeCell,\r\n item: item,\r\n grid: self\r\n });\r\n }\r\n };\r\n\r\n if (options.editCommandHandler){\r\n makeActiveCellNormal();\r\n options.editCommandHandler(item, column, editCommand);\r\n } else {\r\n editCommand.execute();\r\n makeActiveCellNormal();\r\n }\r\n } else {\r\n var newItem = {};\r\n currentEditor.applyValue(newItem, currentEditor.serializeValue());\r\n makeActiveCellNormal();\r\n trigger(self.onAddNewRow, {item: newItem, column: column, grid: self});\r\n }\r\n\r\n // check whether the lock has been re-acquired by event handlers\r\n return !getEditorLock().isActive();\r\n } else {\r\n // Re-add the CSS class to trigger transitions, if any.\r\n $(activeCellNode).removeClass('invalid');\r\n $(activeCellNode).width(); // force layout\r\n $(activeCellNode).addClass('invalid');\r\n\r\n trigger(self.onValidationError, {\r\n editor: currentEditor,\r\n cellNode: activeCellNode,\r\n validationResults: validationResults,\r\n row: activeRow,\r\n cell: activeCell,\r\n column: column,\r\n grid: self\r\n });\r\n\r\n currentEditor.focus();\r\n return false;\r\n }\r\n }\r\n\r\n makeActiveCellNormal();\r\n }\r\n return true;\r\n }\r\n\r\n function cancelCurrentEdit(){\r\n makeActiveCellNormal();\r\n return true;\r\n }\r\n\r\n function rowsToRanges(rows){\r\n var ranges = [];\r\n var lastCell = columns.length - 1;\r\n for (var i = 0; i < rows.length; i++){\r\n ranges.push(new Slick.Range(rows[i], 0, rows[i], lastCell));\r\n }\r\n return ranges;\r\n }\r\n\r\n function getSelectedRows(){\r\n if (!selectionModel){\r\n throw 'Selection model is not set';\r\n }\r\n return selectedRows;\r\n }\r\n\r\n function setSelectedRows(rows){\r\n if (!selectionModel){\r\n throw 'Selection model is not set';\r\n }\r\n selectionModel.setSelectedRanges(rowsToRanges(rows));\r\n }\r\n\r\n // ////////////////////////////////////////////////////////////////////////////////////////////\r\n // Debug\r\n\r\n this.debug = function(){\r\n var s = '';\r\n\r\n s += ('\\n' + 'counter_rows_rendered: ' + counter_rows_rendered);\r\n s += ('\\n' + 'counter_rows_removed: ' + counter_rows_removed);\r\n s += ('\\n' + 'renderedRows: ' + renderedRows);\r\n s += ('\\n' + 'numVisibleRows: ' + numVisibleRows);\r\n s += ('\\n' + 'maxSupportedCssHeight: ' + maxSupportedCssHeight);\r\n s += ('\\n' + 'n(umber of pages): ' + n);\r\n s += ('\\n' + '(current) page: ' + page);\r\n s += ('\\n' + 'page height (ph): ' + ph);\r\n s += ('\\n' + 'vScrollDir: ' + vScrollDir);\r\n\r\n alert(s);\r\n };\r\n\r\n // a debug helper to be able to access private members\r\n this.eval = function(expr){\r\n return eval(expr);\r\n };\r\n\r\n // ////////////////////////////////////////////////////////////////////////////////////////////\r\n // Public API\r\n\r\n $.extend(this, {\r\n 'slickGridVersion': '2.2.4',\r\n\r\n // Events\r\n 'onScroll': new Slick.Event(),\r\n 'onSort': new Slick.Event(),\r\n 'onHeaderMouseEnter': new Slick.Event(),\r\n 'onHeaderMouseLeave': new Slick.Event(),\r\n 'onHeaderContextMenu': new Slick.Event(),\r\n 'onHeaderClick': new Slick.Event(),\r\n 'onHeaderCellRendered': new Slick.Event(),\r\n 'onBeforeHeaderCellDestroy': new Slick.Event(),\r\n 'onHeaderRowCellRendered': new Slick.Event(),\r\n 'onFooterRowCellRendered': new Slick.Event(),\r\n 'onBeforeHeaderRowCellDestroy': new Slick.Event(),\r\n 'onBeforeFooterRowCellDestroy': new Slick.Event(),\r\n 'onMouseEnter': new Slick.Event(),\r\n 'onMouseLeave': new Slick.Event(),\r\n 'onClick': new Slick.Event(),\r\n 'onDblClick': new Slick.Event(),\r\n 'onContextMenu': new Slick.Event(),\r\n 'onKeyDown': new Slick.Event(),\r\n 'onAddNewRow': new Slick.Event(),\r\n 'onValidationError': new Slick.Event(),\r\n 'onViewportChanged': new Slick.Event(),\r\n 'onColumnsReordered': new Slick.Event(),\r\n 'onColumnsResized': new Slick.Event(),\r\n 'onCellChange': new Slick.Event(),\r\n 'onBeforeEditCell': new Slick.Event(),\r\n 'onBeforeCellEditorDestroy': new Slick.Event(),\r\n 'onBeforeDestroy': new Slick.Event(),\r\n 'onActiveCellChanged': new Slick.Event(),\r\n 'onActiveCellPositionChanged': new Slick.Event(),\r\n 'onDragInit': new Slick.Event(),\r\n 'onDragStart': new Slick.Event(),\r\n 'onDrag': new Slick.Event(),\r\n 'onDragEnd': new Slick.Event(),\r\n 'onSelectedRowsChanged': new Slick.Event(),\r\n 'onCellCssStylesChanged': new Slick.Event(),\r\n\r\n // Methods\r\n 'registerPlugin': registerPlugin,\r\n 'unregisterPlugin': unregisterPlugin,\r\n 'getColumns': getColumns,\r\n 'setColumns': setColumns,\r\n 'getColumnIndex': getColumnIndex,\r\n 'updateColumnHeader': updateColumnHeader,\r\n 'setSortColumn': setSortColumn,\r\n 'setSortColumns': setSortColumns,\r\n 'getSortColumns': getSortColumns,\r\n 'autosizeColumns': autosizeColumns,\r\n 'getOptions': getOptions,\r\n 'setOptions': setOptions,\r\n 'getData': getData,\r\n 'getDataLength': getDataLength,\r\n 'getDataItem': getDataItem,\r\n 'setData': setData,\r\n 'getSelectionModel': getSelectionModel,\r\n 'setSelectionModel': setSelectionModel,\r\n 'getSelectedRows': getSelectedRows,\r\n 'setSelectedRows': setSelectedRows,\r\n 'getContainerNode': getContainerNode,\r\n\r\n 'render': render,\r\n 'invalidate': invalidate,\r\n 'invalidateRow': invalidateRow,\r\n 'invalidateRows': invalidateRows,\r\n 'invalidateAllRows': invalidateAllRows,\r\n 'updateCell': updateCell,\r\n 'updateRow': updateRow,\r\n 'getViewport': getVisibleRange,\r\n 'getRenderedRange': getRenderedRange,\r\n 'resizeCanvas': resizeCanvas,\r\n 'updateRowCount': updateRowCount,\r\n 'scrollRowIntoView': scrollRowIntoView,\r\n 'scrollRowToTop': scrollRowToTop,\r\n 'scrollCellIntoView': scrollCellIntoView,\r\n 'getCanvasNode': getCanvasNode,\r\n 'focus': setFocus,\r\n\r\n 'getCellFromPoint': getCellFromPoint,\r\n 'getCellFromEvent': getCellFromEvent,\r\n 'getActiveCell': getActiveCell,\r\n 'setActiveCell': setActiveCell,\r\n 'getActiveCellNode': getActiveCellNode,\r\n 'getActiveCellPosition': getActiveCellPosition,\r\n 'resetActiveCell': resetActiveCell,\r\n 'editActiveCell': makeActiveCellEditable,\r\n 'getCellEditor': getCellEditor,\r\n 'getCellNode': getCellNode,\r\n 'getCellNodeBox': getCellNodeBox,\r\n 'canCellBeSelected': canCellBeSelected,\r\n 'canCellBeActive': canCellBeActive,\r\n 'navigatePrev': navigatePrev,\r\n 'navigateNext': navigateNext,\r\n 'navigateUp': navigateUp,\r\n 'navigateDown': navigateDown,\r\n 'navigateLeft': navigateLeft,\r\n 'navigateRight': navigateRight,\r\n 'navigatePageUp': navigatePageUp,\r\n 'navigatePageDown': navigatePageDown,\r\n 'gotoCell': gotoCell,\r\n 'getTopPanel': getTopPanel,\r\n 'setTopPanelVisibility': setTopPanelVisibility,\r\n 'setHeaderRowVisibility': setHeaderRowVisibility,\r\n 'getHeaderRow': getHeaderRow,\r\n 'getHeaderRowColumn': getHeaderRowColumn,\r\n 'setFooterRowVisibility': setFooterRowVisibility,\r\n 'getFooterRow': getFooterRow,\r\n 'getFooterRowColumn': getFooterRowColumn,\r\n 'getGridPosition': getGridPosition,\r\n 'flashCell': flashCell,\r\n 'addCellCssStyles': addCellCssStyles,\r\n 'setCellCssStyles': setCellCssStyles,\r\n 'removeCellCssStyles': removeCellCssStyles,\r\n 'getCellCssStyles': getCellCssStyles,\r\n\r\n 'init': finishInitialization,\r\n 'destroy': destroy,\r\n\r\n // IEditor implementation\r\n 'getEditorLock': getEditorLock,\r\n 'getEditController': getEditController\r\n });\r\n\r\n init();\r\n}\r\n\n\n\n// WEBPACK FOOTER //\n// ../src/slick.grid.js","import $ from 'jquery';\r\nimport Slick from './slick.core';\r\n\r\nexport default GroupItemMetadataProvider;\r\n\r\n/***\r\n * Provides item metadata for group (Slick.Group) and totals (Slick.Totals) rows produced by the DataView.\r\n * This metadata overrides the default behavior and formatting of those rows so that they appear and function\r\n * correctly when processed by the grid.\r\n *\r\n * This class also acts as a grid plugin providing event handlers to expand & collapse groups.\r\n * If \"grid.registerPlugin(...)\" is not called, expand & collapse will not work.\r\n *\r\n * @class GroupItemMetadataProvider\r\n * @module Data\r\n * @namespace Slick.Data\r\n * @constructor\r\n * @param options\r\n */\r\nfunction GroupItemMetadataProvider(options){\r\n let _grid;\r\n let _defaults = {\r\n groupCssClass: \"slick-group\",\r\n groupTitleCssClass: \"slick-group-title\",\r\n totalsCssClass: \"slick-group-totals\",\r\n groupFocusable: true,\r\n totalsFocusable: false,\r\n toggleCssClass: \"slick-group-toggle\",\r\n toggleExpandedCssClass: \"expanded\",\r\n toggleCollapsedCssClass: \"collapsed\",\r\n enableExpandCollapse: true,\r\n groupFormatter: defaultGroupCellFormatter,\r\n totalsFormatter: defaultTotalsCellFormatter\r\n };\r\n\r\n options = $.extend(true, {}, _defaults, options);\r\n\r\n function defaultGroupCellFormatter(row, cell, value, columnDef, item){\r\n if (!options.enableExpandCollapse){\r\n return item.title;\r\n }\r\n\r\n let indentation = item.level * 15 + \"px\";\r\n\r\n return \"\" +\r\n \"\" +\r\n \"\" +\r\n item.title +\r\n \"\";\r\n }\r\n\r\n function defaultTotalsCellFormatter(row, cell, value, columnDef, item){\r\n return (columnDef.groupTotalsFormatter && columnDef.groupTotalsFormatter(item, columnDef)) || \"\";\r\n }\r\n\r\n function init(grid){\r\n _grid = grid;\r\n _grid.onClick.subscribe(handleGridClick);\r\n _grid.onKeyDown.subscribe(handleGridKeyDown);\r\n }\r\n\r\n function destroy(){\r\n if (_grid){\r\n _grid.onClick.unsubscribe(handleGridClick);\r\n _grid.onKeyDown.unsubscribe(handleGridKeyDown);\r\n }\r\n }\r\n\r\n function handleGridClick(e, args){\r\n let item = this.getDataItem(args.row);\r\n if (item && item instanceof Slick.Group && $(e.target).hasClass(options.toggleCssClass)){\r\n let range = _grid.getRenderedRange();\r\n this.getData().setRefreshHints({\r\n ignoreDiffsBefore: range.top,\r\n ignoreDiffsAfter: range.bottom + 1\r\n });\r\n\r\n if (item.collapsed){\r\n this.getData().expandGroup(item.groupingKey);\r\n } else {\r\n this.getData().collapseGroup(item.groupingKey);\r\n }\r\n\r\n e.stopImmediatePropagation();\r\n e.preventDefault();\r\n }\r\n }\r\n\r\n // TODO: add -/+ handling\r\n function handleGridKeyDown(e){\r\n if (options.enableExpandCollapse && (e.which == Slick.keyCode.SPACE)){\r\n let activeCell = this.getActiveCell();\r\n if (activeCell){\r\n let item = this.getDataItem(activeCell.row);\r\n if (item && item instanceof Slick.Group){\r\n let range = _grid.getRenderedRange();\r\n this.getData().setRefreshHints({\r\n ignoreDiffsBefore: range.top,\r\n ignoreDiffsAfter: range.bottom + 1\r\n });\r\n\r\n if (item.collapsed){\r\n this.getData().expandGroup(item.groupingKey);\r\n } else {\r\n this.getData().collapseGroup(item.groupingKey);\r\n }\r\n\r\n e.stopImmediatePropagation();\r\n e.preventDefault();\r\n }\r\n }\r\n }\r\n }\r\n\r\n function getGroupRowMetadata(item){\r\n return {\r\n selectable: false,\r\n focusable: options.groupFocusable,\r\n cssClasses: options.groupCssClass,\r\n columns: {\r\n 0: {\r\n colspan: \"*\",\r\n formatter: options.groupFormatter,\r\n editor: null\r\n }\r\n }\r\n };\r\n }\r\n\r\n function getTotalsRowMetadata(item){\r\n return {\r\n selectable: false,\r\n focusable: options.totalsFocusable,\r\n cssClasses: options.totalsCssClass,\r\n formatter: options.totalsFormatter,\r\n editor: null\r\n };\r\n }\r\n\r\n return {\r\n init,\r\n destroy,\r\n getGroupRowMetadata,\r\n getTotalsRowMetadata\r\n };\r\n}\r\n\n\n\n// WEBPACK FOOTER //\n// ../src/slick.groupmetadataprovider.js","module.exports = require(\"flatpickr\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"flatpickr\"\n// module id = 32\n// module chunks = 0"],"sourceRoot":""}
\ No newline at end of file
diff --git a/src/slick.grid.js b/src/slick.grid.js
index 4ef969a..f4e4a55 100644
--- a/src/slick.grid.js
+++ b/src/slick.grid.js
@@ -977,30 +977,38 @@ function SlickGrid(container, data, columns, options){
absoluteColumnMinWidth = Math.max(headerColumnWidthDiff, cellWidthDiff);
}
- function createCssRules(){
- $style = $("").appendTo($('head'));
+ function createCssRules() {
+ $style = $("").appendTo($("head"));
var rowHeight = (options.rowHeight - cellHeightDiff);
- var rules = [
- '.' + uid + ' .slick-header-column { left: 0; }',
- '.' + uid + ' .slick-top-panel { height:' + options.topPanelHeight + 'px; }',
- '.' + uid + ' .slick-headerrow-columns { height:' + options.headerRowHeight + 'px; }',
- '.' + uid + ' .slick-footerrow-columns { height:' + options.footerRowHeight + 'px; }',
- '.' + uid + ' .slick-cell { height:' + rowHeight + 'px; }',
- '.' + uid + ' .slick-row { height:' + options.rowHeight + 'px; }'
- ];
-
- for (var i = 0; i < columns.length; i++){
- rules.push('.' + uid + ' .l' + i + ' { }');
- rules.push('.' + uid + ' .r' + i + ' { }');
- }
-
- if ($style[0].styleSheet){ // IE
- $style[0].styleSheet.cssText = rules.join(' ');
+ if ($style[0].styleSheet) { // IE
+ $style[0].styleSheet.cssText = "";
} else {
- $style[0].appendChild(document.createTextNode(rules.join(' ')));
+ $style[0].appendChild(document.createTextNode(""));
}
+
+ var sheet = $style[0].sheet;
+ var index = 0;
+ addCSSRule(sheet,"." + uid + " .slick-header-column", "left: 0;", index++);
+ addCSSRule(sheet,"." + uid + " .slick-top-panel", "height:" + options.topPanelHeight + "px;", index++);
+ addCSSRule(sheet,"." + uid + " .slick-headerrow-columns", "height:" + options.headerRowHeight + "px;", index++);
+ addCSSRule(sheet,"." + uid + " .slick-cell", "height:" + rowHeight + "px;", index++);
+ addCSSRule(sheet,"." + uid + " .slick-row", "height:" + options.rowHeight + "px;", index++);
+
+ for (var i = 0; i < columns.length; i++) {
+ addCSSRule(sheet,"." + uid + " .l" + i , "", index++);
+ addCSSRule(sheet,"." + uid + " .r" + i, "", index++);
+ }
}
+ function addCSSRule(sheet, selector, rules, index) {
+ if(sheet.insertRule) {
+ sheet.insertRule(selector + "{" + rules + "}", index);
+ }
+ else {
+ sheet.addRule(selector, rules, index);
+ }
+ }
+
function getColumnCssRules(idx){
if (!stylesheet){
var sheets = document.styleSheets;