(function (global, factory) {
  typeof exports === 'object' && typeof module !== 'undefined' ?
    factory(
      exports,
      require('@jridgewell/set-array'),
      require('@jridgewell/sourcemap-codec'),
      require('@jridgewell/trace-mapping')
    )
  : typeof define === 'function' && define.amd ?
    define(
      [
        'exports',
        '@jridgewell/set-array',
        '@jridgewell/sourcemap-codec',
        '@jridgewell/trace-mapping',
      ],
      factory
    )
  : ((global = typeof globalThis !== 'undefined' ? globalThis : global || self),
    factory(
      (global.genMapping = {}),
      global.setArray,
      global.sourcemapCodec,
      global.traceMapping
    ));
})(this, function (exports, setArray, sourcemapCodec, traceMapping) {
  'use strict';

  const COLUMN = 0;
  const SOURCES_INDEX = 1;
  const SOURCE_LINE = 2;
  const SOURCE_COLUMN = 3;
  const NAMES_INDEX = 4;

  const NO_NAME = -1;
  /**
   * Provides the state to generate a sourcemap.
   */
  class GenMapping {
    constructor({ file, sourceRoot } = {}) {
      this._names = new setArray.SetArray();
      this._sources = new setArray.SetArray();
      this._sourcesContent = [];
      this._mappings = [];
      this.file = file;
      this.sourceRoot = sourceRoot;
      this._ignoreList = new setArray.SetArray();
    }
  }
  /**
   * Typescript doesn't allow friend access to private fields, so this just casts the map into a type
   * with public access modifiers.
   */
  function cast(map) {
    return map;
  }
  function addSegment(
    map,
    genLine,
    genColumn,
    source,
    sourceLine,
    sourceColumn,
    name,
    content
  ) {
    return addSegmentInternal(
      false,
      map,
      genLine,
      genColumn,
      source,
      sourceLine,
      sourceColumn,
      name,
      content
    );
  }
  function addMapping(map, mapping) {
    return addMappingInternal(false, map, mapping);
  }
  /**
   * Same as `addSegment`, but will only add the segment if it generates useful information in the
   * resulting map. This only works correctly if segments are added **in order**, meaning you should
   * not add a segment with a lower generated line/column than one that came before.
   */
  const maybeAddSegment = (
    map,
    genLine,
    genColumn,
    source,
    sourceLine,
    sourceColumn,
    name,
    content
  ) => {
    return addSegmentInternal(
      true,
      map,
      genLine,
      genColumn,
      source,
      sourceLine,
      sourceColumn,
      name,
      content
    );
  };
  /**
   * Same as `addMapping`, but will only add the mapping if it generates useful information in the
   * resulting map. This only works correctly if mappings are added **in order**, meaning you should
   * not add a mapping with a lower generated line/column than one that came before.
   */
  const maybeAddMapping = (map, mapping) => {
    return addMappingInternal(true, map, mapping);
  };
  /**
   * Adds/removes the content of the source file to the source map.
   */
  function setSourceContent(map, source, content) {
    const { _sources: sources, _sourcesContent: sourcesContent } = cast(map);
    const index = setArray.put(sources, source);
    sourcesContent[index] = content;
  }
  function setIgnore(map, source, ignore = true) {
    const {
      _sources: sources,
      _sourcesContent: sourcesContent,
      _ignoreList: ignoreList,
    } = cast(map);
    const index = setArray.put(sources, source);
    if (index === sourcesContent.length) sourcesContent[index] = null;
    if (ignore) setArray.put(ignoreList, index);
    else setArray.remove(ignoreList, index);
  }
  /**
   * Returns a sourcemap object (with decoded mappings) suitable for passing to a library that expects
   * a sourcemap, or to JSON.stringify.
   */
  function toDecodedMap(map) {
    const {
      _mappings: mappings,
      _sources: sources,
      _sourcesContent: sourcesContent,
      _names: names,
      _ignoreList: ignoreList,
    } = cast(map);
    removeEmptyFinalLines(mappings);
    return {
      version: 3,
      file: map.file || undefined,
      names: names.array,
      sourceRoot: map.sourceRoot || undefined,
      sources: sources.array,
      sourcesContent,
      mappings,
      ignoreList: ignoreList.array,
    };
  }
  /**
   * Returns a sourcemap object (with encoded mappings) suitable for passing to a library that expects
   * a sourcemap, or to JSON.stringify.
   */
  function toEncodedMap(map) {
    const decoded = toDecodedMap(map);
    return Object.assign(Object.assign({}, decoded), {
      mappings: sourcemapCodec.encode(decoded.mappings),
    });
  }
  /**
   * Constructs a new GenMapping, using the already present mappings of the input.
   */
  function fromMap(input) {
    const map = new traceMapping.TraceMap(input);
    const gen = new GenMapping({ file: map.file, sourceRoot: map.sourceRoot });
    putAll(cast(gen)._names, map.names);
    putAll(cast(gen)._sources, map.sources);
    cast(gen)._sourcesContent =
      map.sourcesContent || map.sources.map(() => null);
    cast(gen)._mappings = traceMapping.decodedMappings(map);
    if (map.ignoreList) putAll(cast(gen)._ignoreList, map.ignoreList);
    return gen;
  }
  /**
   * Returns an array of high-level mapping objects for every recorded segment, which could then be
   * passed to the `source-map` library.
   */
  function allMappings(map) {
    const out = [];
    const { _mappings: mappings, _sources: sources, _names: names } = cast(map);
    for (let i = 0; i < mappings.length; i++) {
      const line = mappings[i];
      for (let j = 0; j < line.length; j++) {
        const seg = line[j];
        const generated = { line: i + 1, column: seg[COLUMN] };
        let source = undefined;
        let original = undefined;
        let name = undefined;
        if (seg.length !== 1) {
          source = sources.array[seg[SOURCES_INDEX]];
          original = { line: seg[SOURCE_LINE] + 1, column: seg[SOURCE_COLUMN] };
          if (seg.length === 5) name = names.array[seg[NAMES_INDEX]];
        }
        out.push({ generated, source, original, name });
      }
    }
    return out;
  }
  // This split declaration is only so that terser can elminiate the static initialization block.
  function addSegmentInternal(
    skipable,
    map,
    genLine,
    genColumn,
    source,
    sourceLine,
    sourceColumn,
    name,
    content
  ) {
    const {
      _mappings: mappings,
      _sources: sources,
      _sourcesContent: sourcesContent,
      _names: names,
    } = cast(map);
    const line = getLine(mappings, genLine);
    const index = getColumnIndex(line, genColumn);
    if (!source) {
      if (skipable && skipSourceless(line, index)) return;
      return insert(line, index, [genColumn]);
    }
    const sourcesIndex = setArray.put(sources, source);
    const namesIndex = name ? setArray.put(names, name) : NO_NAME;
    if (sourcesIndex === sourcesContent.length)
      sourcesContent[sourcesIndex] =
        content !== null && content !== void 0 ? content : null;
    if (
      skipable &&
      skipSource(
        line,
        index,
        sourcesIndex,
        sourceLine,
        sourceColumn,
        namesIndex
      )
    ) {
      return;
    }
    return insert(
      line,
      index,
      name ?
        [genColumn, sourcesIndex, sourceLine, sourceColumn, namesIndex]
      : [genColumn, sourcesIndex, sourceLine, sourceColumn]
    );
  }
  function getLine(mappings, index) {
    for (let i = mappings.length; i <= index; i++) {
      mappings[i] = [];
    }
    return mappings[index];
  }
  function getColumnIndex(line, genColumn) {
    let index = line.length;
    for (let i = index - 1; i >= 0; index = i--) {
      const current = line[i];
      if (genColumn >= current[COLUMN]) break;
    }
    return index;
  }
  function insert(array, index, value) {
    for (let i = array.length; i > index; i--) {
      array[i] = array[i - 1];
    }
    array[index] = value;
  }
  function removeEmptyFinalLines(mappings) {
    const { length } = mappings;
    let len = length;
    for (let i = len - 1; i >= 0; len = i, i--) {
      if (mappings[i].length > 0) break;
    }
    if (len < length) mappings.length = len;
  }
  function putAll(setarr, array) {
    for (let i = 0; i < array.length; i++) setArray.put(setarr, array[i]);
  }
  function skipSourceless(line, index) {
    // The start of a line is already sourceless, so adding a sourceless segment to the beginning
    // doesn't generate any useful information.
    if (index === 0) return true;
    const prev = line[index - 1];
    // If the previous segment is also sourceless, then adding another sourceless segment doesn't
    // genrate any new information. Else, this segment will end the source/named segment and point to
    // a sourceless position, which is useful.
    return prev.length === 1;
  }
  function skipSource(
    line,
    index,
    sourcesIndex,
    sourceLine,
    sourceColumn,
    namesIndex
  ) {
    // A source/named segment at the start of a line gives position at that genColumn
    if (index === 0) return false;
    const prev = line[index - 1];
    // If the previous segment is sourceless, then we're transitioning to a source.
    if (prev.length === 1) return false;
    // If the previous segment maps to the exact same source position, then this segment doesn't
    // provide any new position information.
    return (
      sourcesIndex === prev[SOURCES_INDEX] &&
      sourceLine === prev[SOURCE_LINE] &&
      sourceColumn === prev[SOURCE_COLUMN] &&
      namesIndex === (prev.length === 5 ? prev[NAMES_INDEX] : NO_NAME)
    );
  }
  function addMappingInternal(skipable, map, mapping) {
    const { generated, source, original, name, content } = mapping;
    if (!source) {
      return addSegmentInternal(
        skipable,
        map,
        generated.line - 1,
        generated.column,
        null,
        null,
        null,
        null,
        null
      );
    }
    return addSegmentInternal(
      skipable,
      map,
      generated.line - 1,
      generated.column,
      source,
      original.line - 1,
      original.column,
      name,
      content
    );
  }

  exports.GenMapping = GenMapping;
  exports.addMapping = addMapping;
  exports.addSegment = addSegment;
  exports.allMappings = allMappings;
  exports.fromMap = fromMap;
  exports.maybeAddMapping = maybeAddMapping;
  exports.maybeAddSegment = maybeAddSegment;
  exports.setIgnore = setIgnore;
  exports.setSourceContent = setSourceContent;
  exports.toDecodedMap = toDecodedMap;
  exports.toEncodedMap = toEncodedMap;

  Object.defineProperty(exports, '__esModule', { value: true });
});
//# sourceMappingURL=gen-mapping.umd.js.map