| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907 | const minimatch = module.exports = (p, pattern, options = {}) => {  assertValidPattern(pattern)  // shortcut: comments match nothing.  if (!options.nocomment && pattern.charAt(0) === '#') {    return false  }  return new Minimatch(pattern, options).match(p)}module.exports = minimatchconst path = require('./lib/path.js')minimatch.sep = path.sepconst GLOBSTAR = Symbol('globstar **')minimatch.GLOBSTAR = GLOBSTARconst expand = require('brace-expansion')const plTypes = {  '!': { open: '(?:(?!(?:', close: '))[^/]*?)'},  '?': { open: '(?:', close: ')?' },  '+': { open: '(?:', close: ')+' },  '*': { open: '(?:', close: ')*' },  '@': { open: '(?:', close: ')' }}// any single thing other than /// don't need to escape / when using new RegExp()const qmark = '[^/]'// * => any number of charactersconst star = qmark + '*?'// ** when dots are allowed.  Anything goes, except .. and .// not (^ or / followed by one or two dots followed by $ or /),// followed by anything, any number of times.const twoStarDot = '(?:(?!(?:\\\/|^)(?:\\.{1,2})($|\\\/)).)*?'// not a ^ or / followed by a dot,// followed by anything, any number of times.const twoStarNoDot = '(?:(?!(?:\\\/|^)\\.).)*?'// "abc" -> { a:true, b:true, c:true }const charSet = s => s.split('').reduce((set, c) => {  set[c] = true  return set}, {})// characters that need to be escaped in RegExp.const reSpecials = charSet('().*{}+?[]^$\\!')// characters that indicate we have to add the pattern startconst addPatternStartSet = charSet('[.(')// normalizes slashes.const slashSplit = /\/+/minimatch.filter = (pattern, options = {}) =>  (p, i, list) => minimatch(p, pattern, options)const ext = (a, b = {}) => {  const t = {}  Object.keys(a).forEach(k => t[k] = a[k])  Object.keys(b).forEach(k => t[k] = b[k])  return t}minimatch.defaults = def => {  if (!def || typeof def !== 'object' || !Object.keys(def).length) {    return minimatch  }  const orig = minimatch  const m = (p, pattern, options) => orig(p, pattern, ext(def, options))  m.Minimatch = class Minimatch extends orig.Minimatch {    constructor (pattern, options) {      super(pattern, ext(def, options))    }  }  m.Minimatch.defaults = options => orig.defaults(ext(def, options)).Minimatch  m.filter = (pattern, options) => orig.filter(pattern, ext(def, options))  m.defaults = options => orig.defaults(ext(def, options))  m.makeRe = (pattern, options) => orig.makeRe(pattern, ext(def, options))  m.braceExpand = (pattern, options) => orig.braceExpand(pattern, ext(def, options))  m.match = (list, pattern, options) => orig.match(list, pattern, ext(def, options))  return m}// Brace expansion:// a{b,c}d -> abd acd// a{b,}c -> abc ac// a{0..3}d -> a0d a1d a2d a3d// a{b,c{d,e}f}g -> abg acdfg acefg// a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg//// Invalid sets are not expanded.// a{2..}b -> a{2..}b// a{b}c -> a{b}cminimatch.braceExpand = (pattern, options) => braceExpand(pattern, options)const braceExpand = (pattern, options = {}) => {  assertValidPattern(pattern)  // Thanks to Yeting Li <https://github.com/yetingli> for  // improving this regexp to avoid a ReDOS vulnerability.  if (options.nobrace || !/\{(?:(?!\{).)*\}/.test(pattern)) {    // shortcut. no need to expand.    return [pattern]  }  return expand(pattern)}const MAX_PATTERN_LENGTH = 1024 * 64const assertValidPattern = pattern => {  if (typeof pattern !== 'string') {    throw new TypeError('invalid pattern')  }  if (pattern.length > MAX_PATTERN_LENGTH) {    throw new TypeError('pattern is too long')  }}// parse a component of the expanded set.// At this point, no pattern may contain "/" in it// so we're going to return a 2d array, where each entry is the full// pattern, split on '/', and then turned into a regular expression.// A regexp is made at the end which joins each array with an// escaped /, and another full one which joins each regexp with |.//// Following the lead of Bash 4.1, note that "**" only has special meaning// when it is the *only* thing in a path portion.  Otherwise, any series// of * is equivalent to a single *.  Globstar behavior is enabled by// default, and can be disabled by setting options.noglobstar.const SUBPARSE = Symbol('subparse')minimatch.makeRe = (pattern, options) =>  new Minimatch(pattern, options || {}).makeRe()minimatch.match = (list, pattern, options = {}) => {  const mm = new Minimatch(pattern, options)  list = list.filter(f => mm.match(f))  if (mm.options.nonull && !list.length) {    list.push(pattern)  }  return list}// replace stuff like \* with *const globUnescape = s => s.replace(/\\(.)/g, '$1')const charUnescape = s => s.replace(/\\([^-\]])/g, '$1')const regExpEscape = s => s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&')const braExpEscape = s => s.replace(/[[\]\\]/g, '\\$&')class Minimatch {  constructor (pattern, options) {    assertValidPattern(pattern)    if (!options) options = {}    this.options = options    this.set = []    this.pattern = pattern    this.windowsPathsNoEscape = !!options.windowsPathsNoEscape ||      options.allowWindowsEscape === false    if (this.windowsPathsNoEscape) {      this.pattern = this.pattern.replace(/\\/g, '/')    }    this.regexp = null    this.negate = false    this.comment = false    this.empty = false    this.partial = !!options.partial    // make the set of regexps etc.    this.make()  }  debug () {}  make () {    const pattern = this.pattern    const options = this.options    // empty patterns and comments match nothing.    if (!options.nocomment && pattern.charAt(0) === '#') {      this.comment = true      return    }    if (!pattern) {      this.empty = true      return    }    // step 1: figure out negation, etc.    this.parseNegate()    // step 2: expand braces    let set = this.globSet = this.braceExpand()    if (options.debug) this.debug = (...args) => console.error(...args)    this.debug(this.pattern, set)    // step 3: now we have a set, so turn each one into a series of path-portion    // matching patterns.    // These will be regexps, except in the case of "**", which is    // set to the GLOBSTAR object for globstar behavior,    // and will not contain any / characters    set = this.globParts = set.map(s => s.split(slashSplit))    this.debug(this.pattern, set)    // glob --> regexps    set = set.map((s, si, set) => s.map(this.parse, this))    this.debug(this.pattern, set)    // filter out everything that didn't compile properly.    set = set.filter(s => s.indexOf(false) === -1)    this.debug(this.pattern, set)    this.set = set  }  parseNegate () {    if (this.options.nonegate) return    const pattern = this.pattern    let negate = false    let negateOffset = 0    for (let i = 0; i < pattern.length && pattern.charAt(i) === '!'; i++) {      negate = !negate      negateOffset++    }    if (negateOffset) this.pattern = pattern.slice(negateOffset)    this.negate = negate  }  // set partial to true to test if, for example,  // "/a/b" matches the start of "/*/b/*/d"  // Partial means, if you run out of file before you run  // out of pattern, then that's fine, as long as all  // the parts match.  matchOne (file, pattern, partial) {    var options = this.options    this.debug('matchOne',      { 'this': this, file: file, pattern: pattern })    this.debug('matchOne', file.length, pattern.length)    for (var fi = 0,        pi = 0,        fl = file.length,        pl = pattern.length        ; (fi < fl) && (pi < pl)        ; fi++, pi++) {      this.debug('matchOne loop')      var p = pattern[pi]      var f = file[fi]      this.debug(pattern, p, f)      // should be impossible.      // some invalid regexp stuff in the set.      /* istanbul ignore if */      if (p === false) return false      if (p === GLOBSTAR) {        this.debug('GLOBSTAR', [pattern, p, f])        // "**"        // a/**/b/**/c would match the following:        // a/b/x/y/z/c        // a/x/y/z/b/c        // a/b/x/b/x/c        // a/b/c        // To do this, take the rest of the pattern after        // the **, and see if it would match the file remainder.        // If so, return success.        // If not, the ** "swallows" a segment, and try again.        // This is recursively awful.        //        // a/**/b/**/c matching a/b/x/y/z/c        // - a matches a        // - doublestar        //   - matchOne(b/x/y/z/c, b/**/c)        //     - b matches b        //     - doublestar        //       - matchOne(x/y/z/c, c) -> no        //       - matchOne(y/z/c, c) -> no        //       - matchOne(z/c, c) -> no        //       - matchOne(c, c) yes, hit        var fr = fi        var pr = pi + 1        if (pr === pl) {          this.debug('** at the end')          // a ** at the end will just swallow the rest.          // We have found a match.          // however, it will not swallow /.x, unless          // options.dot is set.          // . and .. are *never* matched by **, for explosively          // exponential reasons.          for (; fi < fl; fi++) {            if (file[fi] === '.' || file[fi] === '..' ||              (!options.dot && file[fi].charAt(0) === '.')) return false          }          return true        }        // ok, let's see if we can swallow whatever we can.        while (fr < fl) {          var swallowee = file[fr]          this.debug('\nglobstar while', file, fr, pattern, pr, swallowee)          // XXX remove this slice.  Just pass the start index.          if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) {            this.debug('globstar found match!', fr, fl, swallowee)            // found a match.            return true          } else {            // can't swallow "." or ".." ever.            // can only swallow ".foo" when explicitly asked.            if (swallowee === '.' || swallowee === '..' ||              (!options.dot && swallowee.charAt(0) === '.')) {              this.debug('dot detected!', file, fr, pattern, pr)              break            }            // ** swallows a segment, and continue.            this.debug('globstar swallow a segment, and continue')            fr++          }        }        // no match was found.        // However, in partial mode, we can't say this is necessarily over.        // If there's more *pattern* left, then        /* istanbul ignore if */        if (partial) {          // ran out of file          this.debug('\n>>> no match, partial?', file, fr, pattern, pr)          if (fr === fl) return true        }        return false      }      // something other than **      // non-magic patterns just have to match exactly      // patterns with magic have been turned into regexps.      var hit      if (typeof p === 'string') {        hit = f === p        this.debug('string match', p, f, hit)      } else {        hit = f.match(p)        this.debug('pattern match', p, f, hit)      }      if (!hit) return false    }    // Note: ending in / means that we'll get a final ""    // at the end of the pattern.  This can only match a    // corresponding "" at the end of the file.    // If the file ends in /, then it can only match a    // a pattern that ends in /, unless the pattern just    // doesn't have any more for it. But, a/b/ should *not*    // match "a/b/*", even though "" matches against the    // [^/]*? pattern, except in partial mode, where it might    // simply not be reached yet.    // However, a/b/ should still satisfy a/*    // now either we fell off the end of the pattern, or we're done.    if (fi === fl && pi === pl) {      // ran out of pattern and filename at the same time.      // an exact hit!      return true    } else if (fi === fl) {      // ran out of file, but still had pattern left.      // this is ok if we're doing the match as part of      // a glob fs traversal.      return partial    } else /* istanbul ignore else */ if (pi === pl) {      // ran out of pattern, still have file left.      // this is only acceptable if we're on the very last      // empty segment of a file with a trailing slash.      // a/* should match a/b/      return (fi === fl - 1) && (file[fi] === '')    }    // should be unreachable.    /* istanbul ignore next */    throw new Error('wtf?')  }  braceExpand () {    return braceExpand(this.pattern, this.options)  }  parse (pattern, isSub) {    assertValidPattern(pattern)    const options = this.options    // shortcuts    if (pattern === '**') {      if (!options.noglobstar)        return GLOBSTAR      else        pattern = '*'    }    if (pattern === '') return ''    let re = ''    let hasMagic = !!options.nocase    let escaping = false    // ? => one single character    const patternListStack = []    const negativeLists = []    let stateChar    let inClass = false    let reClassStart = -1    let classStart = -1    let cs    let pl    let sp    // . and .. never match anything that doesn't start with .,    // even when options.dot is set.    const patternStart = pattern.charAt(0) === '.' ? '' // anything    // not (start or / followed by . or .. followed by / or end)    : options.dot ? '(?!(?:^|\\\/)\\.{1,2}(?:$|\\\/))'    : '(?!\\.)'    const clearStateChar = () => {      if (stateChar) {        // we had some state-tracking character        // that wasn't consumed by this pass.        switch (stateChar) {          case '*':            re += star            hasMagic = true          break          case '?':            re += qmark            hasMagic = true          break          default:            re += '\\' + stateChar          break        }        this.debug('clearStateChar %j %j', stateChar, re)        stateChar = false      }    }    for (let i = 0, c; (i < pattern.length) && (c = pattern.charAt(i)); i++) {      this.debug('%s\t%s %s %j', pattern, i, re, c)      // skip over any that are escaped.      if (escaping) {        /* istanbul ignore next - completely not allowed, even escaped. */        if (c === '/') {          return false        }        if (reSpecials[c]) {          re += '\\'        }        re += c        escaping = false        continue      }      switch (c) {        /* istanbul ignore next */        case '/': {          // Should already be path-split by now.          return false        }        case '\\':          if (inClass && pattern.charAt(i + 1) === '-') {            re += c            continue          }          clearStateChar()          escaping = true        continue        // the various stateChar values        // for the "extglob" stuff.        case '?':        case '*':        case '+':        case '@':        case '!':          this.debug('%s\t%s %s %j <-- stateChar', pattern, i, re, c)          // all of those are literals inside a class, except that          // the glob [!a] means [^a] in regexp          if (inClass) {            this.debug('  in class')            if (c === '!' && i === classStart + 1) c = '^'            re += c            continue          }          // if we already have a stateChar, then it means          // that there was something like ** or +? in there.          // Handle the stateChar, then proceed with this one.          this.debug('call clearStateChar %j', stateChar)          clearStateChar()          stateChar = c          // if extglob is disabled, then +(asdf|foo) isn't a thing.          // just clear the statechar *now*, rather than even diving into          // the patternList stuff.          if (options.noext) clearStateChar()        continue        case '(':          if (inClass) {            re += '('            continue          }          if (!stateChar) {            re += '\\('            continue          }          patternListStack.push({            type: stateChar,            start: i - 1,            reStart: re.length,            open: plTypes[stateChar].open,            close: plTypes[stateChar].close          })          // negation is (?:(?!js)[^/]*)          re += stateChar === '!' ? '(?:(?!(?:' : '(?:'          this.debug('plType %j %j', stateChar, re)          stateChar = false        continue        case ')':          if (inClass || !patternListStack.length) {            re += '\\)'            continue          }          clearStateChar()          hasMagic = true          pl = patternListStack.pop()          // negation is (?:(?!js)[^/]*)          // The others are (?:<pattern>)<type>          re += pl.close          if (pl.type === '!') {            negativeLists.push(pl)          }          pl.reEnd = re.length        continue        case '|':          if (inClass || !patternListStack.length) {            re += '\\|'            continue          }          clearStateChar()          re += '|'        continue        // these are mostly the same in regexp and glob        case '[':          // swallow any state-tracking char before the [          clearStateChar()          if (inClass) {            re += '\\' + c            continue          }          inClass = true          classStart = i          reClassStart = re.length          re += c        continue        case ']':          //  a right bracket shall lose its special          //  meaning and represent itself in          //  a bracket expression if it occurs          //  first in the list.  -- POSIX.2 2.8.3.2          if (i === classStart + 1 || !inClass) {            re += '\\' + c            continue          }          // split where the last [ was, make sure we don't have          // an invalid re. if so, re-walk the contents of the          // would-be class to re-translate any characters that          // were passed through as-is          // TODO: It would probably be faster to determine this          // without a try/catch and a new RegExp, but it's tricky          // to do safely.  For now, this is safe and works.          cs = pattern.substring(classStart + 1, i)          try {            RegExp('[' + braExpEscape(charUnescape(cs)) + ']')            // looks good, finish up the class.            re += c          } catch (er) {            // out of order ranges in JS are errors, but in glob syntax,            // they're just a range that matches nothing.            re = re.substring(0, reClassStart) + '(?:$.)' // match nothing ever          }          hasMagic = true          inClass = false        continue        default:          // swallow any state char that wasn't consumed          clearStateChar()          if (reSpecials[c] && !(c === '^' && inClass)) {            re += '\\'          }          re += c          break      } // switch    } // for    // handle the case where we left a class open.    // "[abc" is valid, equivalent to "\[abc"    if (inClass) {      // split where the last [ was, and escape it      // this is a huge pita.  We now have to re-walk      // the contents of the would-be class to re-translate      // any characters that were passed through as-is      cs = pattern.slice(classStart + 1)      sp = this.parse(cs, SUBPARSE)      re = re.substring(0, reClassStart) + '\\[' + sp[0]      hasMagic = hasMagic || sp[1]    }    // handle the case where we had a +( thing at the *end*    // of the pattern.    // each pattern list stack adds 3 chars, and we need to go through    // and escape any | chars that were passed through as-is for the regexp.    // Go through and escape them, taking care not to double-escape any    // | chars that were already escaped.    for (pl = patternListStack.pop(); pl; pl = patternListStack.pop()) {      let tail      tail = re.slice(pl.reStart + pl.open.length)      this.debug('setting tail', re, pl)      // maybe some even number of \, then maybe 1 \, followed by a |      tail = tail.replace(/((?:\\{2}){0,64})(\\?)\|/g, (_, $1, $2) => {        /* istanbul ignore else - should already be done */        if (!$2) {          // the | isn't already escaped, so escape it.          $2 = '\\'        }        // need to escape all those slashes *again*, without escaping the        // one that we need for escaping the | character.  As it works out,        // escaping an even number of slashes can be done by simply repeating        // it exactly after itself.  That's why this trick works.        //        // I am sorry that you have to see this.        return $1 + $1 + $2 + '|'      })      this.debug('tail=%j\n   %s', tail, tail, pl, re)      const t = pl.type === '*' ? star        : pl.type === '?' ? qmark        : '\\' + pl.type      hasMagic = true      re = re.slice(0, pl.reStart) + t + '\\(' + tail    }    // handle trailing things that only matter at the very end.    clearStateChar()    if (escaping) {      // trailing \\      re += '\\\\'    }    // only need to apply the nodot start if the re starts with    // something that could conceivably capture a dot    const addPatternStart = addPatternStartSet[re.charAt(0)]    // Hack to work around lack of negative lookbehind in JS    // A pattern like: *.!(x).!(y|z) needs to ensure that a name    // like 'a.xyz.yz' doesn't match.  So, the first negative    // lookahead, has to look ALL the way ahead, to the end of    // the pattern.    for (let n = negativeLists.length - 1; n > -1; n--) {      const nl = negativeLists[n]      const nlBefore = re.slice(0, nl.reStart)      const nlFirst = re.slice(nl.reStart, nl.reEnd - 8)      let nlAfter = re.slice(nl.reEnd)      const nlLast = re.slice(nl.reEnd - 8, nl.reEnd) + nlAfter      // Handle nested stuff like *(*.js|!(*.json)), where open parens      // mean that we should *not* include the ) in the bit that is considered      // "after" the negated section.      const openParensBefore = nlBefore.split('(').length - 1      let cleanAfter = nlAfter      for (let i = 0; i < openParensBefore; i++) {        cleanAfter = cleanAfter.replace(/\)[+*?]?/, '')      }      nlAfter = cleanAfter      const dollar = nlAfter === '' && isSub !== SUBPARSE ? '$' : ''      re = nlBefore + nlFirst + nlAfter + dollar + nlLast    }    // if the re is not "" at this point, then we need to make sure    // it doesn't match against an empty path part.    // Otherwise a/* will match a/, which it should not.    if (re !== '' && hasMagic) {      re = '(?=.)' + re    }    if (addPatternStart) {      re = patternStart + re    }    // parsing just a piece of a larger pattern.    if (isSub === SUBPARSE) {      return [re, hasMagic]    }    // skip the regexp for non-magical patterns    // unescape anything in it, though, so that it'll be    // an exact match against a file etc.    if (!hasMagic) {      return globUnescape(pattern)    }    const flags = options.nocase ? 'i' : ''    try {      return Object.assign(new RegExp('^' + re + '$', flags), {        _glob: pattern,        _src: re,      })    } catch (er) /* istanbul ignore next - should be impossible */ {      // If it was an invalid regular expression, then it can't match      // anything.  This trick looks for a character after the end of      // the string, which is of course impossible, except in multi-line      // mode, but it's not a /m regex.      return new RegExp('$.')    }  }  makeRe () {    if (this.regexp || this.regexp === false) return this.regexp    // at this point, this.set is a 2d array of partial    // pattern strings, or "**".    //    // It's better to use .match().  This function shouldn't    // be used, really, but it's pretty convenient sometimes,    // when you just want to work with a regex.    const set = this.set    if (!set.length) {      this.regexp = false      return this.regexp    }    const options = this.options    const twoStar = options.noglobstar ? star      : options.dot ? twoStarDot      : twoStarNoDot    const flags = options.nocase ? 'i' : ''    // coalesce globstars and regexpify non-globstar patterns    // if it's the only item, then we just do one twoStar    // if it's the first, and there are more, prepend (\/|twoStar\/)? to next    // if it's the last, append (\/twoStar|) to previous    // if it's in the middle, append (\/|\/twoStar\/) to previous    // then filter out GLOBSTAR symbols    let re = set.map(pattern => {      pattern = pattern.map(p =>        typeof p === 'string' ? regExpEscape(p)        : p === GLOBSTAR ? GLOBSTAR        : p._src      ).reduce((set, p) => {        if (!(set[set.length - 1] === GLOBSTAR && p === GLOBSTAR)) {          set.push(p)        }        return set      }, [])      pattern.forEach((p, i) => {        if (p !== GLOBSTAR || pattern[i-1] === GLOBSTAR) {          return        }        if (i === 0) {          if (pattern.length > 1) {            pattern[i+1] = '(?:\\\/|' + twoStar + '\\\/)?' + pattern[i+1]          } else {            pattern[i] = twoStar          }        } else if (i === pattern.length - 1) {          pattern[i-1] += '(?:\\\/|' + twoStar + ')?'        } else {          pattern[i-1] += '(?:\\\/|\\\/' + twoStar + '\\\/)' + pattern[i+1]          pattern[i+1] = GLOBSTAR        }      })      return pattern.filter(p => p !== GLOBSTAR).join('/')    }).join('|')    // must match entire pattern    // ending in a * or ** will make it less strict.    re = '^(?:' + re + ')$'    // can match anything, as long as it's not this.    if (this.negate) re = '^(?!' + re + ').*$'    try {      this.regexp = new RegExp(re, flags)    } catch (ex) /* istanbul ignore next - should be impossible */ {      this.regexp = false    }    return this.regexp  }  match (f, partial = this.partial) {    this.debug('match', f, this.pattern)    // short-circuit in the case of busted things.    // comments, etc.    if (this.comment) return false    if (this.empty) return f === ''    if (f === '/' && partial) return true    const options = this.options    // windows: need to use /, not \    if (path.sep !== '/') {      f = f.split(path.sep).join('/')    }    // treat the test path as a set of pathparts.    f = f.split(slashSplit)    this.debug(this.pattern, 'split', f)    // just ONE of the pattern sets in this.set needs to match    // in order for it to be valid.  If negating, then just one    // match means that we have failed.    // Either way, return on the first hit.    const set = this.set    this.debug(this.pattern, 'set', set)    // Find the basename of the path by looking for the last non-empty segment    let filename    for (let i = f.length - 1; i >= 0; i--) {      filename = f[i]      if (filename) break    }    for (let i = 0; i < set.length; i++) {      const pattern = set[i]      let file = f      if (options.matchBase && pattern.length === 1) {        file = [filename]      }      const hit = this.matchOne(file, pattern, partial)      if (hit) {        if (options.flipNegate) return true        return !this.negate      }    }    // didn't get any hits.  this is success if it's a negative    // pattern, failure otherwise.    if (options.flipNegate) return false    return this.negate  }  static defaults (def) {    return minimatch.defaults(def).Minimatch  }}minimatch.Minimatch = Minimatch
 |