| const { MAX_SAFE_COMPONENT_LENGTH } = require('./constants') | 
| const debug = require('./debug') | 
| exports = module.exports = {} | 
|   | 
| // The actual regexps go on exports.re | 
| const re = exports.re = [] | 
| const src = exports.src = [] | 
| const t = exports.t = {} | 
| let R = 0 | 
|   | 
| const createToken = (name, value, isGlobal) => { | 
|   const index = R++ | 
|   debug(name, index, value) | 
|   t[name] = index | 
|   src[index] = value | 
|   re[index] = new RegExp(value, isGlobal ? 'g' : undefined) | 
| } | 
|   | 
| // The following Regular Expressions can be used for tokenizing, | 
| // validating, and parsing SemVer version strings. | 
|   | 
| // ## Numeric Identifier | 
| // A single `0`, or a non-zero digit followed by zero or more digits. | 
|   | 
| createToken('NUMERICIDENTIFIER', '0|[1-9]\\d*') | 
| createToken('NUMERICIDENTIFIERLOOSE', '[0-9]+') | 
|   | 
| // ## Non-numeric Identifier | 
| // Zero or more digits, followed by a letter or hyphen, and then zero or | 
| // more letters, digits, or hyphens. | 
|   | 
| createToken('NONNUMERICIDENTIFIER', '\\d*[a-zA-Z-][a-zA-Z0-9-]*') | 
|   | 
| // ## Main Version | 
| // Three dot-separated numeric identifiers. | 
|   | 
| createToken('MAINVERSION', `(${src[t.NUMERICIDENTIFIER]})\\.` + | 
|                    `(${src[t.NUMERICIDENTIFIER]})\\.` + | 
|                    `(${src[t.NUMERICIDENTIFIER]})`) | 
|   | 
| createToken('MAINVERSIONLOOSE', `(${src[t.NUMERICIDENTIFIERLOOSE]})\\.` + | 
|                         `(${src[t.NUMERICIDENTIFIERLOOSE]})\\.` + | 
|                         `(${src[t.NUMERICIDENTIFIERLOOSE]})`) | 
|   | 
| // ## Pre-release Version Identifier | 
| // A numeric identifier, or a non-numeric identifier. | 
|   | 
| createToken('PRERELEASEIDENTIFIER', `(?:${src[t.NUMERICIDENTIFIER] | 
| }|${src[t.NONNUMERICIDENTIFIER]})`) | 
|   | 
| createToken('PRERELEASEIDENTIFIERLOOSE', `(?:${src[t.NUMERICIDENTIFIERLOOSE] | 
| }|${src[t.NONNUMERICIDENTIFIER]})`) | 
|   | 
| // ## Pre-release Version | 
| // Hyphen, followed by one or more dot-separated pre-release version | 
| // identifiers. | 
|   | 
| createToken('PRERELEASE', `(?:-(${src[t.PRERELEASEIDENTIFIER] | 
| }(?:\\.${src[t.PRERELEASEIDENTIFIER]})*))`) | 
|   | 
| createToken('PRERELEASELOOSE', `(?:-?(${src[t.PRERELEASEIDENTIFIERLOOSE] | 
| }(?:\\.${src[t.PRERELEASEIDENTIFIERLOOSE]})*))`) | 
|   | 
| // ## Build Metadata Identifier | 
| // Any combination of digits, letters, or hyphens. | 
|   | 
| createToken('BUILDIDENTIFIER', '[0-9A-Za-z-]+') | 
|   | 
| // ## Build Metadata | 
| // Plus sign, followed by one or more period-separated build metadata | 
| // identifiers. | 
|   | 
| createToken('BUILD', `(?:\\+(${src[t.BUILDIDENTIFIER] | 
| }(?:\\.${src[t.BUILDIDENTIFIER]})*))`) | 
|   | 
| // ## Full Version String | 
| // A main version, followed optionally by a pre-release version and | 
| // build metadata. | 
|   | 
| // Note that the only major, minor, patch, and pre-release sections of | 
| // the version string are capturing groups.  The build metadata is not a | 
| // capturing group, because it should not ever be used in version | 
| // comparison. | 
|   | 
| createToken('FULLPLAIN', `v?${src[t.MAINVERSION] | 
| }${src[t.PRERELEASE]}?${ | 
|   src[t.BUILD]}?`) | 
|   | 
| createToken('FULL', `^${src[t.FULLPLAIN]}$`) | 
|   | 
| // like full, but allows v1.2.3 and =1.2.3, which people do sometimes. | 
| // also, 1.0.0alpha1 (prerelease without the hyphen) which is pretty | 
| // common in the npm registry. | 
| createToken('LOOSEPLAIN', `[v=\\s]*${src[t.MAINVERSIONLOOSE] | 
| }${src[t.PRERELEASELOOSE]}?${ | 
|   src[t.BUILD]}?`) | 
|   | 
| createToken('LOOSE', `^${src[t.LOOSEPLAIN]}$`) | 
|   | 
| createToken('GTLT', '((?:<|>)?=?)') | 
|   | 
| // Something like "2.*" or "1.2.x". | 
| // Note that "x.x" is a valid xRange identifer, meaning "any version" | 
| // Only the first item is strictly required. | 
| createToken('XRANGEIDENTIFIERLOOSE', `${src[t.NUMERICIDENTIFIERLOOSE]}|x|X|\\*`) | 
| createToken('XRANGEIDENTIFIER', `${src[t.NUMERICIDENTIFIER]}|x|X|\\*`) | 
|   | 
| createToken('XRANGEPLAIN', `[v=\\s]*(${src[t.XRANGEIDENTIFIER]})` + | 
|                    `(?:\\.(${src[t.XRANGEIDENTIFIER]})` + | 
|                    `(?:\\.(${src[t.XRANGEIDENTIFIER]})` + | 
|                    `(?:${src[t.PRERELEASE]})?${ | 
|                      src[t.BUILD]}?` + | 
|                    `)?)?`) | 
|   | 
| createToken('XRANGEPLAINLOOSE', `[v=\\s]*(${src[t.XRANGEIDENTIFIERLOOSE]})` + | 
|                         `(?:\\.(${src[t.XRANGEIDENTIFIERLOOSE]})` + | 
|                         `(?:\\.(${src[t.XRANGEIDENTIFIERLOOSE]})` + | 
|                         `(?:${src[t.PRERELEASELOOSE]})?${ | 
|                           src[t.BUILD]}?` + | 
|                         `)?)?`) | 
|   | 
| createToken('XRANGE', `^${src[t.GTLT]}\\s*${src[t.XRANGEPLAIN]}$`) | 
| createToken('XRANGELOOSE', `^${src[t.GTLT]}\\s*${src[t.XRANGEPLAINLOOSE]}$`) | 
|   | 
| // Coercion. | 
| // Extract anything that could conceivably be a part of a valid semver | 
| createToken('COERCE', `${'(^|[^\\d])' + | 
|               '(\\d{1,'}${MAX_SAFE_COMPONENT_LENGTH}})` + | 
|               `(?:\\.(\\d{1,${MAX_SAFE_COMPONENT_LENGTH}}))?` + | 
|               `(?:\\.(\\d{1,${MAX_SAFE_COMPONENT_LENGTH}}))?` + | 
|               `(?:$|[^\\d])`) | 
| createToken('COERCERTL', src[t.COERCE], true) | 
|   | 
| // Tilde ranges. | 
| // Meaning is "reasonably at or greater than" | 
| createToken('LONETILDE', '(?:~>?)') | 
|   | 
| createToken('TILDETRIM', `(\\s*)${src[t.LONETILDE]}\\s+`, true) | 
| exports.tildeTrimReplace = '$1~' | 
|   | 
| createToken('TILDE', `^${src[t.LONETILDE]}${src[t.XRANGEPLAIN]}$`) | 
| createToken('TILDELOOSE', `^${src[t.LONETILDE]}${src[t.XRANGEPLAINLOOSE]}$`) | 
|   | 
| // Caret ranges. | 
| // Meaning is "at least and backwards compatible with" | 
| createToken('LONECARET', '(?:\\^)') | 
|   | 
| createToken('CARETTRIM', `(\\s*)${src[t.LONECARET]}\\s+`, true) | 
| exports.caretTrimReplace = '$1^' | 
|   | 
| createToken('CARET', `^${src[t.LONECARET]}${src[t.XRANGEPLAIN]}$`) | 
| createToken('CARETLOOSE', `^${src[t.LONECARET]}${src[t.XRANGEPLAINLOOSE]}$`) | 
|   | 
| // A simple gt/lt/eq thing, or just "" to indicate "any version" | 
| createToken('COMPARATORLOOSE', `^${src[t.GTLT]}\\s*(${src[t.LOOSEPLAIN]})$|^$`) | 
| createToken('COMPARATOR', `^${src[t.GTLT]}\\s*(${src[t.FULLPLAIN]})$|^$`) | 
|   | 
| // An expression to strip any whitespace between the gtlt and the thing | 
| // it modifies, so that `> 1.2.3` ==> `>1.2.3` | 
| createToken('COMPARATORTRIM', `(\\s*)${src[t.GTLT] | 
| }\\s*(${src[t.LOOSEPLAIN]}|${src[t.XRANGEPLAIN]})`, true) | 
| exports.comparatorTrimReplace = '$1$2$3' | 
|   | 
| // Something like `1.2.3 - 1.2.4` | 
| // Note that these all use the loose form, because they'll be | 
| // checked against either the strict or loose comparator form | 
| // later. | 
| createToken('HYPHENRANGE', `^\\s*(${src[t.XRANGEPLAIN]})` + | 
|                    `\\s+-\\s+` + | 
|                    `(${src[t.XRANGEPLAIN]})` + | 
|                    `\\s*$`) | 
|   | 
| createToken('HYPHENRANGELOOSE', `^\\s*(${src[t.XRANGEPLAINLOOSE]})` + | 
|                         `\\s+-\\s+` + | 
|                         `(${src[t.XRANGEPLAINLOOSE]})` + | 
|                         `\\s*$`) | 
|   | 
| // Star ranges basically just allow anything at all. | 
| createToken('STAR', '(<|>)?=?\\s*\\*') | 
| // >=0.0.0 is like a star | 
| createToken('GTE0', '^\\s*>=\\s*0\\.0\\.0\\s*$') | 
| createToken('GTE0PRE', '^\\s*>=\\s*0\\.0\\.0-0\\s*$') |