Bug:Fix file validation issue
[vnfsdk/refrepo.git] / vnfmarket / src / main / webapp / vnfmarket / node_modules / fileset / node_modules / minimatch / minimatch.js
1 ;(function (require, exports, module, platform) {
2
3 if (module) module.exports = minimatch
4 else exports.minimatch = minimatch
5
6 if (!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
33 minimatch.Minimatch = Minimatch
34
35 var LRU = require("lru-cache")
36   , cache = minimatch.cache = new LRU({max: 100})
37   , GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {}
38   , sigmund = require("sigmund")
39
40 var 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 }
61 function charSet (s) {
62   return s.split("").reduce(function (set, c) {
63     set[c] = true
64     return set
65   }, {})
66 }
67
68 // normalizes slashes.
69 var slashSplit = /\/+/
70
71 minimatch.filter = filter
72 function filter (pattern, options) {
73   options = options || {}
74   return function (p, i, list) {
75     return minimatch(p, pattern, options)
76   }
77 }
78
79 function 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
92 minimatch.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
108 Minimatch.defaults = function (def) {
109   if (!def || !Object.keys(def).length) return Minimatch
110   return minimatch.defaults(def).Minimatch
111 }
112
113
114 function 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
132 function 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
170 Minimatch.prototype.debug = function() {}
171
172 Minimatch.prototype.make = make
173 function 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
228 Minimatch.prototype.parseNegate = parseNegate
229 function 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
258 minimatch.braceExpand = function (pattern, options) {
259   return new Minimatch(pattern, options).braceExpand()
260 }
261
262 Minimatch.prototype.braceExpand = braceExpand
263
264 function 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
270 function 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.
479 Minimatch.prototype.parse = parse
480 var SUBPARSE = {}
481 function 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
781 minimatch.makeRe = function (pattern, options) {
782   return new Minimatch(pattern, options || {}).makeRe()
783 }
784
785 Minimatch.prototype.makeRe = makeRe
786 function 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
827 minimatch.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
839 Minimatch.prototype.match = match
840 function 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.
899 Minimatch.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 *
1060 function globUnescape (s) {
1061   return s.replace(/\\(.)/g, "$1")
1062 }
1063
1064
1065 function 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   )