text: "use strict";
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.getSystemPath = exports.asPosixPath = exports.asWindowsPath = exports.path = exports.noCacheNormalize = exports.normalize = exports.resetNormalizeCache = exports.fragment = exports.resolve = exports.relative = exports.isAbsolute = exports.join = exports.dirname = exports.basename = exports.extname = exports.split = exports.NormalizedRoot = exports.NormalizedSep = exports.PathCannotBeFragmentException = exports.PathMustBeAbsoluteException = exports.InvalidPathException = void 0;
  /**
   * @license
   * Copyright Google Inc. All Rights Reserved.
   *
   * Use of this source code is governed by an MIT-style license that can be
   * found in the LICENSE file at https://angular.io/license
   */
  const exception_1 = require("../exception");
  class InvalidPathException extends exception_1.BaseException {
      constructor(path) { super(`Path ${JSON.stringify(path)} is invalid.`); }
  }
  exports.InvalidPathException = InvalidPathException;
  class PathMustBeAbsoluteException extends exception_1.BaseException {
      constructor(path) { super(`Path ${JSON.stringify(path)} must be absolute.`); }
  }
  exports.PathMustBeAbsoluteException = PathMustBeAbsoluteException;
  class PathCannotBeFragmentException extends exception_1.BaseException {
      constructor(path) { super(`Path ${JSON.stringify(path)} cannot be made a fragment.`); }
  }
  exports.PathCannotBeFragmentException = PathCannotBeFragmentException;
  /**
   * The Separator for normalized path.
   * @type {Path}
   */
  exports.NormalizedSep = '/';
  /**
   * The root of a normalized path.
   * @type {Path}
   */
  exports.NormalizedRoot = exports.NormalizedSep;
  /**
   * Split a path into multiple path fragments. Each fragments except the last one will end with
   * a path separator.
   * @param {Path} path The path to split.
   * @returns {Path[]} An array of path fragments.
   */
  function split(path) {
      const fragments = path.split(exports.NormalizedSep).map(x => fragment(x));
      if (fragments[fragments.length - 1].length === 0) {
          fragments.pop();
      }
      return fragments;
  }
  exports.split = split;
  /**
   *
   */
  function extname(path) {
      const base = basename(path);
      const i = base.lastIndexOf('.');
      if (i < 1) {
          return '';
      }
      else {
          return base.substr(i);
      }
  }
  exports.extname = extname;
  /**
   * Return the basename of the path, as a Path. See path.basename
   */
  function basename(path) {
      const i = path.lastIndexOf(exports.NormalizedSep);
      if (i == -1) {
          return fragment(path);
      }
      else {
          return fragment(path.substr(path.lastIndexOf(exports.NormalizedSep) + 1));
      }
  }
  exports.basename = basename;
  /**
   * Return the dirname of the path, as a Path. See path.dirname
   */
  function dirname(path) {
      const index = path.lastIndexOf(exports.NormalizedSep);
      if (index === -1) {
          return '';
      }
      const endIndex = index === 0 ? 1 : index; // case of file under root: '/file'
      return normalize(path.substr(0, endIndex));
  }
  exports.dirname = dirname;
  /**
   * Join multiple paths together, and normalize the result. Accepts strings that will be
   * normalized as well (but the original must be a path).
   */
  function join(p1, ...others) {
      if (others.length > 0) {
          return normalize((p1 ? p1 + exports.NormalizedSep : '') + others.join(exports.NormalizedSep));
      }
      else {
          return p1;
      }
  }
  exports.join = join;
  /**
   * Returns true if a path is absolute.
   */
  function isAbsolute(p) {
      return p.startsWith(exports.NormalizedSep);
  }
  exports.isAbsolute = isAbsolute;
  /**
   * Returns a path such that `join(from, relative(from, to)) == to`.
   * Both paths must be absolute, otherwise it does not make much sense.
   */
  function relative(from, to) {
      if (!isAbsolute(from)) {
          throw new PathMustBeAbsoluteException(from);
      }
      if (!isAbsolute(to)) {
          throw new PathMustBeAbsoluteException(to);
      }
      let p;
      if (from == to) {
          p = '';
      }
      else {
          const splitFrom = split(from);
          const splitTo = split(to);
          while (splitFrom.length > 0 && splitTo.length > 0 && splitFrom[0] == splitTo[0]) {
              splitFrom.shift();
              splitTo.shift();
          }
          if (splitFrom.length == 0) {
              p = splitTo.join(exports.NormalizedSep);
          }
          else {
              p = splitFrom.map(_ => '..').concat(splitTo).join(exports.NormalizedSep);
          }
      }
      return normalize(p);
  }
  exports.relative = relative;
  /**
   * Returns a Path that is the resolution of p2, from p1. If p2 is absolute, it will return p2,
   * otherwise will join both p1 and p2.
   */
  function resolve(p1, p2) {
      if (isAbsolute(p2)) {
          return p2;
      }
      else {
          return join(p1, p2);
      }
  }
  exports.resolve = resolve;
  function fragment(path) {
      if (path.indexOf(exports.NormalizedSep) != -1) {
          throw new PathCannotBeFragmentException(path);
      }
      return path;
  }
  exports.fragment = fragment;
  /**
   * normalize() cache to reduce computation. For now this grows and we never flush it, but in the
   * future we might want to add a few cache flush to prevent this from growing too large.
   */
  let normalizedCache = new Map();
  /**
   * Reset the cache. This is only useful for testing.
   * @private
   */
  function resetNormalizeCache() {
      normalizedCache = new Map();
  }
  exports.resetNormalizeCache = resetNormalizeCache;
  /**
   * Normalize a string into a Path. This is the only mean to get a Path type from a string that
   * represents a system path. This method cache the results as real world paths tend to be
   * duplicated often.
   * Normalization includes:
   *   - Windows backslashes `\\` are replaced with `/`.
   *   - Windows drivers are replaced with `/X/`, where X is the drive letter.
   *   - Absolute paths starts with `/`.
   *   - Multiple `/` are replaced by a single one.
   *   - Path segments `.` are removed.
   *   - Path segments `..` are resolved.
   *   - If a path is absolute, having a `..` at the start is invalid (and will throw).
   * @param path The path to be normalized.
   */
  function normalize(path) {
      let maybePath = normalizedCache.get(path);
      if (!maybePath) {
          maybePath = noCacheNormalize(path);
          normalizedCache.set(path, maybePath);
      }
      return maybePath;
  }
  exports.normalize = normalize;
  /**
   * The no cache version of the normalize() function. Used for benchmarking and testing.
   */
  function noCacheNormalize(path) {
      if (path == '' || path == '.') {
          return '';
      }
      else if (path == exports.NormalizedRoot) {
          return exports.NormalizedRoot;
      }
      // Match absolute windows path.
      const original = path;
      if (path.match(/^[A-Z]:[\/\\]/i)) {
          path = '\\' + path[0] + '\\' + path.substr(3);
      }
      // We convert Windows paths as well here.
      const p = path.split(/[\/\\]/g);
      let relative = false;
      let i = 1;
      // Special case the first one.
      if (p[0] != '') {
          p.unshift('.');
          relative = true;
      }
      while (i < p.length) {
          if (p[i] == '.') {
              p.splice(i, 1);
          }
          else if (p[i] == '..') {
              if (i < 2 && !relative) {
                  throw new InvalidPathException(original);
              }
              else if (i >= 2 && p[i - 1] != '..') {
                  p.splice(i - 1, 2);
                  i--;
              }
              else {
                  i++;
              }
          }
          else if (p[i] == '') {
              p.splice(i, 1);
          }
          else {
              i++;
          }
      }
      if (p.length == 1) {
          return p[0] == '' ? exports.NormalizedSep : '';
      }
      else {
          if (p[0] == '.') {
              p.shift();
          }
          return p.join(exports.NormalizedSep);
      }
  }
  exports.noCacheNormalize = noCacheNormalize;
  exports.path = (strings, ...values) => {
      return normalize(String.raw(strings, ...values));
  };
  function asWindowsPath(path) {
      const drive = path.match(/^\/(\w)(?:\/(.*))?$/);
      if (drive) {
          const subPath = drive[2] ? drive[2].replace(/\//g, '\\') : '';
          return `${drive[1]}:\\${subPath}`;
      }
      return path.replace(/\//g, '\\');
  }
  exports.asWindowsPath = asWindowsPath;
  function asPosixPath(path) {
      return path;
  }
  exports.asPosixPath = asPosixPath;
  function getSystemPath(path) {
      if (process.platform.startsWith('win32')) {
          return asWindowsPath(path);
      }
      else {
          return asPosixPath(path);
      }
  }
  exports.getSystemPath = getSystemPath;
  