text: "use strict";
  
  require("core-js/modules/es.symbol");
  
  require("core-js/modules/es.symbol.description");
  
  require("core-js/modules/es.symbol.iterator");
  
  require("core-js/modules/es.array.index-of");
  
  require("core-js/modules/es.array.iterator");
  
  require("core-js/modules/es.object.to-string");
  
  require("core-js/modules/es.regexp.to-string");
  
  require("core-js/modules/es.string.iterator");
  
  require("core-js/modules/es.string.match");
  
  require("core-js/modules/es.string.replace");
  
  require("core-js/modules/es.string.split");
  
  require("core-js/modules/es.string.starts-with");
  
  require("core-js/modules/web.dom-collections.iterator");
  
  exports.__esModule = true;
  exports.default = void 0;
  
  var _hotFormulaParser = require("hot-formula-parser");
  
  var _array = require("../../helpers/array");
  
  var _object = require("../../helpers/object");
  
  var _localHooks = _interopRequireDefault(require("../../mixins/localHooks"));
  
  var _utils = require("./utils");
  
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  
  function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); }
  
  function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); }
  
  function _iterableToArrayLimit(arr, i) { if (!(Symbol.iterator in Object(arr) || Object.prototype.toString.call(arr) === "[object Arguments]")) { return; } 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"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
  
  function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
  
  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  
  function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
  
  function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
  
  var BARE_CELL_STRICT_REGEX = /^\$?[A-Z]+\$?\d+$/;
  var BARE_CELL_REGEX = /\$?[A-Z]+\$?\d+/;
  var CELL_REGEX = /(?:[^0-9A-Z$: ]|^)\s*(\$?[A-Z]+\$?\d+)\s*(?![0-9A-Z_: ])/g;
  var RANGE_REGEX = /\$?[A-Z]+\$?\d+\s*:\s*\$?[A-Z]+\$?\d+/g;
  var CELL_AND_RANGE_REGEX = /((?:[^0-9A-Z$: ]|^)\s*(\$?[A-Z]+\$?\d+)\s*(?![0-9A-Z_: ]))|(\$?[A-Z]+\$?\d+\s*:\s*\$?[A-Z]+\$?\d+)/g;
  /**
   * Component adds an ability to parse and modify formula expressions. It is designed for translating cell
   * coordinates and cell ranges in any direction. By default, component translates only relative coordinates but this
   * behavior can be overwritten by passing custom modifier which controls translating process.
   *
   * @class ExpressionModifier
   * @util
   */
  
  var ExpressionModifier =
  /*#__PURE__*/
  function () {
    function ExpressionModifier(expression) {
      _classCallCheck(this, ExpressionModifier);
  
      /**
       * Formula expression to modify.
       *
       * @type {String}
       */
      this.expression = '';
      /**
       * Extracted cells and cells ranges.
       *
       * @type {Array}
       */
  
      this.cells = [];
      /**
       * Function which can modify default behaviour of how cells and cell ranges will be translated.
       *
       * @type {null|Function}
       */
  
      this.customModifier = null;
  
      if (typeof expression === 'string') {
        this.setExpression(expression);
      }
    }
    /**
     * Set formula expression to modify.
     *
     * @param {String} expression Formula expression to process.
     * @returns {ExpressionModifier}
     */
  
  
    _createClass(ExpressionModifier, [{
      key: "setExpression",
      value: function setExpression(expression) {
        this.cells.length = 0;
        this.expression = (0, _utils.toUpperCaseFormula)(expression);
  
        this._extractCells();
  
        this._extractCellsRange();
  
        return this;
      }
      /**
       * Set function which can modify default behavior of how cells and cell ranges will be translated.
       * The passed function will be called with 4 arguments:
       *  - cell, A cell object with structure
       *            like this: {start: {row, column}, end: {row, column}, origLabel, type: 'cell|range', refError, toLabel: () => {}}
       *  - axis, Type of currently processing axis ('row' or 'column')
       *  - delta, Number as distance to translate. Can be positive or negative.
       *  - startFromIndex, Base index which translation will be applied from.
       *
       * the function must return an array with 3 items, where:
       *  [
       *    deltaStart, Number as a delta to translate first part of coordinates.
       *    deltaEnd,   Number as a delta to translate second part of coordinates (if cell range is modified).
       *    refError,   Defines an error which refers to the situation when translated cell overcrossed the data boundary.
       *  ]
       *
       *
       * @param {Function} customModifier Function with custom logic.
       */
  
    }, {
      key: "useCustomModifier",
      value: function useCustomModifier(customModifier) {
        this.customModifier = customModifier;
      }
      /**
       * Translate formula expression cells.
       *
       * @param {Object} delta Distance to move in proper direction.
       * @param {Object} [startFrom] Coordinates which translation will be applied from.
       * @returns {ExpressionModifier}
       */
  
    }, {
      key: "translate",
      value: function translate(_ref) {
        var _this = this;
  
        var deltaRow = _ref.row,
            deltaColumn = _ref.column;
        var startFrom = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
        (0, _array.arrayEach)(this.cells, function (cell) {
          if (deltaRow !== null && deltaRow !== void 0) {
            _this._translateCell(cell, 'row', deltaRow, startFrom.row);
          }
  
          if (deltaColumn !== null && deltaColumn !== void 0) {
            _this._translateCell(cell, 'column', deltaColumn, startFrom.column);
          }
        });
        return this;
      }
      /**
       * Translate object into string representation.
       *
       * @returns {String}
       */
  
    }, {
      key: "toString",
      value: function toString() {
        var _this2 = this;
  
        var expression = this.expression.replace(CELL_AND_RANGE_REGEX, function (match, p1, p2) {
          var isSingleCell = match.indexOf(':') === -1;
          var result = match;
          var cellLabel = match;
          var translatedCellLabel = null;
  
          if (isSingleCell) {
            cellLabel = BARE_CELL_STRICT_REGEX.test(p1) ? p1 : p2;
          }
  
          var cell = _this2._searchCell(cellLabel);
  
          if (cell) {
            translatedCellLabel = cell.refError ? (0, _hotFormulaParser.error)(_hotFormulaParser.ERROR_REF) : cell.toLabel();
  
            if (isSingleCell) {
              result = match.replace(cellLabel, translatedCellLabel);
            } else {
              result = translatedCellLabel;
            }
          }
  
          return result;
        });
  
        if (!expression.startsWith('=')) {
          expression = "=".concat(expression);
        }
  
        return expression;
      }
      /**
       * Translate single cell.
       *
       * @param {Object} cell Cell object.
       * @param {String} axis Axis to modify.
       * @param {Number} delta Distance to move.
       * @param {Number} [startFromIndex] Base index which translation will be applied from.
       * @private
       */
  
    }, {
      key: "_translateCell",
      value: function _translateCell(cell, axis, delta, startFromIndex) {
        var start = cell.start,
            end = cell.end;
        var startIndex = start[axis].index;
        var endIndex = end[axis].index;
        var deltaStart = delta;
        var deltaEnd = delta;
        var refError = false;
  
        if (this.customModifier) {
          var _this$customModifier = this.customModifier(cell, axis, delta, startFromIndex);
  
          var _this$customModifier2 = _slicedToArray(_this$customModifier, 3);
  
          deltaStart = _this$customModifier2[0];
          deltaEnd = _this$customModifier2[1];
          refError = _this$customModifier2[2];
        } else {
          // By default only relative cells are translated, if meets absolute reset deltas to 0
          if (start[axis].isAbsolute) {
            deltaStart = 0;
          }
  
          if (end[axis].isAbsolute) {
            deltaEnd = 0;
          }
        }
  
        if (deltaStart && !refError) {
          if (startIndex + deltaStart < 0) {
            refError = true;
          }
  
          start[axis].index = Math.max(startIndex + deltaStart, 0);
        }
  
        if (deltaEnd && !refError) {
          if (endIndex + deltaEnd < 0) {
            refError = true;
          }
  
          end[axis].index = Math.max(endIndex + deltaEnd, 0);
        }
  
        if (refError) {
          cell.refError = true;
        }
      }
      /**
       * Extract all cells from the formula expression.
       *
       * @private
       */
  
    }, {
      key: "_extractCells",
      value: function _extractCells() {
        var _this3 = this;
  
        var matches = this.expression.match(CELL_REGEX);
  
        if (!matches) {
          return;
        }
  
        (0, _array.arrayEach)(matches, function (coord) {
          var cellCoords = coord.match(BARE_CELL_REGEX);
  
          if (!cellCoords) {
            return;
          }
  
          var _extractLabel = (0, _hotFormulaParser.extractLabel)(cellCoords[0]),
              _extractLabel2 = _slicedToArray(_extractLabel, 2),
              row = _extractLabel2[0],
              column = _extractLabel2[1];
  
          _this3.cells.push(_this3._createCell({
            row: row,
            column: column
          }, {
            row: row,
            column: column
          }, cellCoords[0]));
        });
      }
      /**
       * Extract all cells range from the formula expression.
       *
       * @private
       */
  
    }, {
      key: "_extractCellsRange",
      value: function _extractCellsRange() {
        var _this4 = this;
  
        var matches = this.expression.match(RANGE_REGEX);
  
        if (!matches) {
          return;
        }
  
        (0, _array.arrayEach)(matches, function (match) {
          var _match$split = match.split(':'),
              _match$split2 = _slicedToArray(_match$split, 2),
              start = _match$split2[0],
              end = _match$split2[1];
  
          var _extractLabel3 = (0, _hotFormulaParser.extractLabel)(start),
              _extractLabel4 = _slicedToArray(_extractLabel3, 2),
              startRow = _extractLabel4[0],
              startColumn = _extractLabel4[1];
  
          var _extractLabel5 = (0, _hotFormulaParser.extractLabel)(end),
              _extractLabel6 = _slicedToArray(_extractLabel5, 2),
              endRow = _extractLabel6[0],
              endColumn = _extractLabel6[1];
  
          var startCell = {
            row: startRow,
            column: startColumn
          };
          var endCell = {
            row: endRow,
            column: endColumn
          };
  
          _this4.cells.push(_this4._createCell(startCell, endCell, match));
        });
      }
      /**
       * Search cell by its label.
       *
       * @param {String} label Cell label eq. `B4` or `$B$6`.
       * @returns {Object|null}
       * @private
       */
  
    }, {
      key: "_searchCell",
      value: function _searchCell(label) {
        var _arrayFilter = (0, _array.arrayFilter)(this.cells, function (cellMeta) {
          return cellMeta.origLabel === label;
        }),
            _arrayFilter2 = _slicedToArray(_arrayFilter, 1),
            cell = _arrayFilter2[0];
  
        return cell || null;
      }
      /**
       * Create object cell.
       *
       * @param {Object} start Start coordinates (top-left).
       * @param {Object} end End coordinates (bottom-right).
       * @param {String} label Original label name.
       * @returns {Object}
       * @private
       */
  
    }, {
      key: "_createCell",
      value: function _createCell(start, end, label) {
        return {
          start: start,
          end: end,
          origLabel: label,
          type: label.indexOf(':') === -1 ? 'cell' : 'range',
          refError: false,
          toLabel: function toLabel() {
            var newLabel = (0, _hotFormulaParser.toLabel)(this.start.row, this.start.column);
  
            if (this.type === 'range') {
              newLabel += ":".concat((0, _hotFormulaParser.toLabel)(this.end.row, this.end.column));
            }
  
            return newLabel;
          }
        };
      }
    }]);
  
    return ExpressionModifier;
  }();
  
  (0, _object.mixin)(ExpressionModifier, _localHooks.default);
  var _default = ExpressionModifier;
  exports.default = _default;