UNPKG

111 kBJavaScriptView Raw
1import path, { extname, sep, resolve } from 'path';
2import { walk } from 'estree-walker';
3import util from 'util';
4
5const addExtension = function addExtension(filename, ext = '.js') {
6 if (!extname(filename))
7 filename += ext;
8 return filename;
9};
10
11const extractors = {
12 ArrayPattern(names, param) {
13 for (const element of param.elements) {
14 if (element)
15 extractors[element.type](names, element);
16 }
17 },
18 AssignmentPattern(names, param) {
19 extractors[param.left.type](names, param.left);
20 },
21 Identifier(names, param) {
22 names.push(param.name);
23 },
24 MemberExpression() { },
25 ObjectPattern(names, param) {
26 for (const prop of param.properties) {
27 if (prop.type === 'RestElement') {
28 extractors.RestElement(names, prop);
29 }
30 else {
31 extractors[prop.value.type](names, prop.value);
32 }
33 }
34 },
35 RestElement(names, param) {
36 extractors[param.argument.type](names, param.argument);
37 }
38};
39const extractAssignedNames = function extractAssignedNames(param) {
40 const names = [];
41 extractors[param.type](names, param);
42 return names;
43};
44
45const blockDeclarations = {
46 const: true,
47 let: true
48};
49class Scope {
50 constructor(options = {}) {
51 this.parent = options.parent;
52 this.isBlockScope = !!options.block;
53 this.declarations = Object.create(null);
54 if (options.params) {
55 options.params.forEach(param => {
56 extractAssignedNames(param).forEach(name => {
57 this.declarations[name] = true;
58 });
59 });
60 }
61 }
62 addDeclaration(node, isBlockDeclaration, isVar) {
63 if (!isBlockDeclaration && this.isBlockScope) {
64 // it's a `var` or function node, and this
65 // is a block scope, so we need to go up
66 this.parent.addDeclaration(node, isBlockDeclaration, isVar);
67 }
68 else if (node.id) {
69 extractAssignedNames(node.id).forEach(name => {
70 this.declarations[name] = true;
71 });
72 }
73 }
74 contains(name) {
75 return this.declarations[name] || (this.parent ? this.parent.contains(name) : false);
76 }
77}
78const attachScopes = function attachScopes(ast, propertyName = 'scope') {
79 let scope = new Scope();
80 walk(ast, {
81 enter(node, parent) {
82 // function foo () {...}
83 // class Foo {...}
84 if (/(Function|Class)Declaration/.test(node.type)) {
85 scope.addDeclaration(node, false, false);
86 }
87 // var foo = 1
88 if (node.type === 'VariableDeclaration') {
89 const kind = node.kind;
90 const isBlockDeclaration = blockDeclarations[kind];
91 node.declarations.forEach((declaration) => {
92 scope.addDeclaration(declaration, isBlockDeclaration, true);
93 });
94 }
95 let newScope;
96 // create new function scope
97 if (/Function/.test(node.type)) {
98 newScope = new Scope({
99 parent: scope,
100 block: false,
101 params: node.params
102 });
103 // named function expressions - the name is considered
104 // part of the function's scope
105 if (node.type === 'FunctionExpression' && node.id) {
106 newScope.addDeclaration(node, false, false);
107 }
108 }
109 // create new block scope
110 if (node.type === 'BlockStatement' && !/Function/.test(parent.type)) {
111 newScope = new Scope({
112 parent: scope,
113 block: true
114 });
115 }
116 // catch clause has its own block scope
117 if (node.type === 'CatchClause') {
118 newScope = new Scope({
119 parent: scope,
120 params: node.param ? [node.param] : [],
121 block: true
122 });
123 }
124 if (newScope) {
125 Object.defineProperty(node, propertyName, {
126 value: newScope,
127 configurable: true
128 });
129 scope = newScope;
130 }
131 },
132 leave(node) {
133 if (node[propertyName])
134 scope = scope.parent;
135 }
136 });
137 return scope;
138};
139
140function createCommonjsModule(fn, module) {
141 return module = { exports: {} }, fn(module, module.exports), module.exports;
142}
143
144var utils = createCommonjsModule(function (module, exports) {
145 exports.isInteger = num => {
146 if (typeof num === 'number') {
147 return Number.isInteger(num);
148 }
149 if (typeof num === 'string' && num.trim() !== '') {
150 return Number.isInteger(Number(num));
151 }
152 return false;
153 };
154 /**
155 * Find a node of the given type
156 */
157 exports.find = (node, type) => node.nodes.find(node => node.type === type);
158 /**
159 * Find a node of the given type
160 */
161 exports.exceedsLimit = (min, max, step = 1, limit) => {
162 if (limit === false)
163 return false;
164 if (!exports.isInteger(min) || !exports.isInteger(max))
165 return false;
166 return ((Number(max) - Number(min)) / Number(step)) >= limit;
167 };
168 /**
169 * Escape the given node with '\\' before node.value
170 */
171 exports.escapeNode = (block, n = 0, type) => {
172 let node = block.nodes[n];
173 if (!node)
174 return;
175 if ((type && node.type === type) || node.type === 'open' || node.type === 'close') {
176 if (node.escaped !== true) {
177 node.value = '\\' + node.value;
178 node.escaped = true;
179 }
180 }
181 };
182 /**
183 * Returns true if the given brace node should be enclosed in literal braces
184 */
185 exports.encloseBrace = node => {
186 if (node.type !== 'brace')
187 return false;
188 if ((node.commas >> 0 + node.ranges >> 0) === 0) {
189 node.invalid = true;
190 return true;
191 }
192 return false;
193 };
194 /**
195 * Returns true if a brace node is invalid.
196 */
197 exports.isInvalidBrace = block => {
198 if (block.type !== 'brace')
199 return false;
200 if (block.invalid === true || block.dollar)
201 return true;
202 if ((block.commas >> 0 + block.ranges >> 0) === 0) {
203 block.invalid = true;
204 return true;
205 }
206 if (block.open !== true || block.close !== true) {
207 block.invalid = true;
208 return true;
209 }
210 return false;
211 };
212 /**
213 * Returns true if a node is an open or close node
214 */
215 exports.isOpenOrClose = node => {
216 if (node.type === 'open' || node.type === 'close') {
217 return true;
218 }
219 return node.open === true || node.close === true;
220 };
221 /**
222 * Reduce an array of text nodes.
223 */
224 exports.reduce = nodes => nodes.reduce((acc, node) => {
225 if (node.type === 'text')
226 acc.push(node.value);
227 if (node.type === 'range')
228 node.type = 'text';
229 return acc;
230 }, []);
231 /**
232 * Flatten an array
233 */
234 exports.flatten = (...args) => {
235 const result = [];
236 const flat = arr => {
237 for (let i = 0; i < arr.length; i++) {
238 let ele = arr[i];
239 Array.isArray(ele) ? flat(ele, result) : ele !== void 0 && result.push(ele);
240 }
241 return result;
242 };
243 flat(args);
244 return result;
245 };
246});
247var utils_1 = utils.isInteger;
248var utils_2 = utils.find;
249var utils_3 = utils.exceedsLimit;
250var utils_4 = utils.escapeNode;
251var utils_5 = utils.encloseBrace;
252var utils_6 = utils.isInvalidBrace;
253var utils_7 = utils.isOpenOrClose;
254var utils_8 = utils.reduce;
255var utils_9 = utils.flatten;
256
257var stringify = (ast, options = {}) => {
258 let stringify = (node, parent = {}) => {
259 let invalidBlock = options.escapeInvalid && utils.isInvalidBrace(parent);
260 let invalidNode = node.invalid === true && options.escapeInvalid === true;
261 let output = '';
262 if (node.value) {
263 if ((invalidBlock || invalidNode) && utils.isOpenOrClose(node)) {
264 return '\\' + node.value;
265 }
266 return node.value;
267 }
268 if (node.value) {
269 return node.value;
270 }
271 if (node.nodes) {
272 for (let child of node.nodes) {
273 output += stringify(child);
274 }
275 }
276 return output;
277 };
278 return stringify(ast);
279};
280
281/*!
282 * is-number <https://github.com/jonschlinkert/is-number>
283 *
284 * Copyright (c) 2014-present, Jon Schlinkert.
285 * Released under the MIT License.
286 */
287var isNumber = function (num) {
288 if (typeof num === 'number') {
289 return num - num === 0;
290 }
291 if (typeof num === 'string' && num.trim() !== '') {
292 return Number.isFinite ? Number.isFinite(+num) : isFinite(+num);
293 }
294 return false;
295};
296
297const toRegexRange = (min, max, options) => {
298 if (isNumber(min) === false) {
299 throw new TypeError('toRegexRange: expected the first argument to be a number');
300 }
301 if (max === void 0 || min === max) {
302 return String(min);
303 }
304 if (isNumber(max) === false) {
305 throw new TypeError('toRegexRange: expected the second argument to be a number.');
306 }
307 let opts = Object.assign({ relaxZeros: true }, options);
308 if (typeof opts.strictZeros === 'boolean') {
309 opts.relaxZeros = opts.strictZeros === false;
310 }
311 let relax = String(opts.relaxZeros);
312 let shorthand = String(opts.shorthand);
313 let capture = String(opts.capture);
314 let wrap = String(opts.wrap);
315 let cacheKey = min + ':' + max + '=' + relax + shorthand + capture + wrap;
316 if (toRegexRange.cache.hasOwnProperty(cacheKey)) {
317 return toRegexRange.cache[cacheKey].result;
318 }
319 let a = Math.min(min, max);
320 let b = Math.max(min, max);
321 if (Math.abs(a - b) === 1) {
322 let result = min + '|' + max;
323 if (opts.capture) {
324 return `(${result})`;
325 }
326 if (opts.wrap === false) {
327 return result;
328 }
329 return `(?:${result})`;
330 }
331 let isPadded = hasPadding(min) || hasPadding(max);
332 let state = { min, max, a, b };
333 let positives = [];
334 let negatives = [];
335 if (isPadded) {
336 state.isPadded = isPadded;
337 state.maxLen = String(state.max).length;
338 }
339 if (a < 0) {
340 let newMin = b < 0 ? Math.abs(b) : 1;
341 negatives = splitToPatterns(newMin, Math.abs(a), state, opts);
342 a = state.a = 0;
343 }
344 if (b >= 0) {
345 positives = splitToPatterns(a, b, state, opts);
346 }
347 state.negatives = negatives;
348 state.positives = positives;
349 state.result = collatePatterns(negatives, positives, opts);
350 if (opts.capture === true) {
351 state.result = `(${state.result})`;
352 }
353 else if (opts.wrap !== false && (positives.length + negatives.length) > 1) {
354 state.result = `(?:${state.result})`;
355 }
356 toRegexRange.cache[cacheKey] = state;
357 return state.result;
358};
359function collatePatterns(neg, pos, options) {
360 let onlyNegative = filterPatterns(neg, pos, '-', false, options) || [];
361 let onlyPositive = filterPatterns(pos, neg, '', false, options) || [];
362 let intersected = filterPatterns(neg, pos, '-?', true, options) || [];
363 let subpatterns = onlyNegative.concat(intersected).concat(onlyPositive);
364 return subpatterns.join('|');
365}
366function splitToRanges(min, max) {
367 let nines = 1;
368 let zeros = 1;
369 let stop = countNines(min, nines);
370 let stops = new Set([max]);
371 while (min <= stop && stop <= max) {
372 stops.add(stop);
373 nines += 1;
374 stop = countNines(min, nines);
375 }
376 stop = countZeros(max + 1, zeros) - 1;
377 while (min < stop && stop <= max) {
378 stops.add(stop);
379 zeros += 1;
380 stop = countZeros(max + 1, zeros) - 1;
381 }
382 stops = [...stops];
383 stops.sort(compare);
384 return stops;
385}
386/**
387 * Convert a range to a regex pattern
388 * @param {Number} `start`
389 * @param {Number} `stop`
390 * @return {String}
391 */
392function rangeToPattern(start, stop, options) {
393 if (start === stop) {
394 return { pattern: start, count: [], digits: 0 };
395 }
396 let zipped = zip(start, stop);
397 let digits = zipped.length;
398 let pattern = '';
399 let count = 0;
400 for (let i = 0; i < digits; i++) {
401 let [startDigit, stopDigit] = zipped[i];
402 if (startDigit === stopDigit) {
403 pattern += startDigit;
404 }
405 else if (startDigit !== '0' || stopDigit !== '9') {
406 pattern += toCharacterClass(startDigit, stopDigit, options);
407 }
408 else {
409 count++;
410 }
411 }
412 if (count) {
413 pattern += options.shorthand === true ? '\\d' : '[0-9]';
414 }
415 return { pattern, count: [count], digits };
416}
417function splitToPatterns(min, max, tok, options) {
418 let ranges = splitToRanges(min, max);
419 let tokens = [];
420 let start = min;
421 let prev;
422 for (let i = 0; i < ranges.length; i++) {
423 let max = ranges[i];
424 let obj = rangeToPattern(String(start), String(max), options);
425 let zeros = '';
426 if (!tok.isPadded && prev && prev.pattern === obj.pattern) {
427 if (prev.count.length > 1) {
428 prev.count.pop();
429 }
430 prev.count.push(obj.count[0]);
431 prev.string = prev.pattern + toQuantifier(prev.count);
432 start = max + 1;
433 continue;
434 }
435 if (tok.isPadded) {
436 zeros = padZeros(max, tok, options);
437 }
438 obj.string = zeros + obj.pattern + toQuantifier(obj.count);
439 tokens.push(obj);
440 start = max + 1;
441 prev = obj;
442 }
443 return tokens;
444}
445function filterPatterns(arr, comparison, prefix, intersection, options) {
446 let result = [];
447 for (let ele of arr) {
448 let { string } = ele;
449 // only push if _both_ are negative...
450 if (!intersection && !contains(comparison, 'string', string)) {
451 result.push(prefix + string);
452 }
453 // or _both_ are positive
454 if (intersection && contains(comparison, 'string', string)) {
455 result.push(prefix + string);
456 }
457 }
458 return result;
459}
460/**
461 * Zip strings
462 */
463function zip(a, b) {
464 let arr = [];
465 for (let i = 0; i < a.length; i++)
466 arr.push([a[i], b[i]]);
467 return arr;
468}
469function compare(a, b) {
470 return a > b ? 1 : b > a ? -1 : 0;
471}
472function contains(arr, key, val) {
473 return arr.some(ele => ele[key] === val);
474}
475function countNines(min, len) {
476 return Number(String(min).slice(0, -len) + '9'.repeat(len));
477}
478function countZeros(integer, zeros) {
479 return integer - (integer % Math.pow(10, zeros));
480}
481function toQuantifier(digits) {
482 let [start = 0, stop = ''] = digits;
483 if (stop || start > 1) {
484 return `{${start + (stop ? ',' + stop : '')}}`;
485 }
486 return '';
487}
488function toCharacterClass(a, b, options) {
489 return `[${a}${(b - a === 1) ? '' : '-'}${b}]`;
490}
491function hasPadding(str) {
492 return /^-?(0+)\d/.test(str);
493}
494function padZeros(value, tok, options) {
495 if (!tok.isPadded) {
496 return value;
497 }
498 let diff = Math.abs(tok.maxLen - String(value).length);
499 let relax = options.relaxZeros !== false;
500 switch (diff) {
501 case 0:
502 return '';
503 case 1:
504 return relax ? '0?' : '0';
505 case 2:
506 return relax ? '0{0,2}' : '00';
507 default: {
508 return relax ? `0{0,${diff}}` : `0{${diff}}`;
509 }
510 }
511}
512/**
513 * Cache
514 */
515toRegexRange.cache = {};
516toRegexRange.clearCache = () => (toRegexRange.cache = {});
517/**
518 * Expose `toRegexRange`
519 */
520var toRegexRange_1 = toRegexRange;
521
522const isObject = val => val !== null && typeof val === 'object' && !Array.isArray(val);
523const transform = toNumber => {
524 return value => toNumber === true ? Number(value) : String(value);
525};
526const isValidValue = value => {
527 return typeof value === 'number' || (typeof value === 'string' && value !== '');
528};
529const isNumber$1 = num => Number.isInteger(+num);
530const zeros = input => {
531 let value = `${input}`;
532 let index = -1;
533 if (value[0] === '-')
534 value = value.slice(1);
535 if (value === '0')
536 return false;
537 while (value[++index] === '0')
538 ;
539 return index > 0;
540};
541const stringify$1 = (start, end, options) => {
542 if (typeof start === 'string' || typeof end === 'string') {
543 return true;
544 }
545 return options.stringify === true;
546};
547const pad = (input, maxLength, toNumber) => {
548 if (maxLength > 0) {
549 let dash = input[0] === '-' ? '-' : '';
550 if (dash)
551 input = input.slice(1);
552 input = (dash + input.padStart(dash ? maxLength - 1 : maxLength, '0'));
553 }
554 if (toNumber === false) {
555 return String(input);
556 }
557 return input;
558};
559const toMaxLen = (input, maxLength) => {
560 let negative = input[0] === '-' ? '-' : '';
561 if (negative) {
562 input = input.slice(1);
563 maxLength--;
564 }
565 while (input.length < maxLength)
566 input = '0' + input;
567 return negative ? ('-' + input) : input;
568};
569const toSequence = (parts, options) => {
570 parts.negatives.sort((a, b) => a < b ? -1 : a > b ? 1 : 0);
571 parts.positives.sort((a, b) => a < b ? -1 : a > b ? 1 : 0);
572 let prefix = options.capture ? '' : '?:';
573 let positives = '';
574 let negatives = '';
575 let result;
576 if (parts.positives.length) {
577 positives = parts.positives.join('|');
578 }
579 if (parts.negatives.length) {
580 negatives = `-(${prefix}${parts.negatives.join('|')})`;
581 }
582 if (positives && negatives) {
583 result = `${positives}|${negatives}`;
584 }
585 else {
586 result = positives || negatives;
587 }
588 if (options.wrap) {
589 return `(${prefix}${result})`;
590 }
591 return result;
592};
593const toRange = (a, b, isNumbers, options) => {
594 if (isNumbers) {
595 return toRegexRange_1(a, b, Object.assign({ wrap: false }, options));
596 }
597 let start = String.fromCharCode(a);
598 if (a === b)
599 return start;
600 let stop = String.fromCharCode(b);
601 return `[${start}-${stop}]`;
602};
603const toRegex = (start, end, options) => {
604 if (Array.isArray(start)) {
605 let wrap = options.wrap === true;
606 let prefix = options.capture ? '' : '?:';
607 return wrap ? `(${prefix}${start.join('|')})` : start.join('|');
608 }
609 return toRegexRange_1(start, end, options);
610};
611const rangeError = (...args) => {
612 return new RangeError('Invalid range arguments: ' + util.inspect(...args));
613};
614const invalidRange = (start, end, options) => {
615 if (options.strictRanges === true)
616 throw rangeError([start, end]);
617 return [];
618};
619const invalidStep = (step, options) => {
620 if (options.strictRanges === true) {
621 throw new TypeError(`Expected step "${step}" to be a number`);
622 }
623 return [];
624};
625const fillNumbers = (start, end, step = 1, options = {}) => {
626 let a = Number(start);
627 let b = Number(end);
628 if (!Number.isInteger(a) || !Number.isInteger(b)) {
629 if (options.strictRanges === true)
630 throw rangeError([start, end]);
631 return [];
632 }
633 // fix negative zero
634 if (a === 0)
635 a = 0;
636 if (b === 0)
637 b = 0;
638 let descending = a > b;
639 let startString = String(start);
640 let endString = String(end);
641 let stepString = String(step);
642 step = Math.max(Math.abs(step), 1);
643 let padded = zeros(startString) || zeros(endString) || zeros(stepString);
644 let maxLen = padded ? Math.max(startString.length, endString.length, stepString.length) : 0;
645 let toNumber = padded === false && stringify$1(start, end, options) === false;
646 let format = options.transform || transform(toNumber);
647 if (options.toRegex && step === 1) {
648 return toRange(toMaxLen(start, maxLen), toMaxLen(end, maxLen), true, options);
649 }
650 let parts = { negatives: [], positives: [] };
651 let push = num => parts[num < 0 ? 'negatives' : 'positives'].push(Math.abs(num));
652 let range = [];
653 let index = 0;
654 while (descending ? a >= b : a <= b) {
655 if (options.toRegex === true && step > 1) {
656 push(a);
657 }
658 else {
659 range.push(pad(format(a, index), maxLen, toNumber));
660 }
661 a = descending ? a - step : a + step;
662 index++;
663 }
664 if (options.toRegex === true) {
665 return step > 1
666 ? toSequence(parts, options)
667 : toRegex(range, null, Object.assign({ wrap: false }, options));
668 }
669 return range;
670};
671const fillLetters = (start, end, step = 1, options = {}) => {
672 if ((!isNumber$1(start) && start.length > 1) || (!isNumber$1(end) && end.length > 1)) {
673 return invalidRange(start, end, options);
674 }
675 let format = options.transform || (val => String.fromCharCode(val));
676 let a = `${start}`.charCodeAt(0);
677 let b = `${end}`.charCodeAt(0);
678 let descending = a > b;
679 let min = Math.min(a, b);
680 let max = Math.max(a, b);
681 if (options.toRegex && step === 1) {
682 return toRange(min, max, false, options);
683 }
684 let range = [];
685 let index = 0;
686 while (descending ? a >= b : a <= b) {
687 range.push(format(a, index));
688 a = descending ? a - step : a + step;
689 index++;
690 }
691 if (options.toRegex === true) {
692 return toRegex(range, null, { wrap: false, options });
693 }
694 return range;
695};
696const fill = (start, end, step, options = {}) => {
697 if (end == null && isValidValue(start)) {
698 return [start];
699 }
700 if (!isValidValue(start) || !isValidValue(end)) {
701 return invalidRange(start, end, options);
702 }
703 if (typeof step === 'function') {
704 return fill(start, end, 1, { transform: step });
705 }
706 if (isObject(step)) {
707 return fill(start, end, 0, step);
708 }
709 let opts = Object.assign({}, options);
710 if (opts.capture === true)
711 opts.wrap = true;
712 step = step || opts.step || 1;
713 if (!isNumber$1(step)) {
714 if (step != null && !isObject(step))
715 return invalidStep(step, opts);
716 return fill(start, end, 1, step);
717 }
718 if (isNumber$1(start) && isNumber$1(end)) {
719 return fillNumbers(start, end, step, opts);
720 }
721 return fillLetters(start, end, Math.max(Math.abs(step), 1), opts);
722};
723var fillRange = fill;
724
725const compile = (ast, options = {}) => {
726 let walk = (node, parent = {}) => {
727 let invalidBlock = utils.isInvalidBrace(parent);
728 let invalidNode = node.invalid === true && options.escapeInvalid === true;
729 let invalid = invalidBlock === true || invalidNode === true;
730 let prefix = options.escapeInvalid === true ? '\\' : '';
731 let output = '';
732 if (node.isOpen === true) {
733 return prefix + node.value;
734 }
735 if (node.isClose === true) {
736 return prefix + node.value;
737 }
738 if (node.type === 'open') {
739 return invalid ? (prefix + node.value) : '(';
740 }
741 if (node.type === 'close') {
742 return invalid ? (prefix + node.value) : ')';
743 }
744 if (node.type === 'comma') {
745 return node.prev.type === 'comma' ? '' : (invalid ? node.value : '|');
746 }
747 if (node.value) {
748 return node.value;
749 }
750 if (node.nodes && node.ranges > 0) {
751 let args = utils.reduce(node.nodes);
752 let range = fillRange(...args, Object.assign({}, options, { wrap: false, toRegex: true }));
753 if (range.length !== 0) {
754 return args.length > 1 && range.length > 1 ? `(${range})` : range;
755 }
756 }
757 if (node.nodes) {
758 for (let child of node.nodes) {
759 output += walk(child, node);
760 }
761 }
762 return output;
763 };
764 return walk(ast);
765};
766var compile_1 = compile;
767
768const append = (queue = '', stash = '', enclose = false) => {
769 let result = [];
770 queue = [].concat(queue);
771 stash = [].concat(stash);
772 if (!stash.length)
773 return queue;
774 if (!queue.length) {
775 return enclose ? utils.flatten(stash).map(ele => `{${ele}}`) : stash;
776 }
777 for (let item of queue) {
778 if (Array.isArray(item)) {
779 for (let value of item) {
780 result.push(append(value, stash, enclose));
781 }
782 }
783 else {
784 for (let ele of stash) {
785 if (enclose === true && typeof ele === 'string')
786 ele = `{${ele}}`;
787 result.push(Array.isArray(ele) ? append(item, ele, enclose) : (item + ele));
788 }
789 }
790 }
791 return utils.flatten(result);
792};
793const expand = (ast, options = {}) => {
794 let rangeLimit = options.rangeLimit === void 0 ? 1000 : options.rangeLimit;
795 let walk = (node, parent = {}) => {
796 node.queue = [];
797 let p = parent;
798 let q = parent.queue;
799 while (p.type !== 'brace' && p.type !== 'root' && p.parent) {
800 p = p.parent;
801 q = p.queue;
802 }
803 if (node.invalid || node.dollar) {
804 q.push(append(q.pop(), stringify(node, options)));
805 return;
806 }
807 if (node.type === 'brace' && node.invalid !== true && node.nodes.length === 2) {
808 q.push(append(q.pop(), ['{}']));
809 return;
810 }
811 if (node.nodes && node.ranges > 0) {
812 let args = utils.reduce(node.nodes);
813 if (utils.exceedsLimit(...args, options.step, rangeLimit)) {
814 throw new RangeError('expanded array length exceeds range limit. Use options.rangeLimit to increase or disable the limit.');
815 }
816 let range = fillRange(...args, options);
817 if (range.length === 0) {
818 range = stringify(node, options);
819 }
820 q.push(append(q.pop(), range));
821 node.nodes = [];
822 return;
823 }
824 let enclose = utils.encloseBrace(node);
825 let queue = node.queue;
826 let block = node;
827 while (block.type !== 'brace' && block.type !== 'root' && block.parent) {
828 block = block.parent;
829 queue = block.queue;
830 }
831 for (let i = 0; i < node.nodes.length; i++) {
832 let child = node.nodes[i];
833 if (child.type === 'comma' && node.type === 'brace') {
834 if (i === 1)
835 queue.push('');
836 queue.push('');
837 continue;
838 }
839 if (child.type === 'close') {
840 q.push(append(q.pop(), queue, enclose));
841 continue;
842 }
843 if (child.value && child.type !== 'open') {
844 queue.push(append(queue.pop(), child.value));
845 continue;
846 }
847 if (child.nodes) {
848 walk(child, node);
849 }
850 }
851 return queue;
852 };
853 return utils.flatten(walk(ast));
854};
855var expand_1 = expand;
856
857var constants = {
858 MAX_LENGTH: 1024 * 64,
859 // Digits
860 CHAR_0: '0',
861 CHAR_9: '9',
862 // Alphabet chars.
863 CHAR_UPPERCASE_A: 'A',
864 CHAR_LOWERCASE_A: 'a',
865 CHAR_UPPERCASE_Z: 'Z',
866 CHAR_LOWERCASE_Z: 'z',
867 CHAR_LEFT_PARENTHESES: '(',
868 CHAR_RIGHT_PARENTHESES: ')',
869 CHAR_ASTERISK: '*',
870 // Non-alphabetic chars.
871 CHAR_AMPERSAND: '&',
872 CHAR_AT: '@',
873 CHAR_BACKSLASH: '\\',
874 CHAR_BACKTICK: '`',
875 CHAR_CARRIAGE_RETURN: '\r',
876 CHAR_CIRCUMFLEX_ACCENT: '^',
877 CHAR_COLON: ':',
878 CHAR_COMMA: ',',
879 CHAR_DOLLAR: '$',
880 CHAR_DOT: '.',
881 CHAR_DOUBLE_QUOTE: '"',
882 CHAR_EQUAL: '=',
883 CHAR_EXCLAMATION_MARK: '!',
884 CHAR_FORM_FEED: '\f',
885 CHAR_FORWARD_SLASH: '/',
886 CHAR_HASH: '#',
887 CHAR_HYPHEN_MINUS: '-',
888 CHAR_LEFT_ANGLE_BRACKET: '<',
889 CHAR_LEFT_CURLY_BRACE: '{',
890 CHAR_LEFT_SQUARE_BRACKET: '[',
891 CHAR_LINE_FEED: '\n',
892 CHAR_NO_BREAK_SPACE: '\u00A0',
893 CHAR_PERCENT: '%',
894 CHAR_PLUS: '+',
895 CHAR_QUESTION_MARK: '?',
896 CHAR_RIGHT_ANGLE_BRACKET: '>',
897 CHAR_RIGHT_CURLY_BRACE: '}',
898 CHAR_RIGHT_SQUARE_BRACKET: ']',
899 CHAR_SEMICOLON: ';',
900 CHAR_SINGLE_QUOTE: '\'',
901 CHAR_SPACE: ' ',
902 CHAR_TAB: '\t',
903 CHAR_UNDERSCORE: '_',
904 CHAR_VERTICAL_LINE: '|',
905 CHAR_ZERO_WIDTH_NOBREAK_SPACE: '\uFEFF' /* \uFEFF */
906};
907
908/**
909 * Constants
910 */
911const { MAX_LENGTH, CHAR_BACKSLASH, /* \ */ CHAR_BACKTICK, /* ` */ CHAR_COMMA, /* , */ CHAR_DOT, /* . */ CHAR_LEFT_PARENTHESES, /* ( */ CHAR_RIGHT_PARENTHESES, /* ) */ CHAR_LEFT_CURLY_BRACE, /* { */ CHAR_RIGHT_CURLY_BRACE, /* } */ CHAR_LEFT_SQUARE_BRACKET, /* [ */ CHAR_RIGHT_SQUARE_BRACKET, /* ] */ CHAR_DOUBLE_QUOTE, /* " */ CHAR_SINGLE_QUOTE, /* ' */ CHAR_NO_BREAK_SPACE, CHAR_ZERO_WIDTH_NOBREAK_SPACE } = constants;
912/**
913 * parse
914 */
915const parse = (input, options = {}) => {
916 if (typeof input !== 'string') {
917 throw new TypeError('Expected a string');
918 }
919 let opts = options || {};
920 let max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH;
921 if (input.length > max) {
922 throw new SyntaxError(`Input length (${input.length}), exceeds max characters (${max})`);
923 }
924 let ast = { type: 'root', input, nodes: [] };
925 let stack = [ast];
926 let block = ast;
927 let prev = ast;
928 let brackets = 0;
929 let length = input.length;
930 let index = 0;
931 let depth = 0;
932 let value;
933 /**
934 * Helpers
935 */
936 const advance = () => input[index++];
937 const push = node => {
938 if (node.type === 'text' && prev.type === 'dot') {
939 prev.type = 'text';
940 }
941 if (prev && prev.type === 'text' && node.type === 'text') {
942 prev.value += node.value;
943 return;
944 }
945 block.nodes.push(node);
946 node.parent = block;
947 node.prev = prev;
948 prev = node;
949 return node;
950 };
951 push({ type: 'bos' });
952 while (index < length) {
953 block = stack[stack.length - 1];
954 value = advance();
955 /**
956 * Invalid chars
957 */
958 if (value === CHAR_ZERO_WIDTH_NOBREAK_SPACE || value === CHAR_NO_BREAK_SPACE) {
959 continue;
960 }
961 /**
962 * Escaped chars
963 */
964 if (value === CHAR_BACKSLASH) {
965 push({ type: 'text', value: (options.keepEscaping ? value : '') + advance() });
966 continue;
967 }
968 /**
969 * Right square bracket (literal): ']'
970 */
971 if (value === CHAR_RIGHT_SQUARE_BRACKET) {
972 push({ type: 'text', value: '\\' + value });
973 continue;
974 }
975 /**
976 * Left square bracket: '['
977 */
978 if (value === CHAR_LEFT_SQUARE_BRACKET) {
979 brackets++;
980 let next;
981 while (index < length && (next = advance())) {
982 value += next;
983 if (next === CHAR_LEFT_SQUARE_BRACKET) {
984 brackets++;
985 continue;
986 }
987 if (next === CHAR_BACKSLASH) {
988 value += advance();
989 continue;
990 }
991 if (next === CHAR_RIGHT_SQUARE_BRACKET) {
992 brackets--;
993 if (brackets === 0) {
994 break;
995 }
996 }
997 }
998 push({ type: 'text', value });
999 continue;
1000 }
1001 /**
1002 * Parentheses
1003 */
1004 if (value === CHAR_LEFT_PARENTHESES) {
1005 block = push({ type: 'paren', nodes: [] });
1006 stack.push(block);
1007 push({ type: 'text', value });
1008 continue;
1009 }
1010 if (value === CHAR_RIGHT_PARENTHESES) {
1011 if (block.type !== 'paren') {
1012 push({ type: 'text', value });
1013 continue;
1014 }
1015 block = stack.pop();
1016 push({ type: 'text', value });
1017 block = stack[stack.length - 1];
1018 continue;
1019 }
1020 /**
1021 * Quotes: '|"|`
1022 */
1023 if (value === CHAR_DOUBLE_QUOTE || value === CHAR_SINGLE_QUOTE || value === CHAR_BACKTICK) {
1024 let open = value;
1025 let next;
1026 if (options.keepQuotes !== true) {
1027 value = '';
1028 }
1029 while (index < length && (next = advance())) {
1030 if (next === CHAR_BACKSLASH) {
1031 value += next + advance();
1032 continue;
1033 }
1034 if (next === open) {
1035 if (options.keepQuotes === true)
1036 value += next;
1037 break;
1038 }
1039 value += next;
1040 }
1041 push({ type: 'text', value });
1042 continue;
1043 }
1044 /**
1045 * Left curly brace: '{'
1046 */
1047 if (value === CHAR_LEFT_CURLY_BRACE) {
1048 depth++;
1049 let dollar = prev.value && prev.value.slice(-1) === '$' || block.dollar === true;
1050 let brace = {
1051 type: 'brace',
1052 open: true,
1053 close: false,
1054 dollar,
1055 depth,
1056 commas: 0,
1057 ranges: 0,
1058 nodes: []
1059 };
1060 block = push(brace);
1061 stack.push(block);
1062 push({ type: 'open', value });
1063 continue;
1064 }
1065 /**
1066 * Right curly brace: '}'
1067 */
1068 if (value === CHAR_RIGHT_CURLY_BRACE) {
1069 if (block.type !== 'brace') {
1070 push({ type: 'text', value });
1071 continue;
1072 }
1073 let type = 'close';
1074 block = stack.pop();
1075 block.close = true;
1076 push({ type, value });
1077 depth--;
1078 block = stack[stack.length - 1];
1079 continue;
1080 }
1081 /**
1082 * Comma: ','
1083 */
1084 if (value === CHAR_COMMA && depth > 0) {
1085 if (block.ranges > 0) {
1086 block.ranges = 0;
1087 let open = block.nodes.shift();
1088 block.nodes = [open, { type: 'text', value: stringify(block) }];
1089 }
1090 push({ type: 'comma', value });
1091 block.commas++;
1092 continue;
1093 }
1094 /**
1095 * Dot: '.'
1096 */
1097 if (value === CHAR_DOT && depth > 0 && block.commas === 0) {
1098 let siblings = block.nodes;
1099 if (depth === 0 || siblings.length === 0) {
1100 push({ type: 'text', value });
1101 continue;
1102 }
1103 if (prev.type === 'dot') {
1104 block.range = [];
1105 prev.value += value;
1106 prev.type = 'range';
1107 if (block.nodes.length !== 3 && block.nodes.length !== 5) {
1108 block.invalid = true;
1109 block.ranges = 0;
1110 prev.type = 'text';
1111 continue;
1112 }
1113 block.ranges++;
1114 block.args = [];
1115 continue;
1116 }
1117 if (prev.type === 'range') {
1118 siblings.pop();
1119 let before = siblings[siblings.length - 1];
1120 before.value += prev.value + value;
1121 prev = before;
1122 block.ranges--;
1123 continue;
1124 }
1125 push({ type: 'dot', value });
1126 continue;
1127 }
1128 /**
1129 * Text
1130 */
1131 push({ type: 'text', value });
1132 }
1133 // Mark imbalanced braces and brackets as invalid
1134 do {
1135 block = stack.pop();
1136 if (block.type !== 'root') {
1137 block.nodes.forEach(node => {
1138 if (!node.nodes) {
1139 if (node.type === 'open')
1140 node.isOpen = true;
1141 if (node.type === 'close')
1142 node.isClose = true;
1143 if (!node.nodes)
1144 node.type = 'text';
1145 node.invalid = true;
1146 }
1147 });
1148 // get the location of the block on parent.nodes (block's siblings)
1149 let parent = stack[stack.length - 1];
1150 let index = parent.nodes.indexOf(block);
1151 // replace the (invalid) block with it's nodes
1152 parent.nodes.splice(index, 1, ...block.nodes);
1153 }
1154 } while (stack.length > 0);
1155 push({ type: 'eos' });
1156 return ast;
1157};
1158var parse_1 = parse;
1159
1160/**
1161 * Expand the given pattern or create a regex-compatible string.
1162 *
1163 * ```js
1164 * const braces = require('braces');
1165 * console.log(braces('{a,b,c}', { compile: true })); //=> ['(a|b|c)']
1166 * console.log(braces('{a,b,c}')); //=> ['a', 'b', 'c']
1167 * ```
1168 * @param {String} `str`
1169 * @param {Object} `options`
1170 * @return {String}
1171 * @api public
1172 */
1173const braces = (input, options = {}) => {
1174 let output = [];
1175 if (Array.isArray(input)) {
1176 for (let pattern of input) {
1177 let result = braces.create(pattern, options);
1178 if (Array.isArray(result)) {
1179 output.push(...result);
1180 }
1181 else {
1182 output.push(result);
1183 }
1184 }
1185 }
1186 else {
1187 output = [].concat(braces.create(input, options));
1188 }
1189 if (options && options.expand === true && options.nodupes === true) {
1190 output = [...new Set(output)];
1191 }
1192 return output;
1193};
1194/**
1195 * Parse the given `str` with the given `options`.
1196 *
1197 * ```js
1198 * // braces.parse(pattern, [, options]);
1199 * const ast = braces.parse('a/{b,c}/d');
1200 * console.log(ast);
1201 * ```
1202 * @param {String} pattern Brace pattern to parse
1203 * @param {Object} options
1204 * @return {Object} Returns an AST
1205 * @api public
1206 */
1207braces.parse = (input, options = {}) => parse_1(input, options);
1208/**
1209 * Creates a braces string from an AST, or an AST node.
1210 *
1211 * ```js
1212 * const braces = require('braces');
1213 * let ast = braces.parse('foo/{a,b}/bar');
1214 * console.log(stringify(ast.nodes[2])); //=> '{a,b}'
1215 * ```
1216 * @param {String} `input` Brace pattern or AST.
1217 * @param {Object} `options`
1218 * @return {Array} Returns an array of expanded values.
1219 * @api public
1220 */
1221braces.stringify = (input, options = {}) => {
1222 if (typeof input === 'string') {
1223 return stringify(braces.parse(input, options), options);
1224 }
1225 return stringify(input, options);
1226};
1227/**
1228 * Compiles a brace pattern into a regex-compatible, optimized string.
1229 * This method is called by the main [braces](#braces) function by default.
1230 *
1231 * ```js
1232 * const braces = require('braces');
1233 * console.log(braces.compile('a/{b,c}/d'));
1234 * //=> ['a/(b|c)/d']
1235 * ```
1236 * @param {String} `input` Brace pattern or AST.
1237 * @param {Object} `options`
1238 * @return {Array} Returns an array of expanded values.
1239 * @api public
1240 */
1241braces.compile = (input, options = {}) => {
1242 if (typeof input === 'string') {
1243 input = braces.parse(input, options);
1244 }
1245 return compile_1(input, options);
1246};
1247/**
1248 * Expands a brace pattern into an array. This method is called by the
1249 * main [braces](#braces) function when `options.expand` is true. Before
1250 * using this method it's recommended that you read the [performance notes](#performance))
1251 * and advantages of using [.compile](#compile) instead.
1252 *
1253 * ```js
1254 * const braces = require('braces');
1255 * console.log(braces.expand('a/{b,c}/d'));
1256 * //=> ['a/b/d', 'a/c/d'];
1257 * ```
1258 * @param {String} `pattern` Brace pattern
1259 * @param {Object} `options`
1260 * @return {Array} Returns an array of expanded values.
1261 * @api public
1262 */
1263braces.expand = (input, options = {}) => {
1264 if (typeof input === 'string') {
1265 input = braces.parse(input, options);
1266 }
1267 let result = expand_1(input, options);
1268 // filter out empty strings if specified
1269 if (options.noempty === true) {
1270 result = result.filter(Boolean);
1271 }
1272 // filter out duplicates if specified
1273 if (options.nodupes === true) {
1274 result = [...new Set(result)];
1275 }
1276 return result;
1277};
1278/**
1279 * Processes a brace pattern and returns either an expanded array
1280 * (if `options.expand` is true), a highly optimized regex-compatible string.
1281 * This method is called by the main [braces](#braces) function.
1282 *
1283 * ```js
1284 * const braces = require('braces');
1285 * console.log(braces.create('user-{200..300}/project-{a,b,c}-{1..10}'))
1286 * //=> 'user-(20[0-9]|2[1-9][0-9]|300)/project-(a|b|c)-([1-9]|10)'
1287 * ```
1288 * @param {String} `pattern` Brace pattern
1289 * @param {Object} `options`
1290 * @return {Array} Returns an array of expanded values.
1291 * @api public
1292 */
1293braces.create = (input, options = {}) => {
1294 if (input === '' || input.length < 3) {
1295 return [input];
1296 }
1297 return options.expand !== true
1298 ? braces.compile(input, options)
1299 : braces.expand(input, options);
1300};
1301/**
1302 * Expose "braces"
1303 */
1304var braces_1 = braces;
1305
1306const WIN_SLASH = '\\\\/';
1307const WIN_NO_SLASH = `[^${WIN_SLASH}]`;
1308/**
1309 * Posix glob regex
1310 */
1311const DOT_LITERAL = '\\.';
1312const PLUS_LITERAL = '\\+';
1313const QMARK_LITERAL = '\\?';
1314const SLASH_LITERAL = '\\/';
1315const ONE_CHAR = '(?=.)';
1316const QMARK = '[^/]';
1317const END_ANCHOR = `(?:${SLASH_LITERAL}|$)`;
1318const START_ANCHOR = `(?:^|${SLASH_LITERAL})`;
1319const DOTS_SLASH = `${DOT_LITERAL}{1,2}${END_ANCHOR}`;
1320const NO_DOT = `(?!${DOT_LITERAL})`;
1321const NO_DOTS = `(?!${START_ANCHOR}${DOTS_SLASH})`;
1322const NO_DOT_SLASH = `(?!${DOT_LITERAL}{0,1}${END_ANCHOR})`;
1323const NO_DOTS_SLASH = `(?!${DOTS_SLASH})`;
1324const QMARK_NO_DOT = `[^.${SLASH_LITERAL}]`;
1325const STAR = `${QMARK}*?`;
1326const POSIX_CHARS = {
1327 DOT_LITERAL,
1328 PLUS_LITERAL,
1329 QMARK_LITERAL,
1330 SLASH_LITERAL,
1331 ONE_CHAR,
1332 QMARK,
1333 END_ANCHOR,
1334 DOTS_SLASH,
1335 NO_DOT,
1336 NO_DOTS,
1337 NO_DOT_SLASH,
1338 NO_DOTS_SLASH,
1339 QMARK_NO_DOT,
1340 STAR,
1341 START_ANCHOR
1342};
1343/**
1344 * Windows glob regex
1345 */
1346const WINDOWS_CHARS = Object.assign({}, POSIX_CHARS, { SLASH_LITERAL: `[${WIN_SLASH}]`, QMARK: WIN_NO_SLASH, STAR: `${WIN_NO_SLASH}*?`, DOTS_SLASH: `${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$)`, NO_DOT: `(?!${DOT_LITERAL})`, NO_DOTS: `(?!(?:^|[${WIN_SLASH}])${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`, NO_DOT_SLASH: `(?!${DOT_LITERAL}{0,1}(?:[${WIN_SLASH}]|$))`, NO_DOTS_SLASH: `(?!${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`, QMARK_NO_DOT: `[^.${WIN_SLASH}]`, START_ANCHOR: `(?:^|[${WIN_SLASH}])`, END_ANCHOR: `(?:[${WIN_SLASH}]|$)` });
1347/**
1348 * POSIX Bracket Regex
1349 */
1350const POSIX_REGEX_SOURCE = {
1351 alnum: 'a-zA-Z0-9',
1352 alpha: 'a-zA-Z',
1353 ascii: '\\x00-\\x7F',
1354 blank: ' \\t',
1355 cntrl: '\\x00-\\x1F\\x7F',
1356 digit: '0-9',
1357 graph: '\\x21-\\x7E',
1358 lower: 'a-z',
1359 print: '\\x20-\\x7E ',
1360 punct: '\\-!"#$%&\'()\\*+,./:;<=>?@[\\]^_`{|}~',
1361 space: ' \\t\\r\\n\\v\\f',
1362 upper: 'A-Z',
1363 word: 'A-Za-z0-9_',
1364 xdigit: 'A-Fa-f0-9'
1365};
1366var constants$1 = {
1367 MAX_LENGTH: 1024 * 64,
1368 POSIX_REGEX_SOURCE,
1369 // regular expressions
1370 REGEX_BACKSLASH: /\\(?![*+?^${}(|)[\]])/g,
1371 REGEX_NON_SPECIAL_CHAR: /^[^@![\].,$*+?^{}()|\\/]+/,
1372 REGEX_SPECIAL_CHARS: /[-*+?.^${}(|)[\]]/,
1373 REGEX_SPECIAL_CHARS_BACKREF: /(\\?)((\W)(\3*))/g,
1374 REGEX_SPECIAL_CHARS_GLOBAL: /([-*+?.^${}(|)[\]])/g,
1375 REGEX_REMOVE_BACKSLASH: /(?:\[.*?[^\\]\]|\\(?=.))/g,
1376 // Replace globs with equivalent patterns to reduce parsing time.
1377 REPLACEMENTS: {
1378 '***': '*',
1379 '**/**': '**',
1380 '**/**/**': '**'
1381 },
1382 // Digits
1383 CHAR_0: 48,
1384 CHAR_9: 57,
1385 // Alphabet chars.
1386 CHAR_UPPERCASE_A: 65,
1387 CHAR_LOWERCASE_A: 97,
1388 CHAR_UPPERCASE_Z: 90,
1389 CHAR_LOWERCASE_Z: 122,
1390 CHAR_LEFT_PARENTHESES: 40,
1391 CHAR_RIGHT_PARENTHESES: 41,
1392 CHAR_ASTERISK: 42,
1393 // Non-alphabetic chars.
1394 CHAR_AMPERSAND: 38,
1395 CHAR_AT: 64,
1396 CHAR_BACKWARD_SLASH: 92,
1397 CHAR_CARRIAGE_RETURN: 13,
1398 CHAR_CIRCUMFLEX_ACCENT: 94,
1399 CHAR_COLON: 58,
1400 CHAR_COMMA: 44,
1401 CHAR_DOT: 46,
1402 CHAR_DOUBLE_QUOTE: 34,
1403 CHAR_EQUAL: 61,
1404 CHAR_EXCLAMATION_MARK: 33,
1405 CHAR_FORM_FEED: 12,
1406 CHAR_FORWARD_SLASH: 47,
1407 CHAR_GRAVE_ACCENT: 96,
1408 CHAR_HASH: 35,
1409 CHAR_HYPHEN_MINUS: 45,
1410 CHAR_LEFT_ANGLE_BRACKET: 60,
1411 CHAR_LEFT_CURLY_BRACE: 123,
1412 CHAR_LEFT_SQUARE_BRACKET: 91,
1413 CHAR_LINE_FEED: 10,
1414 CHAR_NO_BREAK_SPACE: 160,
1415 CHAR_PERCENT: 37,
1416 CHAR_PLUS: 43,
1417 CHAR_QUESTION_MARK: 63,
1418 CHAR_RIGHT_ANGLE_BRACKET: 62,
1419 CHAR_RIGHT_CURLY_BRACE: 125,
1420 CHAR_RIGHT_SQUARE_BRACKET: 93,
1421 CHAR_SEMICOLON: 59,
1422 CHAR_SINGLE_QUOTE: 39,
1423 CHAR_SPACE: 32,
1424 CHAR_TAB: 9,
1425 CHAR_UNDERSCORE: 95,
1426 CHAR_VERTICAL_LINE: 124,
1427 CHAR_ZERO_WIDTH_NOBREAK_SPACE: 65279,
1428 SEP: path.sep,
1429 /**
1430 * Create EXTGLOB_CHARS
1431 */
1432 extglobChars(chars) {
1433 return {
1434 '!': { type: 'negate', open: '(?:(?!(?:', close: `))${chars.STAR})` },
1435 '?': { type: 'qmark', open: '(?:', close: ')?' },
1436 '+': { type: 'plus', open: '(?:', close: ')+' },
1437 '*': { type: 'star', open: '(?:', close: ')*' },
1438 '@': { type: 'at', open: '(?:', close: ')' }
1439 };
1440 },
1441 /**
1442 * Create GLOB_CHARS
1443 */
1444 globChars(win32) {
1445 return win32 === true ? WINDOWS_CHARS : POSIX_CHARS;
1446 }
1447};
1448
1449var utils$1 = createCommonjsModule(function (module, exports) {
1450 const win32 = process.platform === 'win32';
1451 const { REGEX_SPECIAL_CHARS, REGEX_SPECIAL_CHARS_GLOBAL, REGEX_REMOVE_BACKSLASH } = constants$1;
1452 exports.isObject = val => val !== null && typeof val === 'object' && !Array.isArray(val);
1453 exports.hasRegexChars = str => REGEX_SPECIAL_CHARS.test(str);
1454 exports.isRegexChar = str => str.length === 1 && exports.hasRegexChars(str);
1455 exports.escapeRegex = str => str.replace(REGEX_SPECIAL_CHARS_GLOBAL, '\\$1');
1456 exports.toPosixSlashes = str => str.replace(/\\/g, '/');
1457 exports.removeBackslashes = str => {
1458 return str.replace(REGEX_REMOVE_BACKSLASH, match => {
1459 return match === '\\' ? '' : match;
1460 });
1461 };
1462 exports.supportsLookbehinds = () => {
1463 let segs = process.version.slice(1).split('.');
1464 if (segs.length === 3 && +segs[0] >= 9 || (+segs[0] === 8 && +segs[1] >= 10)) {
1465 return true;
1466 }
1467 return false;
1468 };
1469 exports.isWindows = options => {
1470 if (options && typeof options.windows === 'boolean') {
1471 return options.windows;
1472 }
1473 return win32 === true || path.sep === '\\';
1474 };
1475 exports.escapeLast = (input, char, lastIdx) => {
1476 let idx = input.lastIndexOf(char, lastIdx);
1477 if (idx === -1)
1478 return input;
1479 if (input[idx - 1] === '\\')
1480 return exports.escapeLast(input, char, idx - 1);
1481 return input.slice(0, idx) + '\\' + input.slice(idx);
1482 };
1483});
1484var utils_1$1 = utils$1.isObject;
1485var utils_2$1 = utils$1.hasRegexChars;
1486var utils_3$1 = utils$1.isRegexChar;
1487var utils_4$1 = utils$1.escapeRegex;
1488var utils_5$1 = utils$1.toPosixSlashes;
1489var utils_6$1 = utils$1.removeBackslashes;
1490var utils_7$1 = utils$1.supportsLookbehinds;
1491var utils_8$1 = utils$1.isWindows;
1492var utils_9$1 = utils$1.escapeLast;
1493
1494const { CHAR_ASTERISK, /* * */ CHAR_AT, /* @ */ CHAR_BACKWARD_SLASH, /* \ */ CHAR_COMMA: CHAR_COMMA$1, /* , */ CHAR_DOT: CHAR_DOT$1, /* . */ CHAR_EXCLAMATION_MARK, /* ! */ CHAR_FORWARD_SLASH, /* / */ CHAR_LEFT_CURLY_BRACE: CHAR_LEFT_CURLY_BRACE$1, /* { */ CHAR_LEFT_PARENTHESES: CHAR_LEFT_PARENTHESES$1, /* ( */ CHAR_LEFT_SQUARE_BRACKET: CHAR_LEFT_SQUARE_BRACKET$1, /* [ */ CHAR_PLUS, /* + */ CHAR_QUESTION_MARK, /* ? */ CHAR_RIGHT_CURLY_BRACE: CHAR_RIGHT_CURLY_BRACE$1, /* } */ CHAR_RIGHT_PARENTHESES: CHAR_RIGHT_PARENTHESES$1, /* ) */ CHAR_RIGHT_SQUARE_BRACKET: CHAR_RIGHT_SQUARE_BRACKET$1 /* ] */ } = constants$1;
1495const isPathSeparator = code => {
1496 return code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH;
1497};
1498/**
1499 * Quickly scans a glob pattern and returns an object with a handful of
1500 * useful properties, like `isGlob`, `path` (the leading non-glob, if it exists),
1501 * `glob` (the actual pattern), and `negated` (true if the path starts with `!`).
1502 *
1503 * ```js
1504 * const pm = require('picomatch');
1505 * console.log(pm.scan('foo/bar/*.js'));
1506 * { isGlob: true, input: 'foo/bar/*.js', base: 'foo/bar', glob: '*.js' }
1507 * ```
1508 * @param {String} `str`
1509 * @param {Object} `options`
1510 * @return {Object} Returns an object with tokens and regex source string.
1511 * @api public
1512 */
1513var scan = (input, options) => {
1514 let opts = options || {};
1515 let length = input.length - 1;
1516 let index = -1;
1517 let start = 0;
1518 let lastIndex = 0;
1519 let isGlob = false;
1520 let backslashes = false;
1521 let negated = false;
1522 let braces = 0;
1523 let prev;
1524 let code;
1525 let braceEscaped = false;
1526 let eos = () => index >= length;
1527 let advance = () => {
1528 prev = code;
1529 return input.charCodeAt(++index);
1530 };
1531 while (index < length) {
1532 code = advance();
1533 let next;
1534 if (code === CHAR_BACKWARD_SLASH) {
1535 backslashes = true;
1536 next = advance();
1537 if (next === CHAR_LEFT_CURLY_BRACE$1) {
1538 braceEscaped = true;
1539 }
1540 continue;
1541 }
1542 if (braceEscaped === true || code === CHAR_LEFT_CURLY_BRACE$1) {
1543 braces++;
1544 while (!eos() && (next = advance())) {
1545 if (next === CHAR_BACKWARD_SLASH) {
1546 backslashes = true;
1547 next = advance();
1548 continue;
1549 }
1550 if (next === CHAR_LEFT_CURLY_BRACE$1) {
1551 braces++;
1552 continue;
1553 }
1554 if (!braceEscaped && next === CHAR_DOT$1 && (next = advance()) === CHAR_DOT$1) {
1555 isGlob = true;
1556 break;
1557 }
1558 if (!braceEscaped && next === CHAR_COMMA$1) {
1559 isGlob = true;
1560 break;
1561 }
1562 if (next === CHAR_RIGHT_CURLY_BRACE$1) {
1563 braces--;
1564 if (braces === 0) {
1565 braceEscaped = false;
1566 break;
1567 }
1568 }
1569 }
1570 }
1571 if (code === CHAR_FORWARD_SLASH) {
1572 if (prev === CHAR_DOT$1 && index === (start + 1)) {
1573 start += 2;
1574 continue;
1575 }
1576 lastIndex = index + 1;
1577 continue;
1578 }
1579 if (code === CHAR_ASTERISK) {
1580 isGlob = true;
1581 break;
1582 }
1583 if (code === CHAR_ASTERISK || code === CHAR_QUESTION_MARK) {
1584 isGlob = true;
1585 break;
1586 }
1587 if (code === CHAR_LEFT_SQUARE_BRACKET$1) {
1588 while (!eos() && (next = advance())) {
1589 if (next === CHAR_BACKWARD_SLASH) {
1590 backslashes = true;
1591 next = advance();
1592 continue;
1593 }
1594 if (next === CHAR_RIGHT_SQUARE_BRACKET$1) {
1595 isGlob = true;
1596 break;
1597 }
1598 }
1599 }
1600 let isExtglobChar = code === CHAR_PLUS
1601 || code === CHAR_AT
1602 || code === CHAR_EXCLAMATION_MARK;
1603 if (isExtglobChar && input.charCodeAt(index + 1) === CHAR_LEFT_PARENTHESES$1) {
1604 isGlob = true;
1605 break;
1606 }
1607 if (code === CHAR_EXCLAMATION_MARK && index === start) {
1608 negated = true;
1609 start++;
1610 continue;
1611 }
1612 if (code === CHAR_LEFT_PARENTHESES$1) {
1613 while (!eos() && (next = advance())) {
1614 if (next === CHAR_BACKWARD_SLASH) {
1615 backslashes = true;
1616 next = advance();
1617 continue;
1618 }
1619 if (next === CHAR_RIGHT_PARENTHESES$1) {
1620 isGlob = true;
1621 break;
1622 }
1623 }
1624 }
1625 if (isGlob) {
1626 break;
1627 }
1628 }
1629 let prefix = '';
1630 let orig = input;
1631 let base = input;
1632 let glob = '';
1633 if (start > 0) {
1634 prefix = input.slice(0, start);
1635 input = input.slice(start);
1636 lastIndex -= start;
1637 }
1638 if (base && isGlob === true && lastIndex > 0) {
1639 base = input.slice(0, lastIndex);
1640 glob = input.slice(lastIndex);
1641 }
1642 else if (isGlob === true) {
1643 base = '';
1644 glob = input;
1645 }
1646 else {
1647 base = input;
1648 }
1649 if (base && base !== '' && base !== '/' && base !== input) {
1650 if (isPathSeparator(base.charCodeAt(base.length - 1))) {
1651 base = base.slice(0, -1);
1652 }
1653 }
1654 if (opts.unescape === true) {
1655 if (glob)
1656 glob = utils$1.removeBackslashes(glob);
1657 if (base && backslashes === true) {
1658 base = utils$1.removeBackslashes(base);
1659 }
1660 }
1661 return { prefix, input: orig, base, glob, negated, isGlob };
1662};
1663
1664/**
1665 * Constants
1666 */
1667const { MAX_LENGTH: MAX_LENGTH$1, POSIX_REGEX_SOURCE: POSIX_REGEX_SOURCE$1, REGEX_NON_SPECIAL_CHAR, REGEX_SPECIAL_CHARS_BACKREF, REPLACEMENTS } = constants$1;
1668/**
1669 * Helpers
1670 */
1671const expandRange = (args, options) => {
1672 if (typeof options.expandRange === 'function') {
1673 return options.expandRange(...args, options);
1674 }
1675 args.sort();
1676 let value = `[${args.join('-')}]`;
1677 try {
1678 }
1679 catch (ex) {
1680 return args.map(v => utils$1.escapeRegex(v)).join('..');
1681 }
1682 return value;
1683};
1684const negate = state => {
1685 let count = 1;
1686 while (state.peek() === '!' && (state.peek(2) !== '(' || state.peek(3) === '?')) {
1687 state.advance();
1688 state.start++;
1689 count++;
1690 }
1691 if (count % 2 === 0) {
1692 return false;
1693 }
1694 state.negated = true;
1695 state.start++;
1696 return true;
1697};
1698/**
1699 * Create the message for a syntax error
1700 */
1701const syntaxError = (type, char) => {
1702 return `Missing ${type}: "${char}" - use "\\\\${char}" to match literal characters`;
1703};
1704/**
1705 * Parse the given input string.
1706 * @param {String} input
1707 * @param {Object} options
1708 * @return {Object}
1709 */
1710const parse$1 = (input, options) => {
1711 if (typeof input !== 'string') {
1712 throw new TypeError('Expected a string');
1713 }
1714 input = REPLACEMENTS[input] || input;
1715 let opts = Object.assign({}, options);
1716 let max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH$1, opts.maxLength) : MAX_LENGTH$1;
1717 let len = input.length;
1718 if (len > max) {
1719 throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`);
1720 }
1721 let bos = { type: 'bos', value: '', output: opts.prepend || '' };
1722 let tokens = [bos];
1723 let capture = opts.capture ? '' : '?:';
1724 let win32 = utils$1.isWindows(options);
1725 // create constants based on platform, for windows or posix
1726 const PLATFORM_CHARS = constants$1.globChars(win32);
1727 const EXTGLOB_CHARS = constants$1.extglobChars(PLATFORM_CHARS);
1728 const { DOT_LITERAL, PLUS_LITERAL, SLASH_LITERAL, ONE_CHAR, DOTS_SLASH, NO_DOT, NO_DOT_SLASH, NO_DOTS_SLASH, QMARK, QMARK_NO_DOT, STAR, START_ANCHOR } = PLATFORM_CHARS;
1729 const globstar = (opts) => {
1730 return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`;
1731 };
1732 let nodot = opts.dot ? '' : NO_DOT;
1733 let star = opts.bash === true ? globstar(opts) : STAR;
1734 let qmarkNoDot = opts.dot ? QMARK : QMARK_NO_DOT;
1735 if (opts.capture) {
1736 star = `(${star})`;
1737 }
1738 // minimatch options support
1739 if (typeof opts.noext === 'boolean') {
1740 opts.noextglob = opts.noext;
1741 }
1742 let state = {
1743 index: -1,
1744 start: 0,
1745 consumed: '',
1746 output: '',
1747 backtrack: false,
1748 brackets: 0,
1749 braces: 0,
1750 parens: 0,
1751 quotes: 0,
1752 tokens
1753 };
1754 let extglobs = [];
1755 let stack = [];
1756 let prev = bos;
1757 let value;
1758 /**
1759 * Tokenizing helpers
1760 */
1761 const eos = () => state.index === len - 1;
1762 const peek = state.peek = (n = 1) => input[state.index + n];
1763 const advance = state.advance = () => input[++state.index];
1764 const append = token => {
1765 state.output += token.output != null ? token.output : token.value;
1766 state.consumed += token.value || '';
1767 };
1768 const increment = type => {
1769 state[type]++;
1770 stack.push(type);
1771 };
1772 const decrement = type => {
1773 state[type]--;
1774 stack.pop();
1775 };
1776 /**
1777 * Push tokens onto the tokens array. This helper speeds up
1778 * tokenizing by 1) helping us avoid backtracking as much as possible,
1779 * and 2) helping us avoid creating extra tokens when consecutive
1780 * characters are plain text. This improves performance and simplifies
1781 * lookbehinds.
1782 */
1783 const push = tok => {
1784 if (prev.type === 'globstar') {
1785 let isBrace = state.braces > 0 && (tok.type === 'comma' || tok.type === 'brace');
1786 let isExtglob = extglobs.length && (tok.type === 'pipe' || tok.type === 'paren');
1787 if (tok.type !== 'slash' && tok.type !== 'paren' && !isBrace && !isExtglob) {
1788 state.output = state.output.slice(0, -prev.output.length);
1789 prev.type = 'star';
1790 prev.value = '*';
1791 prev.output = star;
1792 state.output += prev.output;
1793 }
1794 }
1795 if (extglobs.length && tok.type !== 'paren' && !EXTGLOB_CHARS[tok.value]) {
1796 extglobs[extglobs.length - 1].inner += tok.value;
1797 }
1798 if (tok.value || tok.output)
1799 append(tok);
1800 if (prev && prev.type === 'text' && tok.type === 'text') {
1801 prev.value += tok.value;
1802 return;
1803 }
1804 tok.prev = prev;
1805 tokens.push(tok);
1806 prev = tok;
1807 };
1808 const extglobOpen = (type, value) => {
1809 let token = Object.assign({}, EXTGLOB_CHARS[value], { conditions: 1, inner: '' });
1810 token.prev = prev;
1811 token.parens = state.parens;
1812 token.output = state.output;
1813 let output = (opts.capture ? '(' : '') + token.open;
1814 push({ type, value, output: state.output ? '' : ONE_CHAR });
1815 push({ type: 'paren', extglob: true, value: advance(), output });
1816 increment('parens');
1817 extglobs.push(token);
1818 };
1819 const extglobClose = token => {
1820 let output = token.close + (opts.capture ? ')' : '');
1821 if (token.type === 'negate') {
1822 let extglobStar = star;
1823 if (token.inner && token.inner.length > 1 && token.inner.includes('/')) {
1824 extglobStar = globstar(opts);
1825 }
1826 if (extglobStar !== star || eos() || /^\)+$/.test(input.slice(state.index + 1))) {
1827 output = token.close = ')$))' + extglobStar;
1828 }
1829 if (token.prev.type === 'bos' && eos()) {
1830 state.negatedExtglob = true;
1831 }
1832 }
1833 push({ type: 'paren', extglob: true, value, output });
1834 decrement('parens');
1835 };
1836 if (opts.fastpaths !== false && !/(^[*!]|[/{[()\]}"])/.test(input)) {
1837 let backslashes = false;
1838 let output = input.replace(REGEX_SPECIAL_CHARS_BACKREF, (m, esc, chars, first, rest, index) => {
1839 if (first === '\\') {
1840 backslashes = true;
1841 return m;
1842 }
1843 if (first === '?') {
1844 if (esc) {
1845 return esc + first + (rest ? QMARK.repeat(rest.length) : '');
1846 }
1847 if (index === 0) {
1848 return qmarkNoDot + (rest ? QMARK.repeat(rest.length) : '');
1849 }
1850 return QMARK.repeat(chars.length);
1851 }
1852 if (first === '.') {
1853 return DOT_LITERAL.repeat(chars.length);
1854 }
1855 if (first === '*') {
1856 if (esc) {
1857 return esc + first + (rest ? star : '');
1858 }
1859 return star;
1860 }
1861 return esc ? m : '\\' + m;
1862 });
1863 if (backslashes === true) {
1864 if (opts.unescape === true) {
1865 output = output.replace(/\\/g, '');
1866 }
1867 else {
1868 output = output.replace(/\\+/g, m => {
1869 return m.length % 2 === 0 ? '\\\\' : (m ? '\\' : '');
1870 });
1871 }
1872 }
1873 state.output = output;
1874 return state;
1875 }
1876 /**
1877 * Tokenize input until we reach end-of-string
1878 */
1879 while (!eos()) {
1880 value = advance();
1881 if (value === '\u0000') {
1882 continue;
1883 }
1884 /**
1885 * Escaped characters
1886 */
1887 if (value === '\\') {
1888 let next = peek();
1889 if (next === '/' && opts.bash !== true) {
1890 continue;
1891 }
1892 if (next === '.' || next === ';') {
1893 continue;
1894 }
1895 if (!next) {
1896 value += '\\';
1897 push({ type: 'text', value });
1898 continue;
1899 }
1900 // collapse slashes to reduce potential for exploits
1901 let match = /^\\+/.exec(input.slice(state.index + 1));
1902 let slashes = 0;
1903 if (match && match[0].length > 2) {
1904 slashes = match[0].length;
1905 state.index += slashes;
1906 if (slashes % 2 !== 0) {
1907 value += '\\';
1908 }
1909 }
1910 if (opts.unescape === true) {
1911 value = advance() || '';
1912 }
1913 else {
1914 value += advance() || '';
1915 }
1916 if (state.brackets === 0) {
1917 push({ type: 'text', value });
1918 continue;
1919 }
1920 }
1921 /**
1922 * If we're inside a regex character class, continue
1923 * until we reach the closing bracket.
1924 */
1925 if (state.brackets > 0 && (value !== ']' || prev.value === '[' || prev.value === '[^')) {
1926 if (opts.posix !== false && value === ':') {
1927 let inner = prev.value.slice(1);
1928 if (inner.includes('[')) {
1929 prev.posix = true;
1930 if (inner.includes(':')) {
1931 let idx = prev.value.lastIndexOf('[');
1932 let pre = prev.value.slice(0, idx);
1933 let rest = prev.value.slice(idx + 2);
1934 let posix = POSIX_REGEX_SOURCE$1[rest];
1935 if (posix) {
1936 prev.value = pre + posix;
1937 state.backtrack = true;
1938 advance();
1939 if (!bos.output && tokens.indexOf(prev) === 1) {
1940 bos.output = ONE_CHAR;
1941 }
1942 continue;
1943 }
1944 }
1945 }
1946 }
1947 if ((value === '[' && peek() !== ':') || (value === '-' && peek() === ']')) {
1948 value = '\\' + value;
1949 }
1950 if (value === ']' && (prev.value === '[' || prev.value === '[^')) {
1951 value = '\\' + value;
1952 }
1953 if (opts.posix === true && value === '!' && prev.value === '[') {
1954 value = '^';
1955 }
1956 prev.value += value;
1957 append({ value });
1958 continue;
1959 }
1960 /**
1961 * If we're inside a quoted string, continue
1962 * until we reach the closing double quote.
1963 */
1964 if (state.quotes === 1 && value !== '"') {
1965 value = utils$1.escapeRegex(value);
1966 prev.value += value;
1967 append({ value });
1968 continue;
1969 }
1970 /**
1971 * Double quotes
1972 */
1973 if (value === '"') {
1974 state.quotes = state.quotes === 1 ? 0 : 1;
1975 if (opts.keepQuotes === true) {
1976 push({ type: 'text', value });
1977 }
1978 continue;
1979 }
1980 /**
1981 * Parentheses
1982 */
1983 if (value === '(') {
1984 push({ type: 'paren', value });
1985 increment('parens');
1986 continue;
1987 }
1988 if (value === ')') {
1989 if (state.parens === 0 && opts.strictBrackets === true) {
1990 throw new SyntaxError(syntaxError('opening', '('));
1991 }
1992 let extglob = extglobs[extglobs.length - 1];
1993 if (extglob && state.parens === extglob.parens + 1) {
1994 extglobClose(extglobs.pop());
1995 continue;
1996 }
1997 push({ type: 'paren', value, output: state.parens ? ')' : '\\)' });
1998 decrement('parens');
1999 continue;
2000 }
2001 /**
2002 * Brackets
2003 */
2004 if (value === '[') {
2005 if (opts.nobracket === true || !input.slice(state.index + 1).includes(']')) {
2006 if (opts.nobracket !== true && opts.strictBrackets === true) {
2007 throw new SyntaxError(syntaxError('closing', ']'));
2008 }
2009 value = '\\' + value;
2010 }
2011 else {
2012 increment('brackets');
2013 }
2014 push({ type: 'bracket', value });
2015 continue;
2016 }
2017 if (value === ']') {
2018 if (opts.nobracket === true || (prev && prev.type === 'bracket' && prev.value.length === 1)) {
2019 push({ type: 'text', value, output: '\\' + value });
2020 continue;
2021 }
2022 if (state.brackets === 0) {
2023 if (opts.strictBrackets === true) {
2024 throw new SyntaxError(syntaxError('opening', '['));
2025 }
2026 push({ type: 'text', value, output: '\\' + value });
2027 continue;
2028 }
2029 decrement('brackets');
2030 let prevValue = prev.value.slice(1);
2031 if (prev.posix !== true && prevValue[0] === '^' && !prevValue.includes('/')) {
2032 value = '/' + value;
2033 }
2034 prev.value += value;
2035 append({ value });
2036 // when literal brackets are explicitly disabled
2037 // assume we should match with a regex character class
2038 if (opts.literalBrackets === false || utils$1.hasRegexChars(prevValue)) {
2039 continue;
2040 }
2041 let escaped = utils$1.escapeRegex(prev.value);
2042 state.output = state.output.slice(0, -prev.value.length);
2043 // when literal brackets are explicitly enabled
2044 // assume we should escape the brackets to match literal characters
2045 if (opts.literalBrackets === true) {
2046 state.output += escaped;
2047 prev.value = escaped;
2048 continue;
2049 }
2050 // when the user specifies nothing, try to match both
2051 prev.value = `(${capture}${escaped}|${prev.value})`;
2052 state.output += prev.value;
2053 continue;
2054 }
2055 /**
2056 * Braces
2057 */
2058 if (value === '{' && opts.nobrace !== true) {
2059 push({ type: 'brace', value, output: '(' });
2060 increment('braces');
2061 continue;
2062 }
2063 if (value === '}') {
2064 if (opts.nobrace === true || state.braces === 0) {
2065 push({ type: 'text', value, output: '\\' + value });
2066 continue;
2067 }
2068 let output = ')';
2069 if (state.dots === true) {
2070 let arr = tokens.slice();
2071 let range = [];
2072 for (let i = arr.length - 1; i >= 0; i--) {
2073 tokens.pop();
2074 if (arr[i].type === 'brace') {
2075 break;
2076 }
2077 if (arr[i].type !== 'dots') {
2078 range.unshift(arr[i].value);
2079 }
2080 }
2081 output = expandRange(range, opts);
2082 state.backtrack = true;
2083 }
2084 push({ type: 'brace', value, output });
2085 decrement('braces');
2086 continue;
2087 }
2088 /**
2089 * Pipes
2090 */
2091 if (value === '|') {
2092 if (extglobs.length > 0) {
2093 extglobs[extglobs.length - 1].conditions++;
2094 }
2095 push({ type: 'text', value });
2096 continue;
2097 }
2098 /**
2099 * Commas
2100 */
2101 if (value === ',') {
2102 let output = value;
2103 if (state.braces > 0 && stack[stack.length - 1] === 'braces') {
2104 output = '|';
2105 }
2106 push({ type: 'comma', value, output });
2107 continue;
2108 }
2109 /**
2110 * Slashes
2111 */
2112 if (value === '/') {
2113 // if the beginning of the glob is "./", advance the start
2114 // to the current index, and don't add the "./" characters
2115 // to the state. This greatly simplifies lookbehinds when
2116 // checking for BOS characters like "!" and "." (not "./")
2117 if (prev.type === 'dot' && state.index === 1) {
2118 state.start = state.index + 1;
2119 state.consumed = '';
2120 state.output = '';
2121 tokens.pop();
2122 prev = bos; // reset "prev" to the first token
2123 continue;
2124 }
2125 push({ type: 'slash', value, output: SLASH_LITERAL });
2126 continue;
2127 }
2128 /**
2129 * Dots
2130 */
2131 if (value === '.') {
2132 if (state.braces > 0 && prev.type === 'dot') {
2133 if (prev.value === '.')
2134 prev.output = DOT_LITERAL;
2135 prev.type = 'dots';
2136 prev.output += value;
2137 prev.value += value;
2138 state.dots = true;
2139 continue;
2140 }
2141 push({ type: 'dot', value, output: DOT_LITERAL });
2142 continue;
2143 }
2144 /**
2145 * Question marks
2146 */
2147 if (value === '?') {
2148 if (prev && prev.type === 'paren') {
2149 let next = peek();
2150 let output = value;
2151 if (next === '<' && !utils$1.supportsLookbehinds()) {
2152 throw new Error('Node.js v10 or higher is required for regex lookbehinds');
2153 }
2154 if (prev.value === '(' && !/[!=<:]/.test(next) || (next === '<' && !/[!=]/.test(peek(2)))) {
2155 output = '\\' + value;
2156 }
2157 push({ type: 'text', value, output });
2158 continue;
2159 }
2160 if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') {
2161 extglobOpen('qmark', value);
2162 continue;
2163 }
2164 if (opts.dot !== true && (prev.type === 'slash' || prev.type === 'bos')) {
2165 push({ type: 'qmark', value, output: QMARK_NO_DOT });
2166 continue;
2167 }
2168 push({ type: 'qmark', value, output: QMARK });
2169 continue;
2170 }
2171 /**
2172 * Exclamation
2173 */
2174 if (value === '!') {
2175 if (opts.noextglob !== true && peek() === '(') {
2176 if (peek(2) !== '?' || !/[!=<:]/.test(peek(3))) {
2177 extglobOpen('negate', value);
2178 continue;
2179 }
2180 }
2181 if (opts.nonegate !== true && state.index === 0) {
2182 negate(state);
2183 continue;
2184 }
2185 }
2186 /**
2187 * Plus
2188 */
2189 if (value === '+') {
2190 if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') {
2191 extglobOpen('plus', value);
2192 continue;
2193 }
2194 if (prev && (prev.type === 'bracket' || prev.type === 'paren' || prev.type === 'brace')) {
2195 let output = prev.extglob === true ? '\\' + value : value;
2196 push({ type: 'plus', value, output });
2197 continue;
2198 }
2199 // use regex behavior inside parens
2200 if (state.parens > 0 && opts.regex !== false) {
2201 push({ type: 'plus', value });
2202 continue;
2203 }
2204 push({ type: 'plus', value: PLUS_LITERAL });
2205 continue;
2206 }
2207 /**
2208 * Plain text
2209 */
2210 if (value === '@') {
2211 if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') {
2212 push({ type: 'at', value, output: '' });
2213 continue;
2214 }
2215 push({ type: 'text', value });
2216 continue;
2217 }
2218 /**
2219 * Plain text
2220 */
2221 if (value !== '*') {
2222 if (value === '$' || value === '^') {
2223 value = '\\' + value;
2224 }
2225 let match = REGEX_NON_SPECIAL_CHAR.exec(input.slice(state.index + 1));
2226 if (match) {
2227 value += match[0];
2228 state.index += match[0].length;
2229 }
2230 push({ type: 'text', value });
2231 continue;
2232 }
2233 /**
2234 * Stars
2235 */
2236 if (prev && (prev.type === 'globstar' || prev.star === true)) {
2237 prev.type = 'star';
2238 prev.star = true;
2239 prev.value += value;
2240 prev.output = star;
2241 state.backtrack = true;
2242 state.consumed += value;
2243 continue;
2244 }
2245 if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') {
2246 extglobOpen('star', value);
2247 continue;
2248 }
2249 if (prev.type === 'star') {
2250 if (opts.noglobstar === true) {
2251 state.consumed += value;
2252 continue;
2253 }
2254 let prior = prev.prev;
2255 let before = prior.prev;
2256 let isStart = prior.type === 'slash' || prior.type === 'bos';
2257 let afterStar = before && (before.type === 'star' || before.type === 'globstar');
2258 if (opts.bash === true && (!isStart || (!eos() && peek() !== '/'))) {
2259 push({ type: 'star', value, output: '' });
2260 continue;
2261 }
2262 let isBrace = state.braces > 0 && (prior.type === 'comma' || prior.type === 'brace');
2263 let isExtglob = extglobs.length && (prior.type === 'pipe' || prior.type === 'paren');
2264 if (!isStart && prior.type !== 'paren' && !isBrace && !isExtglob) {
2265 push({ type: 'star', value, output: '' });
2266 continue;
2267 }
2268 // strip consecutive `/**/`
2269 while (input.slice(state.index + 1, state.index + 4) === '/**') {
2270 let after = input[state.index + 4];
2271 if (after && after !== '/') {
2272 break;
2273 }
2274 state.consumed += '/**';
2275 state.index += 3;
2276 }
2277 if (prior.type === 'bos' && eos()) {
2278 prev.type = 'globstar';
2279 prev.value += value;
2280 prev.output = globstar(opts);
2281 state.output = prev.output;
2282 state.consumed += value;
2283 continue;
2284 }
2285 if (prior.type === 'slash' && prior.prev.type !== 'bos' && !afterStar && eos()) {
2286 state.output = state.output.slice(0, -(prior.output + prev.output).length);
2287 prior.output = '(?:' + prior.output;
2288 prev.type = 'globstar';
2289 prev.output = globstar(opts) + '|$)';
2290 prev.value += value;
2291 state.output += prior.output + prev.output;
2292 state.consumed += value;
2293 continue;
2294 }
2295 let next = peek();
2296 if (prior.type === 'slash' && prior.prev.type !== 'bos' && next === '/') {
2297 let end = peek(2) !== void 0 ? '|$' : '';
2298 state.output = state.output.slice(0, -(prior.output + prev.output).length);
2299 prior.output = '(?:' + prior.output;
2300 prev.type = 'globstar';
2301 prev.output = `${globstar(opts)}${SLASH_LITERAL}|${SLASH_LITERAL}${end})`;
2302 prev.value += value;
2303 state.output += prior.output + prev.output;
2304 state.consumed += value + advance();
2305 push({ type: 'slash', value, output: '' });
2306 continue;
2307 }
2308 if (prior.type === 'bos' && next === '/') {
2309 prev.type = 'globstar';
2310 prev.value += value;
2311 prev.output = `(?:^|${SLASH_LITERAL}|${globstar(opts)}${SLASH_LITERAL})`;
2312 state.output = prev.output;
2313 state.consumed += value + advance();
2314 push({ type: 'slash', value, output: '' });
2315 continue;
2316 }
2317 // remove single star from output
2318 state.output = state.output.slice(0, -prev.output.length);
2319 // reset previous token to globstar
2320 prev.type = 'globstar';
2321 prev.output = globstar(opts);
2322 prev.value += value;
2323 // reset output with globstar
2324 state.output += prev.output;
2325 state.consumed += value;
2326 continue;
2327 }
2328 let token = { type: 'star', value, output: star };
2329 if (opts.bash === true) {
2330 token.output = '.*?';
2331 if (prev.type === 'bos' || prev.type === 'slash') {
2332 token.output = nodot + token.output;
2333 }
2334 push(token);
2335 continue;
2336 }
2337 if (prev && (prev.type === 'bracket' || prev.type === 'paren') && opts.regex === true) {
2338 token.output = value;
2339 push(token);
2340 continue;
2341 }
2342 if (state.index === state.start || prev.type === 'slash' || prev.type === 'dot') {
2343 if (prev.type === 'dot') {
2344 state.output += NO_DOT_SLASH;
2345 prev.output += NO_DOT_SLASH;
2346 }
2347 else if (opts.dot === true) {
2348 state.output += NO_DOTS_SLASH;
2349 prev.output += NO_DOTS_SLASH;
2350 }
2351 else {
2352 state.output += nodot;
2353 prev.output += nodot;
2354 }
2355 if (peek() !== '*') {
2356 state.output += ONE_CHAR;
2357 prev.output += ONE_CHAR;
2358 }
2359 }
2360 push(token);
2361 }
2362 while (state.brackets > 0) {
2363 if (opts.strictBrackets === true)
2364 throw new SyntaxError(syntaxError('closing', ']'));
2365 state.output = utils$1.escapeLast(state.output, '[');
2366 decrement('brackets');
2367 }
2368 while (state.parens > 0) {
2369 if (opts.strictBrackets === true)
2370 throw new SyntaxError(syntaxError('closing', ')'));
2371 state.output = utils$1.escapeLast(state.output, '(');
2372 decrement('parens');
2373 }
2374 while (state.braces > 0) {
2375 if (opts.strictBrackets === true)
2376 throw new SyntaxError(syntaxError('closing', '}'));
2377 state.output = utils$1.escapeLast(state.output, '{');
2378 decrement('braces');
2379 }
2380 if (opts.strictSlashes !== true && (prev.type === 'star' || prev.type === 'bracket')) {
2381 push({ type: 'maybe_slash', value: '', output: `${SLASH_LITERAL}?` });
2382 }
2383 // rebuild the output if we had to backtrack at any point
2384 if (state.backtrack === true) {
2385 state.output = '';
2386 for (let token of state.tokens) {
2387 state.output += token.output != null ? token.output : token.value;
2388 if (token.suffix) {
2389 state.output += token.suffix;
2390 }
2391 }
2392 }
2393 return state;
2394};
2395/**
2396 * Fast paths for creating regular expressions for common glob patterns.
2397 * This can significantly speed up processing and has very little downside
2398 * impact when none of the fast paths match.
2399 */
2400parse$1.fastpaths = (input, options) => {
2401 let opts = Object.assign({}, options);
2402 let max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH$1, opts.maxLength) : MAX_LENGTH$1;
2403 let len = input.length;
2404 if (len > max) {
2405 throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`);
2406 }
2407 input = REPLACEMENTS[input] || input;
2408 let win32 = utils$1.isWindows(options);
2409 // create constants based on platform, for windows or posix
2410 const { DOT_LITERAL, SLASH_LITERAL, ONE_CHAR, DOTS_SLASH, NO_DOT, NO_DOTS, NO_DOTS_SLASH, STAR, START_ANCHOR } = constants$1.globChars(win32);
2411 let capture = opts.capture ? '' : '?:';
2412 let star = opts.bash === true ? '.*?' : STAR;
2413 let nodot = opts.dot ? NO_DOTS : NO_DOT;
2414 let slashDot = opts.dot ? NO_DOTS_SLASH : NO_DOT;
2415 if (opts.capture) {
2416 star = `(${star})`;
2417 }
2418 const globstar = (opts) => {
2419 return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`;
2420 };
2421 const create = str => {
2422 switch (str) {
2423 case '*':
2424 return `${nodot}${ONE_CHAR}${star}`;
2425 case '.*':
2426 return `${DOT_LITERAL}${ONE_CHAR}${star}`;
2427 case '*.*':
2428 return `${nodot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`;
2429 case '*/*':
2430 return `${nodot}${star}${SLASH_LITERAL}${ONE_CHAR}${slashDot}${star}`;
2431 case '**':
2432 return nodot + globstar(opts);
2433 case '**/*':
2434 return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${ONE_CHAR}${star}`;
2435 case '**/*.*':
2436 return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`;
2437 case '**/.*':
2438 return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${DOT_LITERAL}${ONE_CHAR}${star}`;
2439 default: {
2440 let match = /^(.*?)\.(\w+)$/.exec(str);
2441 if (!match)
2442 return;
2443 let source = create(match[1], options);
2444 if (!source)
2445 return;
2446 return source + DOT_LITERAL + match[2];
2447 }
2448 }
2449 };
2450 let output = create(input);
2451 if (output && opts.strictSlashes !== true) {
2452 output += `${SLASH_LITERAL}?`;
2453 }
2454 return output;
2455};
2456var parse_1$1 = parse$1;
2457
2458/**
2459 * Creates a matcher function from one or more glob patterns. The
2460 * returned function takes a string to match as its first argument,
2461 * and returns true if the string is a match. The returned matcher
2462 * function also takes a boolean as the second argument that, when true,
2463 * returns an object with additional information.
2464 *
2465 * ```js
2466 * const picomatch = require('picomatch');
2467 * // picomatch(glob[, options]);
2468 *
2469 * const isMatch = picomatch('*.!(*a)');
2470 * console.log(isMatch('a.a')); //=> false
2471 * console.log(isMatch('a.b')); //=> true
2472 * ```
2473 * @name picomatch
2474 * @param {String|Array} `globs` One or more glob patterns.
2475 * @param {Object=} `options`
2476 * @return {Function=} Returns a matcher function.
2477 * @api public
2478 */
2479const picomatch = (glob, options, returnState = false) => {
2480 if (Array.isArray(glob)) {
2481 let fns = glob.map(input => picomatch(input, options, returnState));
2482 return str => {
2483 for (let isMatch of fns) {
2484 let state = isMatch(str);
2485 if (state)
2486 return state;
2487 }
2488 return false;
2489 };
2490 }
2491 if (typeof glob !== 'string' || glob === '') {
2492 throw new TypeError('Expected pattern to be a non-empty string');
2493 }
2494 let opts = options || {};
2495 let posix = utils$1.isWindows(options);
2496 let regex = picomatch.makeRe(glob, options, false, true);
2497 let state = regex.state;
2498 delete regex.state;
2499 let isIgnored = () => false;
2500 if (opts.ignore) {
2501 let ignoreOpts = Object.assign({}, options, { ignore: null, onMatch: null, onResult: null });
2502 isIgnored = picomatch(opts.ignore, ignoreOpts, returnState);
2503 }
2504 const matcher = (input, returnObject = false) => {
2505 let { isMatch, match, output } = picomatch.test(input, regex, options, { glob, posix });
2506 let result = { glob, state, regex, posix, input, output, match, isMatch };
2507 if (typeof opts.onResult === 'function') {
2508 opts.onResult(result);
2509 }
2510 if (isMatch === false) {
2511 result.isMatch = false;
2512 return returnObject ? result : false;
2513 }
2514 if (isIgnored(input)) {
2515 if (typeof opts.onIgnore === 'function') {
2516 opts.onIgnore(result);
2517 }
2518 result.isMatch = false;
2519 return returnObject ? result : false;
2520 }
2521 if (typeof opts.onMatch === 'function') {
2522 opts.onMatch(result);
2523 }
2524 return returnObject ? result : true;
2525 };
2526 if (returnState) {
2527 matcher.state = state;
2528 }
2529 return matcher;
2530};
2531/**
2532 * Test `input` with the given `regex`. This is used by the main
2533 * `picomatch()` function to test the input string.
2534 *
2535 * ```js
2536 * const picomatch = require('picomatch');
2537 * // picomatch.test(input, regex[, options]);
2538 *
2539 * console.log(picomatch.test('foo/bar', /^(?:([^/]*?)\/([^/]*?))$/));
2540 * // { isMatch: true, match: [ 'foo/', 'foo', 'bar' ], output: 'foo/bar' }
2541 * ```
2542 * @param {String} `input` String to test.
2543 * @param {RegExp} `regex`
2544 * @return {Object} Returns an object with matching info.
2545 * @api public
2546 */
2547picomatch.test = (input, regex, options, { glob, posix } = {}) => {
2548 if (typeof input !== 'string') {
2549 throw new TypeError('Expected input to be a string');
2550 }
2551 if (input === '') {
2552 return { isMatch: false, output: '' };
2553 }
2554 let opts = options || {};
2555 let format = opts.format || (posix ? utils$1.toPosixSlashes : null);
2556 let match = input === glob;
2557 let output = (match && format) ? format(input) : input;
2558 if (match === false) {
2559 output = format ? format(input) : input;
2560 match = output === glob;
2561 }
2562 if (match === false || opts.capture === true) {
2563 if (opts.matchBase === true || opts.basename === true) {
2564 match = picomatch.matchBase(input, regex, options, posix);
2565 }
2566 else {
2567 match = regex.exec(output);
2568 }
2569 }
2570 return { isMatch: !!match, match, output };
2571};
2572/**
2573 * Match the basename of a filepath.
2574 *
2575 * ```js
2576 * const picomatch = require('picomatch');
2577 * // picomatch.matchBase(input, glob[, options]);
2578 * console.log(picomatch.matchBase('foo/bar.js', '*.js'); // true
2579 * ```
2580 * @param {String} `input` String to test.
2581 * @param {RegExp|String} `glob` Glob pattern or regex created by [.makeRe](#makeRe).
2582 * @return {Boolean}
2583 * @api public
2584 */
2585picomatch.matchBase = (input, glob, options, posix = utils$1.isWindows(options)) => {
2586 let regex = glob instanceof RegExp ? glob : picomatch.makeRe(glob, options);
2587 return regex.test(path.basename(input));
2588};
2589/**
2590 * Returns true if **any** of the given glob `patterns` match the specified `string`.
2591 *
2592 * ```js
2593 * const picomatch = require('picomatch');
2594 * // picomatch.isMatch(string, patterns[, options]);
2595 *
2596 * console.log(picomatch.isMatch('a.a', ['b.*', '*.a'])); //=> true
2597 * console.log(picomatch.isMatch('a.a', 'b.*')); //=> false
2598 * ```
2599 * @param {String|Array} str The string to test.
2600 * @param {String|Array} patterns One or more glob patterns to use for matching.
2601 * @param {Object} [options] See available [options](#options).
2602 * @return {Boolean} Returns true if any patterns match `str`
2603 * @api public
2604 */
2605picomatch.isMatch = (str, patterns, options) => picomatch(patterns, options)(str);
2606/**
2607 * Parse a glob pattern to create the source string for a regular
2608 * expression.
2609 *
2610 * ```js
2611 * const picomatch = require('picomatch');
2612 * const result = picomatch.parse(glob[, options]);
2613 * ```
2614 * @param {String} `glob`
2615 * @param {Object} `options`
2616 * @return {Object} Returns an object with useful properties and output to be used as a regex source string.
2617 * @api public
2618 */
2619picomatch.parse = (glob, options) => parse_1$1(glob, options);
2620/**
2621 * Scan a glob pattern to separate the pattern into segments.
2622 *
2623 * ```js
2624 * const picomatch = require('picomatch');
2625 * // picomatch.scan(input[, options]);
2626 *
2627 * const result = picomatch.scan('!./foo/*.js');
2628 * console.log(result);
2629 * // { prefix: '!./',
2630 * // input: '!./foo/*.js',
2631 * // base: 'foo',
2632 * // glob: '*.js',
2633 * // negated: true,
2634 * // isGlob: true }
2635 * ```
2636 * @param {String} `input` Glob pattern to scan.
2637 * @param {Object} `options`
2638 * @return {Object} Returns an object with
2639 * @api public
2640 */
2641picomatch.scan = (input, options) => scan(input, options);
2642/**
2643 * Create a regular expression from a glob pattern.
2644 *
2645 * ```js
2646 * const picomatch = require('picomatch');
2647 * // picomatch.makeRe(input[, options]);
2648 *
2649 * console.log(picomatch.makeRe('*.js'));
2650 * //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/
2651 * ```
2652 * @param {String} `input` A glob pattern to convert to regex.
2653 * @param {Object} `options`
2654 * @return {RegExp} Returns a regex created from the given pattern.
2655 * @api public
2656 */
2657picomatch.makeRe = (input, options, returnOutput = false, returnState = false) => {
2658 if (!input || typeof input !== 'string') {
2659 throw new TypeError('Expected a non-empty string');
2660 }
2661 let opts = options || {};
2662 let prepend = opts.contains ? '' : '^';
2663 let append = opts.contains ? '' : '$';
2664 let state = { negated: false, fastpaths: true };
2665 let prefix = '';
2666 let output;
2667 if (input.startsWith('./')) {
2668 input = input.slice(2);
2669 prefix = state.prefix = './';
2670 }
2671 if (opts.fastpaths !== false && (input[0] === '.' || input[0] === '*')) {
2672 output = parse_1$1.fastpaths(input, options);
2673 }
2674 if (output === void 0) {
2675 state = picomatch.parse(input, options);
2676 state.prefix = prefix + (state.prefix || '');
2677 output = state.output;
2678 }
2679 if (returnOutput === true) {
2680 return output;
2681 }
2682 let source = `${prepend}(?:${output})${append}`;
2683 if (state && state.negated === true) {
2684 source = `^(?!${source}).*$`;
2685 }
2686 let regex = picomatch.toRegex(source, options);
2687 if (returnState === true) {
2688 regex.state = state;
2689 }
2690 return regex;
2691};
2692/**
2693 * Create a regular expression from the given regex source string.
2694 *
2695 * ```js
2696 * const picomatch = require('picomatch');
2697 * // picomatch.toRegex(source[, options]);
2698 *
2699 * const { output } = picomatch.parse('*.js');
2700 * console.log(picomatch.toRegex(output));
2701 * //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/
2702 * ```
2703 * @param {String} `source` Regular expression source string.
2704 * @param {Object} `options`
2705 * @return {RegExp}
2706 * @api public
2707 */
2708picomatch.toRegex = (source, options) => {
2709 try {
2710 let opts = options || {};
2711 return new RegExp(source, opts.flags || (opts.nocase ? 'i' : ''));
2712 }
2713 catch (err) {
2714 if (options && options.debug === true)
2715 throw err;
2716 return /$^/;
2717 }
2718};
2719/**
2720 * Picomatch constants.
2721 * @return {Object}
2722 */
2723picomatch.constants = constants$1;
2724/**
2725 * Expose "picomatch"
2726 */
2727var picomatch_1 = picomatch;
2728
2729var picomatch$1 = picomatch_1;
2730
2731const isEmptyString = val => typeof val === 'string' && (val === '' || val === './');
2732/**
2733 * Returns an array of strings that match one or more glob patterns.
2734 *
2735 * ```js
2736 * const mm = require('micromatch');
2737 * // mm(list, patterns[, options]);
2738 *
2739 * console.log(mm(['a.js', 'a.txt'], ['*.js']));
2740 * //=> [ 'a.js' ]
2741 * ```
2742 * @param {String|Array<string>} list List of strings to match.
2743 * @param {String|Array<string>} patterns One or more glob patterns to use for matching.
2744 * @param {Object} options See available [options](#options)
2745 * @return {Array} Returns an array of matches
2746 * @summary false
2747 * @api public
2748 */
2749const micromatch = (list, patterns, options) => {
2750 patterns = [].concat(patterns);
2751 list = [].concat(list);
2752 let omit = new Set();
2753 let keep = new Set();
2754 let items = new Set();
2755 let negatives = 0;
2756 let onResult = state => {
2757 items.add(state.output);
2758 if (options && options.onResult) {
2759 options.onResult(state);
2760 }
2761 };
2762 for (let i = 0; i < patterns.length; i++) {
2763 let isMatch = picomatch$1(String(patterns[i]), Object.assign({}, options, { onResult }), true);
2764 let negated = isMatch.state.negated || isMatch.state.negatedExtglob;
2765 if (negated)
2766 negatives++;
2767 for (let item of list) {
2768 let matched = isMatch(item, true);
2769 let match = negated ? !matched.isMatch : matched.isMatch;
2770 if (!match)
2771 continue;
2772 if (negated) {
2773 omit.add(matched.output);
2774 }
2775 else {
2776 omit.delete(matched.output);
2777 keep.add(matched.output);
2778 }
2779 }
2780 }
2781 let result = negatives === patterns.length ? [...items] : [...keep];
2782 let matches = result.filter(item => !omit.has(item));
2783 if (options && matches.length === 0) {
2784 if (options.failglob === true) {
2785 throw new Error(`No matches found for "${patterns.join(', ')}"`);
2786 }
2787 if (options.nonull === true || options.nullglob === true) {
2788 return options.unescape ? patterns.map(p => p.replace(/\\/g, '')) : patterns;
2789 }
2790 }
2791 return matches;
2792};
2793/**
2794 * Backwards compatibility
2795 */
2796micromatch.match = micromatch;
2797/**
2798 * Returns a matcher function from the given glob `pattern` and `options`.
2799 * The returned function takes a string to match as its only argument and returns
2800 * true if the string is a match.
2801 *
2802 * ```js
2803 * const mm = require('micromatch');
2804 * // mm.matcher(pattern[, options]);
2805 *
2806 * const isMatch = mm.matcher('*.!(*a)');
2807 * console.log(isMatch('a.a')); //=> false
2808 * console.log(isMatch('a.b')); //=> true
2809 * ```
2810 * @param {String} `pattern` Glob pattern
2811 * @param {Object} `options`
2812 * @return {Function} Returns a matcher function.
2813 * @api public
2814 */
2815micromatch.matcher = (pattern, options) => picomatch$1(pattern, options);
2816/**
2817 * Returns true if **any** of the given glob `patterns` match the specified `string`.
2818 *
2819 * ```js
2820 * const mm = require('micromatch');
2821 * // mm.isMatch(string, patterns[, options]);
2822 *
2823 * console.log(mm.isMatch('a.a', ['b.*', '*.a'])); //=> true
2824 * console.log(mm.isMatch('a.a', 'b.*')); //=> false
2825 * ```
2826 * @param {String} str The string to test.
2827 * @param {String|Array} patterns One or more glob patterns to use for matching.
2828 * @param {Object} [options] See available [options](#options).
2829 * @return {Boolean} Returns true if any patterns match `str`
2830 * @api public
2831 */
2832micromatch.isMatch = (str, patterns, options) => picomatch$1(patterns, options)(str);
2833/**
2834 * Backwards compatibility
2835 */
2836micromatch.any = micromatch.isMatch;
2837/**
2838 * Returns a list of strings that _**do not match any**_ of the given `patterns`.
2839 *
2840 * ```js
2841 * const mm = require('micromatch');
2842 * // mm.not(list, patterns[, options]);
2843 *
2844 * console.log(mm.not(['a.a', 'b.b', 'c.c'], '*.a'));
2845 * //=> ['b.b', 'c.c']
2846 * ```
2847 * @param {Array} `list` Array of strings to match.
2848 * @param {String|Array} `patterns` One or more glob pattern to use for matching.
2849 * @param {Object} `options` See available [options](#options) for changing how matches are performed
2850 * @return {Array} Returns an array of strings that **do not match** the given patterns.
2851 * @api public
2852 */
2853micromatch.not = (list, patterns, options = {}) => {
2854 patterns = [].concat(patterns).map(String);
2855 let result = new Set();
2856 let items = [];
2857 let onResult = state => {
2858 if (options.onResult)
2859 options.onResult(state);
2860 items.push(state.output);
2861 };
2862 let matches = micromatch(list, patterns, Object.assign({}, options, { onResult }));
2863 for (let item of items) {
2864 if (!matches.includes(item)) {
2865 result.add(item);
2866 }
2867 }
2868 return [...result];
2869};
2870/**
2871 * Returns true if the given `string` contains the given pattern. Similar
2872 * to [.isMatch](#isMatch) but the pattern can match any part of the string.
2873 *
2874 * ```js
2875 * var mm = require('micromatch');
2876 * // mm.contains(string, pattern[, options]);
2877 *
2878 * console.log(mm.contains('aa/bb/cc', '*b'));
2879 * //=> true
2880 * console.log(mm.contains('aa/bb/cc', '*d'));
2881 * //=> false
2882 * ```
2883 * @param {String} `str` The string to match.
2884 * @param {String|Array} `patterns` Glob pattern to use for matching.
2885 * @param {Object} `options` See available [options](#options) for changing how matches are performed
2886 * @return {Boolean} Returns true if the patter matches any part of `str`.
2887 * @api public
2888 */
2889micromatch.contains = (str, pattern, options) => {
2890 if (typeof str !== 'string') {
2891 throw new TypeError(`Expected a string: "${util.inspect(str)}"`);
2892 }
2893 if (Array.isArray(pattern)) {
2894 return pattern.some(p => micromatch.contains(str, p, options));
2895 }
2896 if (typeof pattern === 'string') {
2897 if (isEmptyString(str) || isEmptyString(pattern)) {
2898 return false;
2899 }
2900 if (str.includes(pattern) || (str.startsWith('./') && str.slice(2).includes(pattern))) {
2901 return true;
2902 }
2903 }
2904 return micromatch.isMatch(str, pattern, Object.assign({}, options, { contains: true }));
2905};
2906/**
2907 * Filter the keys of the given object with the given `glob` pattern
2908 * and `options`. Does not attempt to match nested keys. If you need this feature,
2909 * use [glob-object][] instead.
2910 *
2911 * ```js
2912 * const mm = require('micromatch');
2913 * // mm.matchKeys(object, patterns[, options]);
2914 *
2915 * const obj = { aa: 'a', ab: 'b', ac: 'c' };
2916 * console.log(mm.matchKeys(obj, '*b'));
2917 * //=> { ab: 'b' }
2918 * ```
2919 * @param {Object} `object` The object with keys to filter.
2920 * @param {String|Array} `patterns` One or more glob patterns to use for matching.
2921 * @param {Object} `options` See available [options](#options) for changing how matches are performed
2922 * @return {Object} Returns an object with only keys that match the given patterns.
2923 * @api public
2924 */
2925micromatch.matchKeys = (obj, patterns, options) => {
2926 if (!utils$1.isObject(obj)) {
2927 throw new TypeError('Expected the first argument to be an object');
2928 }
2929 let keys = micromatch(Object.keys(obj), patterns, options);
2930 let res = {};
2931 for (let key of keys)
2932 res[key] = obj[key];
2933 return res;
2934};
2935/**
2936 * Returns true if some of the strings in the given `list` match any of the given glob `patterns`.
2937 *
2938 * ```js
2939 * const mm = require('micromatch');
2940 * // mm.some(list, patterns[, options]);
2941 *
2942 * console.log(mm.some(['foo.js', 'bar.js'], ['*.js', '!foo.js']));
2943 * // true
2944 * console.log(mm.some(['foo.js'], ['*.js', '!foo.js']));
2945 * // false
2946 * ```
2947 * @param {String|Array} `list` The string or array of strings to test. Returns as soon as the first match is found.
2948 * @param {String|Array} `patterns` One or more glob patterns to use for matching.
2949 * @param {Object} `options` See available [options](#options) for changing how matches are performed
2950 * @return {Boolean} Returns true if any patterns match `str`
2951 * @api public
2952 */
2953micromatch.some = (list, patterns, options) => {
2954 let items = [].concat(list);
2955 for (let pattern of [].concat(patterns)) {
2956 let isMatch = picomatch$1(String(pattern), options);
2957 if (items.some(item => isMatch(item))) {
2958 return true;
2959 }
2960 }
2961 return false;
2962};
2963/**
2964 * Returns true if every string in the given `list` matches
2965 * any of the given glob `patterns`.
2966 *
2967 * ```js
2968 * const mm = require('micromatch');
2969 * // mm.every(list, patterns[, options]);
2970 *
2971 * console.log(mm.every('foo.js', ['foo.js']));
2972 * // true
2973 * console.log(mm.every(['foo.js', 'bar.js'], ['*.js']));
2974 * // true
2975 * console.log(mm.every(['foo.js', 'bar.js'], ['*.js', '!foo.js']));
2976 * // false
2977 * console.log(mm.every(['foo.js'], ['*.js', '!foo.js']));
2978 * // false
2979 * ```
2980 * @param {String|Array} `list` The string or array of strings to test.
2981 * @param {String|Array} `patterns` One or more glob patterns to use for matching.
2982 * @param {Object} `options` See available [options](#options) for changing how matches are performed
2983 * @return {Boolean} Returns true if any patterns match `str`
2984 * @api public
2985 */
2986micromatch.every = (list, patterns, options) => {
2987 let items = [].concat(list);
2988 for (let pattern of [].concat(patterns)) {
2989 let isMatch = picomatch$1(String(pattern), options);
2990 if (!items.every(item => isMatch(item))) {
2991 return false;
2992 }
2993 }
2994 return true;
2995};
2996/**
2997 * Returns true if **all** of the given `patterns` match
2998 * the specified string.
2999 *
3000 * ```js
3001 * const mm = require('micromatch');
3002 * // mm.all(string, patterns[, options]);
3003 *
3004 * console.log(mm.all('foo.js', ['foo.js']));
3005 * // true
3006 *
3007 * console.log(mm.all('foo.js', ['*.js', '!foo.js']));
3008 * // false
3009 *
3010 * console.log(mm.all('foo.js', ['*.js', 'foo.js']));
3011 * // true
3012 *
3013 * console.log(mm.all('foo.js', ['*.js', 'f*', '*o*', '*o.js']));
3014 * // true
3015 * ```
3016 * @param {String|Array} `str` The string to test.
3017 * @param {String|Array} `patterns` One or more glob patterns to use for matching.
3018 * @param {Object} `options` See available [options](#options) for changing how matches are performed
3019 * @return {Boolean} Returns true if any patterns match `str`
3020 * @api public
3021 */
3022micromatch.all = (str, patterns, options) => {
3023 if (typeof str !== 'string') {
3024 throw new TypeError(`Expected a string: "${util.inspect(str)}"`);
3025 }
3026 return [].concat(patterns).every(p => picomatch$1(p, options)(str));
3027};
3028/**
3029 * Returns an array of matches captured by `pattern` in `string, or `null` if the pattern did not match.
3030 *
3031 * ```js
3032 * const mm = require('micromatch');
3033 * // mm.capture(pattern, string[, options]);
3034 *
3035 * console.log(mm.capture('test/*.js', 'test/foo.js'));
3036 * //=> ['foo']
3037 * console.log(mm.capture('test/*.js', 'foo/bar.css'));
3038 * //=> null
3039 * ```
3040 * @param {String} `glob` Glob pattern to use for matching.
3041 * @param {String} `input` String to match
3042 * @param {Object} `options` See available [options](#options) for changing how matches are performed
3043 * @return {Boolean} Returns an array of captures if the input matches the glob pattern, otherwise `null`.
3044 * @api public
3045 */
3046micromatch.capture = (glob, input, options) => {
3047 let posix = utils$1.isWindows(options);
3048 let regex = picomatch$1.makeRe(String(glob), Object.assign({}, options, { capture: true }));
3049 let match = regex.exec(posix ? utils$1.toPosixSlashes(input) : input);
3050 if (match) {
3051 return match.slice(1).map(v => v === void 0 ? '' : v);
3052 }
3053};
3054/**
3055 * Create a regular expression from the given glob `pattern`.
3056 *
3057 * ```js
3058 * const mm = require('micromatch');
3059 * // mm.makeRe(pattern[, options]);
3060 *
3061 * console.log(mm.makeRe('*.js'));
3062 * //=> /^(?:(\.[\\\/])?(?!\.)(?=.)[^\/]*?\.js)$/
3063 * ```
3064 * @param {String} `pattern` A glob pattern to convert to regex.
3065 * @param {Object} `options`
3066 * @return {RegExp} Returns a regex created from the given pattern.
3067 * @api public
3068 */
3069micromatch.makeRe = (...args) => picomatch$1.makeRe(...args);
3070/**
3071 * Scan a glob pattern to separate the pattern into segments. Used
3072 * by the [split](#split) method.
3073 *
3074 * ```js
3075 * const mm = require('micromatch');
3076 * const state = mm.scan(pattern[, options]);
3077 * ```
3078 * @param {String} `pattern`
3079 * @param {Object} `options`
3080 * @return {Object} Returns an object with
3081 * @api public
3082 */
3083micromatch.scan = (...args) => picomatch$1.scan(...args);
3084/**
3085 * Parse a glob pattern to create the source string for a regular
3086 * expression.
3087 *
3088 * ```js
3089 * const mm = require('micromatch');
3090 * const state = mm(pattern[, options]);
3091 * ```
3092 * @param {String} `glob`
3093 * @param {Object} `options`
3094 * @return {Object} Returns an object with useful properties and output to be used as regex source string.
3095 * @api public
3096 */
3097micromatch.parse = (patterns, options) => {
3098 let res = [];
3099 for (let pattern of [].concat(patterns || [])) {
3100 for (let str of braces_1(String(pattern), options)) {
3101 res.push(picomatch$1.parse(str, options));
3102 }
3103 }
3104 return res;
3105};
3106/**
3107 * Process the given brace `pattern`.
3108 *
3109 * ```js
3110 * const { braces } = require('micromatch');
3111 * console.log(braces('foo/{a,b,c}/bar'));
3112 * //=> [ 'foo/(a|b|c)/bar' ]
3113 *
3114 * console.log(braces('foo/{a,b,c}/bar', { expand: true }));
3115 * //=> [ 'foo/a/bar', 'foo/b/bar', 'foo/c/bar' ]
3116 * ```
3117 * @param {String} `pattern` String with brace pattern to process.
3118 * @param {Object} `options` Any [options](#options) to change how expansion is performed. See the [braces][] library for all available options.
3119 * @return {Array}
3120 * @api public
3121 */
3122micromatch.braces = (pattern, options) => {
3123 if (typeof pattern !== 'string')
3124 throw new TypeError('Expected a string');
3125 if ((options && options.nobrace === true) || !/\{.*\}/.test(pattern)) {
3126 return [pattern];
3127 }
3128 return braces_1(pattern, options);
3129};
3130/**
3131 * Expand braces
3132 */
3133micromatch.braceExpand = (pattern, options) => {
3134 if (typeof pattern !== 'string')
3135 throw new TypeError('Expected a string');
3136 return micromatch.braces(pattern, Object.assign({}, options, { expand: true }));
3137};
3138/**
3139 * Expose micromatch
3140 */
3141var micromatch_1 = micromatch;
3142
3143function ensureArray(thing) {
3144 if (Array.isArray(thing))
3145 return thing;
3146 if (thing == undefined)
3147 return [];
3148 return [thing];
3149}
3150
3151function getMatcherString(id, resolutionBase) {
3152 if (resolutionBase === false) {
3153 return id;
3154 }
3155 return resolve(...(typeof resolutionBase === 'string' ? [resolutionBase, id] : [id]));
3156}
3157const createFilter = function createFilter(include, exclude, options) {
3158 const resolutionBase = options && options.resolve;
3159 const getMatcher = (id) => {
3160 return id instanceof RegExp
3161 ? id
3162 : {
3163 test: micromatch_1.matcher(getMatcherString(id, resolutionBase)
3164 .split(sep)
3165 .join('/'), { dot: true })
3166 };
3167 };
3168 const includeMatchers = ensureArray(include).map(getMatcher);
3169 const excludeMatchers = ensureArray(exclude).map(getMatcher);
3170 return function (id) {
3171 if (typeof id !== 'string')
3172 return false;
3173 if (/\0/.test(id))
3174 return false;
3175 id = id.split(sep).join('/');
3176 for (let i = 0; i < excludeMatchers.length; ++i) {
3177 const matcher = excludeMatchers[i];
3178 if (matcher.test(id))
3179 return false;
3180 }
3181 for (let i = 0; i < includeMatchers.length; ++i) {
3182 const matcher = includeMatchers[i];
3183 if (matcher.test(id))
3184 return true;
3185 }
3186 return !includeMatchers.length;
3187 };
3188};
3189
3190const reservedWords = 'break case class catch const continue debugger default delete do else export extends finally for function if import in instanceof let new return super switch this throw try typeof var void while with yield enum await implements package protected static interface private public';
3191const builtins = 'arguments Infinity NaN undefined null true false eval uneval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Symbol Error EvalError InternalError RangeError ReferenceError SyntaxError TypeError URIError Number Math Date String RegExp Array Int8Array Uint8Array Uint8ClampedArray Int16Array Uint16Array Int32Array Uint32Array Float32Array Float64Array Map Set WeakMap WeakSet SIMD ArrayBuffer DataView JSON Promise Generator GeneratorFunction Reflect Proxy Intl';
3192const forbiddenIdentifiers = new Set(`${reservedWords} ${builtins}`.split(' '));
3193forbiddenIdentifiers.add('');
3194const makeLegalIdentifier = function makeLegalIdentifier(str) {
3195 str = str.replace(/-(\w)/g, (_, letter) => letter.toUpperCase()).replace(/[^$_a-zA-Z0-9]/g, '_');
3196 if (/\d/.test(str[0]) || forbiddenIdentifiers.has(str)) {
3197 str = `_${str}`;
3198 }
3199 return str || '_';
3200};
3201
3202function stringify$2(obj) {
3203 return (JSON.stringify(obj) || 'undefined').replace(/[\u2028\u2029]/g, char => `\\u${('000' + char.charCodeAt(0).toString(16)).slice(-4)}`);
3204}
3205function serializeArray(arr, indent, baseIndent) {
3206 let output = '[';
3207 const separator = indent ? '\n' + baseIndent + indent : '';
3208 for (let i = 0; i < arr.length; i++) {
3209 const key = arr[i];
3210 output += `${i > 0 ? ',' : ''}${separator}${serialize(key, indent, baseIndent + indent)}`;
3211 }
3212 return output + `${indent ? '\n' + baseIndent : ''}]`;
3213}
3214function serializeObject(obj, indent, baseIndent) {
3215 let output = '{';
3216 const separator = indent ? '\n' + baseIndent + indent : '';
3217 const keys = Object.keys(obj);
3218 for (let i = 0; i < keys.length; i++) {
3219 const key = keys[i];
3220 const stringKey = makeLegalIdentifier(key) === key ? key : stringify$2(key);
3221 output += `${i > 0 ? ',' : ''}${separator}${stringKey}:${indent ? ' ' : ''}${serialize(obj[key], indent, baseIndent + indent)}`;
3222 }
3223 return output + `${indent ? '\n' + baseIndent : ''}}`;
3224}
3225function serialize(obj, indent, baseIndent) {
3226 if (obj === Infinity)
3227 return 'Infinity';
3228 if (obj === -Infinity)
3229 return '-Infinity';
3230 if (obj === 0 && 1 / obj === -Infinity)
3231 return '-0';
3232 if (obj instanceof Date)
3233 return 'new Date(' + obj.getTime() + ')';
3234 if (obj instanceof RegExp)
3235 return obj.toString();
3236 if (obj !== obj)
3237 return 'NaN';
3238 if (Array.isArray(obj))
3239 return serializeArray(obj, indent, baseIndent);
3240 if (obj === null)
3241 return 'null';
3242 if (typeof obj === 'object')
3243 return serializeObject(obj, indent, baseIndent);
3244 return stringify$2(obj);
3245}
3246const dataToEsm = function dataToEsm(data, options = {}) {
3247 const t = options.compact ? '' : 'indent' in options ? options.indent : '\t';
3248 const _ = options.compact ? '' : ' ';
3249 const n = options.compact ? '' : '\n';
3250 const declarationType = options.preferConst ? 'const' : 'var';
3251 if (options.namedExports === false ||
3252 typeof data !== 'object' ||
3253 Array.isArray(data) ||
3254 data instanceof Date ||
3255 data instanceof RegExp ||
3256 data === null) {
3257 const code = serialize(data, options.compact ? null : t, '');
3258 const __ = _ || (/^[{[\-\/]/.test(code) ? '' : ' ');
3259 return `export default${__}${code};`;
3260 }
3261 let namedExportCode = '';
3262 const defaultExportRows = [];
3263 const dataKeys = Object.keys(data);
3264 for (let i = 0; i < dataKeys.length; i++) {
3265 const key = dataKeys[i];
3266 if (key === makeLegalIdentifier(key)) {
3267 if (options.objectShorthand)
3268 defaultExportRows.push(key);
3269 else
3270 defaultExportRows.push(`${key}:${_}${key}`);
3271 namedExportCode += `export ${declarationType} ${key}${_}=${_}${serialize(data[key], options.compact ? null : t, '')};${n}`;
3272 }
3273 else {
3274 defaultExportRows.push(`${stringify$2(key)}:${_}${serialize(data[key], options.compact ? null : t, '')}`);
3275 }
3276 }
3277 return (namedExportCode + `export default${_}{${n}${t}${defaultExportRows.join(`,${n}${t}`)}${n}};${n}`);
3278};
3279
3280export { addExtension, attachScopes, createFilter, dataToEsm, extractAssignedNames, makeLegalIdentifier };