text: "use strict";
  
  Object.defineProperty(exports, "__esModule", {
    value: true
  });
  exports.createSubset = void 0;
  
  var _is = require("../../utils/is.js");
  
  var _object = require("../../utils/object.js");
  
  var _array = require("../../utils/array.js");
  
  var _customs = require("../../utils/customs.js");
  
  var _DimensionError = require("../../error/DimensionError.js");
  
  var _factory = require("../../utils/factory.js");
  
  var name = 'subset';
  var dependencies = ['typed', 'matrix'];
  var createSubset = /* #__PURE__ */(0, _factory.factory)(name, dependencies, function (_ref) {
    var typed = _ref.typed,
        matrix = _ref.matrix;
  
    /**
     * Get or set a subset of a matrix or string.
     *
     * Syntax:
     *     math.subset(value, index)                                // retrieve a subset
     *     math.subset(value, index, replacement [, defaultValue])  // replace a subset
     *
     * Examples:
     *
     *     // get a subset
     *     const d = [[1, 2], [3, 4]]
     *     math.subset(d, math.index(1, 0))        // returns 3
     *     math.subset(d, math.index([0, 1], 1))   // returns [[2], [4]]
     *
     *     // replace a subset
     *     const e = []
     *     const f = math.subset(e, math.index(0, [0, 2]), [5, 6])  // f = [[5, 6]]
     *     const g = math.subset(f, math.index(1, 1), 7, 0)         // g = [[5, 6], [0, 7]]
     *
     * See also:
     *
     *     size, resize, squeeze, index
     *
     * @param {Array | Matrix | string} matrix  An array, matrix, or string
     * @param {Index} index                     An index containing ranges for each
     *                                          dimension
     * @param {*} [replacement]                 An array, matrix, or scalar.
     *                                          If provided, the subset is replaced with replacement.
     *                                          If not provided, the subset is returned
     * @param {*} [defaultValue=undefined]      Default value, filled in on new entries when
     *                                          the matrix is resized. If not provided,
     *                                          math.matrix elements will be left undefined.
     * @return {Array | Matrix | string} Either the retrieved subset or the updated matrix.
     */
    return typed(name, {
      // get subset
      'Array, Index': function ArrayIndex(value, index) {
        var m = matrix(value);
        var subset = m.subset(index); // returns a Matrix
  
        return index.isScalar() ? subset : subset.valueOf(); // return an Array (like the input)
      },
      'Matrix, Index': function MatrixIndex(value, index) {
        return value.subset(index);
      },
      'Object, Index': _getObjectProperty,
      'string, Index': _getSubstring,
      // set subset
      'Array, Index, any': function ArrayIndexAny(value, index, replacement) {
        return matrix((0, _object.clone)(value)).subset(index, replacement, undefined).valueOf();
      },
      'Array, Index, any, any': function ArrayIndexAnyAny(value, index, replacement, defaultValue) {
        return matrix((0, _object.clone)(value)).subset(index, replacement, defaultValue).valueOf();
      },
      'Matrix, Index, any': function MatrixIndexAny(value, index, replacement) {
        return value.clone().subset(index, replacement);
      },
      'Matrix, Index, any, any': function MatrixIndexAnyAny(value, index, replacement, defaultValue) {
        return value.clone().subset(index, replacement, defaultValue);
      },
      'string, Index, string': _setSubstring,
      'string, Index, string, string': _setSubstring,
      'Object, Index, any': _setObjectProperty
    });
  });
  /**
   * Retrieve a subset of a string
   * @param {string} str            string from which to get a substring
   * @param {Index} index           An index containing ranges for each dimension
   * @returns {string} substring
   * @private
   */
  
  exports.createSubset = createSubset;
  
  function _getSubstring(str, index) {
    if (!(0, _is.isIndex)(index)) {
      // TODO: better error message
      throw new TypeError('Index expected');
    }
  
    if (index.size().length !== 1) {
      throw new _DimensionError.DimensionError(index.size().length, 1);
    } // validate whether the range is out of range
  
  
    var strLen = str.length;
    (0, _array.validateIndex)(index.min()[0], strLen);
    (0, _array.validateIndex)(index.max()[0], strLen);
    var range = index.dimension(0);
    var substr = '';
    range.forEach(function (v) {
      substr += str.charAt(v);
    });
    return substr;
  }
  /**
   * Replace a substring in a string
   * @param {string} str            string to be replaced
   * @param {Index} index           An index containing ranges for each dimension
   * @param {string} replacement    Replacement string
   * @param {string} [defaultValue] Default value to be uses when resizing
   *                                the string. is ' ' by default
   * @returns {string} result
   * @private
   */
  
  
  function _setSubstring(str, index, replacement, defaultValue) {
    if (!index || index.isIndex !== true) {
      // TODO: better error message
      throw new TypeError('Index expected');
    }
  
    if (index.size().length !== 1) {
      throw new _DimensionError.DimensionError(index.size().length, 1);
    }
  
    if (defaultValue !== undefined) {
      if (typeof defaultValue !== 'string' || defaultValue.length !== 1) {
        throw new TypeError('Single character expected as defaultValue');
      }
    } else {
      defaultValue = ' ';
    }
  
    var range = index.dimension(0);
    var len = range.size()[0];
  
    if (len !== replacement.length) {
      throw new _DimensionError.DimensionError(range.size()[0], replacement.length);
    } // validate whether the range is out of range
  
  
    var strLen = str.length;
    (0, _array.validateIndex)(index.min()[0]);
    (0, _array.validateIndex)(index.max()[0]); // copy the string into an array with characters
  
    var chars = [];
  
    for (var i = 0; i < strLen; i++) {
      chars[i] = str.charAt(i);
    }
  
    range.forEach(function (v, i) {
      chars[v] = replacement.charAt(i[0]);
    }); // initialize undefined characters with a space
  
    if (chars.length > strLen) {
      for (var _i = strLen - 1, _len = chars.length; _i < _len; _i++) {
        if (!chars[_i]) {
          chars[_i] = defaultValue;
        }
      }
    }
  
    return chars.join('');
  }
  /**
   * Retrieve a property from an object
   * @param {Object} object
   * @param {Index} index
   * @return {*} Returns the value of the property
   * @private
   */
  
  
  function _getObjectProperty(object, index) {
    if (index.size().length !== 1) {
      throw new _DimensionError.DimensionError(index.size(), 1);
    }
  
    var key = index.dimension(0);
  
    if (typeof key !== 'string') {
      throw new TypeError('String expected as index to retrieve an object property');
    }
  
    return (0, _customs.getSafeProperty)(object, key);
  }
  /**
   * Set a property on an object
   * @param {Object} object
   * @param {Index} index
   * @param {*} replacement
   * @return {*} Returns the updated object
   * @private
   */
  
  
  function _setObjectProperty(object, index, replacement) {
    if (index.size().length !== 1) {
      throw new _DimensionError.DimensionError(index.size(), 1);
    }
  
    var key = index.dimension(0);
  
    if (typeof key !== 'string') {
      throw new TypeError('String expected as index to retrieve an object property');
    } // clone the object, and apply the property to the clone
  
  
    var updated = (0, _object.clone)(object);
    (0, _customs.setSafeProperty)(updated, key, replacement);
    return updated;
  }