1 // export the class if we are in a Node-like system.
2 if (typeof module === 'object' && module.exports === exports)
3 exports = module.exports = SemVer;
5 // The debug function is excluded entirely from the minified version.
7 /* nomin */ if (typeof process === 'object' &&
8 /* nomin */ process.env &&
9 /* nomin */ process.env.NODE_DEBUG &&
10 /* nomin */ /\bsemver\b/i.test(process.env.NODE_DEBUG))
11 /* nomin */ debug = function() {
12 /* nomin */ var args = Array.prototype.slice.call(arguments, 0);
13 /* nomin */ args.unshift('SEMVER');
14 /* nomin */ console.log.apply(console, args);
17 /* nomin */ debug = function() {};
19 // Note: this is the semver.org version of the spec that it implements
20 // Not necessarily the package version of this code.
21 exports.SEMVER_SPEC_VERSION = '2.0.0';
23 // The actual regexps go on exports.re
24 var re = exports.re = [];
25 var src = exports.src = [];
28 // The following Regular Expressions can be used for tokenizing,
29 // validating, and parsing SemVer version strings.
31 // ## Numeric Identifier
32 // A single `0`, or a non-zero digit followed by zero or more digits.
34 var NUMERICIDENTIFIER = R++;
35 src[NUMERICIDENTIFIER] = '0|[1-9]\\d*';
36 var NUMERICIDENTIFIERLOOSE = R++;
37 src[NUMERICIDENTIFIERLOOSE] = '[0-9]+';
40 // ## Non-numeric Identifier
41 // Zero or more digits, followed by a letter or hyphen, and then zero or
42 // more letters, digits, or hyphens.
44 var NONNUMERICIDENTIFIER = R++;
45 src[NONNUMERICIDENTIFIER] = '\\d*[a-zA-Z-][a-zA-Z0-9-]*';
49 // Three dot-separated numeric identifiers.
51 var MAINVERSION = R++;
52 src[MAINVERSION] = '(' + src[NUMERICIDENTIFIER] + ')\\.' +
53 '(' + src[NUMERICIDENTIFIER] + ')\\.' +
54 '(' + src[NUMERICIDENTIFIER] + ')';
56 var MAINVERSIONLOOSE = R++;
57 src[MAINVERSIONLOOSE] = '(' + src[NUMERICIDENTIFIERLOOSE] + ')\\.' +
58 '(' + src[NUMERICIDENTIFIERLOOSE] + ')\\.' +
59 '(' + src[NUMERICIDENTIFIERLOOSE] + ')';
61 // ## Pre-release Version Identifier
62 // A numeric identifier, or a non-numeric identifier.
64 var PRERELEASEIDENTIFIER = R++;
65 src[PRERELEASEIDENTIFIER] = '(?:' + src[NUMERICIDENTIFIER] +
66 '|' + src[NONNUMERICIDENTIFIER] + ')';
68 var PRERELEASEIDENTIFIERLOOSE = R++;
69 src[PRERELEASEIDENTIFIERLOOSE] = '(?:' + src[NUMERICIDENTIFIERLOOSE] +
70 '|' + src[NONNUMERICIDENTIFIER] + ')';
73 // ## Pre-release Version
74 // Hyphen, followed by one or more dot-separated pre-release version
78 src[PRERELEASE] = '(?:-(' + src[PRERELEASEIDENTIFIER] +
79 '(?:\\.' + src[PRERELEASEIDENTIFIER] + ')*))';
81 var PRERELEASELOOSE = R++;
82 src[PRERELEASELOOSE] = '(?:-?(' + src[PRERELEASEIDENTIFIERLOOSE] +
83 '(?:\\.' + src[PRERELEASEIDENTIFIERLOOSE] + ')*))';
85 // ## Build Metadata Identifier
86 // Any combination of digits, letters, or hyphens.
88 var BUILDIDENTIFIER = R++;
89 src[BUILDIDENTIFIER] = '[0-9A-Za-z-]+';
92 // Plus sign, followed by one or more period-separated build metadata
96 src[BUILD] = '(?:\\+(' + src[BUILDIDENTIFIER] +
97 '(?:\\.' + src[BUILDIDENTIFIER] + ')*))';
100 // ## Full Version String
101 // A main version, followed optionally by a pre-release version and
104 // Note that the only major, minor, patch, and pre-release sections of
105 // the version string are capturing groups. The build metadata is not a
106 // capturing group, because it should not ever be used in version
110 var FULLPLAIN = 'v?' + src[MAINVERSION] +
111 src[PRERELEASE] + '?' +
114 src[FULL] = '^' + FULLPLAIN + '$';
116 // like full, but allows v1.2.3 and =1.2.3, which people do sometimes.
117 // also, 1.0.0alpha1 (prerelease without the hyphen) which is pretty
118 // common in the npm registry.
119 var LOOSEPLAIN = '[v=\\s]*' + src[MAINVERSIONLOOSE] +
120 src[PRERELEASELOOSE] + '?' +
124 src[LOOSE] = '^' + LOOSEPLAIN + '$';
127 src[GTLT] = '((?:<|>)?=?)';
129 // Something like "2.*" or "1.2.x".
130 // Note that "x.x" is a valid xRange identifer, meaning "any version"
131 // Only the first item is strictly required.
132 var XRANGEIDENTIFIERLOOSE = R++;
133 src[XRANGEIDENTIFIERLOOSE] = src[NUMERICIDENTIFIERLOOSE] + '|x|X|\\*';
134 var XRANGEIDENTIFIER = R++;
135 src[XRANGEIDENTIFIER] = src[NUMERICIDENTIFIER] + '|x|X|\\*';
137 var XRANGEPLAIN = R++;
138 src[XRANGEPLAIN] = '[v=\\s]*(' + src[XRANGEIDENTIFIER] + ')' +
139 '(?:\\.(' + src[XRANGEIDENTIFIER] + ')' +
140 '(?:\\.(' + src[XRANGEIDENTIFIER] + ')' +
141 '(?:(' + src[PRERELEASE] + ')' +
144 var XRANGEPLAINLOOSE = R++;
145 src[XRANGEPLAINLOOSE] = '[v=\\s]*(' + src[XRANGEIDENTIFIERLOOSE] + ')' +
146 '(?:\\.(' + src[XRANGEIDENTIFIERLOOSE] + ')' +
147 '(?:\\.(' + src[XRANGEIDENTIFIERLOOSE] + ')' +
148 '(?:(' + src[PRERELEASELOOSE] + ')' +
151 // >=2.x, for example, means >=2.0.0-0
152 // <1.x would be the same as "<1.0.0-0", though.
154 src[XRANGE] = '^' + src[GTLT] + '\\s*' + src[XRANGEPLAIN] + '$';
155 var XRANGELOOSE = R++;
156 src[XRANGELOOSE] = '^' + src[GTLT] + '\\s*' + src[XRANGEPLAINLOOSE] + '$';
159 // Meaning is "reasonably at or greater than"
161 src[LONETILDE] = '(?:~>?)';
164 src[TILDETRIM] = '(\\s*)' + src[LONETILDE] + '\\s+';
165 re[TILDETRIM] = new RegExp(src[TILDETRIM], 'g');
166 var tildeTrimReplace = '$1~';
169 src[TILDE] = '^' + src[LONETILDE] + src[XRANGEPLAIN] + '$';
170 var TILDELOOSE = R++;
171 src[TILDELOOSE] = '^' + src[LONETILDE] + src[XRANGEPLAINLOOSE] + '$';
174 // Meaning is "at least and backwards compatible with"
176 src[LONECARET] = '(?:\\^)';
179 src[CARETTRIM] = '(\\s*)' + src[LONECARET] + '\\s+';
180 re[CARETTRIM] = new RegExp(src[CARETTRIM], 'g');
181 var caretTrimReplace = '$1^';
184 src[CARET] = '^' + src[LONECARET] + src[XRANGEPLAIN] + '$';
185 var CARETLOOSE = R++;
186 src[CARETLOOSE] = '^' + src[LONECARET] + src[XRANGEPLAINLOOSE] + '$';
188 // A simple gt/lt/eq thing, or just "" to indicate "any version"
189 var COMPARATORLOOSE = R++;
190 src[COMPARATORLOOSE] = '^' + src[GTLT] + '\\s*(' + LOOSEPLAIN + ')$|^$';
191 var COMPARATOR = R++;
192 src[COMPARATOR] = '^' + src[GTLT] + '\\s*(' + FULLPLAIN + ')$|^$';
195 // An expression to strip any whitespace between the gtlt and the thing
196 // it modifies, so that `> 1.2.3` ==> `>1.2.3`
197 var COMPARATORTRIM = R++;
198 src[COMPARATORTRIM] = '(\\s*)' + src[GTLT] +
199 '\\s*(' + LOOSEPLAIN + '|' + src[XRANGEPLAIN] + ')';
201 // this one has to use the /g flag
202 re[COMPARATORTRIM] = new RegExp(src[COMPARATORTRIM], 'g');
203 var comparatorTrimReplace = '$1$2$3';
206 // Something like `1.2.3 - 1.2.4`
207 // Note that these all use the loose form, because they'll be
208 // checked against either the strict or loose comparator form
210 var HYPHENRANGE = R++;
211 src[HYPHENRANGE] = '^\\s*(' + src[XRANGEPLAIN] + ')' +
213 '(' + src[XRANGEPLAIN] + ')' +
216 var HYPHENRANGELOOSE = R++;
217 src[HYPHENRANGELOOSE] = '^\\s*(' + src[XRANGEPLAINLOOSE] + ')' +
219 '(' + src[XRANGEPLAINLOOSE] + ')' +
222 // Star ranges basically just allow anything at all.
224 src[STAR] = '(<|>)?=?\\s*\\*';
226 // Compile to actual regexp objects.
227 // All are flag-free, unless they were created above with a flag.
228 for (var i = 0; i < R; i++) {
231 re[i] = new RegExp(src[i]);
234 exports.parse = parse;
235 function parse(version, loose) {
236 var r = loose ? re[LOOSE] : re[FULL];
237 return (r.test(version)) ? new SemVer(version, loose) : null;
240 exports.valid = valid;
241 function valid(version, loose) {
242 var v = parse(version, loose);
243 return v ? v.version : null;
247 exports.clean = clean;
248 function clean(version, loose) {
249 var s = parse(version, loose);
250 return s ? s.version : null;
253 exports.SemVer = SemVer;
255 function SemVer(version, loose) {
256 if (version instanceof SemVer) {
257 if (version.loose === loose)
260 version = version.version;
263 if (!(this instanceof SemVer))
264 return new SemVer(version, loose);
266 debug('SemVer', version, loose);
268 var m = version.trim().match(loose ? re[LOOSE] : re[FULL]);
271 throw new TypeError('Invalid Version: ' + version);
275 // these are actually numbers
280 // numberify any prerelease numeric ids
282 this.prerelease = [];
284 this.prerelease = m[4].split('.').map(function(id) {
285 return (/^[0-9]+$/.test(id)) ? +id : id;
288 this.build = m[5] ? m[5].split('.') : [];
292 SemVer.prototype.format = function() {
293 this.version = this.major + '.' + this.minor + '.' + this.patch;
294 if (this.prerelease.length)
295 this.version += '-' + this.prerelease.join('.');
299 SemVer.prototype.inspect = function() {
300 return '<SemVer "' + this + '">';
303 SemVer.prototype.toString = function() {
307 SemVer.prototype.compare = function(other) {
308 debug('SemVer.compare', this.version, this.loose, other);
309 if (!(other instanceof SemVer))
310 other = new SemVer(other, this.loose);
312 return this.compareMain(other) || this.comparePre(other);
315 SemVer.prototype.compareMain = function(other) {
316 if (!(other instanceof SemVer))
317 other = new SemVer(other, this.loose);
319 return compareIdentifiers(this.major, other.major) ||
320 compareIdentifiers(this.minor, other.minor) ||
321 compareIdentifiers(this.patch, other.patch);
324 SemVer.prototype.comparePre = function(other) {
325 if (!(other instanceof SemVer))
326 other = new SemVer(other, this.loose);
328 // NOT having a prerelease is > having one
329 if (this.prerelease.length && !other.prerelease.length)
331 else if (!this.prerelease.length && other.prerelease.length)
333 else if (!this.prerelease.lenth && !other.prerelease.length)
338 var a = this.prerelease[i];
339 var b = other.prerelease[i];
340 debug('prerelease compare', i, a, b);
341 if (a === undefined && b === undefined)
343 else if (b === undefined)
345 else if (a === undefined)
350 return compareIdentifiers(a, b);
354 SemVer.prototype.inc = function(release) {
364 this.prerelease = [];
367 if (this.prerelease.length === 0)
368 this.prerelease = [0];
370 var i = this.prerelease.length;
372 if (typeof this.prerelease[i] === 'number') {
373 this.prerelease[i]++;
377 if (i === -1) // didn't increment anything
378 this.prerelease.push(0);
383 throw new Error('invalid increment argument: ' + release);
390 function inc(version, release, loose) {
392 return new SemVer(version, loose).inc(release).version;
398 exports.compareIdentifiers = compareIdentifiers;
400 var numeric = /^[0-9]+$/;
401 function compareIdentifiers(a, b) {
402 var anum = numeric.test(a);
403 var bnum = numeric.test(b);
410 return (anum && !bnum) ? -1 :
411 (bnum && !anum) ? 1 :
417 exports.rcompareIdentifiers = rcompareIdentifiers;
418 function rcompareIdentifiers(a, b) {
419 return compareIdentifiers(b, a);
422 exports.compare = compare;
423 function compare(a, b, loose) {
424 return new SemVer(a, loose).compare(b);
427 exports.compareLoose = compareLoose;
428 function compareLoose(a, b) {
429 return compare(a, b, true);
432 exports.rcompare = rcompare;
433 function rcompare(a, b, loose) {
434 return compare(b, a, loose);
438 function sort(list, loose) {
439 return list.sort(function(a, b) {
440 return exports.compare(a, b, loose);
444 exports.rsort = rsort;
445 function rsort(list, loose) {
446 return list.sort(function(a, b) {
447 return exports.rcompare(a, b, loose);
452 function gt(a, b, loose) {
453 return compare(a, b, loose) > 0;
457 function lt(a, b, loose) {
458 return compare(a, b, loose) < 0;
462 function eq(a, b, loose) {
463 return compare(a, b, loose) === 0;
467 function neq(a, b, loose) {
468 return compare(a, b, loose) !== 0;
472 function gte(a, b, loose) {
473 return compare(a, b, loose) >= 0;
477 function lte(a, b, loose) {
478 return compare(a, b, loose) <= 0;
482 function cmp(a, op, b, loose) {
485 case '===': ret = a === b; break;
486 case '!==': ret = a !== b; break;
487 case '': case '=': case '==': ret = eq(a, b, loose); break;
488 case '!=': ret = neq(a, b, loose); break;
489 case '>': ret = gt(a, b, loose); break;
490 case '>=': ret = gte(a, b, loose); break;
491 case '<': ret = lt(a, b, loose); break;
492 case '<=': ret = lte(a, b, loose); break;
493 default: throw new TypeError('Invalid operator: ' + op);
498 exports.Comparator = Comparator;
499 function Comparator(comp, loose) {
500 if (comp instanceof Comparator) {
501 if (comp.loose === loose)
507 if (!(this instanceof Comparator))
508 return new Comparator(comp, loose);
510 debug('comparator', comp, loose);
514 if (this.semver === ANY)
517 this.value = this.operator + this.semver.version;
521 Comparator.prototype.parse = function(comp) {
522 var r = this.loose ? re[COMPARATORLOOSE] : re[COMPARATOR];
523 var m = comp.match(r);
526 throw new TypeError('Invalid comparator: ' + comp);
528 this.operator = m[1];
529 // if it literally is just '>' or '' then allow anything.
533 this.semver = new SemVer(m[2], this.loose);
535 // <1.2.3-rc DOES allow 1.2.3-beta (has prerelease)
536 // >=1.2.3 DOES NOT allow 1.2.3-beta
537 // <=1.2.3 DOES allow 1.2.3-beta
538 // However, <1.2.3 does NOT allow 1.2.3-beta,
539 // even though `1.2.3-beta < 1.2.3`
540 // The assumption is that the 1.2.3 version has something you
541 // *don't* want, so we push the prerelease down to the minimum.
542 if (this.operator === '<' && !this.semver.prerelease.length) {
543 this.semver.prerelease = ['0'];
544 this.semver.format();
549 Comparator.prototype.inspect = function() {
550 return '<SemVer Comparator "' + this + '">';
553 Comparator.prototype.toString = function() {
557 Comparator.prototype.test = function(version) {
558 debug('Comparator.test', version, this.loose);
559 return (this.semver === ANY) ? true :
560 cmp(version, this.operator, this.semver, this.loose);
564 exports.Range = Range;
565 function Range(range, loose) {
566 if ((range instanceof Range) && range.loose === loose)
569 if (!(this instanceof Range))
570 return new Range(range, loose);
574 // First, split based on boolean or ||
576 this.set = range.split(/\s*\|\|\s*/).map(function(range) {
577 return this.parseRange(range.trim());
578 }, this).filter(function(c) {
579 // throw out any that are not relevant for whatever reason
583 if (!this.set.length) {
584 throw new TypeError('Invalid SemVer Range: ' + range);
590 Range.prototype.inspect = function() {
591 return '<SemVer Range "' + this.range + '">';
594 Range.prototype.format = function() {
595 this.range = this.set.map(function(comps) {
596 return comps.join(' ').trim();
597 }).join('||').trim();
601 Range.prototype.toString = function() {
605 Range.prototype.parseRange = function(range) {
606 var loose = this.loose;
607 range = range.trim();
608 debug('range', range, loose);
609 // `1.2.3 - 1.2.4` => `>=1.2.3 <=1.2.4`
610 var hr = loose ? re[HYPHENRANGELOOSE] : re[HYPHENRANGE];
611 range = range.replace(hr, hyphenReplace);
612 debug('hyphen replace', range);
613 // `> 1.2.3 < 1.2.5` => `>1.2.3 <1.2.5`
614 range = range.replace(re[COMPARATORTRIM], comparatorTrimReplace);
615 debug('comparator trim', range, re[COMPARATORTRIM]);
617 // `~ 1.2.3` => `~1.2.3`
618 range = range.replace(re[TILDETRIM], tildeTrimReplace);
620 // `^ 1.2.3` => `^1.2.3`
621 range = range.replace(re[CARETTRIM], caretTrimReplace);
624 range = range.split(/\s+/).join(' ');
626 // At this point, the range is completely trimmed and
627 // ready to be split into comparators.
629 var compRe = loose ? re[COMPARATORLOOSE] : re[COMPARATOR];
630 var set = range.split(' ').map(function(comp) {
631 return parseComparator(comp, loose);
632 }).join(' ').split(/\s+/);
634 // in loose mode, throw out any that are not valid comparators
635 set = set.filter(function(comp) {
636 return !!comp.match(compRe);
639 set = set.map(function(comp) {
640 return new Comparator(comp, loose);
646 // Mostly just for testing and legacy API reasons
647 exports.toComparators = toComparators;
648 function toComparators(range, loose) {
649 return new Range(range, loose).set.map(function(comp) {
650 return comp.map(function(c) {
652 }).join(' ').trim().split(' ');
656 // comprised of xranges, tildes, stars, and gtlt's at this point.
657 // already replaced the hyphen ranges
658 // turn into a set of JUST comparators.
659 function parseComparator(comp, loose) {
661 comp = replaceCarets(comp, loose);
662 debug('caret', comp);
663 comp = replaceTildes(comp, loose);
664 debug('tildes', comp);
665 comp = replaceXRanges(comp, loose);
666 debug('xrange', comp);
667 comp = replaceStars(comp, loose);
668 debug('stars', comp);
673 return !id || id.toLowerCase() === 'x' || id === '*';
676 // ~, ~> --> * (any, kinda silly)
677 // ~2, ~2.x, ~2.x.x, ~>2, ~>2.x ~>2.x.x --> >=2.0.0 <3.0.0
678 // ~2.0, ~2.0.x, ~>2.0, ~>2.0.x --> >=2.0.0 <2.1.0
679 // ~1.2, ~1.2.x, ~>1.2, ~>1.2.x --> >=1.2.0 <1.3.0
680 // ~1.2.3, ~>1.2.3 --> >=1.2.3 <1.3.0
681 // ~1.2.0, ~>1.2.0 --> >=1.2.0 <1.3.0
682 function replaceTildes(comp, loose) {
683 return comp.trim().split(/\s+/).map(function(comp) {
684 return replaceTilde(comp, loose);
688 function replaceTilde(comp, loose) {
689 var r = loose ? re[TILDELOOSE] : re[TILDE];
690 return comp.replace(r, function(_, M, m, p, pr) {
691 debug('tilde', comp, _, M, m, p, pr);
697 ret = '>=' + M + '.0.0-0 <' + (+M + 1) + '.0.0-0';
699 // ~1.2 == >=1.2.0- <1.3.0-
700 ret = '>=' + M + '.' + m + '.0-0 <' + M + '.' + (+m + 1) + '.0-0';
702 debug('replaceTilde pr', pr);
703 if (pr.charAt(0) !== '-')
705 ret = '>=' + M + '.' + m + '.' + p + pr +
706 ' <' + M + '.' + (+m + 1) + '.0-0';
708 // ~1.2.3 == >=1.2.3-0 <1.3.0-0
709 ret = '>=' + M + '.' + m + '.' + p + '-0' +
710 ' <' + M + '.' + (+m + 1) + '.0-0';
712 debug('tilde return', ret);
717 // ^ --> * (any, kinda silly)
718 // ^2, ^2.x, ^2.x.x --> >=2.0.0 <3.0.0
719 // ^2.0, ^2.0.x --> >=2.0.0 <3.0.0
720 // ^1.2, ^1.2.x --> >=1.2.0 <2.0.0
721 // ^1.2.3 --> >=1.2.3 <2.0.0
722 // ^1.2.0 --> >=1.2.0 <2.0.0
723 function replaceCarets(comp, loose) {
724 return comp.trim().split(/\s+/).map(function(comp) {
725 return replaceCaret(comp, loose);
729 function replaceCaret(comp, loose) {
730 var r = loose ? re[CARETLOOSE] : re[CARET];
731 return comp.replace(r, function(_, M, m, p, pr) {
732 debug('caret', comp, _, M, m, p, pr);
738 ret = '>=' + M + '.0.0-0 <' + (+M + 1) + '.0.0-0';
741 ret = '>=' + M + '.' + m + '.0-0 <' + M + '.' + (+m + 1) + '.0-0';
743 ret = '>=' + M + '.' + m + '.0-0 <' + (+M + 1) + '.0.0-0';
745 debug('replaceCaret pr', pr);
746 if (pr.charAt(0) !== '-')
750 ret = '=' + M + '.' + m + '.' + p + pr;
752 ret = '>=' + M + '.' + m + '.' + p + pr +
753 ' <' + M + '.' + (+m + 1) + '.0-0';
755 ret = '>=' + M + '.' + m + '.' + p + pr +
756 ' <' + (+M + 1) + '.0.0-0';
760 ret = '=' + M + '.' + m + '.' + p;
762 ret = '>=' + M + '.' + m + '.' + p + '-0' +
763 ' <' + M + '.' + (+m + 1) + '.0-0';
765 ret = '>=' + M + '.' + m + '.' + p + '-0' +
766 ' <' + (+M + 1) + '.0.0-0';
769 debug('caret return', ret);
774 function replaceXRanges(comp, loose) {
775 debug('replaceXRanges', comp, loose);
776 return comp.split(/\s+/).map(function(comp) {
777 return replaceXRange(comp, loose);
781 function replaceXRange(comp, loose) {
783 var r = loose ? re[XRANGELOOSE] : re[XRANGE];
784 return comp.replace(r, function(ret, gtlt, M, m, p, pr) {
785 debug('xRange', comp, ret, gtlt, M, m, p, pr);
787 var xm = xM || isX(m);
788 var xp = xm || isX(p);
791 if (gtlt === '=' && anyX)
795 // replace X with 0, and then append the -0 min-prerelease
806 // >1.2.3 => >= 1.2.4-0
821 ret = gtlt + M + '.' + m + '.' + p + '-0';
826 // append '-0' onto the version, otherwise
827 // '1.x.x' matches '2.0.0-beta', since the tag
828 // *lowers* the version value
829 ret = '>=' + M + '.0.0-0 <' + (+M + 1) + '.0.0-0';
831 ret = '>=' + M + '.' + m + '.0-0 <' + M + '.' + (+m + 1) + '.0-0';
834 debug('xRange return', ret);
840 // Because * is AND-ed with everything else in the comparator,
841 // and '' means "any version", just remove the *s entirely.
842 function replaceStars(comp, loose) {
843 debug('replaceStars', comp, loose);
844 // Looseness is ignored here. star is always as loose as it gets!
845 return comp.trim().replace(re[STAR], '');
848 // This function is passed to string.replace(re[HYPHENRANGE])
849 // M, m, patch, prerelease, build
850 // 1.2 - 3.4.5 => >=1.2.0-0 <=3.4.5
851 // 1.2.3 - 3.4 => >=1.2.0-0 <3.5.0-0 Any 3.4.x will do
852 // 1.2 - 3.4 => >=1.2.0-0 <3.5.0-0
853 function hyphenReplace($0,
854 from, fM, fm, fp, fpr, fb,
855 to, tM, tm, tp, tpr, tb) {
860 from = '>=' + fM + '.0.0-0';
862 from = '>=' + fM + '.' + fm + '.0-0';
869 to = '<' + (+tM + 1) + '.0.0-0';
871 to = '<' + tM + '.' + (+tm + 1) + '.0-0';
873 to = '<=' + tM + '.' + tm + '.' + tp + '-' + tpr;
877 return (from + ' ' + to).trim();
881 // if ANY of the sets match ALL of its comparators, then pass
882 Range.prototype.test = function(version) {
885 for (var i = 0; i < this.set.length; i++) {
886 if (testSet(this.set[i], version))
892 function testSet(set, version) {
893 for (var i = 0; i < set.length; i++) {
894 if (!set[i].test(version))
900 exports.satisfies = satisfies;
901 function satisfies(version, range, loose) {
903 range = new Range(range, loose);
907 return range.test(version);
910 exports.maxSatisfying = maxSatisfying;
911 function maxSatisfying(versions, range, loose) {
912 return versions.filter(function(version) {
913 return satisfies(version, range, loose);
914 }).sort(function(a, b) {
915 return rcompare(a, b, loose);
919 exports.validRange = validRange;
920 function validRange(range, loose) {
922 // Return '*' instead of '' so that truthiness works.
923 // This will throw if it's invalid anyway
924 return new Range(range, loose).range || '*';
930 // Determine if version is less than all the versions possible in the range
932 function ltr(version, range, loose) {
933 return outside(version, range, '<', loose);
936 // Determine if version is greater than all the versions possible in the range.
938 function gtr(version, range, loose) {
939 return outside(version, range, '>', loose);
942 exports.outside = outside;
943 function outside(version, range, hilo, loose) {
944 version = new SemVer(version, loose);
945 range = new Range(range, loose);
947 var gtfn, ltefn, ltfn, comp, ecomp;
964 throw new TypeError('Must provide a hilo val of "<" or ">"');
967 // If it satisifes the range it is not outside
968 if (satisfies(version, range, loose)) {
972 // From now on, variable terms are as if we're in "gtr" mode.
973 // but note that everything is flipped for the "ltr" function.
975 for (var i = 0; i < range.set.length; ++i) {
976 var comparators = range.set[i];
981 comparators.forEach(function(comparator) {
982 high = high || comparator;
983 low = low || comparator;
984 if (gtfn(comparator.semver, high.semver, loose)) {
986 } else if (ltfn(comparator.semver, low.semver, loose)) {
991 // If the edge version comparator has a operator then our version
993 if (high.operator === comp || high.operator === ecomp) {
997 // If the lowest version comparator has an operator and our version
998 // is less than it then it isn't higher than the range
999 if ((!low.operator || low.operator === comp) &&
1000 ltefn(version, low.semver)) {
1002 } else if (low.operator === ecomp && ltfn(version, low.semver)) {
1009 // Use the define() function if we're in AMD land
1010 if (typeof define === 'function' && define.amd)