/**
 * Bundle of @devexpress/dx-grid-core
 * Generated: 2017-11-10
 * Version: 1.0.0-beta.1
 * License: https://js.devexpress.com/Licensing
 */

(function (global, factory) {
	typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@devexpress/dx-core')) :
	typeof define === 'function' && define.amd ? define(['exports', '@devexpress/dx-core'], factory) :
	(factory((global.DevExpress = global.DevExpress || {}, global.DevExpress.DXGridCore = {}),global.DevExpress.DXCore));
}(this, (function (exports,dxCore) { 'use strict';

var rowIdGetter = function rowIdGetter(getRowId, rows) {
  if (!getRowId) {
    var map = new Map(rows.map(function (row, rowIndex) {
      return [row, rowIndex];
    }));
    return function (row) {
      return map.get(row);
    };
  }
  return getRowId;
};

var cellValueGetter = function cellValueGetter(getCellValue, columns) {
  if (getCellValue) {
    return getCellValue;
  }

  var useFastAccessor = true;
  var map = columns.reduce(function (acc, column) {
    if (column.getCellValue) {
      useFastAccessor = false;
      acc[column.name] = column.getCellValue;
    }
    return acc;
  }, {});

  return useFastAccessor ? function (row, columnName) {
    return row[columnName];
  } : function (row, columnName) {
    return map[columnName] ? map[columnName](row, columnName) : row[columnName];
  };
};

var setColumnSorting = function setColumnSorting(state, _ref) {
  var columnName = _ref.columnName,
      direction = _ref.direction,
      keepOther = _ref.keepOther,
      cancel = _ref.cancel,
      sortIndex = _ref.sortIndex;
  var sorting = state.sorting;


  var nextSorting = [];
  if (keepOther === true) {
    nextSorting = Array.from(sorting).slice();
  }
  if (Array.isArray(keepOther)) {
    nextSorting = Array.from(sorting).filter(function (columnSorting) {
      return keepOther.indexOf(columnSorting.columnName) > -1;
    });
  }

  var columnSortingIndex = sorting.findIndex(function (columnSorting) {
    return columnSorting.columnName === columnName;
  });
  var columnSorting = sorting[columnSortingIndex];
  var newColumnSorting = {
    columnName: columnName,
    direction: direction || (!columnSorting || columnSorting.direction === 'desc' ? 'asc' : 'desc')
  };

  if (columnSortingIndex > -1) {
    nextSorting.splice(columnSortingIndex, 1);
  }

  if (!cancel) {
    var newIndexFallback = columnSortingIndex > -1 ? columnSortingIndex : nextSorting.length;
    var newIndex = sortIndex !== undefined ? sortIndex : newIndexFallback;
    nextSorting.splice(newIndex, 0, newColumnSorting);
  }

  return {
    sorting: nextSorting
  };
};

var getColumnSortingDirection = function getColumnSortingDirection(sorting, columnName) {
  var columnSorting = sorting.filter(function (s) {
    return s.columnName === columnName;
  })[0];
  return columnSorting ? columnSorting.direction : null;
};

/* eslint-disable no-plusplus, no-param-reassign, no-use-before-define, no-constant-condition */

var merge = function merge(array, auxiliary, lo, mid, hi, compare) {
  var i = lo;
  var j = mid + 1;
  var k = lo;
  while (true) {
    var cmp = compare(array[i], array[j]);
    if (cmp <= 0) {
      auxiliary[k++] = array[i++];
      if (i > mid) {
        do {
          auxiliary[k++] = array[j++];
        } while (j <= hi);
        break;
      }
    } else {
      auxiliary[k++] = array[j++];
      if (j > hi) {
        do {
          auxiliary[k++] = array[i++];
        } while (i <= mid);
        break;
      }
    }
  }
};

var sortArrayToAuxiliary = function sortArrayToAuxiliary(array, auxiliary, lo, hi, compare) {
  if (hi < lo) return;
  if (hi === lo) {
    auxiliary[lo] = array[lo];
    return;
  }
  var mid = Math.floor(lo + (hi - lo) / 2);
  sortAuxiliaryToArray(array, auxiliary, lo, mid, compare);
  sortAuxiliaryToArray(array, auxiliary, mid + 1, hi, compare);
  merge(array, auxiliary, lo, mid, hi, compare);
};

var sortAuxiliaryToArray = function sortAuxiliaryToArray(array, auxiliary, lo, hi, compare) {
  if (hi <= lo) return;
  var mid = Math.floor(lo + (hi - lo) / 2);
  sortArrayToAuxiliary(array, auxiliary, lo, mid, compare);
  sortArrayToAuxiliary(array, auxiliary, mid + 1, hi, compare);
  merge(auxiliary, array, lo, mid, hi, compare);
};

var mergeSort = (function (array) {
  var compare = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : function (a, b) {
    if (a < b) return -1;
    if (a > b) return 1;
    return 0;
  };

  var result = array.slice();
  var auxiliary = array.slice();
  sortAuxiliaryToArray(result, auxiliary, 0, result.length - 1, compare);
  return result;
});

var asyncGenerator = function () {
  function AwaitValue(value) {
    this.value = value;
  }

  function AsyncGenerator(gen) {
    var front, back;

    function send(key, arg) {
      return new Promise(function (resolve, reject) {
        var request = {
          key: key,
          arg: arg,
          resolve: resolve,
          reject: reject,
          next: null
        };

        if (back) {
          back = back.next = request;
        } else {
          front = back = request;
          resume(key, arg);
        }
      });
    }

    function resume(key, arg) {
      try {
        var result = gen[key](arg);
        var value = result.value;

        if (value instanceof AwaitValue) {
          Promise.resolve(value.value).then(function (arg) {
            resume("next", arg);
          }, function (arg) {
            resume("throw", arg);
          });
        } else {
          settle(result.done ? "return" : "normal", result.value);
        }
      } catch (err) {
        settle("throw", err);
      }
    }

    function settle(type, value) {
      switch (type) {
        case "return":
          front.resolve({
            value: value,
            done: true
          });
          break;

        case "throw":
          front.reject(value);
          break;

        default:
          front.resolve({
            value: value,
            done: false
          });
          break;
      }

      front = front.next;

      if (front) {
        resume(front.key, front.arg);
      } else {
        back = null;
      }
    }

    this._invoke = send;

    if (typeof gen.return !== "function") {
      this.return = undefined;
    }
  }

  if (typeof Symbol === "function" && Symbol.asyncIterator) {
    AsyncGenerator.prototype[Symbol.asyncIterator] = function () {
      return this;
    };
  }

  AsyncGenerator.prototype.next = function (arg) {
    return this._invoke("next", arg);
  };

  AsyncGenerator.prototype.throw = function (arg) {
    return this._invoke("throw", arg);
  };

  AsyncGenerator.prototype.return = function (arg) {
    return this._invoke("return", arg);
  };

  return {
    wrap: function (fn) {
      return function () {
        return new AsyncGenerator(fn.apply(this, arguments));
      };
    },
    await: function (value) {
      return new AwaitValue(value);
    }
  };
}();













var defineProperty = function (obj, key, value) {
  if (key in obj) {
    Object.defineProperty(obj, key, {
      value: value,
      enumerable: true,
      configurable: true,
      writable: true
    });
  } else {
    obj[key] = value;
  }

  return obj;
};

var _extends = Object.assign || function (target) {
  for (var i = 1; i < arguments.length; i++) {
    var source = arguments[i];

    for (var key in source) {
      if (Object.prototype.hasOwnProperty.call(source, key)) {
        target[key] = source[key];
      }
    }
  }

  return target;
};













var objectWithoutProperties = function (obj, keys) {
  var target = {};

  for (var i in obj) {
    if (keys.indexOf(i) >= 0) continue;
    if (!Object.prototype.hasOwnProperty.call(obj, i)) continue;
    target[i] = obj[i];
  }

  return target;
};







var slicedToArray = function () {
  function sliceIterator(arr, i) {
    var _arr = [];
    var _n = true;
    var _d = false;
    var _e = undefined;

    try {
      for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
        _arr.push(_s.value);

        if (i && _arr.length === i) break;
      }
    } catch (err) {
      _d = true;
      _e = err;
    } finally {
      try {
        if (!_n && _i["return"]) _i["return"]();
      } finally {
        if (_d) throw _e;
      }
    }

    return _arr;
  }

  return function (arr, i) {
    if (Array.isArray(arr)) {
      return arr;
    } else if (Symbol.iterator in Object(arr)) {
      return sliceIterator(arr, i);
    } else {
      throw new TypeError("Invalid attempt to destructure non-iterable instance");
    }
  };
}();













var toConsumableArray = function (arr) {
  if (Array.isArray(arr)) {
    for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];

    return arr2;
  } else {
    return Array.from(arr);
  }
};

var NODE_CHECK = Symbol('node');

var rowsToTree = function rowsToTree(rows, getRowLevelKey) {
  if (!rows.length) return rows;

  var levels = [{ children: [] }];

  rows.forEach(function (row) {
    var levelKey = getRowLevelKey(row);
    if (levelKey) {
      var _node;

      var levelIndex = levels.slice(1).findIndex(function (level) {
        return getRowLevelKey(level.root) === levelKey;
      }) + 1;
      if (levelIndex > 0) {
        levels.splice(levelIndex, levels.length - levelIndex);
      }
      var node = (_node = {}, defineProperty(_node, NODE_CHECK, true), defineProperty(_node, 'root', row), defineProperty(_node, 'children', []), _node);
      levels[levels.length - 1].children.push(node);
      levels.push(node);
    } else {
      levels[levels.length - 1].children.push(row);
    }
  });

  return levels[0].children;
};

var treeToRows = function treeToRows(tree) {
  var rows = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];

  if (!tree.length) return tree;
  return tree.reduce(function (acc, node) {
    if (node[NODE_CHECK]) {
      acc.push(node.root);
      treeToRows(node.children, rows);
    } else {
      acc.push(node);
    }
    return acc;
  }, rows);
};

var defaultCompare = function defaultCompare(a, b) {
  if (a < b) return -1;
  if (a > b) return 1;
  return 0;
};

var createCompare = function createCompare(sorting, getColumnCompare, getComparableValue) {
  return Array.from(sorting).reverse().reduce(function (prevCompare, columnSorting) {
    var columnName = columnSorting.columnName;

    var inverse = columnSorting.direction === 'desc';
    var columnCompare = getColumnCompare && getColumnCompare(columnName) || defaultCompare;

    return function (aRow, bRow) {
      var a = getComparableValue(aRow, columnName);
      var b = getComparableValue(bRow, columnName);
      var result = columnCompare(a, b);

      if (result !== 0) {
        return inverse ? -result : result;
      }
      return prevCompare(aRow, bRow);
    };
  }, function () {
    return 0;
  });
};

var sortTree = function sortTree(tree, compare) {
  var sortedTree = tree.map(function (node) {
    if (node[NODE_CHECK]) {
      return _extends({}, node, {
        children: sortTree(node.children, compare)
      });
    }
    return node;
  });

  return mergeSort(sortedTree, function (a, b) {
    return compare(a[NODE_CHECK] ? a.root : a, b[NODE_CHECK] ? b.root : b);
  });
};

var sortHierarchicalRows = function sortHierarchicalRows(rows, compare, getRowLevelKey) {
  var tree = rowsToTree(rows, getRowLevelKey);

  var sortedTree = sortTree(tree, compare);

  return treeToRows(sortedTree);
};

var sortedRows = function sortedRows(rows, sorting, getCellValue, getColumnCompare, isGroupRow, getRowLevelKey) {
  if (!sorting.length || !rows.length) return rows;

  if (!getRowLevelKey) {
    var _compare = createCompare(sorting, getColumnCompare, getCellValue);
    return mergeSort(Array.from(rows), _compare);
  }

  var compare = createCompare(sorting, getColumnCompare, function (row, columnName) {
    if (isGroupRow(row)) {
      if (row.groupedBy === columnName) {
        return row.value;
      }
      return undefined;
    }
    return getCellValue(row, columnName);
  });
  return sortHierarchicalRows(rows, compare, getRowLevelKey);
};

var setColumnFilter = function setColumnFilter(filters, _ref) {
  var columnName = _ref.columnName,
      config = _ref.config;

  var filterIndex = filters.findIndex(function (f) {
    return f.columnName === columnName;
  });
  var nextState = Array.from(filters);

  if (config) {
    var filter = _extends({ columnName: columnName }, config);
    if (filterIndex > -1) {
      nextState.splice(filterIndex, 1, filter);
    } else {
      nextState.push(filter);
    }
  } else {
    nextState.splice(filterIndex, 1);
  }

  return nextState;
};

var getColumnFilterConfig = function getColumnFilterConfig(filters, columnName) {
  if (!filters.length) {
    return null;
  }

  var filter = filters.filter(function (s) {
    return s.columnName === columnName;
  })[0];
  if (!filter) return null;

  var _ = filter.columnName,
      config = objectWithoutProperties(filter, ["columnName"]);

  return config;
};

var toLowerCase = function toLowerCase(value) {
  return String(value).toLowerCase();
};

var defaultPredicate = function defaultPredicate(value, filter) {
  return toLowerCase(value).indexOf(toLowerCase(filter.value)) > -1;
};

var filterTree = function filterTree(tree, predicate) {
  return tree.reduce(function (acc, node) {
    if (node[NODE_CHECK]) {
      var filteredChildren = filterTree(node.children, predicate);
      if (filteredChildren.length > 0) {
        acc.push(_extends({}, node, {
          children: filteredChildren
        }));
        return acc;
      } else if (predicate(node.root)) {
        acc.push(node.root);
        return acc;
      }
    }

    if (predicate(node)) {
      acc.push(node);
      return acc;
    }

    return acc;
  }, []);
};

var filterHierarchicalRows = function filterHierarchicalRows(rows, predicate, getRowLevelKey, isGroupRow) {
  var tree = rowsToTree(rows, getRowLevelKey);

  var filteredTree = filterTree(tree, function (row) {
    if (isGroupRow(row)) {
      if (row.collapsedRows) {
        return row.collapsedRows.findIndex(predicate) > -1;
      }
      return false;
    }
    return predicate(row);
  });

  return treeToRows(filteredTree);
};

var filteredRows = function filteredRows(rows, filters, getCellValue, getColumnPredicate, isGroupRow, getRowLevelKey) {
  if (!filters.length || !rows.length) return rows;

  var predicate = filters.reduce(function (prevPredicate, filter) {
    var columnName = filter.columnName,
        filterConfig = objectWithoutProperties(filter, ['columnName']);

    var customPredicate = getColumnPredicate && getColumnPredicate(columnName);
    var columnPredicate = customPredicate || defaultPredicate;

    return function (row) {
      var result = columnPredicate(getCellValue(row, columnName), filterConfig, row);
      return result && prevPredicate(row);
    };
  }, function () {
    return true;
  });

  if (!getRowLevelKey) {
    return rows.filter(predicate);
  }

  return filterHierarchicalRows(rows, predicate, getRowLevelKey, isGroupRow);
};

var GROUP_KEY_SEPARATOR = '|';

var groupByColumn = function groupByColumn(state, _ref) {
  var columnName = _ref.columnName,
      groupIndex = _ref.groupIndex;

  var grouping = Array.from(state.grouping);
  var groupingIndex = grouping.findIndex(function (g) {
    return g.columnName === columnName;
  });
  var targetIndex = groupIndex;

  if (groupingIndex > -1) {
    grouping.splice(groupingIndex, 1);
  } else if (groupIndex === undefined) {
    targetIndex = grouping.length;
  }

  if (targetIndex > -1) {
    grouping.splice(targetIndex, 0, {
      columnName: columnName
    });
  }

  var ungroupedColumnIndex = state.grouping.findIndex(function (group, index) {
    return !grouping[index] || group.columnName !== grouping[index].columnName;
  });
  if (ungroupedColumnIndex === -1) {
    return {
      grouping: grouping
    };
  }

  var filteredExpandedGroups = state.expandedGroups.filter(function (group) {
    return group.split(GROUP_KEY_SEPARATOR).length <= ungroupedColumnIndex;
  });
  if (filteredExpandedGroups.length === state.expandedGroups.length) {
    return {
      grouping: grouping
    };
  }

  return {
    grouping: grouping,
    expandedGroups: filteredExpandedGroups
  };
};

var toggleExpandedGroups = function toggleExpandedGroups(state, _ref2) {
  var groupKey = _ref2.groupKey;

  var expandedGroups = Array.from(state.expandedGroups);
  var groupKeyIndex = expandedGroups.indexOf(groupKey);

  if (groupKeyIndex > -1) {
    expandedGroups.splice(groupKeyIndex, 1);
  } else {
    expandedGroups.push(groupKey);
  }

  return {
    expandedGroups: expandedGroups
  };
};

var draftGroupingChange = function draftGroupingChange(state, _ref3) {
  var columnName = _ref3.columnName,
      groupIndex = _ref3.groupIndex;
  return { groupingChange: { columnName: columnName, groupIndex: groupIndex } };
};

var cancelGroupingChange = function cancelGroupingChange() {
  return { groupingChange: null };
};

var draftGrouping = function draftGrouping(grouping, groupingChange) {
  if (!groupingChange) return grouping;

  var columnName = groupingChange.columnName,
      groupIndex = groupingChange.groupIndex;

  var result = Array.from(grouping);

  if (groupIndex !== -1) {
    result = result.filter(function (g) {
      return g.columnName !== columnName;
    });
    result.splice(groupIndex, 0, {
      columnName: columnName,
      draft: true,
      mode: grouping.length > result.length ? 'reorder' : 'add'
    });
  } else {
    result = result.map(function (g) {
      return g.columnName === columnName ? { columnName: columnName, draft: true, mode: 'remove' } : g;
    });
  }

  return result;
};

var GRID_GROUP_TYPE = 'group';
var GRID_GROUP_CHECK = Symbol(GRID_GROUP_TYPE + '_check');
var GRID_GROUP_LEVEL_KEY = Symbol(GRID_GROUP_TYPE + '_levelKey');

var groupRowChecker = function groupRowChecker(row) {
  return row[GRID_GROUP_CHECK];
};

var groupRowLevelKeyGetter = function groupRowLevelKeyGetter(row) {
  return row[GRID_GROUP_LEVEL_KEY];
};

var defaultColumnIdentity = function defaultColumnIdentity(value) {
  return {
    key: String(value),
    value: value
  };
};

var groupedRows = function groupedRows(rows, grouping, getCellValue, getColumnIdentity) {
  var keyPrefix = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : '';

  if (!grouping.length) return rows;

  var columnName = grouping[0].columnName;

  var groupIdentity = getColumnIdentity && getColumnIdentity(columnName) || defaultColumnIdentity;
  var groups = rows.reduce(function (acc, row) {
    var _groupIdentity = groupIdentity(getCellValue(row, columnName), row),
        key = _groupIdentity.key,
        _groupIdentity$value = _groupIdentity.value,
        value = _groupIdentity$value === undefined ? key : _groupIdentity$value;

    var sameKeyItems = acc.get(key);

    if (!sameKeyItems) {
      acc.set(key, [value, key, [row]]);
    } else {
      sameKeyItems[2].push(row);
    }
    return acc;
  }, new Map());

  var groupedBy = grouping[0].columnName;
  var nestedGrouping = grouping.slice(1);
  return [].concat(toConsumableArray(groups.values())).reduce(function (acc, _ref) {
    var _acc$push;

    var _ref2 = slicedToArray(_ref, 3),
        value = _ref2[0],
        key = _ref2[1],
        items = _ref2[2];

    var compoundKey = '' + keyPrefix + key;
    acc.push((_acc$push = {}, defineProperty(_acc$push, GRID_GROUP_CHECK, true), defineProperty(_acc$push, GRID_GROUP_LEVEL_KEY, GRID_GROUP_TYPE + '_' + groupedBy), defineProperty(_acc$push, 'groupedBy', groupedBy), defineProperty(_acc$push, 'compoundKey', compoundKey), defineProperty(_acc$push, 'key', key), defineProperty(_acc$push, 'value', value), _acc$push));
    acc.push.apply(acc, toConsumableArray(groupedRows(items, nestedGrouping, getCellValue, getColumnIdentity, '' + compoundKey + GROUP_KEY_SEPARATOR)));
    return acc;
  }, []);
};

var expandedGroupRows = function expandedGroupRows(rows, grouping, expandedGroups) {
  if (!grouping.length) return rows;

  var groupingColumnNames = grouping.map(function (columnGrouping) {
    return columnGrouping.columnName;
  });
  var currentGroupExpanded = true;
  var currentGroupLevel = 0;

  return rows.reduce(function (acc, row) {
    if (!row[GRID_GROUP_CHECK]) {
      if (currentGroupExpanded) {
        acc.push(row);
      } else {
        acc[acc.length - 1].collapsedRows.push(row);
      }
      return acc;
    }

    var groupLevel = groupingColumnNames.indexOf(row.groupedBy);
    if (groupLevel > currentGroupLevel && !currentGroupExpanded) {
      return acc;
    }

    currentGroupExpanded = expandedGroups.has(row.compoundKey);
    currentGroupLevel = groupLevel;

    if (currentGroupExpanded) {
      acc.push(row);
    } else {
      acc.push(_extends({}, row, {
        collapsedRows: []
      }));
    }

    return acc;
  }, []);
};

var customGroupedRows = function customGroupedRows(currentRows, grouping, getChildGroups) {
  var rootRows = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : currentRows;
  var keyPrefix = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : '';

  if (!currentRows || !currentRows.length) return [];
  if (!grouping.length) return currentRows;

  var groupedBy = grouping[0].columnName;
  var nestedGrouping = grouping.slice(1);
  return getChildGroups(currentRows, grouping[0], rootRows).reduce(function (acc, _ref) {
    var _acc$push;

    var key = _ref.key,
        _ref$value = _ref.value,
        value = _ref$value === undefined ? key : _ref$value,
        childRows = _ref.childRows;

    var compoundKey = '' + keyPrefix + key;
    acc.push((_acc$push = {}, defineProperty(_acc$push, GRID_GROUP_CHECK, true), defineProperty(_acc$push, GRID_GROUP_LEVEL_KEY, GRID_GROUP_TYPE + '_' + groupedBy), defineProperty(_acc$push, 'groupedBy', groupedBy), defineProperty(_acc$push, 'compoundKey', compoundKey), defineProperty(_acc$push, 'key', key), defineProperty(_acc$push, 'value', value), _acc$push));
    acc.push.apply(acc, toConsumableArray(customGroupedRows(childRows, nestedGrouping, getChildGroups, rootRows, '' + compoundKey + GROUP_KEY_SEPARATOR)));
    return acc;
  }, []);
};

var customGroupingRowIdGetter = function customGroupingRowIdGetter(getRowId, rows) {
  var firstRow = rows.find(function (row) {
    return !row[GRID_GROUP_CHECK];
  });
  if (!firstRow || getRowId(firstRow)) {
    return getRowId;
  }
  var map = new Map(rows.filter(function (row) {
    return !row[GRID_GROUP_CHECK];
  }).map(function (row, rowIndex) {
    return [row, rowIndex];
  }));

  return function (row) {
    return map.get(row);
  };
};

var groupingPanelItems = function groupingPanelItems(columns, grouping) {
  return grouping.map(function (_ref) {
    var columnName = _ref.columnName,
        draft = _ref.draft;

    var column = columns.find(function (c) {
      return c.name === columnName;
    });
    return {
      column: column,
      draft: draft
    };
  });
};

var setCurrentPage = function setCurrentPage(prevPage, page) {
  return page;
};
var setPageSize = function setPageSize(prevPageSize, size) {
  return size;
};

var PAGE_HEADERS_OVERFLOW_ERROR = 'Max row level exceeds the page size. Consider increasing the page size.';

var paginatedRows = function paginatedRows(rows, pageSize, page) {
  return pageSize ? rows.slice(pageSize * page, pageSize * (page + 1)) : rows;
};

var rowsWithPageHeaders = function rowsWithPageHeaders(rows, pageSize, getRowLevelKey) {
  if (!pageSize || !getRowLevelKey) return rows;

  var result = rows.slice();

  var headerRows = [];
  var currentIndex = 0;

  var _loop = function _loop() {
    var row = result[currentIndex];
    var levelKey = getRowLevelKey(row);
    if (levelKey) {
      var headerIndex = headerRows.findIndex(function (headerRow) {
        return getRowLevelKey(headerRow) === levelKey;
      });
      if (headerIndex === -1) {
        headerRows = [].concat(toConsumableArray(headerRows), [row]);
      } else {
        headerRows = [].concat(toConsumableArray(headerRows.slice(0, headerIndex)), [row]);
      }
      if (headerRows.length >= pageSize) {
        throw new Error(PAGE_HEADERS_OVERFLOW_ERROR);
      }
    }
    var indexInPage = currentIndex % pageSize;
    if (indexInPage < headerRows.length && row !== headerRows[indexInPage]) {
      result = [].concat(toConsumableArray(result.slice(0, currentIndex)), [headerRows[indexInPage]], toConsumableArray(result.slice(currentIndex)));
    }
    currentIndex += 1;
  };

  while (result.length > currentIndex) {
    _loop();
  }

  return result;
};

var pageCount = function pageCount(count, pageSize) {
  return pageSize ? Math.ceil(count / pageSize) : 1;
};

var rowCount = function rowCount(rows) {
  return rows.length;
};

var firstRowOnPage = function firstRowOnPage(currentPage, pageSize, totalCount) {
  if (totalCount === 0) {
    return 0;
  }
  return pageSize ? currentPage * pageSize + 1 : 1;
};

var lastRowOnPage = function lastRowOnPage(currentPage, pageSize, totalRowCount) {
  var result = totalRowCount;
  if (pageSize) {
    var index = (currentPage + 1) * pageSize;
    result = index > totalRowCount ? totalRowCount : index;
  }

  return result;
};

var setRowSelection = function setRowSelection(selection, _ref) {
  var rowId = _ref.rowId,
      selected = _ref.selected;

  var selectedRows = Array.from(selection);
  var selectedIndex = selectedRows.indexOf(rowId);

  var isRowSelected = selected;

  if (isRowSelected === undefined) {
    isRowSelected = selectedIndex === -1;
  }

  if (selectedIndex > -1 && !isRowSelected) {
    selectedRows.splice(selectedIndex, 1);
  } else if (selectedIndex === -1 && isRowSelected) {
    selectedRows.push(rowId);
  }

  return selectedRows;
};

var setRowsSelection = function setRowsSelection(selection, _ref2) {
  var rowIds = _ref2.rowIds,
      selected = _ref2.selected;

  if (rowIds.length === 1) {
    return setRowSelection(selection, { rowId: rowIds[0], selected: selected });
  }

  var rowIdsSet = new Set(rowIds);

  var isRowsSelected = selected;
  if (isRowsSelected === undefined) {
    var availableSelection = selection.filter(function (rowId) {
      return rowIdsSet.has(rowId);
    });
    isRowsSelected = availableSelection.length !== rowIdsSet.size;
  }

  if (isRowsSelected) {
    var selectionSet = new Set(selection);
    return [].concat(toConsumableArray(selection), toConsumableArray(rowIds.filter(function (rowId) {
      return !selectionSet.has(rowId);
    })));
  }

  return selection.filter(function (rowId) {
    return !rowIdsSet.has(rowId);
  });
};

var getAvailableToSelect = function getAvailableToSelect(rows, getRowId, isGroupRow) {
  var dataRows = rows;
  if (isGroupRow) {
    dataRows = dataRows.filter(function (row) {
      return !isGroupRow(row);
    });
  }
  return dataRows.map(function (row) {
    return getRowId(row);
  });
};

var getAvailableSelection = function getAvailableSelection(selection, availableToSelect) {
  var availableToSelectSet = new Set(availableToSelect);
  return selection.filter(function (selected) {
    return availableToSelectSet.has(selected);
  });
};

var startEditRows = function startEditRows(prevEditingRows, _ref) {
  var rowIds = _ref.rowIds;
  return [].concat(toConsumableArray(prevEditingRows), toConsumableArray(rowIds));
};

var stopEditRows = function stopEditRows(prevEditingRows, _ref2) {
  var rowIds = _ref2.rowIds;

  var rowIdSet = new Set(rowIds);
  return prevEditingRows.filter(function (id) {
    return !rowIdSet.has(id);
  });
};

var addRow = function addRow(addedRows, _ref3) {
  var row = _ref3.row;
  return [].concat(toConsumableArray(addedRows), [row]);
};

var changeAddedRow = function changeAddedRow(addedRows, _ref4) {
  var rowId = _ref4.rowId,
      change = _ref4.change;

  var result = Array.from(addedRows);
  result[rowId] = _extends({}, result[rowId], change);
  return result;
};

var cancelAddedRows = function cancelAddedRows(addedRows, _ref5) {
  var rowIds = _ref5.rowIds;

  var result = [];
  var indexSet = new Set(rowIds);
  addedRows.forEach(function (row, index) {
    if (!indexSet.has(index)) {
      result.push(row);
    }
  });
  return result;
};

var changeRow = function changeRow(prevChangedRows, _ref6) {
  var rowId = _ref6.rowId,
      change = _ref6.change;

  var prevChange = prevChangedRows[rowId] || {};
  return _extends({}, prevChangedRows, defineProperty({}, rowId, _extends({}, prevChange, change)));
};

var cancelChanges = function cancelChanges(prevChangedRows, _ref7) {
  var rowIds = _ref7.rowIds;

  var result = _extends({}, prevChangedRows);
  rowIds.forEach(function (rowId) {
    delete result[rowId];
  });
  return result;
};

var deleteRows = function deleteRows(deletedRows, _ref8) {
  var rowIds = _ref8.rowIds;
  return [].concat(toConsumableArray(deletedRows), toConsumableArray(rowIds));
};

var cancelDeletedRows = function cancelDeletedRows(deletedRows, _ref9) {
  var rowIds = _ref9.rowIds;

  var rowIdSet = new Set(rowIds);
  return deletedRows.filter(function (rowId) {
    return !rowIdSet.has(rowId);
  });
};

var changedRowsByIds = function changedRowsByIds(changes, rowIds) {
  var result = {};
  rowIds.forEach(function (rowId) {
    result[rowId] = changes[rowId];
  });
  return result;
};

var addedRowsByIds = function addedRowsByIds(addedRows, rowIds) {
  var rowIdSet = new Set(rowIds);
  var result = [];
  addedRows.forEach(function (row, index) {
    if (rowIdSet.has(index)) {
      result.push(row);
    }
  });
  return result;
};

var computedCreateRowChange = function computedCreateRowChange(columns) {
  var map = columns.reduce(function (acc, column) {
    if (column.createRowChange) {
      acc[column.name] = column.createRowChange;
    }
    return acc;
  }, {});

  return function (row, columnName, value) {
    return map[columnName] ? map[columnName](row, value, columnName) : defineProperty({}, columnName, value);
  };
};

var getRowChange = function getRowChange(changedRows, rowId) {
  return changedRows[rowId] || {};
};

var TABLE_REORDERING_TYPE = 'reordering';

var changeColumnOrder = function changeColumnOrder(order, _ref) {
  var sourceColumnName = _ref.sourceColumnName,
      targetColumnName = _ref.targetColumnName;

  var sourceColumnIndex = order.indexOf(sourceColumnName);
  var targetColumnIndex = order.indexOf(targetColumnName);
  var newOrder = Array.from(order);

  newOrder.splice(sourceColumnIndex, 1);
  newOrder.splice(targetColumnIndex, 0, sourceColumnName);
  return newOrder;
};

var TABLE_DATA_TYPE = 'data';
var TABLE_NODATA_TYPE = 'nodata';

var orderedColumns = function orderedColumns(tableColumns, order) {
  var result = Array.from(tableColumns);

  result.sort(function (a, b) {
    if (a.type !== TABLE_DATA_TYPE || b.type !== TABLE_DATA_TYPE) return 0;

    var aPos = order.indexOf(a.column.name);
    var bPos = order.indexOf(b.column.name);
    return aPos - bPos;
  });

  return result;
};

var tableHeaderRowsWithReordering = function tableHeaderRowsWithReordering(tableHeaderRows) {
  return [{
    key: TABLE_REORDERING_TYPE,
    type: TABLE_REORDERING_TYPE,
    height: 0
  }].concat(toConsumableArray(tableHeaderRows));
};

var draftOrder = function draftOrder(order, sourceColumnIndex, targetColumnIndex) {
  if (sourceColumnIndex === -1 || targetColumnIndex === -1 || sourceColumnIndex === targetColumnIndex) {
    return order;
  }

  var result = order.slice();
  var sourceColumn = order[sourceColumnIndex];
  result.splice(sourceColumnIndex, 1);
  result.splice(targetColumnIndex, 0, sourceColumn);

  return result;
};

var UNSET_COLUMN_WIDTH_ERROR = ['The "$1" column\'s width is not specified.', 'The TableColumnResizing plugin requires that all columns have the specified width.'].join('\n');

var tableColumnsWithWidths = function tableColumnsWithWidths(tableColumns, columnWidths, draftColumnWidths) {
  return tableColumns.reduce(function (acc, tableColumn) {
    if (tableColumn.type === 'data') {
      var columnName = tableColumn.column.name;
      var width = draftColumnWidths[columnName] || columnWidths[columnName];
      if (width === undefined) {
        throw new Error(UNSET_COLUMN_WIDTH_ERROR.replace('$1', columnName));
      }
      acc.push(_extends({}, tableColumn, { width: width }));
    } else {
      acc.push(tableColumn);
    }
    return acc;
  }, []);
};

var MIN_SIZE = 40;

var changeTableColumnWidths = function changeTableColumnWidths(state, _ref) {
  var shifts = _ref.shifts;
  var columnWidths = state.columnWidths;

  var updatedColumnWidths = Object.keys(shifts).reduce(function (acc, columnName) {
    var size = Math.max(MIN_SIZE, columnWidths[columnName] + shifts[columnName]);
    return Object.assign(acc, defineProperty({}, columnName, size));
  }, {});
  return _extends({}, state, {
    columnWidths: _extends({}, columnWidths, updatedColumnWidths),
    draftColumnWidths: {}
  });
};

var changeDraftTableColumnWidths = function changeDraftTableColumnWidths(state, _ref2) {
  var shifts = _ref2.shifts;
  var columnWidths = state.columnWidths,
      draftColumnWidths = state.draftColumnWidths;

  var updatedDraftColumnWidths = Object.keys(shifts).reduce(function (acc, columnName) {
    if (shifts[columnName] === null) {
      delete acc[columnName];
      return acc;
    }
    var size = Math.max(MIN_SIZE, columnWidths[columnName] + shifts[columnName]);
    return Object.assign(acc, defineProperty({}, columnName, size));
  }, Object.assign({}, draftColumnWidths));
  return _extends({}, state, {
    draftColumnWidths: updatedDraftColumnWidths
  });
};

var TABLE_EDIT_COMMAND_TYPE = 'editCommand';

var TABLE_ADDED_TYPE = 'added';
var TABLE_EDIT_TYPE = 'edit';

var TABLE_HEADING_TYPE = 'heading';

var isHeadingEditCommandsTableCell = function isHeadingEditCommandsTableCell(tableRow, tableColumn) {
  return tableRow.type === TABLE_HEADING_TYPE && tableColumn.type === TABLE_EDIT_COMMAND_TYPE;
};
var isEditCommandsTableCell = function isEditCommandsTableCell(tableRow, tableColumn) {
  return (tableRow.type === TABLE_DATA_TYPE || tableRow.type === TABLE_ADDED_TYPE || tableRow.type === TABLE_EDIT_TYPE) && tableColumn.type === TABLE_EDIT_COMMAND_TYPE;
};

var tableColumnsWithEditing = function tableColumnsWithEditing(tableColumns, width) {
  return [{ key: TABLE_EDIT_COMMAND_TYPE, type: TABLE_EDIT_COMMAND_TYPE, width: width }].concat(toConsumableArray(tableColumns));
};

var isEditTableCell = function isEditTableCell(tableRow, tableColumn) {
  return (tableRow.type === TABLE_ADDED_TYPE || tableRow.type === TABLE_EDIT_TYPE) && tableColumn.type === TABLE_DATA_TYPE;
};
var isAddedTableRow = function isAddedTableRow(tableRow) {
  return tableRow.type === TABLE_ADDED_TYPE;
};
var isEditTableRow = function isEditTableRow(tableRow) {
  return tableRow.type === TABLE_EDIT_TYPE;
};

var tableRowsWithEditing = function tableRowsWithEditing(tableRows, editingRows, addedRows, rowHeight) {
  var rowIds = new Set(editingRows);
  var editedTableRows = tableRows.map(function (tableRow) {
    return tableRow.type === TABLE_DATA_TYPE && rowIds.has(tableRow.rowId) ? _extends({}, tableRow, {
      type: TABLE_EDIT_TYPE,
      height: rowHeight
    }) : tableRow;
  });

  var addedTableRows = addedRows.map(function (row, rowIndex) {
    return {
      key: TABLE_ADDED_TYPE + '_' + rowIndex,
      type: TABLE_ADDED_TYPE,
      rowId: rowIndex,
      height: rowHeight,
      row: row
    };
  });

  return [].concat(toConsumableArray(addedTableRows.reverse()), toConsumableArray(editedTableRows));
};

var TABLE_FILTER_TYPE = 'filter';

var isFilterTableCell = function isFilterTableCell(tableRow, tableColumn) {
  return tableRow.type === TABLE_FILTER_TYPE && tableColumn.type === TABLE_DATA_TYPE;
};
var isFilterTableRow = function isFilterTableRow(tableRow) {
  return tableRow.type === TABLE_FILTER_TYPE;
};

var tableHeaderRowsWithFilter = function tableHeaderRowsWithFilter(headerRows, rowHeight) {
  return [].concat(toConsumableArray(headerRows), [{ key: TABLE_FILTER_TYPE, type: TABLE_FILTER_TYPE, height: rowHeight }]);
};

var TABLE_GROUP_TYPE = 'group';

var isGroupTableCell = function isGroupTableCell(tableRow, tableColumn) {
  return tableRow.type === TABLE_GROUP_TYPE && tableColumn.type === TABLE_GROUP_TYPE && tableRow.row.groupedBy === tableColumn.column.name;
};
var isGroupIndentTableCell = function isGroupIndentTableCell(tableRow, tableColumn) {
  return tableRow.type === TABLE_GROUP_TYPE && tableColumn.type === TABLE_GROUP_TYPE && tableRow.row.groupedBy !== tableColumn.column.name;
};
var isGroupTableRow = function isGroupTableRow(tableRow) {
  return tableRow.type === TABLE_GROUP_TYPE;
};

var tableColumnsWithDraftGrouping = function tableColumnsWithDraftGrouping(tableColumns, draftGrouping, showColumnWhenGrouped) {
  return tableColumns.reduce(function (acc, tableColumn) {
    var isDataColumn = tableColumn.type === TABLE_DATA_TYPE;
    var tableColumnName = isDataColumn ? tableColumn.column.name : '';
    var columnDraftGrouping = draftGrouping.find(function (grouping) {
      return grouping.columnName === tableColumnName;
    });

    if (!columnDraftGrouping || showColumnWhenGrouped(tableColumnName)) {
      return [].concat(toConsumableArray(acc), [tableColumn]);
    } else if (columnDraftGrouping.mode === 'remove' || columnDraftGrouping.mode === 'add') {
      return [].concat(toConsumableArray(acc), [_extends({}, tableColumn, {
        draft: true
      })]);
    }
    return acc;
  }, []);
};

var tableColumnsWithGrouping = function tableColumnsWithGrouping(tableColumns, grouping, draftGrouping, groupIndentColumnWidth, showColumnWhenGrouped) {
  return [].concat(toConsumableArray(grouping.map(function (columnGrouping) {
    var groupedColumn = tableColumns.find(function (tableColumn) {
      return tableColumn.type === TABLE_DATA_TYPE && tableColumn.column.name === columnGrouping.columnName;
    }).column;
    return {
      key: TABLE_GROUP_TYPE + '_' + groupedColumn.name,
      type: TABLE_GROUP_TYPE,
      column: groupedColumn,
      width: groupIndentColumnWidth
    };
  })), toConsumableArray(tableColumnsWithDraftGrouping(tableColumns, draftGrouping, showColumnWhenGrouped)));
};

var tableRowsWithGrouping = function tableRowsWithGrouping(tableRows, isGroupRow) {
  return tableRows.map(function (tableRow) {
    if (tableRow.type !== TABLE_DATA_TYPE || !isGroupRow(tableRow.row)) {
      return tableRow;
    }
    return _extends({}, tableRow, {
      key: TABLE_GROUP_TYPE + '_' + tableRow.row.compoundKey,
      type: TABLE_GROUP_TYPE,
      colSpanStart: TABLE_GROUP_TYPE + '_' + tableRow.row.groupedBy
    });
  });
};

var isHeadingTableCell = function isHeadingTableCell(tableRow, tableColumn) {
  return tableRow.type === TABLE_HEADING_TYPE && tableColumn.type === TABLE_DATA_TYPE;
};

var isHeadingTableRow = function isHeadingTableRow(tableRow) {
  return tableRow.type === TABLE_HEADING_TYPE;
};

var tableRowsWithHeading = function tableRowsWithHeading(headerRows) {
  return [{ key: TABLE_HEADING_TYPE, type: TABLE_HEADING_TYPE }].concat(toConsumableArray(headerRows));
};

var TABLE_DETAIL_TYPE = 'detail';

var isDetailRowExpanded = function isDetailRowExpanded(expandedRows, rowId) {
  return expandedRows.indexOf(rowId) > -1;
};
var isDetailToggleTableCell = function isDetailToggleTableCell(tableRow, tableColumn) {
  return tableColumn.type === TABLE_DETAIL_TYPE && tableRow.type === TABLE_DATA_TYPE;
};
var isDetailTableRow = function isDetailTableRow(tableRow) {
  return tableRow.type === TABLE_DETAIL_TYPE;
};

var setDetailRowExpanded = function setDetailRowExpanded(prevExpanded, _ref) {
  var rowId = _ref.rowId,
      isExpanded = _ref.isExpanded;

  var expandedRows = Array.from(prevExpanded);
  var expandedIndex = expandedRows.indexOf(rowId);
  var isRowExpanded = isExpanded !== undefined ? isExpanded : expandedIndex === -1;

  if (expandedIndex > -1 && !isRowExpanded) {
    expandedRows.splice(expandedIndex, 1);
  } else if (expandedIndex === -1 && isRowExpanded) {
    expandedRows.push(rowId);
  }

  return expandedRows;
};

var tableRowsWithExpandedDetail = function tableRowsWithExpandedDetail(tableRows, expandedRows, rowHeight) {
  var result = tableRows;
  expandedRows.forEach(function (expandedRowId) {
    var rowIndex = result.findIndex(function (tableRow) {
      return tableRow.type === TABLE_DATA_TYPE && tableRow.rowId === expandedRowId;
    });
    if (rowIndex === -1) return;
    var insertIndex = rowIndex + 1;
    var _result$rowIndex = result[rowIndex],
        row = _result$rowIndex.row,
        rowId = _result$rowIndex.rowId;

    result = [].concat(toConsumableArray(result.slice(0, insertIndex)), [{
      key: TABLE_DETAIL_TYPE + '_' + rowId,
      type: TABLE_DETAIL_TYPE,
      rowId: rowId,
      row: row,
      colSpanStart: 0,
      height: rowHeight
    }], toConsumableArray(result.slice(insertIndex)));
  });
  return result;
};

var tableColumnsWithDetail = function tableColumnsWithDetail(tableColumns, detailToggleCellWidth) {
  return [{ key: TABLE_DETAIL_TYPE, type: TABLE_DETAIL_TYPE, width: detailToggleCellWidth }].concat(toConsumableArray(tableColumns));
};

var TABLE_SELECT_TYPE = 'select';

var isSelectTableCell = function isSelectTableCell(tableRow, tableColumn) {
  return tableColumn.type === TABLE_SELECT_TYPE && tableRow.type === TABLE_DATA_TYPE;
};
var isSelectAllTableCell = function isSelectAllTableCell(tableRow, tableColumn) {
  return tableColumn.type === TABLE_SELECT_TYPE && tableRow.type === TABLE_HEADING_TYPE;
};

var tableColumnsWithSelection = function tableColumnsWithSelection(tableColumns, selectionColumnWidth) {
  return [{ key: TABLE_SELECT_TYPE, type: TABLE_SELECT_TYPE, width: selectionColumnWidth }].concat(toConsumableArray(tableColumns));
};

var isNoDataTableRow = function isNoDataTableRow(tableRow) {
  return tableRow.type === TABLE_NODATA_TYPE;
};
var isDataTableCell = function isDataTableCell(tableRow, tableColumn) {
  return tableRow.type === TABLE_DATA_TYPE && tableColumn.type === TABLE_DATA_TYPE;
};
var isHeaderStubTableCell = function isHeaderStubTableCell(tableRow, headerRows) {
  return headerRows.indexOf(tableRow) > -1;
};
var isDataTableRow = function isDataTableRow(tableRow) {
  return tableRow.type === TABLE_DATA_TYPE;
};

var tableColumnsWithDataRows = function tableColumnsWithDataRows(columns) {
  return columns.map(function (column) {
    return {
      key: TABLE_DATA_TYPE + '_' + column.name,
      type: TABLE_DATA_TYPE,
      width: column.width,
      column: column
    };
  });
};

var tableRowsWithDataRows = function tableRowsWithDataRows(rows, getRowId) {
  return !rows.length ? [{ key: TABLE_NODATA_TYPE, type: TABLE_NODATA_TYPE, colSpanStart: 0 }] : rows.map(function (row) {
    var rowId = getRowId(row);
    return {
      row: row,
      rowId: rowId,
      type: TABLE_DATA_TYPE,
      key: TABLE_DATA_TYPE + '_' + rowId
    };
  });
};

var visibleTableColumns = function visibleTableColumns(tableColumns, hiddenColumns) {
  return tableColumns.filter(function (tableColumn) {
    return hiddenColumns.indexOf(tableColumn.column.name) === -1;
  });
};

var columnChooserItems = function columnChooserItems(columns, hiddenColumns) {
  return columns.map(function (column) {
    return { column: column, hidden: hiddenColumns.indexOf(column.name) !== -1 };
  });
};

var toggleColumn = function toggleColumn(hiddenColumns, columnName) {
  return hiddenColumns.indexOf(columnName) === -1 ? [].concat(toConsumableArray(hiddenColumns), [columnName]) : hiddenColumns.filter(function (hiddenColumn) {
    return hiddenColumn !== columnName;
  });
};

var getTargetColumnGeometries = function getTargetColumnGeometries(columnGeometries, sourceIndex) {
  var sourceWidth = columnGeometries[sourceIndex].right - columnGeometries[sourceIndex].left;
  var getWidthDifference = function getWidthDifference(index) {
    return columnGeometries[index].right - columnGeometries[index].left - sourceWidth;
  };

  return columnGeometries.map(function (_ref, targetIndex) {
    var top = _ref.top,
        right = _ref.right,
        bottom = _ref.bottom,
        left = _ref.left;

    var leftBorder = left;
    if (targetIndex > 0 && targetIndex <= sourceIndex) {
      leftBorder = Math.min(leftBorder, leftBorder - getWidthDifference(targetIndex - 1));
    }
    if (targetIndex > sourceIndex) {
      leftBorder = Math.max(leftBorder, leftBorder + getWidthDifference(targetIndex));
    }
    var rightBorder = right;
    if (targetIndex < columnGeometries.length - 1 && targetIndex >= sourceIndex) {
      rightBorder = Math.max(rightBorder, rightBorder + getWidthDifference(targetIndex + 1));
    }
    if (targetIndex < sourceIndex) {
      rightBorder = Math.min(rightBorder, rightBorder - getWidthDifference(targetIndex));
    }

    return {
      top: top,
      right: rightBorder,
      bottom: bottom,
      left: leftBorder
    };
  });
};

var getTableRowColumnsWithColSpan = function getTableRowColumnsWithColSpan(tableColumns, colSpanStart) {
  if (colSpanStart === undefined) return tableColumns;

  var span = false;
  return tableColumns.reduce(function (acc, tableColumn, columnIndex) {
    if (span) return acc;
    if (columnIndex === colSpanStart || tableColumn.key === colSpanStart) {
      span = true;
      return [].concat(toConsumableArray(acc), [_extends({}, tableColumn, { colSpan: tableColumns.length - columnIndex })]);
    }
    return [].concat(toConsumableArray(acc), [tableColumn]);
  }, []);
};

var getTableColumnGeometries = function getTableColumnGeometries(columns, tableWidth) {
  var columnWidths = columns.map(function (column) {
    return column.width;
  });

  var freeSpace = tableWidth;
  var restrictedSpace = columnWidths.reduce(function (accum, width) {
    return accum + (width || 0);
  }, 0);
  var freeSpacePortions = columnWidths.reduce(function (accum, width) {
    return accum + (width === undefined ? 1 : 0);
  }, 0);
  var freeSpacePortion = (freeSpace - restrictedSpace) / freeSpacePortions;

  var lastRightPosition = 0;
  return columnWidths.map(function (width) {
    return width === undefined ? freeSpacePortion : width;
  }).map(function (width) {
    lastRightPosition += width;
    return {
      left: lastRightPosition - width,
      right: lastRightPosition
    };
  });
};

var getTableTargetColumnIndex = function getTableTargetColumnIndex(columnGeometries, sourceIndex, offset) {
  return getTargetColumnGeometries(columnGeometries, sourceIndex).findIndex(function (_ref) {
    var left = _ref.left,
        right = _ref.right;
    return offset > left && offset < right;
  });
};

var ANIMATION_DURATION = 200;

var getAnimationProgress = function getAnimationProgress(animation) {
  return (new Date().getTime() - animation.startTime) / ANIMATION_DURATION;
};

var getAnimations = function getAnimations(prevColumns, nextColumns, tableWidth, prevAnimations) {
  var prevColumnGeometries = new Map(getTableColumnGeometries(prevColumns, tableWidth).map(function (geometry, index) {
    return [prevColumns[index].key, geometry];
  }).map(function (_ref2) {
    var _ref3 = slicedToArray(_ref2, 2),
        key = _ref3[0],
        geometry = _ref3[1];

    var animation = prevAnimations.get(key);
    if (!animation) return [key, geometry];
    var progress = dxCore.easeOutCubic(getAnimationProgress(animation));
    var left = (animation.left.to - animation.left.from) * progress + animation.left.from;
    return [key, {
      left: left,
      right: geometry.right - (geometry.left - left)
    }];
  }));

  var nextColumnGeometries = new Map(getTableColumnGeometries(nextColumns, tableWidth).map(function (geometry, index) {
    return [nextColumns[index].key, geometry];
  }));

  return new Map([].concat(toConsumableArray(nextColumnGeometries.keys())).map(function (key) {
    var prev = prevColumnGeometries.get(key);
    var next = nextColumnGeometries.get(key);

    var result = { startTime: new Date().getTime(), style: {} };
    if (Math.abs(prev.left - next.left) > 1) {
      result.left = { from: prev.left, to: next.left };
    }
    return [key, result];
  }).filter(function (animation) {
    return animation[1].left;
  }));
};

var filterActiveAnimations = function filterActiveAnimations(animations) {
  return new Map([].concat(toConsumableArray(animations.entries())).filter(function (_ref4) {
    var _ref5 = slicedToArray(_ref4, 2),
        animation = _ref5[1];

    return getAnimationProgress(animation) < 1;
  }));
};

var evalAnimations = function evalAnimations(animations) {
  return new Map([].concat(toConsumableArray(animations.entries())).map(function (_ref6) {
    var _ref7 = slicedToArray(_ref6, 2),
        key = _ref7[0],
        animation = _ref7[1];

    var progress = dxCore.easeOutCubic(getAnimationProgress(animation));
    var result = _extends({}, animation.style);
    if (animation.left) {
      var offset = (animation.left.to - animation.left.from) * (progress - 1);
      result.transform = 'translateX(' + offset + 'px)';
    }
    return [key, result];
  }));
};

var isOnTheSameLine = function isOnTheSameLine(geometry, y) {
  return y >= geometry.top && y <= geometry.bottom;
};

var getGroupCellTargetIndex = function getGroupCellTargetIndex(geometries, sourceIndex, _ref) {
  var x = _ref.x,
      y = _ref.y;

  if (geometries.length === 0) return 0;

  var targetGeometries = sourceIndex !== -1 ? getTargetColumnGeometries(geometries, sourceIndex) : geometries;

  var targetIndex = targetGeometries.findIndex(function (geometry, index) {
    var inVerticalBounds = isOnTheSameLine(geometry, y);
    var inHorizontalBounds = x >= geometry.left && x <= geometry.right;
    var shouldGoFirst = index === 0 && x < geometry.left;
    var shouldGoOnLineBreak = !inVerticalBounds && !!geometries[index - 1] && isOnTheSameLine(geometries[index - 1], y);

    return inVerticalBounds && inHorizontalBounds || shouldGoFirst || shouldGoOnLineBreak;
  });

  return targetIndex === -1 ? geometries.length : targetIndex;
};

var processPattern = function processPattern(pattern, params) {
  return Object.keys(params).reduce(function (msg, key) {
    return msg.replace('{' + key + '}', params[key]);
  }, pattern);
};

var getMessagesFormatter = function getMessagesFormatter(messages) {
  return function (key, params) {
    var message = messages[key];

    if (typeof message === 'function') {
      return message(params);
    }
    if (params) {
      return processPattern(message, params);
    }
    return message;
  };
};

exports.getTableRowColumnsWithColSpan = getTableRowColumnsWithColSpan;
exports.getTableColumnGeometries = getTableColumnGeometries;
exports.getTableTargetColumnIndex = getTableTargetColumnIndex;
exports.getAnimations = getAnimations;
exports.filterActiveAnimations = filterActiveAnimations;
exports.evalAnimations = evalAnimations;
exports.getGroupCellTargetIndex = getGroupCellTargetIndex;
exports.getMessagesFormatter = getMessagesFormatter;
exports.rowIdGetter = rowIdGetter;
exports.cellValueGetter = cellValueGetter;
exports.setColumnSorting = setColumnSorting;
exports.getColumnSortingDirection = getColumnSortingDirection;
exports.sortedRows = sortedRows;
exports.setColumnFilter = setColumnFilter;
exports.getColumnFilterConfig = getColumnFilterConfig;
exports.filteredRows = filteredRows;
exports.groupByColumn = groupByColumn;
exports.toggleExpandedGroups = toggleExpandedGroups;
exports.draftGroupingChange = draftGroupingChange;
exports.cancelGroupingChange = cancelGroupingChange;
exports.draftGrouping = draftGrouping;
exports.groupRowChecker = groupRowChecker;
exports.groupRowLevelKeyGetter = groupRowLevelKeyGetter;
exports.groupedRows = groupedRows;
exports.expandedGroupRows = expandedGroupRows;
exports.customGroupedRows = customGroupedRows;
exports.customGroupingRowIdGetter = customGroupingRowIdGetter;
exports.groupingPanelItems = groupingPanelItems;
exports.setCurrentPage = setCurrentPage;
exports.setPageSize = setPageSize;
exports.paginatedRows = paginatedRows;
exports.rowsWithPageHeaders = rowsWithPageHeaders;
exports.pageCount = pageCount;
exports.rowCount = rowCount;
exports.firstRowOnPage = firstRowOnPage;
exports.lastRowOnPage = lastRowOnPage;
exports.setRowsSelection = setRowsSelection;
exports.getAvailableToSelect = getAvailableToSelect;
exports.getAvailableSelection = getAvailableSelection;
exports.startEditRows = startEditRows;
exports.stopEditRows = stopEditRows;
exports.addRow = addRow;
exports.changeAddedRow = changeAddedRow;
exports.cancelAddedRows = cancelAddedRows;
exports.changeRow = changeRow;
exports.cancelChanges = cancelChanges;
exports.deleteRows = deleteRows;
exports.cancelDeletedRows = cancelDeletedRows;
exports.changedRowsByIds = changedRowsByIds;
exports.addedRowsByIds = addedRowsByIds;
exports.computedCreateRowChange = computedCreateRowChange;
exports.getRowChange = getRowChange;
exports.TABLE_REORDERING_TYPE = TABLE_REORDERING_TYPE;
exports.changeColumnOrder = changeColumnOrder;
exports.orderedColumns = orderedColumns;
exports.tableHeaderRowsWithReordering = tableHeaderRowsWithReordering;
exports.draftOrder = draftOrder;
exports.tableColumnsWithWidths = tableColumnsWithWidths;
exports.changeTableColumnWidths = changeTableColumnWidths;
exports.changeDraftTableColumnWidths = changeDraftTableColumnWidths;
exports.TABLE_EDIT_COMMAND_TYPE = TABLE_EDIT_COMMAND_TYPE;
exports.isHeadingEditCommandsTableCell = isHeadingEditCommandsTableCell;
exports.isEditCommandsTableCell = isEditCommandsTableCell;
exports.tableColumnsWithEditing = tableColumnsWithEditing;
exports.TABLE_ADDED_TYPE = TABLE_ADDED_TYPE;
exports.TABLE_EDIT_TYPE = TABLE_EDIT_TYPE;
exports.isEditTableCell = isEditTableCell;
exports.isAddedTableRow = isAddedTableRow;
exports.isEditTableRow = isEditTableRow;
exports.tableRowsWithEditing = tableRowsWithEditing;
exports.TABLE_FILTER_TYPE = TABLE_FILTER_TYPE;
exports.isFilterTableCell = isFilterTableCell;
exports.isFilterTableRow = isFilterTableRow;
exports.tableHeaderRowsWithFilter = tableHeaderRowsWithFilter;
exports.TABLE_GROUP_TYPE = TABLE_GROUP_TYPE;
exports.isGroupTableCell = isGroupTableCell;
exports.isGroupIndentTableCell = isGroupIndentTableCell;
exports.isGroupTableRow = isGroupTableRow;
exports.tableColumnsWithGrouping = tableColumnsWithGrouping;
exports.tableRowsWithGrouping = tableRowsWithGrouping;
exports.TABLE_HEADING_TYPE = TABLE_HEADING_TYPE;
exports.isHeadingTableCell = isHeadingTableCell;
exports.isHeadingTableRow = isHeadingTableRow;
exports.tableRowsWithHeading = tableRowsWithHeading;
exports.TABLE_DETAIL_TYPE = TABLE_DETAIL_TYPE;
exports.isDetailRowExpanded = isDetailRowExpanded;
exports.isDetailToggleTableCell = isDetailToggleTableCell;
exports.isDetailTableRow = isDetailTableRow;
exports.setDetailRowExpanded = setDetailRowExpanded;
exports.tableRowsWithExpandedDetail = tableRowsWithExpandedDetail;
exports.tableColumnsWithDetail = tableColumnsWithDetail;
exports.TABLE_SELECT_TYPE = TABLE_SELECT_TYPE;
exports.isSelectTableCell = isSelectTableCell;
exports.isSelectAllTableCell = isSelectAllTableCell;
exports.tableColumnsWithSelection = tableColumnsWithSelection;
exports.TABLE_DATA_TYPE = TABLE_DATA_TYPE;
exports.TABLE_NODATA_TYPE = TABLE_NODATA_TYPE;
exports.isNoDataTableRow = isNoDataTableRow;
exports.isDataTableCell = isDataTableCell;
exports.isHeaderStubTableCell = isHeaderStubTableCell;
exports.isDataTableRow = isDataTableRow;
exports.tableColumnsWithDataRows = tableColumnsWithDataRows;
exports.tableRowsWithDataRows = tableRowsWithDataRows;
exports.visibleTableColumns = visibleTableColumns;
exports.columnChooserItems = columnChooserItems;
exports.toggleColumn = toggleColumn;

Object.defineProperty(exports, '__esModule', { value: true });

})));
//# sourceMappingURL=dx-grid-core.umd.js.map
