github.com/jfrog/frogbot@v1.1.1-0.20231221090046-821a26f50338/action/node_modules/semver/semver.js (about)

     1  exports = module.exports = SemVer
     2  
     3  var debug
     4  /* istanbul ignore next */
     5  if (typeof process === 'object' &&
     6      process.env &&
     7      process.env.NODE_DEBUG &&
     8      /\bsemver\b/i.test(process.env.NODE_DEBUG)) {
     9    debug = function () {
    10      var args = Array.prototype.slice.call(arguments, 0)
    11      args.unshift('SEMVER')
    12      console.log.apply(console, args)
    13    }
    14  } else {
    15    debug = function () {}
    16  }
    17  
    18  // Note: this is the semver.org version of the spec that it implements
    19  // Not necessarily the package version of this code.
    20  exports.SEMVER_SPEC_VERSION = '2.0.0'
    21  
    22  var MAX_LENGTH = 256
    23  var MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER ||
    24    /* istanbul ignore next */ 9007199254740991
    25  
    26  // Max safe segment length for coercion.
    27  var MAX_SAFE_COMPONENT_LENGTH = 16
    28  
    29  var MAX_SAFE_BUILD_LENGTH = MAX_LENGTH - 6
    30  
    31  // The actual regexps go on exports.re
    32  var re = exports.re = []
    33  var safeRe = exports.safeRe = []
    34  var src = exports.src = []
    35  var t = exports.tokens = {}
    36  var R = 0
    37  
    38  function tok (n) {
    39    t[n] = R++
    40  }
    41  
    42  var LETTERDASHNUMBER = '[a-zA-Z0-9-]'
    43  
    44  // Replace some greedy regex tokens to prevent regex dos issues. These regex are
    45  // used internally via the safeRe object since all inputs in this library get
    46  // normalized first to trim and collapse all extra whitespace. The original
    47  // regexes are exported for userland consumption and lower level usage. A
    48  // future breaking change could export the safer regex only with a note that
    49  // all input should have extra whitespace removed.
    50  var safeRegexReplacements = [
    51    ['\\s', 1],
    52    ['\\d', MAX_LENGTH],
    53    [LETTERDASHNUMBER, MAX_SAFE_BUILD_LENGTH],
    54  ]
    55  
    56  function makeSafeRe (value) {
    57    for (var i = 0; i < safeRegexReplacements.length; i++) {
    58      var token = safeRegexReplacements[i][0]
    59      var max = safeRegexReplacements[i][1]
    60      value = value
    61        .split(token + '*').join(token + '{0,' + max + '}')
    62        .split(token + '+').join(token + '{1,' + max + '}')
    63    }
    64    return value
    65  }
    66  
    67  // The following Regular Expressions can be used for tokenizing,
    68  // validating, and parsing SemVer version strings.
    69  
    70  // ## Numeric Identifier
    71  // A single `0`, or a non-zero digit followed by zero or more digits.
    72  
    73  tok('NUMERICIDENTIFIER')
    74  src[t.NUMERICIDENTIFIER] = '0|[1-9]\\d*'
    75  tok('NUMERICIDENTIFIERLOOSE')
    76  src[t.NUMERICIDENTIFIERLOOSE] = '\\d+'
    77  
    78  // ## Non-numeric Identifier
    79  // Zero or more digits, followed by a letter or hyphen, and then zero or
    80  // more letters, digits, or hyphens.
    81  
    82  tok('NONNUMERICIDENTIFIER')
    83  src[t.NONNUMERICIDENTIFIER] = '\\d*[a-zA-Z-]' + LETTERDASHNUMBER + '*'
    84  
    85  // ## Main Version
    86  // Three dot-separated numeric identifiers.
    87  
    88  tok('MAINVERSION')
    89  src[t.MAINVERSION] = '(' + src[t.NUMERICIDENTIFIER] + ')\\.' +
    90                     '(' + src[t.NUMERICIDENTIFIER] + ')\\.' +
    91                     '(' + src[t.NUMERICIDENTIFIER] + ')'
    92  
    93  tok('MAINVERSIONLOOSE')
    94  src[t.MAINVERSIONLOOSE] = '(' + src[t.NUMERICIDENTIFIERLOOSE] + ')\\.' +
    95                          '(' + src[t.NUMERICIDENTIFIERLOOSE] + ')\\.' +
    96                          '(' + src[t.NUMERICIDENTIFIERLOOSE] + ')'
    97  
    98  // ## Pre-release Version Identifier
    99  // A numeric identifier, or a non-numeric identifier.
   100  
   101  tok('PRERELEASEIDENTIFIER')
   102  src[t.PRERELEASEIDENTIFIER] = '(?:' + src[t.NUMERICIDENTIFIER] +
   103                              '|' + src[t.NONNUMERICIDENTIFIER] + ')'
   104  
   105  tok('PRERELEASEIDENTIFIERLOOSE')
   106  src[t.PRERELEASEIDENTIFIERLOOSE] = '(?:' + src[t.NUMERICIDENTIFIERLOOSE] +
   107                                   '|' + src[t.NONNUMERICIDENTIFIER] + ')'
   108  
   109  // ## Pre-release Version
   110  // Hyphen, followed by one or more dot-separated pre-release version
   111  // identifiers.
   112  
   113  tok('PRERELEASE')
   114  src[t.PRERELEASE] = '(?:-(' + src[t.PRERELEASEIDENTIFIER] +
   115                    '(?:\\.' + src[t.PRERELEASEIDENTIFIER] + ')*))'
   116  
   117  tok('PRERELEASELOOSE')
   118  src[t.PRERELEASELOOSE] = '(?:-?(' + src[t.PRERELEASEIDENTIFIERLOOSE] +
   119                         '(?:\\.' + src[t.PRERELEASEIDENTIFIERLOOSE] + ')*))'
   120  
   121  // ## Build Metadata Identifier
   122  // Any combination of digits, letters, or hyphens.
   123  
   124  tok('BUILDIDENTIFIER')
   125  src[t.BUILDIDENTIFIER] = LETTERDASHNUMBER + '+'
   126  
   127  // ## Build Metadata
   128  // Plus sign, followed by one or more period-separated build metadata
   129  // identifiers.
   130  
   131  tok('BUILD')
   132  src[t.BUILD] = '(?:\\+(' + src[t.BUILDIDENTIFIER] +
   133               '(?:\\.' + src[t.BUILDIDENTIFIER] + ')*))'
   134  
   135  // ## Full Version String
   136  // A main version, followed optionally by a pre-release version and
   137  // build metadata.
   138  
   139  // Note that the only major, minor, patch, and pre-release sections of
   140  // the version string are capturing groups.  The build metadata is not a
   141  // capturing group, because it should not ever be used in version
   142  // comparison.
   143  
   144  tok('FULL')
   145  tok('FULLPLAIN')
   146  src[t.FULLPLAIN] = 'v?' + src[t.MAINVERSION] +
   147                    src[t.PRERELEASE] + '?' +
   148                    src[t.BUILD] + '?'
   149  
   150  src[t.FULL] = '^' + src[t.FULLPLAIN] + '$'
   151  
   152  // like full, but allows v1.2.3 and =1.2.3, which people do sometimes.
   153  // also, 1.0.0alpha1 (prerelease without the hyphen) which is pretty
   154  // common in the npm registry.
   155  tok('LOOSEPLAIN')
   156  src[t.LOOSEPLAIN] = '[v=\\s]*' + src[t.MAINVERSIONLOOSE] +
   157                    src[t.PRERELEASELOOSE] + '?' +
   158                    src[t.BUILD] + '?'
   159  
   160  tok('LOOSE')
   161  src[t.LOOSE] = '^' + src[t.LOOSEPLAIN] + '$'
   162  
   163  tok('GTLT')
   164  src[t.GTLT] = '((?:<|>)?=?)'
   165  
   166  // Something like "2.*" or "1.2.x".
   167  // Note that "x.x" is a valid xRange identifer, meaning "any version"
   168  // Only the first item is strictly required.
   169  tok('XRANGEIDENTIFIERLOOSE')
   170  src[t.XRANGEIDENTIFIERLOOSE] = src[t.NUMERICIDENTIFIERLOOSE] + '|x|X|\\*'
   171  tok('XRANGEIDENTIFIER')
   172  src[t.XRANGEIDENTIFIER] = src[t.NUMERICIDENTIFIER] + '|x|X|\\*'
   173  
   174  tok('XRANGEPLAIN')
   175  src[t.XRANGEPLAIN] = '[v=\\s]*(' + src[t.XRANGEIDENTIFIER] + ')' +
   176                     '(?:\\.(' + src[t.XRANGEIDENTIFIER] + ')' +
   177                     '(?:\\.(' + src[t.XRANGEIDENTIFIER] + ')' +
   178                     '(?:' + src[t.PRERELEASE] + ')?' +
   179                     src[t.BUILD] + '?' +
   180                     ')?)?'
   181  
   182  tok('XRANGEPLAINLOOSE')
   183  src[t.XRANGEPLAINLOOSE] = '[v=\\s]*(' + src[t.XRANGEIDENTIFIERLOOSE] + ')' +
   184                          '(?:\\.(' + src[t.XRANGEIDENTIFIERLOOSE] + ')' +
   185                          '(?:\\.(' + src[t.XRANGEIDENTIFIERLOOSE] + ')' +
   186                          '(?:' + src[t.PRERELEASELOOSE] + ')?' +
   187                          src[t.BUILD] + '?' +
   188                          ')?)?'
   189  
   190  tok('XRANGE')
   191  src[t.XRANGE] = '^' + src[t.GTLT] + '\\s*' + src[t.XRANGEPLAIN] + '$'
   192  tok('XRANGELOOSE')
   193  src[t.XRANGELOOSE] = '^' + src[t.GTLT] + '\\s*' + src[t.XRANGEPLAINLOOSE] + '$'
   194  
   195  // Coercion.
   196  // Extract anything that could conceivably be a part of a valid semver
   197  tok('COERCE')
   198  src[t.COERCE] = '(^|[^\\d])' +
   199                '(\\d{1,' + MAX_SAFE_COMPONENT_LENGTH + '})' +
   200                '(?:\\.(\\d{1,' + MAX_SAFE_COMPONENT_LENGTH + '}))?' +
   201                '(?:\\.(\\d{1,' + MAX_SAFE_COMPONENT_LENGTH + '}))?' +
   202                '(?:$|[^\\d])'
   203  tok('COERCERTL')
   204  re[t.COERCERTL] = new RegExp(src[t.COERCE], 'g')
   205  safeRe[t.COERCERTL] = new RegExp(makeSafeRe(src[t.COERCE]), 'g')
   206  
   207  // Tilde ranges.
   208  // Meaning is "reasonably at or greater than"
   209  tok('LONETILDE')
   210  src[t.LONETILDE] = '(?:~>?)'
   211  
   212  tok('TILDETRIM')
   213  src[t.TILDETRIM] = '(\\s*)' + src[t.LONETILDE] + '\\s+'
   214  re[t.TILDETRIM] = new RegExp(src[t.TILDETRIM], 'g')
   215  safeRe[t.TILDETRIM] = new RegExp(makeSafeRe(src[t.TILDETRIM]), 'g')
   216  var tildeTrimReplace = '$1~'
   217  
   218  tok('TILDE')
   219  src[t.TILDE] = '^' + src[t.LONETILDE] + src[t.XRANGEPLAIN] + '$'
   220  tok('TILDELOOSE')
   221  src[t.TILDELOOSE] = '^' + src[t.LONETILDE] + src[t.XRANGEPLAINLOOSE] + '$'
   222  
   223  // Caret ranges.
   224  // Meaning is "at least and backwards compatible with"
   225  tok('LONECARET')
   226  src[t.LONECARET] = '(?:\\^)'
   227  
   228  tok('CARETTRIM')
   229  src[t.CARETTRIM] = '(\\s*)' + src[t.LONECARET] + '\\s+'
   230  re[t.CARETTRIM] = new RegExp(src[t.CARETTRIM], 'g')
   231  safeRe[t.CARETTRIM] = new RegExp(makeSafeRe(src[t.CARETTRIM]), 'g')
   232  var caretTrimReplace = '$1^'
   233  
   234  tok('CARET')
   235  src[t.CARET] = '^' + src[t.LONECARET] + src[t.XRANGEPLAIN] + '$'
   236  tok('CARETLOOSE')
   237  src[t.CARETLOOSE] = '^' + src[t.LONECARET] + src[t.XRANGEPLAINLOOSE] + '$'
   238  
   239  // A simple gt/lt/eq thing, or just "" to indicate "any version"
   240  tok('COMPARATORLOOSE')
   241  src[t.COMPARATORLOOSE] = '^' + src[t.GTLT] + '\\s*(' + src[t.LOOSEPLAIN] + ')$|^$'
   242  tok('COMPARATOR')
   243  src[t.COMPARATOR] = '^' + src[t.GTLT] + '\\s*(' + src[t.FULLPLAIN] + ')$|^$'
   244  
   245  // An expression to strip any whitespace between the gtlt and the thing
   246  // it modifies, so that `> 1.2.3` ==> `>1.2.3`
   247  tok('COMPARATORTRIM')
   248  src[t.COMPARATORTRIM] = '(\\s*)' + src[t.GTLT] +
   249                        '\\s*(' + src[t.LOOSEPLAIN] + '|' + src[t.XRANGEPLAIN] + ')'
   250  
   251  // this one has to use the /g flag
   252  re[t.COMPARATORTRIM] = new RegExp(src[t.COMPARATORTRIM], 'g')
   253  safeRe[t.COMPARATORTRIM] = new RegExp(makeSafeRe(src[t.COMPARATORTRIM]), 'g')
   254  var comparatorTrimReplace = '$1$2$3'
   255  
   256  // Something like `1.2.3 - 1.2.4`
   257  // Note that these all use the loose form, because they'll be
   258  // checked against either the strict or loose comparator form
   259  // later.
   260  tok('HYPHENRANGE')
   261  src[t.HYPHENRANGE] = '^\\s*(' + src[t.XRANGEPLAIN] + ')' +
   262                     '\\s+-\\s+' +
   263                     '(' + src[t.XRANGEPLAIN] + ')' +
   264                     '\\s*$'
   265  
   266  tok('HYPHENRANGELOOSE')
   267  src[t.HYPHENRANGELOOSE] = '^\\s*(' + src[t.XRANGEPLAINLOOSE] + ')' +
   268                          '\\s+-\\s+' +
   269                          '(' + src[t.XRANGEPLAINLOOSE] + ')' +
   270                          '\\s*$'
   271  
   272  // Star ranges basically just allow anything at all.
   273  tok('STAR')
   274  src[t.STAR] = '(<|>)?=?\\s*\\*'
   275  
   276  // Compile to actual regexp objects.
   277  // All are flag-free, unless they were created above with a flag.
   278  for (var i = 0; i < R; i++) {
   279    debug(i, src[i])
   280    if (!re[i]) {
   281      re[i] = new RegExp(src[i])
   282  
   283      // Replace all greedy whitespace to prevent regex dos issues. These regex are
   284      // used internally via the safeRe object since all inputs in this library get
   285      // normalized first to trim and collapse all extra whitespace. The original
   286      // regexes are exported for userland consumption and lower level usage. A
   287      // future breaking change could export the safer regex only with a note that
   288      // all input should have extra whitespace removed.
   289      safeRe[i] = new RegExp(makeSafeRe(src[i]))
   290    }
   291  }
   292  
   293  exports.parse = parse
   294  function parse (version, options) {
   295    if (!options || typeof options !== 'object') {
   296      options = {
   297        loose: !!options,
   298        includePrerelease: false
   299      }
   300    }
   301  
   302    if (version instanceof SemVer) {
   303      return version
   304    }
   305  
   306    if (typeof version !== 'string') {
   307      return null
   308    }
   309  
   310    if (version.length > MAX_LENGTH) {
   311      return null
   312    }
   313  
   314    var r = options.loose ? safeRe[t.LOOSE] : safeRe[t.FULL]
   315    if (!r.test(version)) {
   316      return null
   317    }
   318  
   319    try {
   320      return new SemVer(version, options)
   321    } catch (er) {
   322      return null
   323    }
   324  }
   325  
   326  exports.valid = valid
   327  function valid (version, options) {
   328    var v = parse(version, options)
   329    return v ? v.version : null
   330  }
   331  
   332  exports.clean = clean
   333  function clean (version, options) {
   334    var s = parse(version.trim().replace(/^[=v]+/, ''), options)
   335    return s ? s.version : null
   336  }
   337  
   338  exports.SemVer = SemVer
   339  
   340  function SemVer (version, options) {
   341    if (!options || typeof options !== 'object') {
   342      options = {
   343        loose: !!options,
   344        includePrerelease: false
   345      }
   346    }
   347    if (version instanceof SemVer) {
   348      if (version.loose === options.loose) {
   349        return version
   350      } else {
   351        version = version.version
   352      }
   353    } else if (typeof version !== 'string') {
   354      throw new TypeError('Invalid Version: ' + version)
   355    }
   356  
   357    if (version.length > MAX_LENGTH) {
   358      throw new TypeError('version is longer than ' + MAX_LENGTH + ' characters')
   359    }
   360  
   361    if (!(this instanceof SemVer)) {
   362      return new SemVer(version, options)
   363    }
   364  
   365    debug('SemVer', version, options)
   366    this.options = options
   367    this.loose = !!options.loose
   368  
   369    var m = version.trim().match(options.loose ? safeRe[t.LOOSE] : safeRe[t.FULL])
   370  
   371    if (!m) {
   372      throw new TypeError('Invalid Version: ' + version)
   373    }
   374  
   375    this.raw = version
   376  
   377    // these are actually numbers
   378    this.major = +m[1]
   379    this.minor = +m[2]
   380    this.patch = +m[3]
   381  
   382    if (this.major > MAX_SAFE_INTEGER || this.major < 0) {
   383      throw new TypeError('Invalid major version')
   384    }
   385  
   386    if (this.minor > MAX_SAFE_INTEGER || this.minor < 0) {
   387      throw new TypeError('Invalid minor version')
   388    }
   389  
   390    if (this.patch > MAX_SAFE_INTEGER || this.patch < 0) {
   391      throw new TypeError('Invalid patch version')
   392    }
   393  
   394    // numberify any prerelease numeric ids
   395    if (!m[4]) {
   396      this.prerelease = []
   397    } else {
   398      this.prerelease = m[4].split('.').map(function (id) {
   399        if (/^[0-9]+$/.test(id)) {
   400          var num = +id
   401          if (num >= 0 && num < MAX_SAFE_INTEGER) {
   402            return num
   403          }
   404        }
   405        return id
   406      })
   407    }
   408  
   409    this.build = m[5] ? m[5].split('.') : []
   410    this.format()
   411  }
   412  
   413  SemVer.prototype.format = function () {
   414    this.version = this.major + '.' + this.minor + '.' + this.patch
   415    if (this.prerelease.length) {
   416      this.version += '-' + this.prerelease.join('.')
   417    }
   418    return this.version
   419  }
   420  
   421  SemVer.prototype.toString = function () {
   422    return this.version
   423  }
   424  
   425  SemVer.prototype.compare = function (other) {
   426    debug('SemVer.compare', this.version, this.options, other)
   427    if (!(other instanceof SemVer)) {
   428      other = new SemVer(other, this.options)
   429    }
   430  
   431    return this.compareMain(other) || this.comparePre(other)
   432  }
   433  
   434  SemVer.prototype.compareMain = function (other) {
   435    if (!(other instanceof SemVer)) {
   436      other = new SemVer(other, this.options)
   437    }
   438  
   439    return compareIdentifiers(this.major, other.major) ||
   440           compareIdentifiers(this.minor, other.minor) ||
   441           compareIdentifiers(this.patch, other.patch)
   442  }
   443  
   444  SemVer.prototype.comparePre = function (other) {
   445    if (!(other instanceof SemVer)) {
   446      other = new SemVer(other, this.options)
   447    }
   448  
   449    // NOT having a prerelease is > having one
   450    if (this.prerelease.length && !other.prerelease.length) {
   451      return -1
   452    } else if (!this.prerelease.length && other.prerelease.length) {
   453      return 1
   454    } else if (!this.prerelease.length && !other.prerelease.length) {
   455      return 0
   456    }
   457  
   458    var i = 0
   459    do {
   460      var a = this.prerelease[i]
   461      var b = other.prerelease[i]
   462      debug('prerelease compare', i, a, b)
   463      if (a === undefined && b === undefined) {
   464        return 0
   465      } else if (b === undefined) {
   466        return 1
   467      } else if (a === undefined) {
   468        return -1
   469      } else if (a === b) {
   470        continue
   471      } else {
   472        return compareIdentifiers(a, b)
   473      }
   474    } while (++i)
   475  }
   476  
   477  SemVer.prototype.compareBuild = function (other) {
   478    if (!(other instanceof SemVer)) {
   479      other = new SemVer(other, this.options)
   480    }
   481  
   482    var i = 0
   483    do {
   484      var a = this.build[i]
   485      var b = other.build[i]
   486      debug('prerelease compare', i, a, b)
   487      if (a === undefined && b === undefined) {
   488        return 0
   489      } else if (b === undefined) {
   490        return 1
   491      } else if (a === undefined) {
   492        return -1
   493      } else if (a === b) {
   494        continue
   495      } else {
   496        return compareIdentifiers(a, b)
   497      }
   498    } while (++i)
   499  }
   500  
   501  // preminor will bump the version up to the next minor release, and immediately
   502  // down to pre-release. premajor and prepatch work the same way.
   503  SemVer.prototype.inc = function (release, identifier) {
   504    switch (release) {
   505      case 'premajor':
   506        this.prerelease.length = 0
   507        this.patch = 0
   508        this.minor = 0
   509        this.major++
   510        this.inc('pre', identifier)
   511        break
   512      case 'preminor':
   513        this.prerelease.length = 0
   514        this.patch = 0
   515        this.minor++
   516        this.inc('pre', identifier)
   517        break
   518      case 'prepatch':
   519        // If this is already a prerelease, it will bump to the next version
   520        // drop any prereleases that might already exist, since they are not
   521        // relevant at this point.
   522        this.prerelease.length = 0
   523        this.inc('patch', identifier)
   524        this.inc('pre', identifier)
   525        break
   526      // If the input is a non-prerelease version, this acts the same as
   527      // prepatch.
   528      case 'prerelease':
   529        if (this.prerelease.length === 0) {
   530          this.inc('patch', identifier)
   531        }
   532        this.inc('pre', identifier)
   533        break
   534  
   535      case 'major':
   536        // If this is a pre-major version, bump up to the same major version.
   537        // Otherwise increment major.
   538        // 1.0.0-5 bumps to 1.0.0
   539        // 1.1.0 bumps to 2.0.0
   540        if (this.minor !== 0 ||
   541            this.patch !== 0 ||
   542            this.prerelease.length === 0) {
   543          this.major++
   544        }
   545        this.minor = 0
   546        this.patch = 0
   547        this.prerelease = []
   548        break
   549      case 'minor':
   550        // If this is a pre-minor version, bump up to the same minor version.
   551        // Otherwise increment minor.
   552        // 1.2.0-5 bumps to 1.2.0
   553        // 1.2.1 bumps to 1.3.0
   554        if (this.patch !== 0 || this.prerelease.length === 0) {
   555          this.minor++
   556        }
   557        this.patch = 0
   558        this.prerelease = []
   559        break
   560      case 'patch':
   561        // If this is not a pre-release version, it will increment the patch.
   562        // If it is a pre-release it will bump up to the same patch version.
   563        // 1.2.0-5 patches to 1.2.0
   564        // 1.2.0 patches to 1.2.1
   565        if (this.prerelease.length === 0) {
   566          this.patch++
   567        }
   568        this.prerelease = []
   569        break
   570      // This probably shouldn't be used publicly.
   571      // 1.0.0 "pre" would become 1.0.0-0 which is the wrong direction.
   572      case 'pre':
   573        if (this.prerelease.length === 0) {
   574          this.prerelease = [0]
   575        } else {
   576          var i = this.prerelease.length
   577          while (--i >= 0) {
   578            if (typeof this.prerelease[i] === 'number') {
   579              this.prerelease[i]++
   580              i = -2
   581            }
   582          }
   583          if (i === -1) {
   584            // didn't increment anything
   585            this.prerelease.push(0)
   586          }
   587        }
   588        if (identifier) {
   589          // 1.2.0-beta.1 bumps to 1.2.0-beta.2,
   590          // 1.2.0-beta.fooblz or 1.2.0-beta bumps to 1.2.0-beta.0
   591          if (this.prerelease[0] === identifier) {
   592            if (isNaN(this.prerelease[1])) {
   593              this.prerelease = [identifier, 0]
   594            }
   595          } else {
   596            this.prerelease = [identifier, 0]
   597          }
   598        }
   599        break
   600  
   601      default:
   602        throw new Error('invalid increment argument: ' + release)
   603    }
   604    this.format()
   605    this.raw = this.version
   606    return this
   607  }
   608  
   609  exports.inc = inc
   610  function inc (version, release, loose, identifier) {
   611    if (typeof (loose) === 'string') {
   612      identifier = loose
   613      loose = undefined
   614    }
   615  
   616    try {
   617      return new SemVer(version, loose).inc(release, identifier).version
   618    } catch (er) {
   619      return null
   620    }
   621  }
   622  
   623  exports.diff = diff
   624  function diff (version1, version2) {
   625    if (eq(version1, version2)) {
   626      return null
   627    } else {
   628      var v1 = parse(version1)
   629      var v2 = parse(version2)
   630      var prefix = ''
   631      if (v1.prerelease.length || v2.prerelease.length) {
   632        prefix = 'pre'
   633        var defaultResult = 'prerelease'
   634      }
   635      for (var key in v1) {
   636        if (key === 'major' || key === 'minor' || key === 'patch') {
   637          if (v1[key] !== v2[key]) {
   638            return prefix + key
   639          }
   640        }
   641      }
   642      return defaultResult // may be undefined
   643    }
   644  }
   645  
   646  exports.compareIdentifiers = compareIdentifiers
   647  
   648  var numeric = /^[0-9]+$/
   649  function compareIdentifiers (a, b) {
   650    var anum = numeric.test(a)
   651    var bnum = numeric.test(b)
   652  
   653    if (anum && bnum) {
   654      a = +a
   655      b = +b
   656    }
   657  
   658    return a === b ? 0
   659      : (anum && !bnum) ? -1
   660      : (bnum && !anum) ? 1
   661      : a < b ? -1
   662      : 1
   663  }
   664  
   665  exports.rcompareIdentifiers = rcompareIdentifiers
   666  function rcompareIdentifiers (a, b) {
   667    return compareIdentifiers(b, a)
   668  }
   669  
   670  exports.major = major
   671  function major (a, loose) {
   672    return new SemVer(a, loose).major
   673  }
   674  
   675  exports.minor = minor
   676  function minor (a, loose) {
   677    return new SemVer(a, loose).minor
   678  }
   679  
   680  exports.patch = patch
   681  function patch (a, loose) {
   682    return new SemVer(a, loose).patch
   683  }
   684  
   685  exports.compare = compare
   686  function compare (a, b, loose) {
   687    return new SemVer(a, loose).compare(new SemVer(b, loose))
   688  }
   689  
   690  exports.compareLoose = compareLoose
   691  function compareLoose (a, b) {
   692    return compare(a, b, true)
   693  }
   694  
   695  exports.compareBuild = compareBuild
   696  function compareBuild (a, b, loose) {
   697    var versionA = new SemVer(a, loose)
   698    var versionB = new SemVer(b, loose)
   699    return versionA.compare(versionB) || versionA.compareBuild(versionB)
   700  }
   701  
   702  exports.rcompare = rcompare
   703  function rcompare (a, b, loose) {
   704    return compare(b, a, loose)
   705  }
   706  
   707  exports.sort = sort
   708  function sort (list, loose) {
   709    return list.sort(function (a, b) {
   710      return exports.compareBuild(a, b, loose)
   711    })
   712  }
   713  
   714  exports.rsort = rsort
   715  function rsort (list, loose) {
   716    return list.sort(function (a, b) {
   717      return exports.compareBuild(b, a, loose)
   718    })
   719  }
   720  
   721  exports.gt = gt
   722  function gt (a, b, loose) {
   723    return compare(a, b, loose) > 0
   724  }
   725  
   726  exports.lt = lt
   727  function lt (a, b, loose) {
   728    return compare(a, b, loose) < 0
   729  }
   730  
   731  exports.eq = eq
   732  function eq (a, b, loose) {
   733    return compare(a, b, loose) === 0
   734  }
   735  
   736  exports.neq = neq
   737  function neq (a, b, loose) {
   738    return compare(a, b, loose) !== 0
   739  }
   740  
   741  exports.gte = gte
   742  function gte (a, b, loose) {
   743    return compare(a, b, loose) >= 0
   744  }
   745  
   746  exports.lte = lte
   747  function lte (a, b, loose) {
   748    return compare(a, b, loose) <= 0
   749  }
   750  
   751  exports.cmp = cmp
   752  function cmp (a, op, b, loose) {
   753    switch (op) {
   754      case '===':
   755        if (typeof a === 'object')
   756          a = a.version
   757        if (typeof b === 'object')
   758          b = b.version
   759        return a === b
   760  
   761      case '!==':
   762        if (typeof a === 'object')
   763          a = a.version
   764        if (typeof b === 'object')
   765          b = b.version
   766        return a !== b
   767  
   768      case '':
   769      case '=':
   770      case '==':
   771        return eq(a, b, loose)
   772  
   773      case '!=':
   774        return neq(a, b, loose)
   775  
   776      case '>':
   777        return gt(a, b, loose)
   778  
   779      case '>=':
   780        return gte(a, b, loose)
   781  
   782      case '<':
   783        return lt(a, b, loose)
   784  
   785      case '<=':
   786        return lte(a, b, loose)
   787  
   788      default:
   789        throw new TypeError('Invalid operator: ' + op)
   790    }
   791  }
   792  
   793  exports.Comparator = Comparator
   794  function Comparator (comp, options) {
   795    if (!options || typeof options !== 'object') {
   796      options = {
   797        loose: !!options,
   798        includePrerelease: false
   799      }
   800    }
   801  
   802    if (comp instanceof Comparator) {
   803      if (comp.loose === !!options.loose) {
   804        return comp
   805      } else {
   806        comp = comp.value
   807      }
   808    }
   809  
   810    if (!(this instanceof Comparator)) {
   811      return new Comparator(comp, options)
   812    }
   813  
   814    comp = comp.trim().split(/\s+/).join(' ')
   815    debug('comparator', comp, options)
   816    this.options = options
   817    this.loose = !!options.loose
   818    this.parse(comp)
   819  
   820    if (this.semver === ANY) {
   821      this.value = ''
   822    } else {
   823      this.value = this.operator + this.semver.version
   824    }
   825  
   826    debug('comp', this)
   827  }
   828  
   829  var ANY = {}
   830  Comparator.prototype.parse = function (comp) {
   831    var r = this.options.loose ? safeRe[t.COMPARATORLOOSE] : safeRe[t.COMPARATOR]
   832    var m = comp.match(r)
   833  
   834    if (!m) {
   835      throw new TypeError('Invalid comparator: ' + comp)
   836    }
   837  
   838    this.operator = m[1] !== undefined ? m[1] : ''
   839    if (this.operator === '=') {
   840      this.operator = ''
   841    }
   842  
   843    // if it literally is just '>' or '' then allow anything.
   844    if (!m[2]) {
   845      this.semver = ANY
   846    } else {
   847      this.semver = new SemVer(m[2], this.options.loose)
   848    }
   849  }
   850  
   851  Comparator.prototype.toString = function () {
   852    return this.value
   853  }
   854  
   855  Comparator.prototype.test = function (version) {
   856    debug('Comparator.test', version, this.options.loose)
   857  
   858    if (this.semver === ANY || version === ANY) {
   859      return true
   860    }
   861  
   862    if (typeof version === 'string') {
   863      try {
   864        version = new SemVer(version, this.options)
   865      } catch (er) {
   866        return false
   867      }
   868    }
   869  
   870    return cmp(version, this.operator, this.semver, this.options)
   871  }
   872  
   873  Comparator.prototype.intersects = function (comp, options) {
   874    if (!(comp instanceof Comparator)) {
   875      throw new TypeError('a Comparator is required')
   876    }
   877  
   878    if (!options || typeof options !== 'object') {
   879      options = {
   880        loose: !!options,
   881        includePrerelease: false
   882      }
   883    }
   884  
   885    var rangeTmp
   886  
   887    if (this.operator === '') {
   888      if (this.value === '') {
   889        return true
   890      }
   891      rangeTmp = new Range(comp.value, options)
   892      return satisfies(this.value, rangeTmp, options)
   893    } else if (comp.operator === '') {
   894      if (comp.value === '') {
   895        return true
   896      }
   897      rangeTmp = new Range(this.value, options)
   898      return satisfies(comp.semver, rangeTmp, options)
   899    }
   900  
   901    var sameDirectionIncreasing =
   902      (this.operator === '>=' || this.operator === '>') &&
   903      (comp.operator === '>=' || comp.operator === '>')
   904    var sameDirectionDecreasing =
   905      (this.operator === '<=' || this.operator === '<') &&
   906      (comp.operator === '<=' || comp.operator === '<')
   907    var sameSemVer = this.semver.version === comp.semver.version
   908    var differentDirectionsInclusive =
   909      (this.operator === '>=' || this.operator === '<=') &&
   910      (comp.operator === '>=' || comp.operator === '<=')
   911    var oppositeDirectionsLessThan =
   912      cmp(this.semver, '<', comp.semver, options) &&
   913      ((this.operator === '>=' || this.operator === '>') &&
   914      (comp.operator === '<=' || comp.operator === '<'))
   915    var oppositeDirectionsGreaterThan =
   916      cmp(this.semver, '>', comp.semver, options) &&
   917      ((this.operator === '<=' || this.operator === '<') &&
   918      (comp.operator === '>=' || comp.operator === '>'))
   919  
   920    return sameDirectionIncreasing || sameDirectionDecreasing ||
   921      (sameSemVer && differentDirectionsInclusive) ||
   922      oppositeDirectionsLessThan || oppositeDirectionsGreaterThan
   923  }
   924  
   925  exports.Range = Range
   926  function Range (range, options) {
   927    if (!options || typeof options !== 'object') {
   928      options = {
   929        loose: !!options,
   930        includePrerelease: false
   931      }
   932    }
   933  
   934    if (range instanceof Range) {
   935      if (range.loose === !!options.loose &&
   936          range.includePrerelease === !!options.includePrerelease) {
   937        return range
   938      } else {
   939        return new Range(range.raw, options)
   940      }
   941    }
   942  
   943    if (range instanceof Comparator) {
   944      return new Range(range.value, options)
   945    }
   946  
   947    if (!(this instanceof Range)) {
   948      return new Range(range, options)
   949    }
   950  
   951    this.options = options
   952    this.loose = !!options.loose
   953    this.includePrerelease = !!options.includePrerelease
   954  
   955    // First reduce all whitespace as much as possible so we do not have to rely
   956    // on potentially slow regexes like \s*. This is then stored and used for
   957    // future error messages as well.
   958    this.raw = range
   959      .trim()
   960      .split(/\s+/)
   961      .join(' ')
   962  
   963    // First, split based on boolean or ||
   964    this.set = this.raw.split('||').map(function (range) {
   965      return this.parseRange(range.trim())
   966    }, this).filter(function (c) {
   967      // throw out any that are not relevant for whatever reason
   968      return c.length
   969    })
   970  
   971    if (!this.set.length) {
   972      throw new TypeError('Invalid SemVer Range: ' + this.raw)
   973    }
   974  
   975    this.format()
   976  }
   977  
   978  Range.prototype.format = function () {
   979    this.range = this.set.map(function (comps) {
   980      return comps.join(' ').trim()
   981    }).join('||').trim()
   982    return this.range
   983  }
   984  
   985  Range.prototype.toString = function () {
   986    return this.range
   987  }
   988  
   989  Range.prototype.parseRange = function (range) {
   990    var loose = this.options.loose
   991    // `1.2.3 - 1.2.4` => `>=1.2.3 <=1.2.4`
   992    var hr = loose ? safeRe[t.HYPHENRANGELOOSE] : safeRe[t.HYPHENRANGE]
   993    range = range.replace(hr, hyphenReplace)
   994    debug('hyphen replace', range)
   995    // `> 1.2.3 < 1.2.5` => `>1.2.3 <1.2.5`
   996    range = range.replace(safeRe[t.COMPARATORTRIM], comparatorTrimReplace)
   997    debug('comparator trim', range, safeRe[t.COMPARATORTRIM])
   998  
   999    // `~ 1.2.3` => `~1.2.3`
  1000    range = range.replace(safeRe[t.TILDETRIM], tildeTrimReplace)
  1001  
  1002    // `^ 1.2.3` => `^1.2.3`
  1003    range = range.replace(safeRe[t.CARETTRIM], caretTrimReplace)
  1004  
  1005    // normalize spaces
  1006    range = range.split(/\s+/).join(' ')
  1007  
  1008    // At this point, the range is completely trimmed and
  1009    // ready to be split into comparators.
  1010  
  1011    var compRe = loose ? safeRe[t.COMPARATORLOOSE] : safeRe[t.COMPARATOR]
  1012    var set = range.split(' ').map(function (comp) {
  1013      return parseComparator(comp, this.options)
  1014    }, this).join(' ').split(/\s+/)
  1015    if (this.options.loose) {
  1016      // in loose mode, throw out any that are not valid comparators
  1017      set = set.filter(function (comp) {
  1018        return !!comp.match(compRe)
  1019      })
  1020    }
  1021    set = set.map(function (comp) {
  1022      return new Comparator(comp, this.options)
  1023    }, this)
  1024  
  1025    return set
  1026  }
  1027  
  1028  Range.prototype.intersects = function (range, options) {
  1029    if (!(range instanceof Range)) {
  1030      throw new TypeError('a Range is required')
  1031    }
  1032  
  1033    return this.set.some(function (thisComparators) {
  1034      return (
  1035        isSatisfiable(thisComparators, options) &&
  1036        range.set.some(function (rangeComparators) {
  1037          return (
  1038            isSatisfiable(rangeComparators, options) &&
  1039            thisComparators.every(function (thisComparator) {
  1040              return rangeComparators.every(function (rangeComparator) {
  1041                return thisComparator.intersects(rangeComparator, options)
  1042              })
  1043            })
  1044          )
  1045        })
  1046      )
  1047    })
  1048  }
  1049  
  1050  // take a set of comparators and determine whether there
  1051  // exists a version which can satisfy it
  1052  function isSatisfiable (comparators, options) {
  1053    var result = true
  1054    var remainingComparators = comparators.slice()
  1055    var testComparator = remainingComparators.pop()
  1056  
  1057    while (result && remainingComparators.length) {
  1058      result = remainingComparators.every(function (otherComparator) {
  1059        return testComparator.intersects(otherComparator, options)
  1060      })
  1061  
  1062      testComparator = remainingComparators.pop()
  1063    }
  1064  
  1065    return result
  1066  }
  1067  
  1068  // Mostly just for testing and legacy API reasons
  1069  exports.toComparators = toComparators
  1070  function toComparators (range, options) {
  1071    return new Range(range, options).set.map(function (comp) {
  1072      return comp.map(function (c) {
  1073        return c.value
  1074      }).join(' ').trim().split(' ')
  1075    })
  1076  }
  1077  
  1078  // comprised of xranges, tildes, stars, and gtlt's at this point.
  1079  // already replaced the hyphen ranges
  1080  // turn into a set of JUST comparators.
  1081  function parseComparator (comp, options) {
  1082    debug('comp', comp, options)
  1083    comp = replaceCarets(comp, options)
  1084    debug('caret', comp)
  1085    comp = replaceTildes(comp, options)
  1086    debug('tildes', comp)
  1087    comp = replaceXRanges(comp, options)
  1088    debug('xrange', comp)
  1089    comp = replaceStars(comp, options)
  1090    debug('stars', comp)
  1091    return comp
  1092  }
  1093  
  1094  function isX (id) {
  1095    return !id || id.toLowerCase() === 'x' || id === '*'
  1096  }
  1097  
  1098  // ~, ~> --> * (any, kinda silly)
  1099  // ~2, ~2.x, ~2.x.x, ~>2, ~>2.x ~>2.x.x --> >=2.0.0 <3.0.0
  1100  // ~2.0, ~2.0.x, ~>2.0, ~>2.0.x --> >=2.0.0 <2.1.0
  1101  // ~1.2, ~1.2.x, ~>1.2, ~>1.2.x --> >=1.2.0 <1.3.0
  1102  // ~1.2.3, ~>1.2.3 --> >=1.2.3 <1.3.0
  1103  // ~1.2.0, ~>1.2.0 --> >=1.2.0 <1.3.0
  1104  function replaceTildes (comp, options) {
  1105    return comp.trim().split(/\s+/).map(function (comp) {
  1106      return replaceTilde(comp, options)
  1107    }).join(' ')
  1108  }
  1109  
  1110  function replaceTilde (comp, options) {
  1111    var r = options.loose ? safeRe[t.TILDELOOSE] : safeRe[t.TILDE]
  1112    return comp.replace(r, function (_, M, m, p, pr) {
  1113      debug('tilde', comp, _, M, m, p, pr)
  1114      var ret
  1115  
  1116      if (isX(M)) {
  1117        ret = ''
  1118      } else if (isX(m)) {
  1119        ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0'
  1120      } else if (isX(p)) {
  1121        // ~1.2 == >=1.2.0 <1.3.0
  1122        ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0'
  1123      } else if (pr) {
  1124        debug('replaceTilde pr', pr)
  1125        ret = '>=' + M + '.' + m + '.' + p + '-' + pr +
  1126              ' <' + M + '.' + (+m + 1) + '.0'
  1127      } else {
  1128        // ~1.2.3 == >=1.2.3 <1.3.0
  1129        ret = '>=' + M + '.' + m + '.' + p +
  1130              ' <' + M + '.' + (+m + 1) + '.0'
  1131      }
  1132  
  1133      debug('tilde return', ret)
  1134      return ret
  1135    })
  1136  }
  1137  
  1138  // ^ --> * (any, kinda silly)
  1139  // ^2, ^2.x, ^2.x.x --> >=2.0.0 <3.0.0
  1140  // ^2.0, ^2.0.x --> >=2.0.0 <3.0.0
  1141  // ^1.2, ^1.2.x --> >=1.2.0 <2.0.0
  1142  // ^1.2.3 --> >=1.2.3 <2.0.0
  1143  // ^1.2.0 --> >=1.2.0 <2.0.0
  1144  function replaceCarets (comp, options) {
  1145    return comp.trim().split(/\s+/).map(function (comp) {
  1146      return replaceCaret(comp, options)
  1147    }).join(' ')
  1148  }
  1149  
  1150  function replaceCaret (comp, options) {
  1151    debug('caret', comp, options)
  1152    var r = options.loose ? safeRe[t.CARETLOOSE] : safeRe[t.CARET]
  1153    return comp.replace(r, function (_, M, m, p, pr) {
  1154      debug('caret', comp, _, M, m, p, pr)
  1155      var ret
  1156  
  1157      if (isX(M)) {
  1158        ret = ''
  1159      } else if (isX(m)) {
  1160        ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0'
  1161      } else if (isX(p)) {
  1162        if (M === '0') {
  1163          ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0'
  1164        } else {
  1165          ret = '>=' + M + '.' + m + '.0 <' + (+M + 1) + '.0.0'
  1166        }
  1167      } else if (pr) {
  1168        debug('replaceCaret pr', pr)
  1169        if (M === '0') {
  1170          if (m === '0') {
  1171            ret = '>=' + M + '.' + m + '.' + p + '-' + pr +
  1172                  ' <' + M + '.' + m + '.' + (+p + 1)
  1173          } else {
  1174            ret = '>=' + M + '.' + m + '.' + p + '-' + pr +
  1175                  ' <' + M + '.' + (+m + 1) + '.0'
  1176          }
  1177        } else {
  1178          ret = '>=' + M + '.' + m + '.' + p + '-' + pr +
  1179                ' <' + (+M + 1) + '.0.0'
  1180        }
  1181      } else {
  1182        debug('no pr')
  1183        if (M === '0') {
  1184          if (m === '0') {
  1185            ret = '>=' + M + '.' + m + '.' + p +
  1186                  ' <' + M + '.' + m + '.' + (+p + 1)
  1187          } else {
  1188            ret = '>=' + M + '.' + m + '.' + p +
  1189                  ' <' + M + '.' + (+m + 1) + '.0'
  1190          }
  1191        } else {
  1192          ret = '>=' + M + '.' + m + '.' + p +
  1193                ' <' + (+M + 1) + '.0.0'
  1194        }
  1195      }
  1196  
  1197      debug('caret return', ret)
  1198      return ret
  1199    })
  1200  }
  1201  
  1202  function replaceXRanges (comp, options) {
  1203    debug('replaceXRanges', comp, options)
  1204    return comp.split(/\s+/).map(function (comp) {
  1205      return replaceXRange(comp, options)
  1206    }).join(' ')
  1207  }
  1208  
  1209  function replaceXRange (comp, options) {
  1210    comp = comp.trim()
  1211    var r = options.loose ? safeRe[t.XRANGELOOSE] : safeRe[t.XRANGE]
  1212    return comp.replace(r, function (ret, gtlt, M, m, p, pr) {
  1213      debug('xRange', comp, ret, gtlt, M, m, p, pr)
  1214      var xM = isX(M)
  1215      var xm = xM || isX(m)
  1216      var xp = xm || isX(p)
  1217      var anyX = xp
  1218  
  1219      if (gtlt === '=' && anyX) {
  1220        gtlt = ''
  1221      }
  1222  
  1223      // if we're including prereleases in the match, then we need
  1224      // to fix this to -0, the lowest possible prerelease value
  1225      pr = options.includePrerelease ? '-0' : ''
  1226  
  1227      if (xM) {
  1228        if (gtlt === '>' || gtlt === '<') {
  1229          // nothing is allowed
  1230          ret = '<0.0.0-0'
  1231        } else {
  1232          // nothing is forbidden
  1233          ret = '*'
  1234        }
  1235      } else if (gtlt && anyX) {
  1236        // we know patch is an x, because we have any x at all.
  1237        // replace X with 0
  1238        if (xm) {
  1239          m = 0
  1240        }
  1241        p = 0
  1242  
  1243        if (gtlt === '>') {
  1244          // >1 => >=2.0.0
  1245          // >1.2 => >=1.3.0
  1246          // >1.2.3 => >= 1.2.4
  1247          gtlt = '>='
  1248          if (xm) {
  1249            M = +M + 1
  1250            m = 0
  1251            p = 0
  1252          } else {
  1253            m = +m + 1
  1254            p = 0
  1255          }
  1256        } else if (gtlt === '<=') {
  1257          // <=0.7.x is actually <0.8.0, since any 0.7.x should
  1258          // pass.  Similarly, <=7.x is actually <8.0.0, etc.
  1259          gtlt = '<'
  1260          if (xm) {
  1261            M = +M + 1
  1262          } else {
  1263            m = +m + 1
  1264          }
  1265        }
  1266  
  1267        ret = gtlt + M + '.' + m + '.' + p + pr
  1268      } else if (xm) {
  1269        ret = '>=' + M + '.0.0' + pr + ' <' + (+M + 1) + '.0.0' + pr
  1270      } else if (xp) {
  1271        ret = '>=' + M + '.' + m + '.0' + pr +
  1272          ' <' + M + '.' + (+m + 1) + '.0' + pr
  1273      }
  1274  
  1275      debug('xRange return', ret)
  1276  
  1277      return ret
  1278    })
  1279  }
  1280  
  1281  // Because * is AND-ed with everything else in the comparator,
  1282  // and '' means "any version", just remove the *s entirely.
  1283  function replaceStars (comp, options) {
  1284    debug('replaceStars', comp, options)
  1285    // Looseness is ignored here.  star is always as loose as it gets!
  1286    return comp.trim().replace(safeRe[t.STAR], '')
  1287  }
  1288  
  1289  // This function is passed to string.replace(re[t.HYPHENRANGE])
  1290  // M, m, patch, prerelease, build
  1291  // 1.2 - 3.4.5 => >=1.2.0 <=3.4.5
  1292  // 1.2.3 - 3.4 => >=1.2.0 <3.5.0 Any 3.4.x will do
  1293  // 1.2 - 3.4 => >=1.2.0 <3.5.0
  1294  function hyphenReplace ($0,
  1295    from, fM, fm, fp, fpr, fb,
  1296    to, tM, tm, tp, tpr, tb) {
  1297    if (isX(fM)) {
  1298      from = ''
  1299    } else if (isX(fm)) {
  1300      from = '>=' + fM + '.0.0'
  1301    } else if (isX(fp)) {
  1302      from = '>=' + fM + '.' + fm + '.0'
  1303    } else {
  1304      from = '>=' + from
  1305    }
  1306  
  1307    if (isX(tM)) {
  1308      to = ''
  1309    } else if (isX(tm)) {
  1310      to = '<' + (+tM + 1) + '.0.0'
  1311    } else if (isX(tp)) {
  1312      to = '<' + tM + '.' + (+tm + 1) + '.0'
  1313    } else if (tpr) {
  1314      to = '<=' + tM + '.' + tm + '.' + tp + '-' + tpr
  1315    } else {
  1316      to = '<=' + to
  1317    }
  1318  
  1319    return (from + ' ' + to).trim()
  1320  }
  1321  
  1322  // if ANY of the sets match ALL of its comparators, then pass
  1323  Range.prototype.test = function (version) {
  1324    if (!version) {
  1325      return false
  1326    }
  1327  
  1328    if (typeof version === 'string') {
  1329      try {
  1330        version = new SemVer(version, this.options)
  1331      } catch (er) {
  1332        return false
  1333      }
  1334    }
  1335  
  1336    for (var i = 0; i < this.set.length; i++) {
  1337      if (testSet(this.set[i], version, this.options)) {
  1338        return true
  1339      }
  1340    }
  1341    return false
  1342  }
  1343  
  1344  function testSet (set, version, options) {
  1345    for (var i = 0; i < set.length; i++) {
  1346      if (!set[i].test(version)) {
  1347        return false
  1348      }
  1349    }
  1350  
  1351    if (version.prerelease.length && !options.includePrerelease) {
  1352      // Find the set of versions that are allowed to have prereleases
  1353      // For example, ^1.2.3-pr.1 desugars to >=1.2.3-pr.1 <2.0.0
  1354      // That should allow `1.2.3-pr.2` to pass.
  1355      // However, `1.2.4-alpha.notready` should NOT be allowed,
  1356      // even though it's within the range set by the comparators.
  1357      for (i = 0; i < set.length; i++) {
  1358        debug(set[i].semver)
  1359        if (set[i].semver === ANY) {
  1360          continue
  1361        }
  1362  
  1363        if (set[i].semver.prerelease.length > 0) {
  1364          var allowed = set[i].semver
  1365          if (allowed.major === version.major &&
  1366              allowed.minor === version.minor &&
  1367              allowed.patch === version.patch) {
  1368            return true
  1369          }
  1370        }
  1371      }
  1372  
  1373      // Version has a -pre, but it's not one of the ones we like.
  1374      return false
  1375    }
  1376  
  1377    return true
  1378  }
  1379  
  1380  exports.satisfies = satisfies
  1381  function satisfies (version, range, options) {
  1382    try {
  1383      range = new Range(range, options)
  1384    } catch (er) {
  1385      return false
  1386    }
  1387    return range.test(version)
  1388  }
  1389  
  1390  exports.maxSatisfying = maxSatisfying
  1391  function maxSatisfying (versions, range, options) {
  1392    var max = null
  1393    var maxSV = null
  1394    try {
  1395      var rangeObj = new Range(range, options)
  1396    } catch (er) {
  1397      return null
  1398    }
  1399    versions.forEach(function (v) {
  1400      if (rangeObj.test(v)) {
  1401        // satisfies(v, range, options)
  1402        if (!max || maxSV.compare(v) === -1) {
  1403          // compare(max, v, true)
  1404          max = v
  1405          maxSV = new SemVer(max, options)
  1406        }
  1407      }
  1408    })
  1409    return max
  1410  }
  1411  
  1412  exports.minSatisfying = minSatisfying
  1413  function minSatisfying (versions, range, options) {
  1414    var min = null
  1415    var minSV = null
  1416    try {
  1417      var rangeObj = new Range(range, options)
  1418    } catch (er) {
  1419      return null
  1420    }
  1421    versions.forEach(function (v) {
  1422      if (rangeObj.test(v)) {
  1423        // satisfies(v, range, options)
  1424        if (!min || minSV.compare(v) === 1) {
  1425          // compare(min, v, true)
  1426          min = v
  1427          minSV = new SemVer(min, options)
  1428        }
  1429      }
  1430    })
  1431    return min
  1432  }
  1433  
  1434  exports.minVersion = minVersion
  1435  function minVersion (range, loose) {
  1436    range = new Range(range, loose)
  1437  
  1438    var minver = new SemVer('0.0.0')
  1439    if (range.test(minver)) {
  1440      return minver
  1441    }
  1442  
  1443    minver = new SemVer('0.0.0-0')
  1444    if (range.test(minver)) {
  1445      return minver
  1446    }
  1447  
  1448    minver = null
  1449    for (var i = 0; i < range.set.length; ++i) {
  1450      var comparators = range.set[i]
  1451  
  1452      comparators.forEach(function (comparator) {
  1453        // Clone to avoid manipulating the comparator's semver object.
  1454        var compver = new SemVer(comparator.semver.version)
  1455        switch (comparator.operator) {
  1456          case '>':
  1457            if (compver.prerelease.length === 0) {
  1458              compver.patch++
  1459            } else {
  1460              compver.prerelease.push(0)
  1461            }
  1462            compver.raw = compver.format()
  1463            /* fallthrough */
  1464          case '':
  1465          case '>=':
  1466            if (!minver || gt(minver, compver)) {
  1467              minver = compver
  1468            }
  1469            break
  1470          case '<':
  1471          case '<=':
  1472            /* Ignore maximum versions */
  1473            break
  1474          /* istanbul ignore next */
  1475          default:
  1476            throw new Error('Unexpected operation: ' + comparator.operator)
  1477        }
  1478      })
  1479    }
  1480  
  1481    if (minver && range.test(minver)) {
  1482      return minver
  1483    }
  1484  
  1485    return null
  1486  }
  1487  
  1488  exports.validRange = validRange
  1489  function validRange (range, options) {
  1490    try {
  1491      // Return '*' instead of '' so that truthiness works.
  1492      // This will throw if it's invalid anyway
  1493      return new Range(range, options).range || '*'
  1494    } catch (er) {
  1495      return null
  1496    }
  1497  }
  1498  
  1499  // Determine if version is less than all the versions possible in the range
  1500  exports.ltr = ltr
  1501  function ltr (version, range, options) {
  1502    return outside(version, range, '<', options)
  1503  }
  1504  
  1505  // Determine if version is greater than all the versions possible in the range.
  1506  exports.gtr = gtr
  1507  function gtr (version, range, options) {
  1508    return outside(version, range, '>', options)
  1509  }
  1510  
  1511  exports.outside = outside
  1512  function outside (version, range, hilo, options) {
  1513    version = new SemVer(version, options)
  1514    range = new Range(range, options)
  1515  
  1516    var gtfn, ltefn, ltfn, comp, ecomp
  1517    switch (hilo) {
  1518      case '>':
  1519        gtfn = gt
  1520        ltefn = lte
  1521        ltfn = lt
  1522        comp = '>'
  1523        ecomp = '>='
  1524        break
  1525      case '<':
  1526        gtfn = lt
  1527        ltefn = gte
  1528        ltfn = gt
  1529        comp = '<'
  1530        ecomp = '<='
  1531        break
  1532      default:
  1533        throw new TypeError('Must provide a hilo val of "<" or ">"')
  1534    }
  1535  
  1536    // If it satisifes the range it is not outside
  1537    if (satisfies(version, range, options)) {
  1538      return false
  1539    }
  1540  
  1541    // From now on, variable terms are as if we're in "gtr" mode.
  1542    // but note that everything is flipped for the "ltr" function.
  1543  
  1544    for (var i = 0; i < range.set.length; ++i) {
  1545      var comparators = range.set[i]
  1546  
  1547      var high = null
  1548      var low = null
  1549  
  1550      comparators.forEach(function (comparator) {
  1551        if (comparator.semver === ANY) {
  1552          comparator = new Comparator('>=0.0.0')
  1553        }
  1554        high = high || comparator
  1555        low = low || comparator
  1556        if (gtfn(comparator.semver, high.semver, options)) {
  1557          high = comparator
  1558        } else if (ltfn(comparator.semver, low.semver, options)) {
  1559          low = comparator
  1560        }
  1561      })
  1562  
  1563      // If the edge version comparator has a operator then our version
  1564      // isn't outside it
  1565      if (high.operator === comp || high.operator === ecomp) {
  1566        return false
  1567      }
  1568  
  1569      // If the lowest version comparator has an operator and our version
  1570      // is less than it then it isn't higher than the range
  1571      if ((!low.operator || low.operator === comp) &&
  1572          ltefn(version, low.semver)) {
  1573        return false
  1574      } else if (low.operator === ecomp && ltfn(version, low.semver)) {
  1575        return false
  1576      }
  1577    }
  1578    return true
  1579  }
  1580  
  1581  exports.prerelease = prerelease
  1582  function prerelease (version, options) {
  1583    var parsed = parse(version, options)
  1584    return (parsed && parsed.prerelease.length) ? parsed.prerelease : null
  1585  }
  1586  
  1587  exports.intersects = intersects
  1588  function intersects (r1, r2, options) {
  1589    r1 = new Range(r1, options)
  1590    r2 = new Range(r2, options)
  1591    return r1.intersects(r2)
  1592  }
  1593  
  1594  exports.coerce = coerce
  1595  function coerce (version, options) {
  1596    if (version instanceof SemVer) {
  1597      return version
  1598    }
  1599  
  1600    if (typeof version === 'number') {
  1601      version = String(version)
  1602    }
  1603  
  1604    if (typeof version !== 'string') {
  1605      return null
  1606    }
  1607  
  1608    options = options || {}
  1609  
  1610    var match = null
  1611    if (!options.rtl) {
  1612      match = version.match(safeRe[t.COERCE])
  1613    } else {
  1614      // Find the right-most coercible string that does not share
  1615      // a terminus with a more left-ward coercible string.
  1616      // Eg, '1.2.3.4' wants to coerce '2.3.4', not '3.4' or '4'
  1617      //
  1618      // Walk through the string checking with a /g regexp
  1619      // Manually set the index so as to pick up overlapping matches.
  1620      // Stop when we get a match that ends at the string end, since no
  1621      // coercible string can be more right-ward without the same terminus.
  1622      var next
  1623      while ((next = safeRe[t.COERCERTL].exec(version)) &&
  1624        (!match || match.index + match[0].length !== version.length)
  1625      ) {
  1626        if (!match ||
  1627            next.index + next[0].length !== match.index + match[0].length) {
  1628          match = next
  1629        }
  1630        safeRe[t.COERCERTL].lastIndex = next.index + next[1].length + next[2].length
  1631      }
  1632      // leave it in a clean state
  1633      safeRe[t.COERCERTL].lastIndex = -1
  1634    }
  1635  
  1636    if (match === null) {
  1637      return null
  1638    }
  1639  
  1640    return parse(match[2] +
  1641      '.' + (match[3] || '0') +
  1642      '.' + (match[4] || '0'), options)
  1643  }