PageRenderTime 68ms CodeModel.GetById 16ms app.highlight 43ms RepoModel.GetById 2ms app.codeStats 0ms

/node_modules/minimatch/minimatch.js

https://bitbucket.org/coleman333/smartsite
JavaScript | 1073 lines | 863 code | 85 blank | 125 comment | 78 complexity | d15af391b681506a5b3cda5b7e83c62f MD5 | raw file
   1;(function (require, exports, module, platform) {
   2
   3if (module) module.exports = minimatch
   4else exports.minimatch = minimatch
   5
   6if (!require) {
   7  require = function (id) {
   8    switch (id) {
   9      case "sigmund": return function sigmund (obj) {
  10        return JSON.stringify(obj)
  11      }
  12      case "path": return { basename: function (f) {
  13        f = f.split(/[\/\\]/)
  14        var e = f.pop()
  15        if (!e) e = f.pop()
  16        return e
  17      }}
  18      case "lru-cache": return function LRUCache () {
  19        // not quite an LRU, but still space-limited.
  20        var cache = {}
  21        var cnt = 0
  22        this.set = function (k, v) {
  23          cnt ++
  24          if (cnt >= 100) cache = {}
  25          cache[k] = v
  26        }
  27        this.get = function (k) { return cache[k] }
  28      }
  29    }
  30  }
  31}
  32
  33minimatch.Minimatch = Minimatch
  34
  35var LRU = require("lru-cache")
  36  , cache = minimatch.cache = new LRU({max: 100})
  37  , GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {}
  38  , sigmund = require("sigmund")
  39
  40var path = require("path")
  41  // any single thing other than /
  42  // don't need to escape / when using new RegExp()
  43  , qmark = "[^/]"
  44
  45  // * => any number of characters
  46  , star = qmark + "*?"
  47
  48  // ** when dots are allowed.  Anything goes, except .. and .
  49  // not (^ or / followed by one or two dots followed by $ or /),
  50  // followed by anything, any number of times.
  51  , twoStarDot = "(?:(?!(?:\\\/|^)(?:\\.{1,2})($|\\\/)).)*?"
  52
  53  // not a ^ or / followed by a dot,
  54  // followed by anything, any number of times.
  55  , twoStarNoDot = "(?:(?!(?:\\\/|^)\\.).)*?"
  56
  57  // characters that need to be escaped in RegExp.
  58  , reSpecials = charSet("().*{}+?[]^$\\!")
  59
  60// "abc" -> { a:true, b:true, c:true }
  61function charSet (s) {
  62  return s.split("").reduce(function (set, c) {
  63    set[c] = true
  64    return set
  65  }, {})
  66}
  67
  68// normalizes slashes.
  69var slashSplit = /\/+/
  70
  71minimatch.filter = filter
  72function filter (pattern, options) {
  73  options = options || {}
  74  return function (p, i, list) {
  75    return minimatch(p, pattern, options)
  76  }
  77}
  78
  79function ext (a, b) {
  80  a = a || {}
  81  b = b || {}
  82  var t = {}
  83  Object.keys(b).forEach(function (k) {
  84    t[k] = b[k]
  85  })
  86  Object.keys(a).forEach(function (k) {
  87    t[k] = a[k]
  88  })
  89  return t
  90}
  91
  92minimatch.defaults = function (def) {
  93  if (!def || !Object.keys(def).length) return minimatch
  94
  95  var orig = minimatch
  96
  97  var m = function minimatch (p, pattern, options) {
  98    return orig.minimatch(p, pattern, ext(def, options))
  99  }
 100
 101  m.Minimatch = function Minimatch (pattern, options) {
 102    return new orig.Minimatch(pattern, ext(def, options))
 103  }
 104
 105  return m
 106}
 107
 108Minimatch.defaults = function (def) {
 109  if (!def || !Object.keys(def).length) return Minimatch
 110  return minimatch.defaults(def).Minimatch
 111}
 112
 113
 114function minimatch (p, pattern, options) {
 115  if (typeof pattern !== "string") {
 116    throw new TypeError("glob pattern string required")
 117  }
 118
 119  if (!options) options = {}
 120
 121  // shortcut: comments match nothing.
 122  if (!options.nocomment && pattern.charAt(0) === "#") {
 123    return false
 124  }
 125
 126  // "" only matches ""
 127  if (pattern.trim() === "") return p === ""
 128
 129  return new Minimatch(pattern, options).match(p)
 130}
 131
 132function Minimatch (pattern, options) {
 133  if (!(this instanceof Minimatch)) {
 134    return new Minimatch(pattern, options, cache)
 135  }
 136
 137  if (typeof pattern !== "string") {
 138    throw new TypeError("glob pattern string required")
 139  }
 140
 141  if (!options) options = {}
 142  pattern = pattern.trim()
 143
 144  // windows: need to use /, not \
 145  // On other platforms, \ is a valid (albeit bad) filename char.
 146  if (platform === "win32") {
 147    pattern = pattern.split("\\").join("/")
 148  }
 149
 150  // lru storage.
 151  // these things aren't particularly big, but walking down the string
 152  // and turning it into a regexp can get pretty costly.
 153  var cacheKey = pattern + "\n" + sigmund(options)
 154  var cached = minimatch.cache.get(cacheKey)
 155  if (cached) return cached
 156  minimatch.cache.set(cacheKey, this)
 157
 158  this.options = options
 159  this.set = []
 160  this.pattern = pattern
 161  this.regexp = null
 162  this.negate = false
 163  this.comment = false
 164  this.empty = false
 165
 166  // make the set of regexps etc.
 167  this.make()
 168}
 169
 170Minimatch.prototype.debug = function() {}
 171
 172Minimatch.prototype.make = make
 173function make () {
 174  // don't do it more than once.
 175  if (this._made) return
 176
 177  var pattern = this.pattern
 178  var options = this.options
 179
 180  // empty patterns and comments match nothing.
 181  if (!options.nocomment && pattern.charAt(0) === "#") {
 182    this.comment = true
 183    return
 184  }
 185  if (!pattern) {
 186    this.empty = true
 187    return
 188  }
 189
 190  // step 1: figure out negation, etc.
 191  this.parseNegate()
 192
 193  // step 2: expand braces
 194  var set = this.globSet = this.braceExpand()
 195
 196  if (options.debug) this.debug = console.error
 197
 198  this.debug(this.pattern, set)
 199
 200  // step 3: now we have a set, so turn each one into a series of path-portion
 201  // matching patterns.
 202  // These will be regexps, except in the case of "**", which is
 203  // set to the GLOBSTAR object for globstar behavior,
 204  // and will not contain any / characters
 205  set = this.globParts = set.map(function (s) {
 206    return s.split(slashSplit)
 207  })
 208
 209  this.debug(this.pattern, set)
 210
 211  // glob --> regexps
 212  set = set.map(function (s, si, set) {
 213    return s.map(this.parse, this)
 214  }, this)
 215
 216  this.debug(this.pattern, set)
 217
 218  // filter out everything that didn't compile properly.
 219  set = set.filter(function (s) {
 220    return -1 === s.indexOf(false)
 221  })
 222
 223  this.debug(this.pattern, set)
 224
 225  this.set = set
 226}
 227
 228Minimatch.prototype.parseNegate = parseNegate
 229function parseNegate () {
 230  var pattern = this.pattern
 231    , negate = false
 232    , options = this.options
 233    , negateOffset = 0
 234
 235  if (options.nonegate) return
 236
 237  for ( var i = 0, l = pattern.length
 238      ; i < l && pattern.charAt(i) === "!"
 239      ; i ++) {
 240    negate = !negate
 241    negateOffset ++
 242  }
 243
 244  if (negateOffset) this.pattern = pattern.substr(negateOffset)
 245  this.negate = negate
 246}
 247
 248// Brace expansion:
 249// a{b,c}d -> abd acd
 250// a{b,}c -> abc ac
 251// a{0..3}d -> a0d a1d a2d a3d
 252// a{b,c{d,e}f}g -> abg acdfg acefg
 253// a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg
 254//
 255// Invalid sets are not expanded.
 256// a{2..}b -> a{2..}b
 257// a{b}c -> a{b}c
 258minimatch.braceExpand = function (pattern, options) {
 259  return new Minimatch(pattern, options).braceExpand()
 260}
 261
 262Minimatch.prototype.braceExpand = braceExpand
 263
 264function pad(n, width, z) {
 265  z = z || '0';
 266  n = n + '';
 267  return n.length >= width ? n : new Array(width - n.length + 1).join(z) + n;
 268}
 269
 270function braceExpand (pattern, options) {
 271  options = options || this.options
 272  pattern = typeof pattern === "undefined"
 273    ? this.pattern : pattern
 274
 275  if (typeof pattern === "undefined") {
 276    throw new Error("undefined pattern")
 277  }
 278
 279  if (options.nobrace ||
 280      !pattern.match(/\{.*\}/)) {
 281    // shortcut. no need to expand.
 282    return [pattern]
 283  }
 284
 285  var escaping = false
 286
 287  // examples and comments refer to this crazy pattern:
 288  // a{b,c{d,e},{f,g}h}x{y,z}
 289  // expected:
 290  // abxy
 291  // abxz
 292  // acdxy
 293  // acdxz
 294  // acexy
 295  // acexz
 296  // afhxy
 297  // afhxz
 298  // aghxy
 299  // aghxz
 300
 301  // everything before the first \{ is just a prefix.
 302  // So, we pluck that off, and work with the rest,
 303  // and then prepend it to everything we find.
 304  if (pattern.charAt(0) !== "{") {
 305    this.debug(pattern)
 306    var prefix = null
 307    for (var i = 0, l = pattern.length; i < l; i ++) {
 308      var c = pattern.charAt(i)
 309      this.debug(i, c)
 310      if (c === "\\") {
 311        escaping = !escaping
 312      } else if (c === "{" && !escaping) {
 313        prefix = pattern.substr(0, i)
 314        break
 315      }
 316    }
 317
 318    // actually no sets, all { were escaped.
 319    if (prefix === null) {
 320      this.debug("no sets")
 321      return [pattern]
 322    }
 323
 324   var tail = braceExpand.call(this, pattern.substr(i), options)
 325    return tail.map(function (t) {
 326      return prefix + t
 327    })
 328  }
 329
 330  // now we have something like:
 331  // {b,c{d,e},{f,g}h}x{y,z}
 332  // walk through the set, expanding each part, until
 333  // the set ends.  then, we'll expand the suffix.
 334  // If the set only has a single member, then'll put the {} back
 335
 336  // first, handle numeric sets, since they're easier
 337  var numset = pattern.match(/^\{(-?[0-9]+)\.\.(-?[0-9]+)\}/)
 338  if (numset) {
 339    this.debug("numset", numset[1], numset[2])
 340    var suf = braceExpand.call(this, pattern.substr(numset[0].length), options)
 341      , start = +numset[1]
 342      , needPadding = numset[1][0] === '0'
 343      , startWidth = numset[1].length
 344      , padded
 345      , end = +numset[2]
 346      , inc = start > end ? -1 : 1
 347      , set = []
 348
 349    for (var i = start; i != (end + inc); i += inc) {
 350      padded = needPadding ? pad(i, startWidth) : i + ''
 351      // append all the suffixes
 352      for (var ii = 0, ll = suf.length; ii < ll; ii ++) {
 353        set.push(padded + suf[ii])
 354      }
 355    }
 356    return set
 357  }
 358
 359  // ok, walk through the set
 360  // We hope, somewhat optimistically, that there
 361  // will be a } at the end.
 362  // If the closing brace isn't found, then the pattern is
 363  // interpreted as braceExpand("\\" + pattern) so that
 364  // the leading \{ will be interpreted literally.
 365  var i = 1 // skip the \{
 366    , depth = 1
 367    , set = []
 368    , member = ""
 369    , sawEnd = false
 370    , escaping = false
 371
 372  function addMember () {
 373    set.push(member)
 374    member = ""
 375  }
 376
 377  this.debug("Entering for")
 378  FOR: for (i = 1, l = pattern.length; i < l; i ++) {
 379    var c = pattern.charAt(i)
 380    this.debug("", i, c)
 381
 382    if (escaping) {
 383      escaping = false
 384      member += "\\" + c
 385    } else {
 386      switch (c) {
 387        case "\\":
 388          escaping = true
 389          continue
 390
 391        case "{":
 392          depth ++
 393          member += "{"
 394          continue
 395
 396        case "}":
 397          depth --
 398          // if this closes the actual set, then we're done
 399          if (depth === 0) {
 400            addMember()
 401            // pluck off the close-brace
 402            i ++
 403            break FOR
 404          } else {
 405            member += c
 406            continue
 407          }
 408
 409        case ",":
 410          if (depth === 1) {
 411            addMember()
 412          } else {
 413            member += c
 414          }
 415          continue
 416
 417        default:
 418          member += c
 419          continue
 420      } // switch
 421    } // else
 422  } // for
 423
 424  // now we've either finished the set, and the suffix is
 425  // pattern.substr(i), or we have *not* closed the set,
 426  // and need to escape the leading brace
 427  if (depth !== 0) {
 428    this.debug("didn't close", pattern)
 429    return braceExpand.call(this, "\\" + pattern, options)
 430  }
 431
 432  // x{y,z} -> ["xy", "xz"]
 433  this.debug("set", set)
 434  this.debug("suffix", pattern.substr(i))
 435  var suf = braceExpand.call(this, pattern.substr(i), options)
 436  // ["b", "c{d,e}","{f,g}h"] ->
 437  //   [["b"], ["cd", "ce"], ["fh", "gh"]]
 438  var addBraces = set.length === 1
 439  this.debug("set pre-expanded", set)
 440  set = set.map(function (p) {
 441    return braceExpand.call(this, p, options)
 442  }, this)
 443  this.debug("set expanded", set)
 444
 445
 446  // [["b"], ["cd", "ce"], ["fh", "gh"]] ->
 447  //   ["b", "cd", "ce", "fh", "gh"]
 448  set = set.reduce(function (l, r) {
 449    return l.concat(r)
 450  })
 451
 452  if (addBraces) {
 453    set = set.map(function (s) {
 454      return "{" + s + "}"
 455    })
 456  }
 457
 458  // now attach the suffixes.
 459  var ret = []
 460  for (var i = 0, l = set.length; i < l; i ++) {
 461    for (var ii = 0, ll = suf.length; ii < ll; ii ++) {
 462      ret.push(set[i] + suf[ii])
 463    }
 464  }
 465  return ret
 466}
 467
 468// parse a component of the expanded set.
 469// At this point, no pattern may contain "/" in it
 470// so we're going to return a 2d array, where each entry is the full
 471// pattern, split on '/', and then turned into a regular expression.
 472// A regexp is made at the end which joins each array with an
 473// escaped /, and another full one which joins each regexp with |.
 474//
 475// Following the lead of Bash 4.1, note that "**" only has special meaning
 476// when it is the *only* thing in a path portion.  Otherwise, any series
 477// of * is equivalent to a single *.  Globstar behavior is enabled by
 478// default, and can be disabled by setting options.noglobstar.
 479Minimatch.prototype.parse = parse
 480var SUBPARSE = {}
 481function parse (pattern, isSub) {
 482  var options = this.options
 483
 484  // shortcuts
 485  if (!options.noglobstar && pattern === "**") return GLOBSTAR
 486  if (pattern === "") return ""
 487
 488  var re = ""
 489    , hasMagic = !!options.nocase
 490    , escaping = false
 491    // ? => one single character
 492    , patternListStack = []
 493    , plType
 494    , stateChar
 495    , inClass = false
 496    , reClassStart = -1
 497    , classStart = -1
 498    // . and .. never match anything that doesn't start with .,
 499    // even when options.dot is set.
 500    , patternStart = pattern.charAt(0) === "." ? "" // anything
 501      // not (start or / followed by . or .. followed by / or end)
 502      : options.dot ? "(?!(?:^|\\\/)\\.{1,2}(?:$|\\\/))"
 503      : "(?!\\.)"
 504    , self = this
 505
 506  function clearStateChar () {
 507    if (stateChar) {
 508      // we had some state-tracking character
 509      // that wasn't consumed by this pass.
 510      switch (stateChar) {
 511        case "*":
 512          re += star
 513          hasMagic = true
 514          break
 515        case "?":
 516          re += qmark
 517          hasMagic = true
 518          break
 519        default:
 520          re += "\\"+stateChar
 521          break
 522      }
 523      self.debug('clearStateChar %j %j', stateChar, re)
 524      stateChar = false
 525    }
 526  }
 527
 528  for ( var i = 0, len = pattern.length, c
 529      ; (i < len) && (c = pattern.charAt(i))
 530      ; i ++ ) {
 531
 532    this.debug("%s\t%s %s %j", pattern, i, re, c)
 533
 534    // skip over any that are escaped.
 535    if (escaping && reSpecials[c]) {
 536      re += "\\" + c
 537      escaping = false
 538      continue
 539    }
 540
 541    SWITCH: switch (c) {
 542      case "/":
 543        // completely not allowed, even escaped.
 544        // Should already be path-split by now.
 545        return false
 546
 547      case "\\":
 548        clearStateChar()
 549        escaping = true
 550        continue
 551
 552      // the various stateChar values
 553      // for the "extglob" stuff.
 554      case "?":
 555      case "*":
 556      case "+":
 557      case "@":
 558      case "!":
 559        this.debug("%s\t%s %s %j <-- stateChar", pattern, i, re, c)
 560
 561        // all of those are literals inside a class, except that
 562        // the glob [!a] means [^a] in regexp
 563        if (inClass) {
 564          this.debug('  in class')
 565          if (c === "!" && i === classStart + 1) c = "^"
 566          re += c
 567          continue
 568        }
 569
 570        // if we already have a stateChar, then it means
 571        // that there was something like ** or +? in there.
 572        // Handle the stateChar, then proceed with this one.
 573        self.debug('call clearStateChar %j', stateChar)
 574        clearStateChar()
 575        stateChar = c
 576        // if extglob is disabled, then +(asdf|foo) isn't a thing.
 577        // just clear the statechar *now*, rather than even diving into
 578        // the patternList stuff.
 579        if (options.noext) clearStateChar()
 580        continue
 581
 582      case "(":
 583        if (inClass) {
 584          re += "("
 585          continue
 586        }
 587
 588        if (!stateChar) {
 589          re += "\\("
 590          continue
 591        }
 592
 593        plType = stateChar
 594        patternListStack.push({ type: plType
 595                              , start: i - 1
 596                              , reStart: re.length })
 597        // negation is (?:(?!js)[^/]*)
 598        re += stateChar === "!" ? "(?:(?!" : "(?:"
 599        this.debug('plType %j %j', stateChar, re)
 600        stateChar = false
 601        continue
 602
 603      case ")":
 604        if (inClass || !patternListStack.length) {
 605          re += "\\)"
 606          continue
 607        }
 608
 609        clearStateChar()
 610        hasMagic = true
 611        re += ")"
 612        plType = patternListStack.pop().type
 613        // negation is (?:(?!js)[^/]*)
 614        // The others are (?:<pattern>)<type>
 615        switch (plType) {
 616          case "!":
 617            re += "[^/]*?)"
 618            break
 619          case "?":
 620          case "+":
 621          case "*": re += plType
 622          case "@": break // the default anyway
 623        }
 624        continue
 625
 626      case "|":
 627        if (inClass || !patternListStack.length || escaping) {
 628          re += "\\|"
 629          escaping = false
 630          continue
 631        }
 632
 633        clearStateChar()
 634        re += "|"
 635        continue
 636
 637      // these are mostly the same in regexp and glob
 638      case "[":
 639        // swallow any state-tracking char before the [
 640        clearStateChar()
 641
 642        if (inClass) {
 643          re += "\\" + c
 644          continue
 645        }
 646
 647        inClass = true
 648        classStart = i
 649        reClassStart = re.length
 650        re += c
 651        continue
 652
 653      case "]":
 654        //  a right bracket shall lose its special
 655        //  meaning and represent itself in
 656        //  a bracket expression if it occurs
 657        //  first in the list.  -- POSIX.2 2.8.3.2
 658        if (i === classStart + 1 || !inClass) {
 659          re += "\\" + c
 660          escaping = false
 661          continue
 662        }
 663
 664        // finish up the class.
 665        hasMagic = true
 666        inClass = false
 667        re += c
 668        continue
 669
 670      default:
 671        // swallow any state char that wasn't consumed
 672        clearStateChar()
 673
 674        if (escaping) {
 675          // no need
 676          escaping = false
 677        } else if (reSpecials[c]
 678                   && !(c === "^" && inClass)) {
 679          re += "\\"
 680        }
 681
 682        re += c
 683
 684    } // switch
 685  } // for
 686
 687
 688  // handle the case where we left a class open.
 689  // "[abc" is valid, equivalent to "\[abc"
 690  if (inClass) {
 691    // split where the last [ was, and escape it
 692    // this is a huge pita.  We now have to re-walk
 693    // the contents of the would-be class to re-translate
 694    // any characters that were passed through as-is
 695    var cs = pattern.substr(classStart + 1)
 696      , sp = this.parse(cs, SUBPARSE)
 697    re = re.substr(0, reClassStart) + "\\[" + sp[0]
 698    hasMagic = hasMagic || sp[1]
 699  }
 700
 701  // handle the case where we had a +( thing at the *end*
 702  // of the pattern.
 703  // each pattern list stack adds 3 chars, and we need to go through
 704  // and escape any | chars that were passed through as-is for the regexp.
 705  // Go through and escape them, taking care not to double-escape any
 706  // | chars that were already escaped.
 707  var pl
 708  while (pl = patternListStack.pop()) {
 709    var tail = re.slice(pl.reStart + 3)
 710    // maybe some even number of \, then maybe 1 \, followed by a |
 711    tail = tail.replace(/((?:\\{2})*)(\\?)\|/g, function (_, $1, $2) {
 712      if (!$2) {
 713        // the | isn't already escaped, so escape it.
 714        $2 = "\\"
 715      }
 716
 717      // need to escape all those slashes *again*, without escaping the
 718      // one that we need for escaping the | character.  As it works out,
 719      // escaping an even number of slashes can be done by simply repeating
 720      // it exactly after itself.  That's why this trick works.
 721      //
 722      // I am sorry that you have to see this.
 723      return $1 + $1 + $2 + "|"
 724    })
 725
 726    this.debug("tail=%j\n   %s", tail, tail)
 727    var t = pl.type === "*" ? star
 728          : pl.type === "?" ? qmark
 729          : "\\" + pl.type
 730
 731    hasMagic = true
 732    re = re.slice(0, pl.reStart)
 733       + t + "\\("
 734       + tail
 735  }
 736
 737  // handle trailing things that only matter at the very end.
 738  clearStateChar()
 739  if (escaping) {
 740    // trailing \\
 741    re += "\\\\"
 742  }
 743
 744  // only need to apply the nodot start if the re starts with
 745  // something that could conceivably capture a dot
 746  var addPatternStart = false
 747  switch (re.charAt(0)) {
 748    case ".":
 749    case "[":
 750    case "(": addPatternStart = true
 751  }
 752
 753  // if the re is not "" at this point, then we need to make sure
 754  // it doesn't match against an empty path part.
 755  // Otherwise a/* will match a/, which it should not.
 756  if (re !== "" && hasMagic) re = "(?=.)" + re
 757
 758  if (addPatternStart) re = patternStart + re
 759
 760  // parsing just a piece of a larger pattern.
 761  if (isSub === SUBPARSE) {
 762    return [ re, hasMagic ]
 763  }
 764
 765  // skip the regexp for non-magical patterns
 766  // unescape anything in it, though, so that it'll be
 767  // an exact match against a file etc.
 768  if (!hasMagic) {
 769    return globUnescape(pattern)
 770  }
 771
 772  var flags = options.nocase ? "i" : ""
 773    , regExp = new RegExp("^" + re + "$", flags)
 774
 775  regExp._glob = pattern
 776  regExp._src = re
 777
 778  return regExp
 779}
 780
 781minimatch.makeRe = function (pattern, options) {
 782  return new Minimatch(pattern, options || {}).makeRe()
 783}
 784
 785Minimatch.prototype.makeRe = makeRe
 786function makeRe () {
 787  if (this.regexp || this.regexp === false) return this.regexp
 788
 789  // at this point, this.set is a 2d array of partial
 790  // pattern strings, or "**".
 791  //
 792  // It's better to use .match().  This function shouldn't
 793  // be used, really, but it's pretty convenient sometimes,
 794  // when you just want to work with a regex.
 795  var set = this.set
 796
 797  if (!set.length) return this.regexp = false
 798  var options = this.options
 799
 800  var twoStar = options.noglobstar ? star
 801      : options.dot ? twoStarDot
 802      : twoStarNoDot
 803    , flags = options.nocase ? "i" : ""
 804
 805  var re = set.map(function (pattern) {
 806    return pattern.map(function (p) {
 807      return (p === GLOBSTAR) ? twoStar
 808           : (typeof p === "string") ? regExpEscape(p)
 809           : p._src
 810    }).join("\\\/")
 811  }).join("|")
 812
 813  // must match entire pattern
 814  // ending in a * or ** will make it less strict.
 815  re = "^(?:" + re + ")$"
 816
 817  // can match anything, as long as it's not this.
 818  if (this.negate) re = "^(?!" + re + ").*$"
 819
 820  try {
 821    return this.regexp = new RegExp(re, flags)
 822  } catch (ex) {
 823    return this.regexp = false
 824  }
 825}
 826
 827minimatch.match = function (list, pattern, options) {
 828  options = options || {}
 829  var mm = new Minimatch(pattern, options)
 830  list = list.filter(function (f) {
 831    return mm.match(f)
 832  })
 833  if (mm.options.nonull && !list.length) {
 834    list.push(pattern)
 835  }
 836  return list
 837}
 838
 839Minimatch.prototype.match = match
 840function match (f, partial) {
 841  this.debug("match", f, this.pattern)
 842  // short-circuit in the case of busted things.
 843  // comments, etc.
 844  if (this.comment) return false
 845  if (this.empty) return f === ""
 846
 847  if (f === "/" && partial) return true
 848
 849  var options = this.options
 850
 851  // windows: need to use /, not \
 852  // On other platforms, \ is a valid (albeit bad) filename char.
 853  if (platform === "win32") {
 854    f = f.split("\\").join("/")
 855  }
 856
 857  // treat the test path as a set of pathparts.
 858  f = f.split(slashSplit)
 859  this.debug(this.pattern, "split", f)
 860
 861  // just ONE of the pattern sets in this.set needs to match
 862  // in order for it to be valid.  If negating, then just one
 863  // match means that we have failed.
 864  // Either way, return on the first hit.
 865
 866  var set = this.set
 867  this.debug(this.pattern, "set", set)
 868
 869  // Find the basename of the path by looking for the last non-empty segment
 870  var filename;
 871  for (var i = f.length - 1; i >= 0; i--) {
 872    filename = f[i]
 873    if (filename) break
 874  }
 875
 876  for (var i = 0, l = set.length; i < l; i ++) {
 877    var pattern = set[i], file = f
 878    if (options.matchBase && pattern.length === 1) {
 879      file = [filename]
 880    }
 881    var hit = this.matchOne(file, pattern, partial)
 882    if (hit) {
 883      if (options.flipNegate) return true
 884      return !this.negate
 885    }
 886  }
 887
 888  // didn't get any hits.  this is success if it's a negative
 889  // pattern, failure otherwise.
 890  if (options.flipNegate) return false
 891  return this.negate
 892}
 893
 894// set partial to true to test if, for example,
 895// "/a/b" matches the start of "/*/b/*/d"
 896// Partial means, if you run out of file before you run
 897// out of pattern, then that's fine, as long as all
 898// the parts match.
 899Minimatch.prototype.matchOne = function (file, pattern, partial) {
 900  var options = this.options
 901
 902  this.debug("matchOne",
 903              { "this": this
 904              , file: file
 905              , pattern: pattern })
 906
 907  this.debug("matchOne", file.length, pattern.length)
 908
 909  for ( var fi = 0
 910          , pi = 0
 911          , fl = file.length
 912          , pl = pattern.length
 913      ; (fi < fl) && (pi < pl)
 914      ; fi ++, pi ++ ) {
 915
 916    this.debug("matchOne loop")
 917    var p = pattern[pi]
 918      , f = file[fi]
 919
 920    this.debug(pattern, p, f)
 921
 922    // should be impossible.
 923    // some invalid regexp stuff in the set.
 924    if (p === false) return false
 925
 926    if (p === GLOBSTAR) {
 927      this.debug('GLOBSTAR', [pattern, p, f])
 928
 929      // "**"
 930      // a/**/b/**/c would match the following:
 931      // a/b/x/y/z/c
 932      // a/x/y/z/b/c
 933      // a/b/x/b/x/c
 934      // a/b/c
 935      // To do this, take the rest of the pattern after
 936      // the **, and see if it would match the file remainder.
 937      // If so, return success.
 938      // If not, the ** "swallows" a segment, and try again.
 939      // This is recursively awful.
 940      //
 941      // a/**/b/**/c matching a/b/x/y/z/c
 942      // - a matches a
 943      // - doublestar
 944      //   - matchOne(b/x/y/z/c, b/**/c)
 945      //     - b matches b
 946      //     - doublestar
 947      //       - matchOne(x/y/z/c, c) -> no
 948      //       - matchOne(y/z/c, c) -> no
 949      //       - matchOne(z/c, c) -> no
 950      //       - matchOne(c, c) yes, hit
 951      var fr = fi
 952        , pr = pi + 1
 953      if (pr === pl) {
 954        this.debug('** at the end')
 955        // a ** at the end will just swallow the rest.
 956        // We have found a match.
 957        // however, it will not swallow /.x, unless
 958        // options.dot is set.
 959        // . and .. are *never* matched by **, for explosively
 960        // exponential reasons.
 961        for ( ; fi < fl; fi ++) {
 962          if (file[fi] === "." || file[fi] === ".." ||
 963              (!options.dot && file[fi].charAt(0) === ".")) return false
 964        }
 965        return true
 966      }
 967
 968      // ok, let's see if we can swallow whatever we can.
 969      WHILE: while (fr < fl) {
 970        var swallowee = file[fr]
 971
 972        this.debug('\nglobstar while',
 973                    file, fr, pattern, pr, swallowee)
 974
 975        // XXX remove this slice.  Just pass the start index.
 976        if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) {
 977          this.debug('globstar found match!', fr, fl, swallowee)
 978          // found a match.
 979          return true
 980        } else {
 981          // can't swallow "." or ".." ever.
 982          // can only swallow ".foo" when explicitly asked.
 983          if (swallowee === "." || swallowee === ".." ||
 984              (!options.dot && swallowee.charAt(0) === ".")) {
 985            this.debug("dot detected!", file, fr, pattern, pr)
 986            break WHILE
 987          }
 988
 989          // ** swallows a segment, and continue.
 990          this.debug('globstar swallow a segment, and continue')
 991          fr ++
 992        }
 993      }
 994      // no match was found.
 995      // However, in partial mode, we can't say this is necessarily over.
 996      // If there's more *pattern* left, then
 997      if (partial) {
 998        // ran out of file
 999        this.debug("\n>>> no match, partial?", file, fr, pattern, pr)
1000        if (fr === fl) return true
1001      }
1002      return false
1003    }
1004
1005    // something other than **
1006    // non-magic patterns just have to match exactly
1007    // patterns with magic have been turned into regexps.
1008    var hit
1009    if (typeof p === "string") {
1010      if (options.nocase) {
1011        hit = f.toLowerCase() === p.toLowerCase()
1012      } else {
1013        hit = f === p
1014      }
1015      this.debug("string match", p, f, hit)
1016    } else {
1017      hit = f.match(p)
1018      this.debug("pattern match", p, f, hit)
1019    }
1020
1021    if (!hit) return false
1022  }
1023
1024  // Note: ending in / means that we'll get a final ""
1025  // at the end of the pattern.  This can only match a
1026  // corresponding "" at the end of the file.
1027  // If the file ends in /, then it can only match a
1028  // a pattern that ends in /, unless the pattern just
1029  // doesn't have any more for it. But, a/b/ should *not*
1030  // match "a/b/*", even though "" matches against the
1031  // [^/]*? pattern, except in partial mode, where it might
1032  // simply not be reached yet.
1033  // However, a/b/ should still satisfy a/*
1034
1035  // now either we fell off the end of the pattern, or we're done.
1036  if (fi === fl && pi === pl) {
1037    // ran out of pattern and filename at the same time.
1038    // an exact hit!
1039    return true
1040  } else if (fi === fl) {
1041    // ran out of file, but still had pattern left.
1042    // this is ok if we're doing the match as part of
1043    // a glob fs traversal.
1044    return partial
1045  } else if (pi === pl) {
1046    // ran out of pattern, still have file left.
1047    // this is only acceptable if we're on the very last
1048    // empty segment of a file with a trailing slash.
1049    // a/* should match a/b/
1050    var emptyFileEnd = (fi === fl - 1) && (file[fi] === "")
1051    return emptyFileEnd
1052  }
1053
1054  // should be unreachable.
1055  throw new Error("wtf?")
1056}
1057
1058
1059// replace stuff like \* with *
1060function globUnescape (s) {
1061  return s.replace(/\\(.)/g, "$1")
1062}
1063
1064
1065function regExpEscape (s) {
1066  return s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&")
1067}
1068
1069})( typeof require === "function" ? require : null,
1070    this,
1071    typeof module === "object" ? module : null,
1072    typeof process === "object" ? process.platform : "win32"
1073  )