CoolFace
Apppublic

Pinsave/counterstrike

sourceHugging Faceupdated 3mo agoView on Hugging Face
1likes
util.js595 linesDownload Raw Back to lib
1/* -*- Mode: js; js-indent-level: 2; -*- */2/*3 * Copyright 2011 Mozilla Foundation and contributors4 * Licensed under the New BSD license. See LICENSE or:5 * http://opensource.org/licenses/BSD-3-Clause6 */7 8/**9 * This is a helper function for getting values from parameter/options10 * objects.11 *12 * @param args The object we are extracting values from13 * @param name The name of the property we are getting.14 * @param defaultValue An optional value to return if the property is missing15 * from the object. If this is not specified and the property is missing, an16 * error will be thrown.17 */18function getArg(aArgs, aName, aDefaultValue) {19  if (aName in aArgs) {20    return aArgs[aName];21  } else if (arguments.length === 3) {22    return aDefaultValue;23  } else {24    throw new Error('"' + aName + '" is a required argument.');25  }26}27exports.getArg = getArg;28 29var urlRegexp = /^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.-]*)(?::(\d+))?(.*)$/;30var dataUrlRegexp = /^data:.+\,.+$/;31 32function urlParse(aUrl) {33  var match = aUrl.match(urlRegexp);34  if (!match) {35    return null;36  }37  return {38    scheme: match[1],39    auth: match[2],40    host: match[3],41    port: match[4],42    path: match[5]43  };44}45exports.urlParse = urlParse;46 47function urlGenerate(aParsedUrl) {48  var url = '';49  if (aParsedUrl.scheme) {50    url += aParsedUrl.scheme + ':';51  }52  url += '//';53  if (aParsedUrl.auth) {54    url += aParsedUrl.auth + '@';55  }56  if (aParsedUrl.host) {57    url += aParsedUrl.host;58  }59  if (aParsedUrl.port) {60    url += ":" + aParsedUrl.port61  }62  if (aParsedUrl.path) {63    url += aParsedUrl.path;64  }65  return url;66}67exports.urlGenerate = urlGenerate;68 69var MAX_CACHED_INPUTS = 32;70 71/**72 * Takes some function `f(input) -> result` and returns a memoized version of73 * `f`.74 *75 * We keep at most `MAX_CACHED_INPUTS` memoized results of `f` alive. The76 * memoization is a dumb-simple, linear least-recently-used cache.77 */78function lruMemoize(f) {79  var cache = [];80 81  return function(input) {82    for (var i = 0; i < cache.length; i++) {83      if (cache[i].input === input) {84        var temp = cache[0];85        cache[0] = cache[i];86        cache[i] = temp;87        return cache[0].result;88      }89    }90 91    var result = f(input);92 93    cache.unshift({94      input,95      result,96    });97 98    if (cache.length > MAX_CACHED_INPUTS) {99      cache.pop();100    }101 102    return result;103  };104}105 106/**107 * Normalizes a path, or the path portion of a URL:108 *109 * - Replaces consecutive slashes with one slash.110 * - Removes unnecessary '.' parts.111 * - Removes unnecessary '<dir>/..' parts.112 *113 * Based on code in the Node.js 'path' core module.114 *115 * @param aPath The path or url to normalize.116 */117var normalize = lruMemoize(function normalize(aPath) {118  var path = aPath;119  var url = urlParse(aPath);120  if (url) {121    if (!url.path) {122      return aPath;123    }124    path = url.path;125  }126  var isAbsolute = exports.isAbsolute(path);127  // Split the path into parts between `/` characters. This is much faster than128  // using `.split(/\/+/g)`.129  var parts = [];130  var start = 0;131  var i = 0;132  while (true) {133    start = i;134    i = path.indexOf("/", start);135    if (i === -1) {136      parts.push(path.slice(start));137      break;138    } else {139      parts.push(path.slice(start, i));140      while (i < path.length && path[i] === "/") {141        i++;142      }143    }144  }145 146  for (var part, up = 0, i = parts.length - 1; i >= 0; i--) {147    part = parts[i];148    if (part === '.') {149      parts.splice(i, 1);150    } else if (part === '..') {151      up++;152    } else if (up > 0) {153      if (part === '') {154        // The first part is blank if the path is absolute. Trying to go155        // above the root is a no-op. Therefore we can remove all '..' parts156        // directly after the root.157        parts.splice(i + 1, up);158        up = 0;159      } else {160        parts.splice(i, 2);161        up--;162      }163    }164  }165  path = parts.join('/');166 167  if (path === '') {168    path = isAbsolute ? '/' : '.';169  }170 171  if (url) {172    url.path = path;173    return urlGenerate(url);174  }175  return path;176});177exports.normalize = normalize;178 179/**180 * Joins two paths/URLs.181 *182 * @param aRoot The root path or URL.183 * @param aPath The path or URL to be joined with the root.184 *185 * - If aPath is a URL or a data URI, aPath is returned, unless aPath is a186 *   scheme-relative URL: Then the scheme of aRoot, if any, is prepended187 *   first.188 * - Otherwise aPath is a path. If aRoot is a URL, then its path portion189 *   is updated with the result and aRoot is returned. Otherwise the result190 *   is returned.191 *   - If aPath is absolute, the result is aPath.192 *   - Otherwise the two paths are joined with a slash.193 * - Joining for example 'http://' and 'www.example.com' is also supported.194 */195function join(aRoot, aPath) {196  if (aRoot === "") {197    aRoot = ".";198  }199  if (aPath === "") {200    aPath = ".";201  }202  var aPathUrl = urlParse(aPath);203  var aRootUrl = urlParse(aRoot);204  if (aRootUrl) {205    aRoot = aRootUrl.path || '/';206  }207 208  // `join(foo, '//www.example.org')`209  if (aPathUrl && !aPathUrl.scheme) {210    if (aRootUrl) {211      aPathUrl.scheme = aRootUrl.scheme;212    }213    return urlGenerate(aPathUrl);214  }215 216  if (aPathUrl || aPath.match(dataUrlRegexp)) {217    return aPath;218  }219 220  // `join('http://', 'www.example.com')`221  if (aRootUrl && !aRootUrl.host && !aRootUrl.path) {222    aRootUrl.host = aPath;223    return urlGenerate(aRootUrl);224  }225 226  var joined = aPath.charAt(0) === '/'227    ? aPath228    : normalize(aRoot.replace(/\/+$/, '') + '/' + aPath);229 230  if (aRootUrl) {231    aRootUrl.path = joined;232    return urlGenerate(aRootUrl);233  }234  return joined;235}236exports.join = join;237 238exports.isAbsolute = function (aPath) {239  return aPath.charAt(0) === '/' || urlRegexp.test(aPath);240};241 242/**243 * Make a path relative to a URL or another path.244 *245 * @param aRoot The root path or URL.246 * @param aPath The path or URL to be made relative to aRoot.247 */248function relative(aRoot, aPath) {249  if (aRoot === "") {250    aRoot = ".";251  }252 253  aRoot = aRoot.replace(/\/$/, '');254 255  // It is possible for the path to be above the root. In this case, simply256  // checking whether the root is a prefix of the path won't work. Instead, we257  // need to remove components from the root one by one, until either we find258  // a prefix that fits, or we run out of components to remove.259  var level = 0;260  while (aPath.indexOf(aRoot + '/') !== 0) {261    var index = aRoot.lastIndexOf("/");262    if (index < 0) {263      return aPath;264    }265 266    // If the only part of the root that is left is the scheme (i.e. http://,267    // file:///, etc.), one or more slashes (/), or simply nothing at all, we268    // have exhausted all components, so the path is not relative to the root.269    aRoot = aRoot.slice(0, index);270    if (aRoot.match(/^([^\/]+:\/)?\/*$/)) {271      return aPath;272    }273 274    ++level;275  }276 277  // Make sure we add a "../" for each component we removed from the root.278  return Array(level + 1).join("../") + aPath.substr(aRoot.length + 1);279}280exports.relative = relative;281 282var supportsNullProto = (function () {283  var obj = Object.create(null);284  return !('__proto__' in obj);285}());286 287function identity (s) {288  return s;289}290 291/**292 * Because behavior goes wacky when you set `__proto__` on objects, we293 * have to prefix all the strings in our set with an arbitrary character.294 *295 * See https://github.com/mozilla/source-map/pull/31 and296 * https://github.com/mozilla/source-map/issues/30297 *298 * @param String aStr299 */300function toSetString(aStr) {301  if (isProtoString(aStr)) {302    return '$' + aStr;303  }304 305  return aStr;306}307exports.toSetString = supportsNullProto ? identity : toSetString;308 309function fromSetString(aStr) {310  if (isProtoString(aStr)) {311    return aStr.slice(1);312  }313 314  return aStr;315}316exports.fromSetString = supportsNullProto ? identity : fromSetString;317 318function isProtoString(s) {319  if (!s) {320    return false;321  }322 323  var length = s.length;324 325  if (length < 9 /* "__proto__".length */) {326    return false;327  }328 329  if (s.charCodeAt(length - 1) !== 95  /* '_' */ ||330      s.charCodeAt(length - 2) !== 95  /* '_' */ ||331      s.charCodeAt(length - 3) !== 111 /* 'o' */ ||332      s.charCodeAt(length - 4) !== 116 /* 't' */ ||333      s.charCodeAt(length - 5) !== 111 /* 'o' */ ||334      s.charCodeAt(length - 6) !== 114 /* 'r' */ ||335      s.charCodeAt(length - 7) !== 112 /* 'p' */ ||336      s.charCodeAt(length - 8) !== 95  /* '_' */ ||337      s.charCodeAt(length - 9) !== 95  /* '_' */) {338    return false;339  }340 341  for (var i = length - 10; i >= 0; i--) {342    if (s.charCodeAt(i) !== 36 /* '$' */) {343      return false;344    }345  }346 347  return true;348}349 350/**351 * Comparator between two mappings where the original positions are compared.352 *353 * Optionally pass in `true` as `onlyCompareGenerated` to consider two354 * mappings with the same original source/line/column, but different generated355 * line and column the same. Useful when searching for a mapping with a356 * stubbed out mapping.357 */358function compareByOriginalPositions(mappingA, mappingB, onlyCompareOriginal) {359  var cmp = strcmp(mappingA.source, mappingB.source);360  if (cmp !== 0) {361    return cmp;362  }363 364  cmp = mappingA.originalLine - mappingB.originalLine;365  if (cmp !== 0) {366    return cmp;367  }368 369  cmp = mappingA.originalColumn - mappingB.originalColumn;370  if (cmp !== 0 || onlyCompareOriginal) {371    return cmp;372  }373 374  cmp = mappingA.generatedColumn - mappingB.generatedColumn;375  if (cmp !== 0) {376    return cmp;377  }378 379  cmp = mappingA.generatedLine - mappingB.generatedLine;380  if (cmp !== 0) {381    return cmp;382  }383 384  return strcmp(mappingA.name, mappingB.name);385}386exports.compareByOriginalPositions = compareByOriginalPositions;387 388function compareByOriginalPositionsNoSource(mappingA, mappingB, onlyCompareOriginal) {389  var cmp390 391  cmp = mappingA.originalLine - mappingB.originalLine;392  if (cmp !== 0) {393    return cmp;394  }395 396  cmp = mappingA.originalColumn - mappingB.originalColumn;397  if (cmp !== 0 || onlyCompareOriginal) {398    return cmp;399  }400 401  cmp = mappingA.generatedColumn - mappingB.generatedColumn;402  if (cmp !== 0) {403    return cmp;404  }405 406  cmp = mappingA.generatedLine - mappingB.generatedLine;407  if (cmp !== 0) {408    return cmp;409  }410 411  return strcmp(mappingA.name, mappingB.name);412}413exports.compareByOriginalPositionsNoSource = compareByOriginalPositionsNoSource;414 415/**416 * Comparator between two mappings with deflated source and name indices where417 * the generated positions are compared.418 *419 * Optionally pass in `true` as `onlyCompareGenerated` to consider two420 * mappings with the same generated line and column, but different421 * source/name/original line and column the same. Useful when searching for a422 * mapping with a stubbed out mapping.423 */424function compareByGeneratedPositionsDeflated(mappingA, mappingB, onlyCompareGenerated) {425  var cmp = mappingA.generatedLine - mappingB.generatedLine;426  if (cmp !== 0) {427    return cmp;428  }429 430  cmp = mappingA.generatedColumn - mappingB.generatedColumn;431  if (cmp !== 0 || onlyCompareGenerated) {432    return cmp;433  }434 435  cmp = strcmp(mappingA.source, mappingB.source);436  if (cmp !== 0) {437    return cmp;438  }439 440  cmp = mappingA.originalLine - mappingB.originalLine;441  if (cmp !== 0) {442    return cmp;443  }444 445  cmp = mappingA.originalColumn - mappingB.originalColumn;446  if (cmp !== 0) {447    return cmp;448  }449 450  return strcmp(mappingA.name, mappingB.name);451}452exports.compareByGeneratedPositionsDeflated = compareByGeneratedPositionsDeflated;453 454function compareByGeneratedPositionsDeflatedNoLine(mappingA, mappingB, onlyCompareGenerated) {455  var cmp = mappingA.generatedColumn - mappingB.generatedColumn;456  if (cmp !== 0 || onlyCompareGenerated) {457    return cmp;458  }459 460  cmp = strcmp(mappingA.source, mappingB.source);461  if (cmp !== 0) {462    return cmp;463  }464 465  cmp = mappingA.originalLine - mappingB.originalLine;466  if (cmp !== 0) {467    return cmp;468  }469 470  cmp = mappingA.originalColumn - mappingB.originalColumn;471  if (cmp !== 0) {472    return cmp;473  }474 475  return strcmp(mappingA.name, mappingB.name);476}477exports.compareByGeneratedPositionsDeflatedNoLine = compareByGeneratedPositionsDeflatedNoLine;478 479function strcmp(aStr1, aStr2) {480  if (aStr1 === aStr2) {481    return 0;482  }483 484  if (aStr1 === null) {485    return 1; // aStr2 !== null486  }487 488  if (aStr2 === null) {489    return -1; // aStr1 !== null490  }491 492  if (aStr1 > aStr2) {493    return 1;494  }495 496  return -1;497}498 499/**500 * Comparator between two mappings with inflated source and name strings where501 * the generated positions are compared.502 */503function compareByGeneratedPositionsInflated(mappingA, mappingB) {504  var cmp = mappingA.generatedLine - mappingB.generatedLine;505  if (cmp !== 0) {506    return cmp;507  }508 509  cmp = mappingA.generatedColumn - mappingB.generatedColumn;510  if (cmp !== 0) {511    return cmp;512  }513 514  cmp = strcmp(mappingA.source, mappingB.source);515  if (cmp !== 0) {516    return cmp;517  }518 519  cmp = mappingA.originalLine - mappingB.originalLine;520  if (cmp !== 0) {521    return cmp;522  }523 524  cmp = mappingA.originalColumn - mappingB.originalColumn;525  if (cmp !== 0) {526    return cmp;527  }528 529  return strcmp(mappingA.name, mappingB.name);530}531exports.compareByGeneratedPositionsInflated = compareByGeneratedPositionsInflated;532 533/**534 * Strip any JSON XSSI avoidance prefix from the string (as documented535 * in the source maps specification), and then parse the string as536 * JSON.537 */538function parseSourceMapInput(str) {539  return JSON.parse(str.replace(/^\)]}'[^\n]*\n/, ''));540}541exports.parseSourceMapInput = parseSourceMapInput;542 543/**544 * Compute the URL of a source given the the source root, the source's545 * URL, and the source map's URL.546 */547function computeSourceURL(sourceRoot, sourceURL, sourceMapURL) {548  sourceURL = sourceURL || '';549 550  if (sourceRoot) {551    // This follows what Chrome does.552    if (sourceRoot[sourceRoot.length - 1] !== '/' && sourceURL[0] !== '/') {553      sourceRoot += '/';554    }555    // The spec says:556    //   Line 4: An optional source root, useful for relocating source557    //   files on a server or removing repeated values in the558    //   “sources” entry.  This value is prepended to the individual559    //   entries in the “source” field.560    sourceURL = sourceRoot + sourceURL;561  }562 563  // Historically, SourceMapConsumer did not take the sourceMapURL as564  // a parameter.  This mode is still somewhat supported, which is why565  // this code block is conditional.  However, it's preferable to pass566  // the source map URL to SourceMapConsumer, so that this function567  // can implement the source URL resolution algorithm as outlined in568  // the spec.  This block is basically the equivalent of:569  //    new URL(sourceURL, sourceMapURL).toString()570  // ... except it avoids using URL, which wasn't available in the571  // older releases of node still supported by this library.572  //573  // The spec says:574  //   If the sources are not absolute URLs after prepending of the575  //   “sourceRoot”, the sources are resolved relative to the576  //   SourceMap (like resolving script src in a html document).577  if (sourceMapURL) {578    var parsed = urlParse(sourceMapURL);579    if (!parsed) {580      throw new Error("sourceMapURL could not be parsed");581    }582    if (parsed.path) {583      // Strip the last path component, but keep the "/".584      var index = parsed.path.lastIndexOf('/');585      if (index >= 0) {586        parsed.path = parsed.path.substring(0, index + 1);587      }588    }589    sourceURL = join(urlGenerate(parsed), sourceURL);590  }591 592  return normalize(sourceURL);593}594exports.computeSourceURL = computeSourceURL;595