source: imaps-frontend/node_modules/rollup/dist/es/shared/watch.js@ 0c6b92a

main
Last change on this file since 0c6b92a was 0c6b92a, checked in by stefan toskovski <stefantoska84@…>, 5 weeks ago

Pred finalna verzija

  • Property mode set to 100644
File size: 245.0 KB
Line 
1/*
2 @license
3 Rollup.js v4.27.4
4 Sat, 23 Nov 2024 06:59:50 GMT - commit e805b546405a4e6cfccd3fe73e9f4df770023824
5
6 https://github.com/rollup/rollup
7
8 Released under the MIT License.
9*/
10import { getAugmentedNamespace, fseventsImporter, getDefaultExportFromCjs, createFilter, rollupInternal } from './node-entry.js';
11import path from 'node:path';
12import process$1 from 'node:process';
13import require$$0$1 from 'path';
14import require$$0$2 from 'fs';
15import require$$2 from 'util';
16import require$$1 from 'stream';
17import require$$2$1 from 'os';
18import require$$0$3 from 'events';
19import { platform } from 'node:os';
20import './parseAst.js';
21import '../../native.js';
22import 'node:perf_hooks';
23import 'node:fs/promises';
24import 'tty';
25
26var chokidar$1 = {};
27
28var utils$2 = {};
29
30var constants$3;
31var hasRequiredConstants$3;
32
33function requireConstants$3 () {
34 if (hasRequiredConstants$3) return constants$3;
35 hasRequiredConstants$3 = 1;
36
37 const path = require$$0$1;
38 const WIN_SLASH = '\\\\/';
39 const WIN_NO_SLASH = `[^${WIN_SLASH}]`;
40
41 /**
42 * Posix glob regex
43 */
44
45 const DOT_LITERAL = '\\.';
46 const PLUS_LITERAL = '\\+';
47 const QMARK_LITERAL = '\\?';
48 const SLASH_LITERAL = '\\/';
49 const ONE_CHAR = '(?=.)';
50 const QMARK = '[^/]';
51 const END_ANCHOR = `(?:${SLASH_LITERAL}|$)`;
52 const START_ANCHOR = `(?:^|${SLASH_LITERAL})`;
53 const DOTS_SLASH = `${DOT_LITERAL}{1,2}${END_ANCHOR}`;
54 const NO_DOT = `(?!${DOT_LITERAL})`;
55 const NO_DOTS = `(?!${START_ANCHOR}${DOTS_SLASH})`;
56 const NO_DOT_SLASH = `(?!${DOT_LITERAL}{0,1}${END_ANCHOR})`;
57 const NO_DOTS_SLASH = `(?!${DOTS_SLASH})`;
58 const QMARK_NO_DOT = `[^.${SLASH_LITERAL}]`;
59 const STAR = `${QMARK}*?`;
60
61 const POSIX_CHARS = {
62 DOT_LITERAL,
63 PLUS_LITERAL,
64 QMARK_LITERAL,
65 SLASH_LITERAL,
66 ONE_CHAR,
67 QMARK,
68 END_ANCHOR,
69 DOTS_SLASH,
70 NO_DOT,
71 NO_DOTS,
72 NO_DOT_SLASH,
73 NO_DOTS_SLASH,
74 QMARK_NO_DOT,
75 STAR,
76 START_ANCHOR
77 };
78
79 /**
80 * Windows glob regex
81 */
82
83 const WINDOWS_CHARS = {
84 ...POSIX_CHARS,
85
86 SLASH_LITERAL: `[${WIN_SLASH}]`,
87 QMARK: WIN_NO_SLASH,
88 STAR: `${WIN_NO_SLASH}*?`,
89 DOTS_SLASH: `${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$)`,
90 NO_DOT: `(?!${DOT_LITERAL})`,
91 NO_DOTS: `(?!(?:^|[${WIN_SLASH}])${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`,
92 NO_DOT_SLASH: `(?!${DOT_LITERAL}{0,1}(?:[${WIN_SLASH}]|$))`,
93 NO_DOTS_SLASH: `(?!${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`,
94 QMARK_NO_DOT: `[^.${WIN_SLASH}]`,
95 START_ANCHOR: `(?:^|[${WIN_SLASH}])`,
96 END_ANCHOR: `(?:[${WIN_SLASH}]|$)`
97 };
98
99 /**
100 * POSIX Bracket Regex
101 */
102
103 const POSIX_REGEX_SOURCE = {
104 alnum: 'a-zA-Z0-9',
105 alpha: 'a-zA-Z',
106 ascii: '\\x00-\\x7F',
107 blank: ' \\t',
108 cntrl: '\\x00-\\x1F\\x7F',
109 digit: '0-9',
110 graph: '\\x21-\\x7E',
111 lower: 'a-z',
112 print: '\\x20-\\x7E ',
113 punct: '\\-!"#$%&\'()\\*+,./:;<=>?@[\\]^_`{|}~',
114 space: ' \\t\\r\\n\\v\\f',
115 upper: 'A-Z',
116 word: 'A-Za-z0-9_',
117 xdigit: 'A-Fa-f0-9'
118 };
119
120 constants$3 = {
121 MAX_LENGTH: 1024 * 64,
122 POSIX_REGEX_SOURCE,
123
124 // regular expressions
125 REGEX_BACKSLASH: /\\(?![*+?^${}(|)[\]])/g,
126 REGEX_NON_SPECIAL_CHARS: /^[^@![\].,$*+?^{}()|\\/]+/,
127 REGEX_SPECIAL_CHARS: /[-*+?.^${}(|)[\]]/,
128 REGEX_SPECIAL_CHARS_BACKREF: /(\\?)((\W)(\3*))/g,
129 REGEX_SPECIAL_CHARS_GLOBAL: /([-*+?.^${}(|)[\]])/g,
130 REGEX_REMOVE_BACKSLASH: /(?:\[.*?[^\\]\]|\\(?=.))/g,
131
132 // Replace globs with equivalent patterns to reduce parsing time.
133 REPLACEMENTS: {
134 '***': '*',
135 '**/**': '**',
136 '**/**/**': '**'
137 },
138
139 // Digits
140 CHAR_0: 48, /* 0 */
141 CHAR_9: 57, /* 9 */
142
143 // Alphabet chars.
144 CHAR_UPPERCASE_A: 65, /* A */
145 CHAR_LOWERCASE_A: 97, /* a */
146 CHAR_UPPERCASE_Z: 90, /* Z */
147 CHAR_LOWERCASE_Z: 122, /* z */
148
149 CHAR_LEFT_PARENTHESES: 40, /* ( */
150 CHAR_RIGHT_PARENTHESES: 41, /* ) */
151
152 CHAR_ASTERISK: 42, /* * */
153
154 // Non-alphabetic chars.
155 CHAR_AMPERSAND: 38, /* & */
156 CHAR_AT: 64, /* @ */
157 CHAR_BACKWARD_SLASH: 92, /* \ */
158 CHAR_CARRIAGE_RETURN: 13, /* \r */
159 CHAR_CIRCUMFLEX_ACCENT: 94, /* ^ */
160 CHAR_COLON: 58, /* : */
161 CHAR_COMMA: 44, /* , */
162 CHAR_DOT: 46, /* . */
163 CHAR_DOUBLE_QUOTE: 34, /* " */
164 CHAR_EQUAL: 61, /* = */
165 CHAR_EXCLAMATION_MARK: 33, /* ! */
166 CHAR_FORM_FEED: 12, /* \f */
167 CHAR_FORWARD_SLASH: 47, /* / */
168 CHAR_GRAVE_ACCENT: 96, /* ` */
169 CHAR_HASH: 35, /* # */
170 CHAR_HYPHEN_MINUS: 45, /* - */
171 CHAR_LEFT_ANGLE_BRACKET: 60, /* < */
172 CHAR_LEFT_CURLY_BRACE: 123, /* { */
173 CHAR_LEFT_SQUARE_BRACKET: 91, /* [ */
174 CHAR_LINE_FEED: 10, /* \n */
175 CHAR_NO_BREAK_SPACE: 160, /* \u00A0 */
176 CHAR_PERCENT: 37, /* % */
177 CHAR_PLUS: 43, /* + */
178 CHAR_QUESTION_MARK: 63, /* ? */
179 CHAR_RIGHT_ANGLE_BRACKET: 62, /* > */
180 CHAR_RIGHT_CURLY_BRACE: 125, /* } */
181 CHAR_RIGHT_SQUARE_BRACKET: 93, /* ] */
182 CHAR_SEMICOLON: 59, /* ; */
183 CHAR_SINGLE_QUOTE: 39, /* ' */
184 CHAR_SPACE: 32, /* */
185 CHAR_TAB: 9, /* \t */
186 CHAR_UNDERSCORE: 95, /* _ */
187 CHAR_VERTICAL_LINE: 124, /* | */
188 CHAR_ZERO_WIDTH_NOBREAK_SPACE: 65279, /* \uFEFF */
189
190 SEP: path.sep,
191
192 /**
193 * Create EXTGLOB_CHARS
194 */
195
196 extglobChars(chars) {
197 return {
198 '!': { type: 'negate', open: '(?:(?!(?:', close: `))${chars.STAR})` },
199 '?': { type: 'qmark', open: '(?:', close: ')?' },
200 '+': { type: 'plus', open: '(?:', close: ')+' },
201 '*': { type: 'star', open: '(?:', close: ')*' },
202 '@': { type: 'at', open: '(?:', close: ')' }
203 };
204 },
205
206 /**
207 * Create GLOB_CHARS
208 */
209
210 globChars(win32) {
211 return win32 === true ? WINDOWS_CHARS : POSIX_CHARS;
212 }
213 };
214 return constants$3;
215}
216
217var hasRequiredUtils$2;
218
219function requireUtils$2 () {
220 if (hasRequiredUtils$2) return utils$2;
221 hasRequiredUtils$2 = 1;
222 (function (exports) {
223
224 const path = require$$0$1;
225 const win32 = process.platform === 'win32';
226 const {
227 REGEX_BACKSLASH,
228 REGEX_REMOVE_BACKSLASH,
229 REGEX_SPECIAL_CHARS,
230 REGEX_SPECIAL_CHARS_GLOBAL
231 } = /*@__PURE__*/ requireConstants$3();
232
233 exports.isObject = val => val !== null && typeof val === 'object' && !Array.isArray(val);
234 exports.hasRegexChars = str => REGEX_SPECIAL_CHARS.test(str);
235 exports.isRegexChar = str => str.length === 1 && exports.hasRegexChars(str);
236 exports.escapeRegex = str => str.replace(REGEX_SPECIAL_CHARS_GLOBAL, '\\$1');
237 exports.toPosixSlashes = str => str.replace(REGEX_BACKSLASH, '/');
238
239 exports.removeBackslashes = str => {
240 return str.replace(REGEX_REMOVE_BACKSLASH, match => {
241 return match === '\\' ? '' : match;
242 });
243 };
244
245 exports.supportsLookbehinds = () => {
246 const segs = process.version.slice(1).split('.').map(Number);
247 if (segs.length === 3 && segs[0] >= 9 || (segs[0] === 8 && segs[1] >= 10)) {
248 return true;
249 }
250 return false;
251 };
252
253 exports.isWindows = options => {
254 if (options && typeof options.windows === 'boolean') {
255 return options.windows;
256 }
257 return win32 === true || path.sep === '\\';
258 };
259
260 exports.escapeLast = (input, char, lastIdx) => {
261 const idx = input.lastIndexOf(char, lastIdx);
262 if (idx === -1) return input;
263 if (input[idx - 1] === '\\') return exports.escapeLast(input, char, idx - 1);
264 return `${input.slice(0, idx)}\\${input.slice(idx)}`;
265 };
266
267 exports.removePrefix = (input, state = {}) => {
268 let output = input;
269 if (output.startsWith('./')) {
270 output = output.slice(2);
271 state.prefix = './';
272 }
273 return output;
274 };
275
276 exports.wrapOutput = (input, state = {}, options = {}) => {
277 const prepend = options.contains ? '' : '^';
278 const append = options.contains ? '' : '$';
279
280 let output = `${prepend}(?:${input})${append}`;
281 if (state.negated === true) {
282 output = `(?:^(?!${output}).*$)`;
283 }
284 return output;
285 };
286 } (utils$2));
287 return utils$2;
288}
289
290var scan_1$1;
291var hasRequiredScan$1;
292
293function requireScan$1 () {
294 if (hasRequiredScan$1) return scan_1$1;
295 hasRequiredScan$1 = 1;
296
297 const utils = /*@__PURE__*/ requireUtils$2();
298 const {
299 CHAR_ASTERISK, /* * */
300 CHAR_AT, /* @ */
301 CHAR_BACKWARD_SLASH, /* \ */
302 CHAR_COMMA, /* , */
303 CHAR_DOT, /* . */
304 CHAR_EXCLAMATION_MARK, /* ! */
305 CHAR_FORWARD_SLASH, /* / */
306 CHAR_LEFT_CURLY_BRACE, /* { */
307 CHAR_LEFT_PARENTHESES, /* ( */
308 CHAR_LEFT_SQUARE_BRACKET, /* [ */
309 CHAR_PLUS, /* + */
310 CHAR_QUESTION_MARK, /* ? */
311 CHAR_RIGHT_CURLY_BRACE, /* } */
312 CHAR_RIGHT_PARENTHESES, /* ) */
313 CHAR_RIGHT_SQUARE_BRACKET /* ] */
314 } = /*@__PURE__*/ requireConstants$3();
315
316 const isPathSeparator = code => {
317 return code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH;
318 };
319
320 const depth = token => {
321 if (token.isPrefix !== true) {
322 token.depth = token.isGlobstar ? Infinity : 1;
323 }
324 };
325
326 /**
327 * Quickly scans a glob pattern and returns an object with a handful of
328 * useful properties, like `isGlob`, `path` (the leading non-glob, if it exists),
329 * `glob` (the actual pattern), `negated` (true if the path starts with `!` but not
330 * with `!(`) and `negatedExtglob` (true if the path starts with `!(`).
331 *
332 * ```js
333 * const pm = require('picomatch');
334 * console.log(pm.scan('foo/bar/*.js'));
335 * { isGlob: true, input: 'foo/bar/*.js', base: 'foo/bar', glob: '*.js' }
336 * ```
337 * @param {String} `str`
338 * @param {Object} `options`
339 * @return {Object} Returns an object with tokens and regex source string.
340 * @api public
341 */
342
343 const scan = (input, options) => {
344 const opts = options || {};
345
346 const length = input.length - 1;
347 const scanToEnd = opts.parts === true || opts.scanToEnd === true;
348 const slashes = [];
349 const tokens = [];
350 const parts = [];
351
352 let str = input;
353 let index = -1;
354 let start = 0;
355 let lastIndex = 0;
356 let isBrace = false;
357 let isBracket = false;
358 let isGlob = false;
359 let isExtglob = false;
360 let isGlobstar = false;
361 let braceEscaped = false;
362 let backslashes = false;
363 let negated = false;
364 let negatedExtglob = false;
365 let finished = false;
366 let braces = 0;
367 let prev;
368 let code;
369 let token = { value: '', depth: 0, isGlob: false };
370
371 const eos = () => index >= length;
372 const peek = () => str.charCodeAt(index + 1);
373 const advance = () => {
374 prev = code;
375 return str.charCodeAt(++index);
376 };
377
378 while (index < length) {
379 code = advance();
380 let next;
381
382 if (code === CHAR_BACKWARD_SLASH) {
383 backslashes = token.backslashes = true;
384 code = advance();
385
386 if (code === CHAR_LEFT_CURLY_BRACE) {
387 braceEscaped = true;
388 }
389 continue;
390 }
391
392 if (braceEscaped === true || code === CHAR_LEFT_CURLY_BRACE) {
393 braces++;
394
395 while (eos() !== true && (code = advance())) {
396 if (code === CHAR_BACKWARD_SLASH) {
397 backslashes = token.backslashes = true;
398 advance();
399 continue;
400 }
401
402 if (code === CHAR_LEFT_CURLY_BRACE) {
403 braces++;
404 continue;
405 }
406
407 if (braceEscaped !== true && code === CHAR_DOT && (code = advance()) === CHAR_DOT) {
408 isBrace = token.isBrace = true;
409 isGlob = token.isGlob = true;
410 finished = true;
411
412 if (scanToEnd === true) {
413 continue;
414 }
415
416 break;
417 }
418
419 if (braceEscaped !== true && code === CHAR_COMMA) {
420 isBrace = token.isBrace = true;
421 isGlob = token.isGlob = true;
422 finished = true;
423
424 if (scanToEnd === true) {
425 continue;
426 }
427
428 break;
429 }
430
431 if (code === CHAR_RIGHT_CURLY_BRACE) {
432 braces--;
433
434 if (braces === 0) {
435 braceEscaped = false;
436 isBrace = token.isBrace = true;
437 finished = true;
438 break;
439 }
440 }
441 }
442
443 if (scanToEnd === true) {
444 continue;
445 }
446
447 break;
448 }
449
450 if (code === CHAR_FORWARD_SLASH) {
451 slashes.push(index);
452 tokens.push(token);
453 token = { value: '', depth: 0, isGlob: false };
454
455 if (finished === true) continue;
456 if (prev === CHAR_DOT && index === (start + 1)) {
457 start += 2;
458 continue;
459 }
460
461 lastIndex = index + 1;
462 continue;
463 }
464
465 if (opts.noext !== true) {
466 const isExtglobChar = code === CHAR_PLUS
467 || code === CHAR_AT
468 || code === CHAR_ASTERISK
469 || code === CHAR_QUESTION_MARK
470 || code === CHAR_EXCLAMATION_MARK;
471
472 if (isExtglobChar === true && peek() === CHAR_LEFT_PARENTHESES) {
473 isGlob = token.isGlob = true;
474 isExtglob = token.isExtglob = true;
475 finished = true;
476 if (code === CHAR_EXCLAMATION_MARK && index === start) {
477 negatedExtglob = true;
478 }
479
480 if (scanToEnd === true) {
481 while (eos() !== true && (code = advance())) {
482 if (code === CHAR_BACKWARD_SLASH) {
483 backslashes = token.backslashes = true;
484 code = advance();
485 continue;
486 }
487
488 if (code === CHAR_RIGHT_PARENTHESES) {
489 isGlob = token.isGlob = true;
490 finished = true;
491 break;
492 }
493 }
494 continue;
495 }
496 break;
497 }
498 }
499
500 if (code === CHAR_ASTERISK) {
501 if (prev === CHAR_ASTERISK) isGlobstar = token.isGlobstar = true;
502 isGlob = token.isGlob = true;
503 finished = true;
504
505 if (scanToEnd === true) {
506 continue;
507 }
508 break;
509 }
510
511 if (code === CHAR_QUESTION_MARK) {
512 isGlob = token.isGlob = true;
513 finished = true;
514
515 if (scanToEnd === true) {
516 continue;
517 }
518 break;
519 }
520
521 if (code === CHAR_LEFT_SQUARE_BRACKET) {
522 while (eos() !== true && (next = advance())) {
523 if (next === CHAR_BACKWARD_SLASH) {
524 backslashes = token.backslashes = true;
525 advance();
526 continue;
527 }
528
529 if (next === CHAR_RIGHT_SQUARE_BRACKET) {
530 isBracket = token.isBracket = true;
531 isGlob = token.isGlob = true;
532 finished = true;
533 break;
534 }
535 }
536
537 if (scanToEnd === true) {
538 continue;
539 }
540
541 break;
542 }
543
544 if (opts.nonegate !== true && code === CHAR_EXCLAMATION_MARK && index === start) {
545 negated = token.negated = true;
546 start++;
547 continue;
548 }
549
550 if (opts.noparen !== true && code === CHAR_LEFT_PARENTHESES) {
551 isGlob = token.isGlob = true;
552
553 if (scanToEnd === true) {
554 while (eos() !== true && (code = advance())) {
555 if (code === CHAR_LEFT_PARENTHESES) {
556 backslashes = token.backslashes = true;
557 code = advance();
558 continue;
559 }
560
561 if (code === CHAR_RIGHT_PARENTHESES) {
562 finished = true;
563 break;
564 }
565 }
566 continue;
567 }
568 break;
569 }
570
571 if (isGlob === true) {
572 finished = true;
573
574 if (scanToEnd === true) {
575 continue;
576 }
577
578 break;
579 }
580 }
581
582 if (opts.noext === true) {
583 isExtglob = false;
584 isGlob = false;
585 }
586
587 let base = str;
588 let prefix = '';
589 let glob = '';
590
591 if (start > 0) {
592 prefix = str.slice(0, start);
593 str = str.slice(start);
594 lastIndex -= start;
595 }
596
597 if (base && isGlob === true && lastIndex > 0) {
598 base = str.slice(0, lastIndex);
599 glob = str.slice(lastIndex);
600 } else if (isGlob === true) {
601 base = '';
602 glob = str;
603 } else {
604 base = str;
605 }
606
607 if (base && base !== '' && base !== '/' && base !== str) {
608 if (isPathSeparator(base.charCodeAt(base.length - 1))) {
609 base = base.slice(0, -1);
610 }
611 }
612
613 if (opts.unescape === true) {
614 if (glob) glob = utils.removeBackslashes(glob);
615
616 if (base && backslashes === true) {
617 base = utils.removeBackslashes(base);
618 }
619 }
620
621 const state = {
622 prefix,
623 input,
624 start,
625 base,
626 glob,
627 isBrace,
628 isBracket,
629 isGlob,
630 isExtglob,
631 isGlobstar,
632 negated,
633 negatedExtglob
634 };
635
636 if (opts.tokens === true) {
637 state.maxDepth = 0;
638 if (!isPathSeparator(code)) {
639 tokens.push(token);
640 }
641 state.tokens = tokens;
642 }
643
644 if (opts.parts === true || opts.tokens === true) {
645 let prevIndex;
646
647 for (let idx = 0; idx < slashes.length; idx++) {
648 const n = prevIndex ? prevIndex + 1 : start;
649 const i = slashes[idx];
650 const value = input.slice(n, i);
651 if (opts.tokens) {
652 if (idx === 0 && start !== 0) {
653 tokens[idx].isPrefix = true;
654 tokens[idx].value = prefix;
655 } else {
656 tokens[idx].value = value;
657 }
658 depth(tokens[idx]);
659 state.maxDepth += tokens[idx].depth;
660 }
661 if (idx !== 0 || value !== '') {
662 parts.push(value);
663 }
664 prevIndex = i;
665 }
666
667 if (prevIndex && prevIndex + 1 < input.length) {
668 const value = input.slice(prevIndex + 1);
669 parts.push(value);
670
671 if (opts.tokens) {
672 tokens[tokens.length - 1].value = value;
673 depth(tokens[tokens.length - 1]);
674 state.maxDepth += tokens[tokens.length - 1].depth;
675 }
676 }
677
678 state.slashes = slashes;
679 state.parts = parts;
680 }
681
682 return state;
683 };
684
685 scan_1$1 = scan;
686 return scan_1$1;
687}
688
689var parse_1$2;
690var hasRequiredParse$2;
691
692function requireParse$2 () {
693 if (hasRequiredParse$2) return parse_1$2;
694 hasRequiredParse$2 = 1;
695
696 const constants = /*@__PURE__*/ requireConstants$3();
697 const utils = /*@__PURE__*/ requireUtils$2();
698
699 /**
700 * Constants
701 */
702
703 const {
704 MAX_LENGTH,
705 POSIX_REGEX_SOURCE,
706 REGEX_NON_SPECIAL_CHARS,
707 REGEX_SPECIAL_CHARS_BACKREF,
708 REPLACEMENTS
709 } = constants;
710
711 /**
712 * Helpers
713 */
714
715 const expandRange = (args, options) => {
716 if (typeof options.expandRange === 'function') {
717 return options.expandRange(...args, options);
718 }
719
720 args.sort();
721 const value = `[${args.join('-')}]`;
722
723 return value;
724 };
725
726 /**
727 * Create the message for a syntax error
728 */
729
730 const syntaxError = (type, char) => {
731 return `Missing ${type}: "${char}" - use "\\\\${char}" to match literal characters`;
732 };
733
734 /**
735 * Parse the given input string.
736 * @param {String} input
737 * @param {Object} options
738 * @return {Object}
739 */
740
741 const parse = (input, options) => {
742 if (typeof input !== 'string') {
743 throw new TypeError('Expected a string');
744 }
745
746 input = REPLACEMENTS[input] || input;
747
748 const opts = { ...options };
749 const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH;
750
751 let len = input.length;
752 if (len > max) {
753 throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`);
754 }
755
756 const bos = { type: 'bos', value: '', output: opts.prepend || '' };
757 const tokens = [bos];
758
759 const capture = opts.capture ? '' : '?:';
760 const win32 = utils.isWindows(options);
761
762 // create constants based on platform, for windows or posix
763 const PLATFORM_CHARS = constants.globChars(win32);
764 const EXTGLOB_CHARS = constants.extglobChars(PLATFORM_CHARS);
765
766 const {
767 DOT_LITERAL,
768 PLUS_LITERAL,
769 SLASH_LITERAL,
770 ONE_CHAR,
771 DOTS_SLASH,
772 NO_DOT,
773 NO_DOT_SLASH,
774 NO_DOTS_SLASH,
775 QMARK,
776 QMARK_NO_DOT,
777 STAR,
778 START_ANCHOR
779 } = PLATFORM_CHARS;
780
781 const globstar = opts => {
782 return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`;
783 };
784
785 const nodot = opts.dot ? '' : NO_DOT;
786 const qmarkNoDot = opts.dot ? QMARK : QMARK_NO_DOT;
787 let star = opts.bash === true ? globstar(opts) : STAR;
788
789 if (opts.capture) {
790 star = `(${star})`;
791 }
792
793 // minimatch options support
794 if (typeof opts.noext === 'boolean') {
795 opts.noextglob = opts.noext;
796 }
797
798 const state = {
799 input,
800 index: -1,
801 start: 0,
802 dot: opts.dot === true,
803 consumed: '',
804 output: '',
805 prefix: '',
806 backtrack: false,
807 negated: false,
808 brackets: 0,
809 braces: 0,
810 parens: 0,
811 quotes: 0,
812 globstar: false,
813 tokens
814 };
815
816 input = utils.removePrefix(input, state);
817 len = input.length;
818
819 const extglobs = [];
820 const braces = [];
821 const stack = [];
822 let prev = bos;
823 let value;
824
825 /**
826 * Tokenizing helpers
827 */
828
829 const eos = () => state.index === len - 1;
830 const peek = state.peek = (n = 1) => input[state.index + n];
831 const advance = state.advance = () => input[++state.index] || '';
832 const remaining = () => input.slice(state.index + 1);
833 const consume = (value = '', num = 0) => {
834 state.consumed += value;
835 state.index += num;
836 };
837
838 const append = token => {
839 state.output += token.output != null ? token.output : token.value;
840 consume(token.value);
841 };
842
843 const negate = () => {
844 let count = 1;
845
846 while (peek() === '!' && (peek(2) !== '(' || peek(3) === '?')) {
847 advance();
848 state.start++;
849 count++;
850 }
851
852 if (count % 2 === 0) {
853 return false;
854 }
855
856 state.negated = true;
857 state.start++;
858 return true;
859 };
860
861 const increment = type => {
862 state[type]++;
863 stack.push(type);
864 };
865
866 const decrement = type => {
867 state[type]--;
868 stack.pop();
869 };
870
871 /**
872 * Push tokens onto the tokens array. This helper speeds up
873 * tokenizing by 1) helping us avoid backtracking as much as possible,
874 * and 2) helping us avoid creating extra tokens when consecutive
875 * characters are plain text. This improves performance and simplifies
876 * lookbehinds.
877 */
878
879 const push = tok => {
880 if (prev.type === 'globstar') {
881 const isBrace = state.braces > 0 && (tok.type === 'comma' || tok.type === 'brace');
882 const isExtglob = tok.extglob === true || (extglobs.length && (tok.type === 'pipe' || tok.type === 'paren'));
883
884 if (tok.type !== 'slash' && tok.type !== 'paren' && !isBrace && !isExtglob) {
885 state.output = state.output.slice(0, -prev.output.length);
886 prev.type = 'star';
887 prev.value = '*';
888 prev.output = star;
889 state.output += prev.output;
890 }
891 }
892
893 if (extglobs.length && tok.type !== 'paren') {
894 extglobs[extglobs.length - 1].inner += tok.value;
895 }
896
897 if (tok.value || tok.output) append(tok);
898 if (prev && prev.type === 'text' && tok.type === 'text') {
899 prev.value += tok.value;
900 prev.output = (prev.output || '') + tok.value;
901 return;
902 }
903
904 tok.prev = prev;
905 tokens.push(tok);
906 prev = tok;
907 };
908
909 const extglobOpen = (type, value) => {
910 const token = { ...EXTGLOB_CHARS[value], conditions: 1, inner: '' };
911
912 token.prev = prev;
913 token.parens = state.parens;
914 token.output = state.output;
915 const output = (opts.capture ? '(' : '') + token.open;
916
917 increment('parens');
918 push({ type, value, output: state.output ? '' : ONE_CHAR });
919 push({ type: 'paren', extglob: true, value: advance(), output });
920 extglobs.push(token);
921 };
922
923 const extglobClose = token => {
924 let output = token.close + (opts.capture ? ')' : '');
925 let rest;
926
927 if (token.type === 'negate') {
928 let extglobStar = star;
929
930 if (token.inner && token.inner.length > 1 && token.inner.includes('/')) {
931 extglobStar = globstar(opts);
932 }
933
934 if (extglobStar !== star || eos() || /^\)+$/.test(remaining())) {
935 output = token.close = `)$))${extglobStar}`;
936 }
937
938 if (token.inner.includes('*') && (rest = remaining()) && /^\.[^\\/.]+$/.test(rest)) {
939 // Any non-magical string (`.ts`) or even nested expression (`.{ts,tsx}`) can follow after the closing parenthesis.
940 // In this case, we need to parse the string and use it in the output of the original pattern.
941 // Suitable patterns: `/!(*.d).ts`, `/!(*.d).{ts,tsx}`, `**/!(*-dbg).@(js)`.
942 //
943 // Disabling the `fastpaths` option due to a problem with parsing strings as `.ts` in the pattern like `**/!(*.d).ts`.
944 const expression = parse(rest, { ...options, fastpaths: false }).output;
945
946 output = token.close = `)${expression})${extglobStar})`;
947 }
948
949 if (token.prev.type === 'bos') {
950 state.negatedExtglob = true;
951 }
952 }
953
954 push({ type: 'paren', extglob: true, value, output });
955 decrement('parens');
956 };
957
958 /**
959 * Fast paths
960 */
961
962 if (opts.fastpaths !== false && !/(^[*!]|[/()[\]{}"])/.test(input)) {
963 let backslashes = false;
964
965 let output = input.replace(REGEX_SPECIAL_CHARS_BACKREF, (m, esc, chars, first, rest, index) => {
966 if (first === '\\') {
967 backslashes = true;
968 return m;
969 }
970
971 if (first === '?') {
972 if (esc) {
973 return esc + first + (rest ? QMARK.repeat(rest.length) : '');
974 }
975 if (index === 0) {
976 return qmarkNoDot + (rest ? QMARK.repeat(rest.length) : '');
977 }
978 return QMARK.repeat(chars.length);
979 }
980
981 if (first === '.') {
982 return DOT_LITERAL.repeat(chars.length);
983 }
984
985 if (first === '*') {
986 if (esc) {
987 return esc + first + (rest ? star : '');
988 }
989 return star;
990 }
991 return esc ? m : `\\${m}`;
992 });
993
994 if (backslashes === true) {
995 if (opts.unescape === true) {
996 output = output.replace(/\\/g, '');
997 } else {
998 output = output.replace(/\\+/g, m => {
999 return m.length % 2 === 0 ? '\\\\' : (m ? '\\' : '');
1000 });
1001 }
1002 }
1003
1004 if (output === input && opts.contains === true) {
1005 state.output = input;
1006 return state;
1007 }
1008
1009 state.output = utils.wrapOutput(output, state, options);
1010 return state;
1011 }
1012
1013 /**
1014 * Tokenize input until we reach end-of-string
1015 */
1016
1017 while (!eos()) {
1018 value = advance();
1019
1020 if (value === '\u0000') {
1021 continue;
1022 }
1023
1024 /**
1025 * Escaped characters
1026 */
1027
1028 if (value === '\\') {
1029 const next = peek();
1030
1031 if (next === '/' && opts.bash !== true) {
1032 continue;
1033 }
1034
1035 if (next === '.' || next === ';') {
1036 continue;
1037 }
1038
1039 if (!next) {
1040 value += '\\';
1041 push({ type: 'text', value });
1042 continue;
1043 }
1044
1045 // collapse slashes to reduce potential for exploits
1046 const match = /^\\+/.exec(remaining());
1047 let slashes = 0;
1048
1049 if (match && match[0].length > 2) {
1050 slashes = match[0].length;
1051 state.index += slashes;
1052 if (slashes % 2 !== 0) {
1053 value += '\\';
1054 }
1055 }
1056
1057 if (opts.unescape === true) {
1058 value = advance();
1059 } else {
1060 value += advance();
1061 }
1062
1063 if (state.brackets === 0) {
1064 push({ type: 'text', value });
1065 continue;
1066 }
1067 }
1068
1069 /**
1070 * If we're inside a regex character class, continue
1071 * until we reach the closing bracket.
1072 */
1073
1074 if (state.brackets > 0 && (value !== ']' || prev.value === '[' || prev.value === '[^')) {
1075 if (opts.posix !== false && value === ':') {
1076 const inner = prev.value.slice(1);
1077 if (inner.includes('[')) {
1078 prev.posix = true;
1079
1080 if (inner.includes(':')) {
1081 const idx = prev.value.lastIndexOf('[');
1082 const pre = prev.value.slice(0, idx);
1083 const rest = prev.value.slice(idx + 2);
1084 const posix = POSIX_REGEX_SOURCE[rest];
1085 if (posix) {
1086 prev.value = pre + posix;
1087 state.backtrack = true;
1088 advance();
1089
1090 if (!bos.output && tokens.indexOf(prev) === 1) {
1091 bos.output = ONE_CHAR;
1092 }
1093 continue;
1094 }
1095 }
1096 }
1097 }
1098
1099 if ((value === '[' && peek() !== ':') || (value === '-' && peek() === ']')) {
1100 value = `\\${value}`;
1101 }
1102
1103 if (value === ']' && (prev.value === '[' || prev.value === '[^')) {
1104 value = `\\${value}`;
1105 }
1106
1107 if (opts.posix === true && value === '!' && prev.value === '[') {
1108 value = '^';
1109 }
1110
1111 prev.value += value;
1112 append({ value });
1113 continue;
1114 }
1115
1116 /**
1117 * If we're inside a quoted string, continue
1118 * until we reach the closing double quote.
1119 */
1120
1121 if (state.quotes === 1 && value !== '"') {
1122 value = utils.escapeRegex(value);
1123 prev.value += value;
1124 append({ value });
1125 continue;
1126 }
1127
1128 /**
1129 * Double quotes
1130 */
1131
1132 if (value === '"') {
1133 state.quotes = state.quotes === 1 ? 0 : 1;
1134 if (opts.keepQuotes === true) {
1135 push({ type: 'text', value });
1136 }
1137 continue;
1138 }
1139
1140 /**
1141 * Parentheses
1142 */
1143
1144 if (value === '(') {
1145 increment('parens');
1146 push({ type: 'paren', value });
1147 continue;
1148 }
1149
1150 if (value === ')') {
1151 if (state.parens === 0 && opts.strictBrackets === true) {
1152 throw new SyntaxError(syntaxError('opening', '('));
1153 }
1154
1155 const extglob = extglobs[extglobs.length - 1];
1156 if (extglob && state.parens === extglob.parens + 1) {
1157 extglobClose(extglobs.pop());
1158 continue;
1159 }
1160
1161 push({ type: 'paren', value, output: state.parens ? ')' : '\\)' });
1162 decrement('parens');
1163 continue;
1164 }
1165
1166 /**
1167 * Square brackets
1168 */
1169
1170 if (value === '[') {
1171 if (opts.nobracket === true || !remaining().includes(']')) {
1172 if (opts.nobracket !== true && opts.strictBrackets === true) {
1173 throw new SyntaxError(syntaxError('closing', ']'));
1174 }
1175
1176 value = `\\${value}`;
1177 } else {
1178 increment('brackets');
1179 }
1180
1181 push({ type: 'bracket', value });
1182 continue;
1183 }
1184
1185 if (value === ']') {
1186 if (opts.nobracket === true || (prev && prev.type === 'bracket' && prev.value.length === 1)) {
1187 push({ type: 'text', value, output: `\\${value}` });
1188 continue;
1189 }
1190
1191 if (state.brackets === 0) {
1192 if (opts.strictBrackets === true) {
1193 throw new SyntaxError(syntaxError('opening', '['));
1194 }
1195
1196 push({ type: 'text', value, output: `\\${value}` });
1197 continue;
1198 }
1199
1200 decrement('brackets');
1201
1202 const prevValue = prev.value.slice(1);
1203 if (prev.posix !== true && prevValue[0] === '^' && !prevValue.includes('/')) {
1204 value = `/${value}`;
1205 }
1206
1207 prev.value += value;
1208 append({ value });
1209
1210 // when literal brackets are explicitly disabled
1211 // assume we should match with a regex character class
1212 if (opts.literalBrackets === false || utils.hasRegexChars(prevValue)) {
1213 continue;
1214 }
1215
1216 const escaped = utils.escapeRegex(prev.value);
1217 state.output = state.output.slice(0, -prev.value.length);
1218
1219 // when literal brackets are explicitly enabled
1220 // assume we should escape the brackets to match literal characters
1221 if (opts.literalBrackets === true) {
1222 state.output += escaped;
1223 prev.value = escaped;
1224 continue;
1225 }
1226
1227 // when the user specifies nothing, try to match both
1228 prev.value = `(${capture}${escaped}|${prev.value})`;
1229 state.output += prev.value;
1230 continue;
1231 }
1232
1233 /**
1234 * Braces
1235 */
1236
1237 if (value === '{' && opts.nobrace !== true) {
1238 increment('braces');
1239
1240 const open = {
1241 type: 'brace',
1242 value,
1243 output: '(',
1244 outputIndex: state.output.length,
1245 tokensIndex: state.tokens.length
1246 };
1247
1248 braces.push(open);
1249 push(open);
1250 continue;
1251 }
1252
1253 if (value === '}') {
1254 const brace = braces[braces.length - 1];
1255
1256 if (opts.nobrace === true || !brace) {
1257 push({ type: 'text', value, output: value });
1258 continue;
1259 }
1260
1261 let output = ')';
1262
1263 if (brace.dots === true) {
1264 const arr = tokens.slice();
1265 const range = [];
1266
1267 for (let i = arr.length - 1; i >= 0; i--) {
1268 tokens.pop();
1269 if (arr[i].type === 'brace') {
1270 break;
1271 }
1272 if (arr[i].type !== 'dots') {
1273 range.unshift(arr[i].value);
1274 }
1275 }
1276
1277 output = expandRange(range, opts);
1278 state.backtrack = true;
1279 }
1280
1281 if (brace.comma !== true && brace.dots !== true) {
1282 const out = state.output.slice(0, brace.outputIndex);
1283 const toks = state.tokens.slice(brace.tokensIndex);
1284 brace.value = brace.output = '\\{';
1285 value = output = '\\}';
1286 state.output = out;
1287 for (const t of toks) {
1288 state.output += (t.output || t.value);
1289 }
1290 }
1291
1292 push({ type: 'brace', value, output });
1293 decrement('braces');
1294 braces.pop();
1295 continue;
1296 }
1297
1298 /**
1299 * Pipes
1300 */
1301
1302 if (value === '|') {
1303 if (extglobs.length > 0) {
1304 extglobs[extglobs.length - 1].conditions++;
1305 }
1306 push({ type: 'text', value });
1307 continue;
1308 }
1309
1310 /**
1311 * Commas
1312 */
1313
1314 if (value === ',') {
1315 let output = value;
1316
1317 const brace = braces[braces.length - 1];
1318 if (brace && stack[stack.length - 1] === 'braces') {
1319 brace.comma = true;
1320 output = '|';
1321 }
1322
1323 push({ type: 'comma', value, output });
1324 continue;
1325 }
1326
1327 /**
1328 * Slashes
1329 */
1330
1331 if (value === '/') {
1332 // if the beginning of the glob is "./", advance the start
1333 // to the current index, and don't add the "./" characters
1334 // to the state. This greatly simplifies lookbehinds when
1335 // checking for BOS characters like "!" and "." (not "./")
1336 if (prev.type === 'dot' && state.index === state.start + 1) {
1337 state.start = state.index + 1;
1338 state.consumed = '';
1339 state.output = '';
1340 tokens.pop();
1341 prev = bos; // reset "prev" to the first token
1342 continue;
1343 }
1344
1345 push({ type: 'slash', value, output: SLASH_LITERAL });
1346 continue;
1347 }
1348
1349 /**
1350 * Dots
1351 */
1352
1353 if (value === '.') {
1354 if (state.braces > 0 && prev.type === 'dot') {
1355 if (prev.value === '.') prev.output = DOT_LITERAL;
1356 const brace = braces[braces.length - 1];
1357 prev.type = 'dots';
1358 prev.output += value;
1359 prev.value += value;
1360 brace.dots = true;
1361 continue;
1362 }
1363
1364 if ((state.braces + state.parens) === 0 && prev.type !== 'bos' && prev.type !== 'slash') {
1365 push({ type: 'text', value, output: DOT_LITERAL });
1366 continue;
1367 }
1368
1369 push({ type: 'dot', value, output: DOT_LITERAL });
1370 continue;
1371 }
1372
1373 /**
1374 * Question marks
1375 */
1376
1377 if (value === '?') {
1378 const isGroup = prev && prev.value === '(';
1379 if (!isGroup && opts.noextglob !== true && peek() === '(' && peek(2) !== '?') {
1380 extglobOpen('qmark', value);
1381 continue;
1382 }
1383
1384 if (prev && prev.type === 'paren') {
1385 const next = peek();
1386 let output = value;
1387
1388 if (next === '<' && !utils.supportsLookbehinds()) {
1389 throw new Error('Node.js v10 or higher is required for regex lookbehinds');
1390 }
1391
1392 if ((prev.value === '(' && !/[!=<:]/.test(next)) || (next === '<' && !/<([!=]|\w+>)/.test(remaining()))) {
1393 output = `\\${value}`;
1394 }
1395
1396 push({ type: 'text', value, output });
1397 continue;
1398 }
1399
1400 if (opts.dot !== true && (prev.type === 'slash' || prev.type === 'bos')) {
1401 push({ type: 'qmark', value, output: QMARK_NO_DOT });
1402 continue;
1403 }
1404
1405 push({ type: 'qmark', value, output: QMARK });
1406 continue;
1407 }
1408
1409 /**
1410 * Exclamation
1411 */
1412
1413 if (value === '!') {
1414 if (opts.noextglob !== true && peek() === '(') {
1415 if (peek(2) !== '?' || !/[!=<:]/.test(peek(3))) {
1416 extglobOpen('negate', value);
1417 continue;
1418 }
1419 }
1420
1421 if (opts.nonegate !== true && state.index === 0) {
1422 negate();
1423 continue;
1424 }
1425 }
1426
1427 /**
1428 * Plus
1429 */
1430
1431 if (value === '+') {
1432 if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') {
1433 extglobOpen('plus', value);
1434 continue;
1435 }
1436
1437 if ((prev && prev.value === '(') || opts.regex === false) {
1438 push({ type: 'plus', value, output: PLUS_LITERAL });
1439 continue;
1440 }
1441
1442 if ((prev && (prev.type === 'bracket' || prev.type === 'paren' || prev.type === 'brace')) || state.parens > 0) {
1443 push({ type: 'plus', value });
1444 continue;
1445 }
1446
1447 push({ type: 'plus', value: PLUS_LITERAL });
1448 continue;
1449 }
1450
1451 /**
1452 * Plain text
1453 */
1454
1455 if (value === '@') {
1456 if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') {
1457 push({ type: 'at', extglob: true, value, output: '' });
1458 continue;
1459 }
1460
1461 push({ type: 'text', value });
1462 continue;
1463 }
1464
1465 /**
1466 * Plain text
1467 */
1468
1469 if (value !== '*') {
1470 if (value === '$' || value === '^') {
1471 value = `\\${value}`;
1472 }
1473
1474 const match = REGEX_NON_SPECIAL_CHARS.exec(remaining());
1475 if (match) {
1476 value += match[0];
1477 state.index += match[0].length;
1478 }
1479
1480 push({ type: 'text', value });
1481 continue;
1482 }
1483
1484 /**
1485 * Stars
1486 */
1487
1488 if (prev && (prev.type === 'globstar' || prev.star === true)) {
1489 prev.type = 'star';
1490 prev.star = true;
1491 prev.value += value;
1492 prev.output = star;
1493 state.backtrack = true;
1494 state.globstar = true;
1495 consume(value);
1496 continue;
1497 }
1498
1499 let rest = remaining();
1500 if (opts.noextglob !== true && /^\([^?]/.test(rest)) {
1501 extglobOpen('star', value);
1502 continue;
1503 }
1504
1505 if (prev.type === 'star') {
1506 if (opts.noglobstar === true) {
1507 consume(value);
1508 continue;
1509 }
1510
1511 const prior = prev.prev;
1512 const before = prior.prev;
1513 const isStart = prior.type === 'slash' || prior.type === 'bos';
1514 const afterStar = before && (before.type === 'star' || before.type === 'globstar');
1515
1516 if (opts.bash === true && (!isStart || (rest[0] && rest[0] !== '/'))) {
1517 push({ type: 'star', value, output: '' });
1518 continue;
1519 }
1520
1521 const isBrace = state.braces > 0 && (prior.type === 'comma' || prior.type === 'brace');
1522 const isExtglob = extglobs.length && (prior.type === 'pipe' || prior.type === 'paren');
1523 if (!isStart && prior.type !== 'paren' && !isBrace && !isExtglob) {
1524 push({ type: 'star', value, output: '' });
1525 continue;
1526 }
1527
1528 // strip consecutive `/**/`
1529 while (rest.slice(0, 3) === '/**') {
1530 const after = input[state.index + 4];
1531 if (after && after !== '/') {
1532 break;
1533 }
1534 rest = rest.slice(3);
1535 consume('/**', 3);
1536 }
1537
1538 if (prior.type === 'bos' && eos()) {
1539 prev.type = 'globstar';
1540 prev.value += value;
1541 prev.output = globstar(opts);
1542 state.output = prev.output;
1543 state.globstar = true;
1544 consume(value);
1545 continue;
1546 }
1547
1548 if (prior.type === 'slash' && prior.prev.type !== 'bos' && !afterStar && eos()) {
1549 state.output = state.output.slice(0, -(prior.output + prev.output).length);
1550 prior.output = `(?:${prior.output}`;
1551
1552 prev.type = 'globstar';
1553 prev.output = globstar(opts) + (opts.strictSlashes ? ')' : '|$)');
1554 prev.value += value;
1555 state.globstar = true;
1556 state.output += prior.output + prev.output;
1557 consume(value);
1558 continue;
1559 }
1560
1561 if (prior.type === 'slash' && prior.prev.type !== 'bos' && rest[0] === '/') {
1562 const end = rest[1] !== void 0 ? '|$' : '';
1563
1564 state.output = state.output.slice(0, -(prior.output + prev.output).length);
1565 prior.output = `(?:${prior.output}`;
1566
1567 prev.type = 'globstar';
1568 prev.output = `${globstar(opts)}${SLASH_LITERAL}|${SLASH_LITERAL}${end})`;
1569 prev.value += value;
1570
1571 state.output += prior.output + prev.output;
1572 state.globstar = true;
1573
1574 consume(value + advance());
1575
1576 push({ type: 'slash', value: '/', output: '' });
1577 continue;
1578 }
1579
1580 if (prior.type === 'bos' && rest[0] === '/') {
1581 prev.type = 'globstar';
1582 prev.value += value;
1583 prev.output = `(?:^|${SLASH_LITERAL}|${globstar(opts)}${SLASH_LITERAL})`;
1584 state.output = prev.output;
1585 state.globstar = true;
1586 consume(value + advance());
1587 push({ type: 'slash', value: '/', output: '' });
1588 continue;
1589 }
1590
1591 // remove single star from output
1592 state.output = state.output.slice(0, -prev.output.length);
1593
1594 // reset previous token to globstar
1595 prev.type = 'globstar';
1596 prev.output = globstar(opts);
1597 prev.value += value;
1598
1599 // reset output with globstar
1600 state.output += prev.output;
1601 state.globstar = true;
1602 consume(value);
1603 continue;
1604 }
1605
1606 const token = { type: 'star', value, output: star };
1607
1608 if (opts.bash === true) {
1609 token.output = '.*?';
1610 if (prev.type === 'bos' || prev.type === 'slash') {
1611 token.output = nodot + token.output;
1612 }
1613 push(token);
1614 continue;
1615 }
1616
1617 if (prev && (prev.type === 'bracket' || prev.type === 'paren') && opts.regex === true) {
1618 token.output = value;
1619 push(token);
1620 continue;
1621 }
1622
1623 if (state.index === state.start || prev.type === 'slash' || prev.type === 'dot') {
1624 if (prev.type === 'dot') {
1625 state.output += NO_DOT_SLASH;
1626 prev.output += NO_DOT_SLASH;
1627
1628 } else if (opts.dot === true) {
1629 state.output += NO_DOTS_SLASH;
1630 prev.output += NO_DOTS_SLASH;
1631
1632 } else {
1633 state.output += nodot;
1634 prev.output += nodot;
1635 }
1636
1637 if (peek() !== '*') {
1638 state.output += ONE_CHAR;
1639 prev.output += ONE_CHAR;
1640 }
1641 }
1642
1643 push(token);
1644 }
1645
1646 while (state.brackets > 0) {
1647 if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', ']'));
1648 state.output = utils.escapeLast(state.output, '[');
1649 decrement('brackets');
1650 }
1651
1652 while (state.parens > 0) {
1653 if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', ')'));
1654 state.output = utils.escapeLast(state.output, '(');
1655 decrement('parens');
1656 }
1657
1658 while (state.braces > 0) {
1659 if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', '}'));
1660 state.output = utils.escapeLast(state.output, '{');
1661 decrement('braces');
1662 }
1663
1664 if (opts.strictSlashes !== true && (prev.type === 'star' || prev.type === 'bracket')) {
1665 push({ type: 'maybe_slash', value: '', output: `${SLASH_LITERAL}?` });
1666 }
1667
1668 // rebuild the output if we had to backtrack at any point
1669 if (state.backtrack === true) {
1670 state.output = '';
1671
1672 for (const token of state.tokens) {
1673 state.output += token.output != null ? token.output : token.value;
1674
1675 if (token.suffix) {
1676 state.output += token.suffix;
1677 }
1678 }
1679 }
1680
1681 return state;
1682 };
1683
1684 /**
1685 * Fast paths for creating regular expressions for common glob patterns.
1686 * This can significantly speed up processing and has very little downside
1687 * impact when none of the fast paths match.
1688 */
1689
1690 parse.fastpaths = (input, options) => {
1691 const opts = { ...options };
1692 const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH;
1693 const len = input.length;
1694 if (len > max) {
1695 throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`);
1696 }
1697
1698 input = REPLACEMENTS[input] || input;
1699 const win32 = utils.isWindows(options);
1700
1701 // create constants based on platform, for windows or posix
1702 const {
1703 DOT_LITERAL,
1704 SLASH_LITERAL,
1705 ONE_CHAR,
1706 DOTS_SLASH,
1707 NO_DOT,
1708 NO_DOTS,
1709 NO_DOTS_SLASH,
1710 STAR,
1711 START_ANCHOR
1712 } = constants.globChars(win32);
1713
1714 const nodot = opts.dot ? NO_DOTS : NO_DOT;
1715 const slashDot = opts.dot ? NO_DOTS_SLASH : NO_DOT;
1716 const capture = opts.capture ? '' : '?:';
1717 const state = { negated: false, prefix: '' };
1718 let star = opts.bash === true ? '.*?' : STAR;
1719
1720 if (opts.capture) {
1721 star = `(${star})`;
1722 }
1723
1724 const globstar = opts => {
1725 if (opts.noglobstar === true) return star;
1726 return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`;
1727 };
1728
1729 const create = str => {
1730 switch (str) {
1731 case '*':
1732 return `${nodot}${ONE_CHAR}${star}`;
1733
1734 case '.*':
1735 return `${DOT_LITERAL}${ONE_CHAR}${star}`;
1736
1737 case '*.*':
1738 return `${nodot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`;
1739
1740 case '*/*':
1741 return `${nodot}${star}${SLASH_LITERAL}${ONE_CHAR}${slashDot}${star}`;
1742
1743 case '**':
1744 return nodot + globstar(opts);
1745
1746 case '**/*':
1747 return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${ONE_CHAR}${star}`;
1748
1749 case '**/*.*':
1750 return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`;
1751
1752 case '**/.*':
1753 return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${DOT_LITERAL}${ONE_CHAR}${star}`;
1754
1755 default: {
1756 const match = /^(.*?)\.(\w+)$/.exec(str);
1757 if (!match) return;
1758
1759 const source = create(match[1]);
1760 if (!source) return;
1761
1762 return source + DOT_LITERAL + match[2];
1763 }
1764 }
1765 };
1766
1767 const output = utils.removePrefix(input, state);
1768 let source = create(output);
1769
1770 if (source && opts.strictSlashes !== true) {
1771 source += `${SLASH_LITERAL}?`;
1772 }
1773
1774 return source;
1775 };
1776
1777 parse_1$2 = parse;
1778 return parse_1$2;
1779}
1780
1781var picomatch_1$1;
1782var hasRequiredPicomatch$3;
1783
1784function requirePicomatch$3 () {
1785 if (hasRequiredPicomatch$3) return picomatch_1$1;
1786 hasRequiredPicomatch$3 = 1;
1787
1788 const path = require$$0$1;
1789 const scan = /*@__PURE__*/ requireScan$1();
1790 const parse = /*@__PURE__*/ requireParse$2();
1791 const utils = /*@__PURE__*/ requireUtils$2();
1792 const constants = /*@__PURE__*/ requireConstants$3();
1793 const isObject = val => val && typeof val === 'object' && !Array.isArray(val);
1794
1795 /**
1796 * Creates a matcher function from one or more glob patterns. The
1797 * returned function takes a string to match as its first argument,
1798 * and returns true if the string is a match. The returned matcher
1799 * function also takes a boolean as the second argument that, when true,
1800 * returns an object with additional information.
1801 *
1802 * ```js
1803 * const picomatch = require('picomatch');
1804 * // picomatch(glob[, options]);
1805 *
1806 * const isMatch = picomatch('*.!(*a)');
1807 * console.log(isMatch('a.a')); //=> false
1808 * console.log(isMatch('a.b')); //=> true
1809 * ```
1810 * @name picomatch
1811 * @param {String|Array} `globs` One or more glob patterns.
1812 * @param {Object=} `options`
1813 * @return {Function=} Returns a matcher function.
1814 * @api public
1815 */
1816
1817 const picomatch = (glob, options, returnState = false) => {
1818 if (Array.isArray(glob)) {
1819 const fns = glob.map(input => picomatch(input, options, returnState));
1820 const arrayMatcher = str => {
1821 for (const isMatch of fns) {
1822 const state = isMatch(str);
1823 if (state) return state;
1824 }
1825 return false;
1826 };
1827 return arrayMatcher;
1828 }
1829
1830 const isState = isObject(glob) && glob.tokens && glob.input;
1831
1832 if (glob === '' || (typeof glob !== 'string' && !isState)) {
1833 throw new TypeError('Expected pattern to be a non-empty string');
1834 }
1835
1836 const opts = options || {};
1837 const posix = utils.isWindows(options);
1838 const regex = isState
1839 ? picomatch.compileRe(glob, options)
1840 : picomatch.makeRe(glob, options, false, true);
1841
1842 const state = regex.state;
1843 delete regex.state;
1844
1845 let isIgnored = () => false;
1846 if (opts.ignore) {
1847 const ignoreOpts = { ...options, ignore: null, onMatch: null, onResult: null };
1848 isIgnored = picomatch(opts.ignore, ignoreOpts, returnState);
1849 }
1850
1851 const matcher = (input, returnObject = false) => {
1852 const { isMatch, match, output } = picomatch.test(input, regex, options, { glob, posix });
1853 const result = { glob, state, regex, posix, input, output, match, isMatch };
1854
1855 if (typeof opts.onResult === 'function') {
1856 opts.onResult(result);
1857 }
1858
1859 if (isMatch === false) {
1860 result.isMatch = false;
1861 return returnObject ? result : false;
1862 }
1863
1864 if (isIgnored(input)) {
1865 if (typeof opts.onIgnore === 'function') {
1866 opts.onIgnore(result);
1867 }
1868 result.isMatch = false;
1869 return returnObject ? result : false;
1870 }
1871
1872 if (typeof opts.onMatch === 'function') {
1873 opts.onMatch(result);
1874 }
1875 return returnObject ? result : true;
1876 };
1877
1878 if (returnState) {
1879 matcher.state = state;
1880 }
1881
1882 return matcher;
1883 };
1884
1885 /**
1886 * Test `input` with the given `regex`. This is used by the main
1887 * `picomatch()` function to test the input string.
1888 *
1889 * ```js
1890 * const picomatch = require('picomatch');
1891 * // picomatch.test(input, regex[, options]);
1892 *
1893 * console.log(picomatch.test('foo/bar', /^(?:([^/]*?)\/([^/]*?))$/));
1894 * // { isMatch: true, match: [ 'foo/', 'foo', 'bar' ], output: 'foo/bar' }
1895 * ```
1896 * @param {String} `input` String to test.
1897 * @param {RegExp} `regex`
1898 * @return {Object} Returns an object with matching info.
1899 * @api public
1900 */
1901
1902 picomatch.test = (input, regex, options, { glob, posix } = {}) => {
1903 if (typeof input !== 'string') {
1904 throw new TypeError('Expected input to be a string');
1905 }
1906
1907 if (input === '') {
1908 return { isMatch: false, output: '' };
1909 }
1910
1911 const opts = options || {};
1912 const format = opts.format || (posix ? utils.toPosixSlashes : null);
1913 let match = input === glob;
1914 let output = (match && format) ? format(input) : input;
1915
1916 if (match === false) {
1917 output = format ? format(input) : input;
1918 match = output === glob;
1919 }
1920
1921 if (match === false || opts.capture === true) {
1922 if (opts.matchBase === true || opts.basename === true) {
1923 match = picomatch.matchBase(input, regex, options, posix);
1924 } else {
1925 match = regex.exec(output);
1926 }
1927 }
1928
1929 return { isMatch: Boolean(match), match, output };
1930 };
1931
1932 /**
1933 * Match the basename of a filepath.
1934 *
1935 * ```js
1936 * const picomatch = require('picomatch');
1937 * // picomatch.matchBase(input, glob[, options]);
1938 * console.log(picomatch.matchBase('foo/bar.js', '*.js'); // true
1939 * ```
1940 * @param {String} `input` String to test.
1941 * @param {RegExp|String} `glob` Glob pattern or regex created by [.makeRe](#makeRe).
1942 * @return {Boolean}
1943 * @api public
1944 */
1945
1946 picomatch.matchBase = (input, glob, options, posix = utils.isWindows(options)) => {
1947 const regex = glob instanceof RegExp ? glob : picomatch.makeRe(glob, options);
1948 return regex.test(path.basename(input));
1949 };
1950
1951 /**
1952 * Returns true if **any** of the given glob `patterns` match the specified `string`.
1953 *
1954 * ```js
1955 * const picomatch = require('picomatch');
1956 * // picomatch.isMatch(string, patterns[, options]);
1957 *
1958 * console.log(picomatch.isMatch('a.a', ['b.*', '*.a'])); //=> true
1959 * console.log(picomatch.isMatch('a.a', 'b.*')); //=> false
1960 * ```
1961 * @param {String|Array} str The string to test.
1962 * @param {String|Array} patterns One or more glob patterns to use for matching.
1963 * @param {Object} [options] See available [options](#options).
1964 * @return {Boolean} Returns true if any patterns match `str`
1965 * @api public
1966 */
1967
1968 picomatch.isMatch = (str, patterns, options) => picomatch(patterns, options)(str);
1969
1970 /**
1971 * Parse a glob pattern to create the source string for a regular
1972 * expression.
1973 *
1974 * ```js
1975 * const picomatch = require('picomatch');
1976 * const result = picomatch.parse(pattern[, options]);
1977 * ```
1978 * @param {String} `pattern`
1979 * @param {Object} `options`
1980 * @return {Object} Returns an object with useful properties and output to be used as a regex source string.
1981 * @api public
1982 */
1983
1984 picomatch.parse = (pattern, options) => {
1985 if (Array.isArray(pattern)) return pattern.map(p => picomatch.parse(p, options));
1986 return parse(pattern, { ...options, fastpaths: false });
1987 };
1988
1989 /**
1990 * Scan a glob pattern to separate the pattern into segments.
1991 *
1992 * ```js
1993 * const picomatch = require('picomatch');
1994 * // picomatch.scan(input[, options]);
1995 *
1996 * const result = picomatch.scan('!./foo/*.js');
1997 * console.log(result);
1998 * { prefix: '!./',
1999 * input: '!./foo/*.js',
2000 * start: 3,
2001 * base: 'foo',
2002 * glob: '*.js',
2003 * isBrace: false,
2004 * isBracket: false,
2005 * isGlob: true,
2006 * isExtglob: false,
2007 * isGlobstar: false,
2008 * negated: true }
2009 * ```
2010 * @param {String} `input` Glob pattern to scan.
2011 * @param {Object} `options`
2012 * @return {Object} Returns an object with
2013 * @api public
2014 */
2015
2016 picomatch.scan = (input, options) => scan(input, options);
2017
2018 /**
2019 * Compile a regular expression from the `state` object returned by the
2020 * [parse()](#parse) method.
2021 *
2022 * @param {Object} `state`
2023 * @param {Object} `options`
2024 * @param {Boolean} `returnOutput` Intended for implementors, this argument allows you to return the raw output from the parser.
2025 * @param {Boolean} `returnState` Adds the state to a `state` property on the returned regex. Useful for implementors and debugging.
2026 * @return {RegExp}
2027 * @api public
2028 */
2029
2030 picomatch.compileRe = (state, options, returnOutput = false, returnState = false) => {
2031 if (returnOutput === true) {
2032 return state.output;
2033 }
2034
2035 const opts = options || {};
2036 const prepend = opts.contains ? '' : '^';
2037 const append = opts.contains ? '' : '$';
2038
2039 let source = `${prepend}(?:${state.output})${append}`;
2040 if (state && state.negated === true) {
2041 source = `^(?!${source}).*$`;
2042 }
2043
2044 const regex = picomatch.toRegex(source, options);
2045 if (returnState === true) {
2046 regex.state = state;
2047 }
2048
2049 return regex;
2050 };
2051
2052 /**
2053 * Create a regular expression from a parsed glob pattern.
2054 *
2055 * ```js
2056 * const picomatch = require('picomatch');
2057 * const state = picomatch.parse('*.js');
2058 * // picomatch.compileRe(state[, options]);
2059 *
2060 * console.log(picomatch.compileRe(state));
2061 * //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/
2062 * ```
2063 * @param {String} `state` The object returned from the `.parse` method.
2064 * @param {Object} `options`
2065 * @param {Boolean} `returnOutput` Implementors may use this argument to return the compiled output, instead of a regular expression. This is not exposed on the options to prevent end-users from mutating the result.
2066 * @param {Boolean} `returnState` Implementors may use this argument to return the state from the parsed glob with the returned regular expression.
2067 * @return {RegExp} Returns a regex created from the given pattern.
2068 * @api public
2069 */
2070
2071 picomatch.makeRe = (input, options = {}, returnOutput = false, returnState = false) => {
2072 if (!input || typeof input !== 'string') {
2073 throw new TypeError('Expected a non-empty string');
2074 }
2075
2076 let parsed = { negated: false, fastpaths: true };
2077
2078 if (options.fastpaths !== false && (input[0] === '.' || input[0] === '*')) {
2079 parsed.output = parse.fastpaths(input, options);
2080 }
2081
2082 if (!parsed.output) {
2083 parsed = parse(input, options);
2084 }
2085
2086 return picomatch.compileRe(parsed, options, returnOutput, returnState);
2087 };
2088
2089 /**
2090 * Create a regular expression from the given regex source string.
2091 *
2092 * ```js
2093 * const picomatch = require('picomatch');
2094 * // picomatch.toRegex(source[, options]);
2095 *
2096 * const { output } = picomatch.parse('*.js');
2097 * console.log(picomatch.toRegex(output));
2098 * //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/
2099 * ```
2100 * @param {String} `source` Regular expression source string.
2101 * @param {Object} `options`
2102 * @return {RegExp}
2103 * @api public
2104 */
2105
2106 picomatch.toRegex = (source, options) => {
2107 try {
2108 const opts = options || {};
2109 return new RegExp(source, opts.flags || (opts.nocase ? 'i' : ''));
2110 } catch (err) {
2111 if (options && options.debug === true) throw err;
2112 return /$^/;
2113 }
2114 };
2115
2116 /**
2117 * Picomatch constants.
2118 * @return {Object}
2119 */
2120
2121 picomatch.constants = constants;
2122
2123 /**
2124 * Expose "picomatch"
2125 */
2126
2127 picomatch_1$1 = picomatch;
2128 return picomatch_1$1;
2129}
2130
2131var picomatch$1;
2132var hasRequiredPicomatch$2;
2133
2134function requirePicomatch$2 () {
2135 if (hasRequiredPicomatch$2) return picomatch$1;
2136 hasRequiredPicomatch$2 = 1;
2137
2138 picomatch$1 = /*@__PURE__*/ requirePicomatch$3();
2139 return picomatch$1;
2140}
2141
2142var readdirp_1;
2143var hasRequiredReaddirp;
2144
2145function requireReaddirp () {
2146 if (hasRequiredReaddirp) return readdirp_1;
2147 hasRequiredReaddirp = 1;
2148
2149 const fs = require$$0$2;
2150 const { Readable } = require$$1;
2151 const sysPath = require$$0$1;
2152 const { promisify } = require$$2;
2153 const picomatch = /*@__PURE__*/ requirePicomatch$2();
2154
2155 const readdir = promisify(fs.readdir);
2156 const stat = promisify(fs.stat);
2157 const lstat = promisify(fs.lstat);
2158 const realpath = promisify(fs.realpath);
2159
2160 /**
2161 * @typedef {Object} EntryInfo
2162 * @property {String} path
2163 * @property {String} fullPath
2164 * @property {fs.Stats=} stats
2165 * @property {fs.Dirent=} dirent
2166 * @property {String} basename
2167 */
2168
2169 const BANG = '!';
2170 const RECURSIVE_ERROR_CODE = 'READDIRP_RECURSIVE_ERROR';
2171 const NORMAL_FLOW_ERRORS = new Set(['ENOENT', 'EPERM', 'EACCES', 'ELOOP', RECURSIVE_ERROR_CODE]);
2172 const FILE_TYPE = 'files';
2173 const DIR_TYPE = 'directories';
2174 const FILE_DIR_TYPE = 'files_directories';
2175 const EVERYTHING_TYPE = 'all';
2176 const ALL_TYPES = [FILE_TYPE, DIR_TYPE, FILE_DIR_TYPE, EVERYTHING_TYPE];
2177
2178 const isNormalFlowError = error => NORMAL_FLOW_ERRORS.has(error.code);
2179 const [maj, min] = process.versions.node.split('.').slice(0, 2).map(n => Number.parseInt(n, 10));
2180 const wantBigintFsStats = process.platform === 'win32' && (maj > 10 || (maj === 10 && min >= 5));
2181
2182 const normalizeFilter = filter => {
2183 if (filter === undefined) return;
2184 if (typeof filter === 'function') return filter;
2185
2186 if (typeof filter === 'string') {
2187 const glob = picomatch(filter.trim());
2188 return entry => glob(entry.basename);
2189 }
2190
2191 if (Array.isArray(filter)) {
2192 const positive = [];
2193 const negative = [];
2194 for (const item of filter) {
2195 const trimmed = item.trim();
2196 if (trimmed.charAt(0) === BANG) {
2197 negative.push(picomatch(trimmed.slice(1)));
2198 } else {
2199 positive.push(picomatch(trimmed));
2200 }
2201 }
2202
2203 if (negative.length > 0) {
2204 if (positive.length > 0) {
2205 return entry =>
2206 positive.some(f => f(entry.basename)) && !negative.some(f => f(entry.basename));
2207 }
2208 return entry => !negative.some(f => f(entry.basename));
2209 }
2210 return entry => positive.some(f => f(entry.basename));
2211 }
2212 };
2213
2214 class ReaddirpStream extends Readable {
2215 static get defaultOptions() {
2216 return {
2217 root: '.',
2218 /* eslint-disable no-unused-vars */
2219 fileFilter: (path) => true,
2220 directoryFilter: (path) => true,
2221 /* eslint-enable no-unused-vars */
2222 type: FILE_TYPE,
2223 lstat: false,
2224 depth: 2147483648,
2225 alwaysStat: false
2226 };
2227 }
2228
2229 constructor(options = {}) {
2230 super({
2231 objectMode: true,
2232 autoDestroy: true,
2233 highWaterMark: options.highWaterMark || 4096
2234 });
2235 const opts = { ...ReaddirpStream.defaultOptions, ...options };
2236 const { root, type } = opts;
2237
2238 this._fileFilter = normalizeFilter(opts.fileFilter);
2239 this._directoryFilter = normalizeFilter(opts.directoryFilter);
2240
2241 const statMethod = opts.lstat ? lstat : stat;
2242 // Use bigint stats if it's windows and stat() supports options (node 10+).
2243 if (wantBigintFsStats) {
2244 this._stat = path => statMethod(path, { bigint: true });
2245 } else {
2246 this._stat = statMethod;
2247 }
2248
2249 this._maxDepth = opts.depth;
2250 this._wantsDir = [DIR_TYPE, FILE_DIR_TYPE, EVERYTHING_TYPE].includes(type);
2251 this._wantsFile = [FILE_TYPE, FILE_DIR_TYPE, EVERYTHING_TYPE].includes(type);
2252 this._wantsEverything = type === EVERYTHING_TYPE;
2253 this._root = sysPath.resolve(root);
2254 this._isDirent = ('Dirent' in fs) && !opts.alwaysStat;
2255 this._statsProp = this._isDirent ? 'dirent' : 'stats';
2256 this._rdOptions = { encoding: 'utf8', withFileTypes: this._isDirent };
2257
2258 // Launch stream with one parent, the root dir.
2259 this.parents = [this._exploreDir(root, 1)];
2260 this.reading = false;
2261 this.parent = undefined;
2262 }
2263
2264 async _read(batch) {
2265 if (this.reading) return;
2266 this.reading = true;
2267
2268 try {
2269 while (!this.destroyed && batch > 0) {
2270 const { path, depth, files = [] } = this.parent || {};
2271
2272 if (files.length > 0) {
2273 const slice = files.splice(0, batch).map(dirent => this._formatEntry(dirent, path));
2274 for (const entry of await Promise.all(slice)) {
2275 if (this.destroyed) return;
2276
2277 const entryType = await this._getEntryType(entry);
2278 if (entryType === 'directory' && this._directoryFilter(entry)) {
2279 if (depth <= this._maxDepth) {
2280 this.parents.push(this._exploreDir(entry.fullPath, depth + 1));
2281 }
2282
2283 if (this._wantsDir) {
2284 this.push(entry);
2285 batch--;
2286 }
2287 } else if ((entryType === 'file' || this._includeAsFile(entry)) && this._fileFilter(entry)) {
2288 if (this._wantsFile) {
2289 this.push(entry);
2290 batch--;
2291 }
2292 }
2293 }
2294 } else {
2295 const parent = this.parents.pop();
2296 if (!parent) {
2297 this.push(null);
2298 break;
2299 }
2300 this.parent = await parent;
2301 if (this.destroyed) return;
2302 }
2303 }
2304 } catch (error) {
2305 this.destroy(error);
2306 } finally {
2307 this.reading = false;
2308 }
2309 }
2310
2311 async _exploreDir(path, depth) {
2312 let files;
2313 try {
2314 files = await readdir(path, this._rdOptions);
2315 } catch (error) {
2316 this._onError(error);
2317 }
2318 return { files, depth, path };
2319 }
2320
2321 async _formatEntry(dirent, path) {
2322 let entry;
2323 try {
2324 const basename = this._isDirent ? dirent.name : dirent;
2325 const fullPath = sysPath.resolve(sysPath.join(path, basename));
2326 entry = { path: sysPath.relative(this._root, fullPath), fullPath, basename };
2327 entry[this._statsProp] = this._isDirent ? dirent : await this._stat(fullPath);
2328 } catch (err) {
2329 this._onError(err);
2330 }
2331 return entry;
2332 }
2333
2334 _onError(err) {
2335 if (isNormalFlowError(err) && !this.destroyed) {
2336 this.emit('warn', err);
2337 } else {
2338 this.destroy(err);
2339 }
2340 }
2341
2342 async _getEntryType(entry) {
2343 // entry may be undefined, because a warning or an error were emitted
2344 // and the statsProp is undefined
2345 const stats = entry && entry[this._statsProp];
2346 if (!stats) {
2347 return;
2348 }
2349 if (stats.isFile()) {
2350 return 'file';
2351 }
2352 if (stats.isDirectory()) {
2353 return 'directory';
2354 }
2355 if (stats && stats.isSymbolicLink()) {
2356 const full = entry.fullPath;
2357 try {
2358 const entryRealPath = await realpath(full);
2359 const entryRealPathStats = await lstat(entryRealPath);
2360 if (entryRealPathStats.isFile()) {
2361 return 'file';
2362 }
2363 if (entryRealPathStats.isDirectory()) {
2364 const len = entryRealPath.length;
2365 if (full.startsWith(entryRealPath) && full.substr(len, 1) === sysPath.sep) {
2366 const recursiveError = new Error(
2367 `Circular symlink detected: "${full}" points to "${entryRealPath}"`
2368 );
2369 recursiveError.code = RECURSIVE_ERROR_CODE;
2370 return this._onError(recursiveError);
2371 }
2372 return 'directory';
2373 }
2374 } catch (error) {
2375 this._onError(error);
2376 }
2377 }
2378 }
2379
2380 _includeAsFile(entry) {
2381 const stats = entry && entry[this._statsProp];
2382
2383 return stats && this._wantsEverything && !stats.isDirectory();
2384 }
2385 }
2386
2387 /**
2388 * @typedef {Object} ReaddirpArguments
2389 * @property {Function=} fileFilter
2390 * @property {Function=} directoryFilter
2391 * @property {String=} type
2392 * @property {Number=} depth
2393 * @property {String=} root
2394 * @property {Boolean=} lstat
2395 * @property {Boolean=} bigint
2396 */
2397
2398 /**
2399 * Main function which ends up calling readdirRec and reads all files and directories in given root recursively.
2400 * @param {String} root Root directory
2401 * @param {ReaddirpArguments=} options Options to specify root (start directory), filters and recursion depth
2402 */
2403 const readdirp = (root, options = {}) => {
2404 let type = options.entryType || options.type;
2405 if (type === 'both') type = FILE_DIR_TYPE; // backwards-compatibility
2406 if (type) options.type = type;
2407 if (!root) {
2408 throw new Error('readdirp: root argument is required. Usage: readdirp(root, options)');
2409 } else if (typeof root !== 'string') {
2410 throw new TypeError('readdirp: root argument must be a string. Usage: readdirp(root, options)');
2411 } else if (type && !ALL_TYPES.includes(type)) {
2412 throw new Error(`readdirp: Invalid type passed. Use one of ${ALL_TYPES.join(', ')}`);
2413 }
2414
2415 options.root = root;
2416 return new ReaddirpStream(options);
2417 };
2418
2419 const readdirpPromise = (root, options = {}) => {
2420 return new Promise((resolve, reject) => {
2421 const files = [];
2422 readdirp(root, options)
2423 .on('data', entry => files.push(entry))
2424 .on('end', () => resolve(files))
2425 .on('error', error => reject(error));
2426 });
2427 };
2428
2429 readdirp.promise = readdirpPromise;
2430 readdirp.ReaddirpStream = ReaddirpStream;
2431 readdirp.default = readdirp;
2432
2433 readdirp_1 = readdirp;
2434 return readdirp_1;
2435}
2436
2437var anymatch = {exports: {}};
2438
2439var utils$1 = {};
2440
2441var constants$2;
2442var hasRequiredConstants$2;
2443
2444function requireConstants$2 () {
2445 if (hasRequiredConstants$2) return constants$2;
2446 hasRequiredConstants$2 = 1;
2447
2448 const path = require$$0$1;
2449 const WIN_SLASH = '\\\\/';
2450 const WIN_NO_SLASH = `[^${WIN_SLASH}]`;
2451
2452 /**
2453 * Posix glob regex
2454 */
2455
2456 const DOT_LITERAL = '\\.';
2457 const PLUS_LITERAL = '\\+';
2458 const QMARK_LITERAL = '\\?';
2459 const SLASH_LITERAL = '\\/';
2460 const ONE_CHAR = '(?=.)';
2461 const QMARK = '[^/]';
2462 const END_ANCHOR = `(?:${SLASH_LITERAL}|$)`;
2463 const START_ANCHOR = `(?:^|${SLASH_LITERAL})`;
2464 const DOTS_SLASH = `${DOT_LITERAL}{1,2}${END_ANCHOR}`;
2465 const NO_DOT = `(?!${DOT_LITERAL})`;
2466 const NO_DOTS = `(?!${START_ANCHOR}${DOTS_SLASH})`;
2467 const NO_DOT_SLASH = `(?!${DOT_LITERAL}{0,1}${END_ANCHOR})`;
2468 const NO_DOTS_SLASH = `(?!${DOTS_SLASH})`;
2469 const QMARK_NO_DOT = `[^.${SLASH_LITERAL}]`;
2470 const STAR = `${QMARK}*?`;
2471
2472 const POSIX_CHARS = {
2473 DOT_LITERAL,
2474 PLUS_LITERAL,
2475 QMARK_LITERAL,
2476 SLASH_LITERAL,
2477 ONE_CHAR,
2478 QMARK,
2479 END_ANCHOR,
2480 DOTS_SLASH,
2481 NO_DOT,
2482 NO_DOTS,
2483 NO_DOT_SLASH,
2484 NO_DOTS_SLASH,
2485 QMARK_NO_DOT,
2486 STAR,
2487 START_ANCHOR
2488 };
2489
2490 /**
2491 * Windows glob regex
2492 */
2493
2494 const WINDOWS_CHARS = {
2495 ...POSIX_CHARS,
2496
2497 SLASH_LITERAL: `[${WIN_SLASH}]`,
2498 QMARK: WIN_NO_SLASH,
2499 STAR: `${WIN_NO_SLASH}*?`,
2500 DOTS_SLASH: `${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$)`,
2501 NO_DOT: `(?!${DOT_LITERAL})`,
2502 NO_DOTS: `(?!(?:^|[${WIN_SLASH}])${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`,
2503 NO_DOT_SLASH: `(?!${DOT_LITERAL}{0,1}(?:[${WIN_SLASH}]|$))`,
2504 NO_DOTS_SLASH: `(?!${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`,
2505 QMARK_NO_DOT: `[^.${WIN_SLASH}]`,
2506 START_ANCHOR: `(?:^|[${WIN_SLASH}])`,
2507 END_ANCHOR: `(?:[${WIN_SLASH}]|$)`
2508 };
2509
2510 /**
2511 * POSIX Bracket Regex
2512 */
2513
2514 const POSIX_REGEX_SOURCE = {
2515 alnum: 'a-zA-Z0-9',
2516 alpha: 'a-zA-Z',
2517 ascii: '\\x00-\\x7F',
2518 blank: ' \\t',
2519 cntrl: '\\x00-\\x1F\\x7F',
2520 digit: '0-9',
2521 graph: '\\x21-\\x7E',
2522 lower: 'a-z',
2523 print: '\\x20-\\x7E ',
2524 punct: '\\-!"#$%&\'()\\*+,./:;<=>?@[\\]^_`{|}~',
2525 space: ' \\t\\r\\n\\v\\f',
2526 upper: 'A-Z',
2527 word: 'A-Za-z0-9_',
2528 xdigit: 'A-Fa-f0-9'
2529 };
2530
2531 constants$2 = {
2532 MAX_LENGTH: 1024 * 64,
2533 POSIX_REGEX_SOURCE,
2534
2535 // regular expressions
2536 REGEX_BACKSLASH: /\\(?![*+?^${}(|)[\]])/g,
2537 REGEX_NON_SPECIAL_CHARS: /^[^@![\].,$*+?^{}()|\\/]+/,
2538 REGEX_SPECIAL_CHARS: /[-*+?.^${}(|)[\]]/,
2539 REGEX_SPECIAL_CHARS_BACKREF: /(\\?)((\W)(\3*))/g,
2540 REGEX_SPECIAL_CHARS_GLOBAL: /([-*+?.^${}(|)[\]])/g,
2541 REGEX_REMOVE_BACKSLASH: /(?:\[.*?[^\\]\]|\\(?=.))/g,
2542
2543 // Replace globs with equivalent patterns to reduce parsing time.
2544 REPLACEMENTS: {
2545 '***': '*',
2546 '**/**': '**',
2547 '**/**/**': '**'
2548 },
2549
2550 // Digits
2551 CHAR_0: 48, /* 0 */
2552 CHAR_9: 57, /* 9 */
2553
2554 // Alphabet chars.
2555 CHAR_UPPERCASE_A: 65, /* A */
2556 CHAR_LOWERCASE_A: 97, /* a */
2557 CHAR_UPPERCASE_Z: 90, /* Z */
2558 CHAR_LOWERCASE_Z: 122, /* z */
2559
2560 CHAR_LEFT_PARENTHESES: 40, /* ( */
2561 CHAR_RIGHT_PARENTHESES: 41, /* ) */
2562
2563 CHAR_ASTERISK: 42, /* * */
2564
2565 // Non-alphabetic chars.
2566 CHAR_AMPERSAND: 38, /* & */
2567 CHAR_AT: 64, /* @ */
2568 CHAR_BACKWARD_SLASH: 92, /* \ */
2569 CHAR_CARRIAGE_RETURN: 13, /* \r */
2570 CHAR_CIRCUMFLEX_ACCENT: 94, /* ^ */
2571 CHAR_COLON: 58, /* : */
2572 CHAR_COMMA: 44, /* , */
2573 CHAR_DOT: 46, /* . */
2574 CHAR_DOUBLE_QUOTE: 34, /* " */
2575 CHAR_EQUAL: 61, /* = */
2576 CHAR_EXCLAMATION_MARK: 33, /* ! */
2577 CHAR_FORM_FEED: 12, /* \f */
2578 CHAR_FORWARD_SLASH: 47, /* / */
2579 CHAR_GRAVE_ACCENT: 96, /* ` */
2580 CHAR_HASH: 35, /* # */
2581 CHAR_HYPHEN_MINUS: 45, /* - */
2582 CHAR_LEFT_ANGLE_BRACKET: 60, /* < */
2583 CHAR_LEFT_CURLY_BRACE: 123, /* { */
2584 CHAR_LEFT_SQUARE_BRACKET: 91, /* [ */
2585 CHAR_LINE_FEED: 10, /* \n */
2586 CHAR_NO_BREAK_SPACE: 160, /* \u00A0 */
2587 CHAR_PERCENT: 37, /* % */
2588 CHAR_PLUS: 43, /* + */
2589 CHAR_QUESTION_MARK: 63, /* ? */
2590 CHAR_RIGHT_ANGLE_BRACKET: 62, /* > */
2591 CHAR_RIGHT_CURLY_BRACE: 125, /* } */
2592 CHAR_RIGHT_SQUARE_BRACKET: 93, /* ] */
2593 CHAR_SEMICOLON: 59, /* ; */
2594 CHAR_SINGLE_QUOTE: 39, /* ' */
2595 CHAR_SPACE: 32, /* */
2596 CHAR_TAB: 9, /* \t */
2597 CHAR_UNDERSCORE: 95, /* _ */
2598 CHAR_VERTICAL_LINE: 124, /* | */
2599 CHAR_ZERO_WIDTH_NOBREAK_SPACE: 65279, /* \uFEFF */
2600
2601 SEP: path.sep,
2602
2603 /**
2604 * Create EXTGLOB_CHARS
2605 */
2606
2607 extglobChars(chars) {
2608 return {
2609 '!': { type: 'negate', open: '(?:(?!(?:', close: `))${chars.STAR})` },
2610 '?': { type: 'qmark', open: '(?:', close: ')?' },
2611 '+': { type: 'plus', open: '(?:', close: ')+' },
2612 '*': { type: 'star', open: '(?:', close: ')*' },
2613 '@': { type: 'at', open: '(?:', close: ')' }
2614 };
2615 },
2616
2617 /**
2618 * Create GLOB_CHARS
2619 */
2620
2621 globChars(win32) {
2622 return win32 === true ? WINDOWS_CHARS : POSIX_CHARS;
2623 }
2624 };
2625 return constants$2;
2626}
2627
2628var hasRequiredUtils$1;
2629
2630function requireUtils$1 () {
2631 if (hasRequiredUtils$1) return utils$1;
2632 hasRequiredUtils$1 = 1;
2633 (function (exports) {
2634
2635 const path = require$$0$1;
2636 const win32 = process.platform === 'win32';
2637 const {
2638 REGEX_BACKSLASH,
2639 REGEX_REMOVE_BACKSLASH,
2640 REGEX_SPECIAL_CHARS,
2641 REGEX_SPECIAL_CHARS_GLOBAL
2642 } = /*@__PURE__*/ requireConstants$2();
2643
2644 exports.isObject = val => val !== null && typeof val === 'object' && !Array.isArray(val);
2645 exports.hasRegexChars = str => REGEX_SPECIAL_CHARS.test(str);
2646 exports.isRegexChar = str => str.length === 1 && exports.hasRegexChars(str);
2647 exports.escapeRegex = str => str.replace(REGEX_SPECIAL_CHARS_GLOBAL, '\\$1');
2648 exports.toPosixSlashes = str => str.replace(REGEX_BACKSLASH, '/');
2649
2650 exports.removeBackslashes = str => {
2651 return str.replace(REGEX_REMOVE_BACKSLASH, match => {
2652 return match === '\\' ? '' : match;
2653 });
2654 };
2655
2656 exports.supportsLookbehinds = () => {
2657 const segs = process.version.slice(1).split('.').map(Number);
2658 if (segs.length === 3 && segs[0] >= 9 || (segs[0] === 8 && segs[1] >= 10)) {
2659 return true;
2660 }
2661 return false;
2662 };
2663
2664 exports.isWindows = options => {
2665 if (options && typeof options.windows === 'boolean') {
2666 return options.windows;
2667 }
2668 return win32 === true || path.sep === '\\';
2669 };
2670
2671 exports.escapeLast = (input, char, lastIdx) => {
2672 const idx = input.lastIndexOf(char, lastIdx);
2673 if (idx === -1) return input;
2674 if (input[idx - 1] === '\\') return exports.escapeLast(input, char, idx - 1);
2675 return `${input.slice(0, idx)}\\${input.slice(idx)}`;
2676 };
2677
2678 exports.removePrefix = (input, state = {}) => {
2679 let output = input;
2680 if (output.startsWith('./')) {
2681 output = output.slice(2);
2682 state.prefix = './';
2683 }
2684 return output;
2685 };
2686
2687 exports.wrapOutput = (input, state = {}, options = {}) => {
2688 const prepend = options.contains ? '' : '^';
2689 const append = options.contains ? '' : '$';
2690
2691 let output = `${prepend}(?:${input})${append}`;
2692 if (state.negated === true) {
2693 output = `(?:^(?!${output}).*$)`;
2694 }
2695 return output;
2696 };
2697 } (utils$1));
2698 return utils$1;
2699}
2700
2701var scan_1;
2702var hasRequiredScan;
2703
2704function requireScan () {
2705 if (hasRequiredScan) return scan_1;
2706 hasRequiredScan = 1;
2707
2708 const utils = /*@__PURE__*/ requireUtils$1();
2709 const {
2710 CHAR_ASTERISK, /* * */
2711 CHAR_AT, /* @ */
2712 CHAR_BACKWARD_SLASH, /* \ */
2713 CHAR_COMMA, /* , */
2714 CHAR_DOT, /* . */
2715 CHAR_EXCLAMATION_MARK, /* ! */
2716 CHAR_FORWARD_SLASH, /* / */
2717 CHAR_LEFT_CURLY_BRACE, /* { */
2718 CHAR_LEFT_PARENTHESES, /* ( */
2719 CHAR_LEFT_SQUARE_BRACKET, /* [ */
2720 CHAR_PLUS, /* + */
2721 CHAR_QUESTION_MARK, /* ? */
2722 CHAR_RIGHT_CURLY_BRACE, /* } */
2723 CHAR_RIGHT_PARENTHESES, /* ) */
2724 CHAR_RIGHT_SQUARE_BRACKET /* ] */
2725 } = /*@__PURE__*/ requireConstants$2();
2726
2727 const isPathSeparator = code => {
2728 return code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH;
2729 };
2730
2731 const depth = token => {
2732 if (token.isPrefix !== true) {
2733 token.depth = token.isGlobstar ? Infinity : 1;
2734 }
2735 };
2736
2737 /**
2738 * Quickly scans a glob pattern and returns an object with a handful of
2739 * useful properties, like `isGlob`, `path` (the leading non-glob, if it exists),
2740 * `glob` (the actual pattern), `negated` (true if the path starts with `!` but not
2741 * with `!(`) and `negatedExtglob` (true if the path starts with `!(`).
2742 *
2743 * ```js
2744 * const pm = require('picomatch');
2745 * console.log(pm.scan('foo/bar/*.js'));
2746 * { isGlob: true, input: 'foo/bar/*.js', base: 'foo/bar', glob: '*.js' }
2747 * ```
2748 * @param {String} `str`
2749 * @param {Object} `options`
2750 * @return {Object} Returns an object with tokens and regex source string.
2751 * @api public
2752 */
2753
2754 const scan = (input, options) => {
2755 const opts = options || {};
2756
2757 const length = input.length - 1;
2758 const scanToEnd = opts.parts === true || opts.scanToEnd === true;
2759 const slashes = [];
2760 const tokens = [];
2761 const parts = [];
2762
2763 let str = input;
2764 let index = -1;
2765 let start = 0;
2766 let lastIndex = 0;
2767 let isBrace = false;
2768 let isBracket = false;
2769 let isGlob = false;
2770 let isExtglob = false;
2771 let isGlobstar = false;
2772 let braceEscaped = false;
2773 let backslashes = false;
2774 let negated = false;
2775 let negatedExtglob = false;
2776 let finished = false;
2777 let braces = 0;
2778 let prev;
2779 let code;
2780 let token = { value: '', depth: 0, isGlob: false };
2781
2782 const eos = () => index >= length;
2783 const peek = () => str.charCodeAt(index + 1);
2784 const advance = () => {
2785 prev = code;
2786 return str.charCodeAt(++index);
2787 };
2788
2789 while (index < length) {
2790 code = advance();
2791 let next;
2792
2793 if (code === CHAR_BACKWARD_SLASH) {
2794 backslashes = token.backslashes = true;
2795 code = advance();
2796
2797 if (code === CHAR_LEFT_CURLY_BRACE) {
2798 braceEscaped = true;
2799 }
2800 continue;
2801 }
2802
2803 if (braceEscaped === true || code === CHAR_LEFT_CURLY_BRACE) {
2804 braces++;
2805
2806 while (eos() !== true && (code = advance())) {
2807 if (code === CHAR_BACKWARD_SLASH) {
2808 backslashes = token.backslashes = true;
2809 advance();
2810 continue;
2811 }
2812
2813 if (code === CHAR_LEFT_CURLY_BRACE) {
2814 braces++;
2815 continue;
2816 }
2817
2818 if (braceEscaped !== true && code === CHAR_DOT && (code = advance()) === CHAR_DOT) {
2819 isBrace = token.isBrace = true;
2820 isGlob = token.isGlob = true;
2821 finished = true;
2822
2823 if (scanToEnd === true) {
2824 continue;
2825 }
2826
2827 break;
2828 }
2829
2830 if (braceEscaped !== true && code === CHAR_COMMA) {
2831 isBrace = token.isBrace = true;
2832 isGlob = token.isGlob = true;
2833 finished = true;
2834
2835 if (scanToEnd === true) {
2836 continue;
2837 }
2838
2839 break;
2840 }
2841
2842 if (code === CHAR_RIGHT_CURLY_BRACE) {
2843 braces--;
2844
2845 if (braces === 0) {
2846 braceEscaped = false;
2847 isBrace = token.isBrace = true;
2848 finished = true;
2849 break;
2850 }
2851 }
2852 }
2853
2854 if (scanToEnd === true) {
2855 continue;
2856 }
2857
2858 break;
2859 }
2860
2861 if (code === CHAR_FORWARD_SLASH) {
2862 slashes.push(index);
2863 tokens.push(token);
2864 token = { value: '', depth: 0, isGlob: false };
2865
2866 if (finished === true) continue;
2867 if (prev === CHAR_DOT && index === (start + 1)) {
2868 start += 2;
2869 continue;
2870 }
2871
2872 lastIndex = index + 1;
2873 continue;
2874 }
2875
2876 if (opts.noext !== true) {
2877 const isExtglobChar = code === CHAR_PLUS
2878 || code === CHAR_AT
2879 || code === CHAR_ASTERISK
2880 || code === CHAR_QUESTION_MARK
2881 || code === CHAR_EXCLAMATION_MARK;
2882
2883 if (isExtglobChar === true && peek() === CHAR_LEFT_PARENTHESES) {
2884 isGlob = token.isGlob = true;
2885 isExtglob = token.isExtglob = true;
2886 finished = true;
2887 if (code === CHAR_EXCLAMATION_MARK && index === start) {
2888 negatedExtglob = true;
2889 }
2890
2891 if (scanToEnd === true) {
2892 while (eos() !== true && (code = advance())) {
2893 if (code === CHAR_BACKWARD_SLASH) {
2894 backslashes = token.backslashes = true;
2895 code = advance();
2896 continue;
2897 }
2898
2899 if (code === CHAR_RIGHT_PARENTHESES) {
2900 isGlob = token.isGlob = true;
2901 finished = true;
2902 break;
2903 }
2904 }
2905 continue;
2906 }
2907 break;
2908 }
2909 }
2910
2911 if (code === CHAR_ASTERISK) {
2912 if (prev === CHAR_ASTERISK) isGlobstar = token.isGlobstar = true;
2913 isGlob = token.isGlob = true;
2914 finished = true;
2915
2916 if (scanToEnd === true) {
2917 continue;
2918 }
2919 break;
2920 }
2921
2922 if (code === CHAR_QUESTION_MARK) {
2923 isGlob = token.isGlob = true;
2924 finished = true;
2925
2926 if (scanToEnd === true) {
2927 continue;
2928 }
2929 break;
2930 }
2931
2932 if (code === CHAR_LEFT_SQUARE_BRACKET) {
2933 while (eos() !== true && (next = advance())) {
2934 if (next === CHAR_BACKWARD_SLASH) {
2935 backslashes = token.backslashes = true;
2936 advance();
2937 continue;
2938 }
2939
2940 if (next === CHAR_RIGHT_SQUARE_BRACKET) {
2941 isBracket = token.isBracket = true;
2942 isGlob = token.isGlob = true;
2943 finished = true;
2944 break;
2945 }
2946 }
2947
2948 if (scanToEnd === true) {
2949 continue;
2950 }
2951
2952 break;
2953 }
2954
2955 if (opts.nonegate !== true && code === CHAR_EXCLAMATION_MARK && index === start) {
2956 negated = token.negated = true;
2957 start++;
2958 continue;
2959 }
2960
2961 if (opts.noparen !== true && code === CHAR_LEFT_PARENTHESES) {
2962 isGlob = token.isGlob = true;
2963
2964 if (scanToEnd === true) {
2965 while (eos() !== true && (code = advance())) {
2966 if (code === CHAR_LEFT_PARENTHESES) {
2967 backslashes = token.backslashes = true;
2968 code = advance();
2969 continue;
2970 }
2971
2972 if (code === CHAR_RIGHT_PARENTHESES) {
2973 finished = true;
2974 break;
2975 }
2976 }
2977 continue;
2978 }
2979 break;
2980 }
2981
2982 if (isGlob === true) {
2983 finished = true;
2984
2985 if (scanToEnd === true) {
2986 continue;
2987 }
2988
2989 break;
2990 }
2991 }
2992
2993 if (opts.noext === true) {
2994 isExtglob = false;
2995 isGlob = false;
2996 }
2997
2998 let base = str;
2999 let prefix = '';
3000 let glob = '';
3001
3002 if (start > 0) {
3003 prefix = str.slice(0, start);
3004 str = str.slice(start);
3005 lastIndex -= start;
3006 }
3007
3008 if (base && isGlob === true && lastIndex > 0) {
3009 base = str.slice(0, lastIndex);
3010 glob = str.slice(lastIndex);
3011 } else if (isGlob === true) {
3012 base = '';
3013 glob = str;
3014 } else {
3015 base = str;
3016 }
3017
3018 if (base && base !== '' && base !== '/' && base !== str) {
3019 if (isPathSeparator(base.charCodeAt(base.length - 1))) {
3020 base = base.slice(0, -1);
3021 }
3022 }
3023
3024 if (opts.unescape === true) {
3025 if (glob) glob = utils.removeBackslashes(glob);
3026
3027 if (base && backslashes === true) {
3028 base = utils.removeBackslashes(base);
3029 }
3030 }
3031
3032 const state = {
3033 prefix,
3034 input,
3035 start,
3036 base,
3037 glob,
3038 isBrace,
3039 isBracket,
3040 isGlob,
3041 isExtglob,
3042 isGlobstar,
3043 negated,
3044 negatedExtglob
3045 };
3046
3047 if (opts.tokens === true) {
3048 state.maxDepth = 0;
3049 if (!isPathSeparator(code)) {
3050 tokens.push(token);
3051 }
3052 state.tokens = tokens;
3053 }
3054
3055 if (opts.parts === true || opts.tokens === true) {
3056 let prevIndex;
3057
3058 for (let idx = 0; idx < slashes.length; idx++) {
3059 const n = prevIndex ? prevIndex + 1 : start;
3060 const i = slashes[idx];
3061 const value = input.slice(n, i);
3062 if (opts.tokens) {
3063 if (idx === 0 && start !== 0) {
3064 tokens[idx].isPrefix = true;
3065 tokens[idx].value = prefix;
3066 } else {
3067 tokens[idx].value = value;
3068 }
3069 depth(tokens[idx]);
3070 state.maxDepth += tokens[idx].depth;
3071 }
3072 if (idx !== 0 || value !== '') {
3073 parts.push(value);
3074 }
3075 prevIndex = i;
3076 }
3077
3078 if (prevIndex && prevIndex + 1 < input.length) {
3079 const value = input.slice(prevIndex + 1);
3080 parts.push(value);
3081
3082 if (opts.tokens) {
3083 tokens[tokens.length - 1].value = value;
3084 depth(tokens[tokens.length - 1]);
3085 state.maxDepth += tokens[tokens.length - 1].depth;
3086 }
3087 }
3088
3089 state.slashes = slashes;
3090 state.parts = parts;
3091 }
3092
3093 return state;
3094 };
3095
3096 scan_1 = scan;
3097 return scan_1;
3098}
3099
3100var parse_1$1;
3101var hasRequiredParse$1;
3102
3103function requireParse$1 () {
3104 if (hasRequiredParse$1) return parse_1$1;
3105 hasRequiredParse$1 = 1;
3106
3107 const constants = /*@__PURE__*/ requireConstants$2();
3108 const utils = /*@__PURE__*/ requireUtils$1();
3109
3110 /**
3111 * Constants
3112 */
3113
3114 const {
3115 MAX_LENGTH,
3116 POSIX_REGEX_SOURCE,
3117 REGEX_NON_SPECIAL_CHARS,
3118 REGEX_SPECIAL_CHARS_BACKREF,
3119 REPLACEMENTS
3120 } = constants;
3121
3122 /**
3123 * Helpers
3124 */
3125
3126 const expandRange = (args, options) => {
3127 if (typeof options.expandRange === 'function') {
3128 return options.expandRange(...args, options);
3129 }
3130
3131 args.sort();
3132 const value = `[${args.join('-')}]`;
3133
3134 return value;
3135 };
3136
3137 /**
3138 * Create the message for a syntax error
3139 */
3140
3141 const syntaxError = (type, char) => {
3142 return `Missing ${type}: "${char}" - use "\\\\${char}" to match literal characters`;
3143 };
3144
3145 /**
3146 * Parse the given input string.
3147 * @param {String} input
3148 * @param {Object} options
3149 * @return {Object}
3150 */
3151
3152 const parse = (input, options) => {
3153 if (typeof input !== 'string') {
3154 throw new TypeError('Expected a string');
3155 }
3156
3157 input = REPLACEMENTS[input] || input;
3158
3159 const opts = { ...options };
3160 const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH;
3161
3162 let len = input.length;
3163 if (len > max) {
3164 throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`);
3165 }
3166
3167 const bos = { type: 'bos', value: '', output: opts.prepend || '' };
3168 const tokens = [bos];
3169
3170 const capture = opts.capture ? '' : '?:';
3171 const win32 = utils.isWindows(options);
3172
3173 // create constants based on platform, for windows or posix
3174 const PLATFORM_CHARS = constants.globChars(win32);
3175 const EXTGLOB_CHARS = constants.extglobChars(PLATFORM_CHARS);
3176
3177 const {
3178 DOT_LITERAL,
3179 PLUS_LITERAL,
3180 SLASH_LITERAL,
3181 ONE_CHAR,
3182 DOTS_SLASH,
3183 NO_DOT,
3184 NO_DOT_SLASH,
3185 NO_DOTS_SLASH,
3186 QMARK,
3187 QMARK_NO_DOT,
3188 STAR,
3189 START_ANCHOR
3190 } = PLATFORM_CHARS;
3191
3192 const globstar = opts => {
3193 return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`;
3194 };
3195
3196 const nodot = opts.dot ? '' : NO_DOT;
3197 const qmarkNoDot = opts.dot ? QMARK : QMARK_NO_DOT;
3198 let star = opts.bash === true ? globstar(opts) : STAR;
3199
3200 if (opts.capture) {
3201 star = `(${star})`;
3202 }
3203
3204 // minimatch options support
3205 if (typeof opts.noext === 'boolean') {
3206 opts.noextglob = opts.noext;
3207 }
3208
3209 const state = {
3210 input,
3211 index: -1,
3212 start: 0,
3213 dot: opts.dot === true,
3214 consumed: '',
3215 output: '',
3216 prefix: '',
3217 backtrack: false,
3218 negated: false,
3219 brackets: 0,
3220 braces: 0,
3221 parens: 0,
3222 quotes: 0,
3223 globstar: false,
3224 tokens
3225 };
3226
3227 input = utils.removePrefix(input, state);
3228 len = input.length;
3229
3230 const extglobs = [];
3231 const braces = [];
3232 const stack = [];
3233 let prev = bos;
3234 let value;
3235
3236 /**
3237 * Tokenizing helpers
3238 */
3239
3240 const eos = () => state.index === len - 1;
3241 const peek = state.peek = (n = 1) => input[state.index + n];
3242 const advance = state.advance = () => input[++state.index] || '';
3243 const remaining = () => input.slice(state.index + 1);
3244 const consume = (value = '', num = 0) => {
3245 state.consumed += value;
3246 state.index += num;
3247 };
3248
3249 const append = token => {
3250 state.output += token.output != null ? token.output : token.value;
3251 consume(token.value);
3252 };
3253
3254 const negate = () => {
3255 let count = 1;
3256
3257 while (peek() === '!' && (peek(2) !== '(' || peek(3) === '?')) {
3258 advance();
3259 state.start++;
3260 count++;
3261 }
3262
3263 if (count % 2 === 0) {
3264 return false;
3265 }
3266
3267 state.negated = true;
3268 state.start++;
3269 return true;
3270 };
3271
3272 const increment = type => {
3273 state[type]++;
3274 stack.push(type);
3275 };
3276
3277 const decrement = type => {
3278 state[type]--;
3279 stack.pop();
3280 };
3281
3282 /**
3283 * Push tokens onto the tokens array. This helper speeds up
3284 * tokenizing by 1) helping us avoid backtracking as much as possible,
3285 * and 2) helping us avoid creating extra tokens when consecutive
3286 * characters are plain text. This improves performance and simplifies
3287 * lookbehinds.
3288 */
3289
3290 const push = tok => {
3291 if (prev.type === 'globstar') {
3292 const isBrace = state.braces > 0 && (tok.type === 'comma' || tok.type === 'brace');
3293 const isExtglob = tok.extglob === true || (extglobs.length && (tok.type === 'pipe' || tok.type === 'paren'));
3294
3295 if (tok.type !== 'slash' && tok.type !== 'paren' && !isBrace && !isExtglob) {
3296 state.output = state.output.slice(0, -prev.output.length);
3297 prev.type = 'star';
3298 prev.value = '*';
3299 prev.output = star;
3300 state.output += prev.output;
3301 }
3302 }
3303
3304 if (extglobs.length && tok.type !== 'paren') {
3305 extglobs[extglobs.length - 1].inner += tok.value;
3306 }
3307
3308 if (tok.value || tok.output) append(tok);
3309 if (prev && prev.type === 'text' && tok.type === 'text') {
3310 prev.value += tok.value;
3311 prev.output = (prev.output || '') + tok.value;
3312 return;
3313 }
3314
3315 tok.prev = prev;
3316 tokens.push(tok);
3317 prev = tok;
3318 };
3319
3320 const extglobOpen = (type, value) => {
3321 const token = { ...EXTGLOB_CHARS[value], conditions: 1, inner: '' };
3322
3323 token.prev = prev;
3324 token.parens = state.parens;
3325 token.output = state.output;
3326 const output = (opts.capture ? '(' : '') + token.open;
3327
3328 increment('parens');
3329 push({ type, value, output: state.output ? '' : ONE_CHAR });
3330 push({ type: 'paren', extglob: true, value: advance(), output });
3331 extglobs.push(token);
3332 };
3333
3334 const extglobClose = token => {
3335 let output = token.close + (opts.capture ? ')' : '');
3336 let rest;
3337
3338 if (token.type === 'negate') {
3339 let extglobStar = star;
3340
3341 if (token.inner && token.inner.length > 1 && token.inner.includes('/')) {
3342 extglobStar = globstar(opts);
3343 }
3344
3345 if (extglobStar !== star || eos() || /^\)+$/.test(remaining())) {
3346 output = token.close = `)$))${extglobStar}`;
3347 }
3348
3349 if (token.inner.includes('*') && (rest = remaining()) && /^\.[^\\/.]+$/.test(rest)) {
3350 // Any non-magical string (`.ts`) or even nested expression (`.{ts,tsx}`) can follow after the closing parenthesis.
3351 // In this case, we need to parse the string and use it in the output of the original pattern.
3352 // Suitable patterns: `/!(*.d).ts`, `/!(*.d).{ts,tsx}`, `**/!(*-dbg).@(js)`.
3353 //
3354 // Disabling the `fastpaths` option due to a problem with parsing strings as `.ts` in the pattern like `**/!(*.d).ts`.
3355 const expression = parse(rest, { ...options, fastpaths: false }).output;
3356
3357 output = token.close = `)${expression})${extglobStar})`;
3358 }
3359
3360 if (token.prev.type === 'bos') {
3361 state.negatedExtglob = true;
3362 }
3363 }
3364
3365 push({ type: 'paren', extglob: true, value, output });
3366 decrement('parens');
3367 };
3368
3369 /**
3370 * Fast paths
3371 */
3372
3373 if (opts.fastpaths !== false && !/(^[*!]|[/()[\]{}"])/.test(input)) {
3374 let backslashes = false;
3375
3376 let output = input.replace(REGEX_SPECIAL_CHARS_BACKREF, (m, esc, chars, first, rest, index) => {
3377 if (first === '\\') {
3378 backslashes = true;
3379 return m;
3380 }
3381
3382 if (first === '?') {
3383 if (esc) {
3384 return esc + first + (rest ? QMARK.repeat(rest.length) : '');
3385 }
3386 if (index === 0) {
3387 return qmarkNoDot + (rest ? QMARK.repeat(rest.length) : '');
3388 }
3389 return QMARK.repeat(chars.length);
3390 }
3391
3392 if (first === '.') {
3393 return DOT_LITERAL.repeat(chars.length);
3394 }
3395
3396 if (first === '*') {
3397 if (esc) {
3398 return esc + first + (rest ? star : '');
3399 }
3400 return star;
3401 }
3402 return esc ? m : `\\${m}`;
3403 });
3404
3405 if (backslashes === true) {
3406 if (opts.unescape === true) {
3407 output = output.replace(/\\/g, '');
3408 } else {
3409 output = output.replace(/\\+/g, m => {
3410 return m.length % 2 === 0 ? '\\\\' : (m ? '\\' : '');
3411 });
3412 }
3413 }
3414
3415 if (output === input && opts.contains === true) {
3416 state.output = input;
3417 return state;
3418 }
3419
3420 state.output = utils.wrapOutput(output, state, options);
3421 return state;
3422 }
3423
3424 /**
3425 * Tokenize input until we reach end-of-string
3426 */
3427
3428 while (!eos()) {
3429 value = advance();
3430
3431 if (value === '\u0000') {
3432 continue;
3433 }
3434
3435 /**
3436 * Escaped characters
3437 */
3438
3439 if (value === '\\') {
3440 const next = peek();
3441
3442 if (next === '/' && opts.bash !== true) {
3443 continue;
3444 }
3445
3446 if (next === '.' || next === ';') {
3447 continue;
3448 }
3449
3450 if (!next) {
3451 value += '\\';
3452 push({ type: 'text', value });
3453 continue;
3454 }
3455
3456 // collapse slashes to reduce potential for exploits
3457 const match = /^\\+/.exec(remaining());
3458 let slashes = 0;
3459
3460 if (match && match[0].length > 2) {
3461 slashes = match[0].length;
3462 state.index += slashes;
3463 if (slashes % 2 !== 0) {
3464 value += '\\';
3465 }
3466 }
3467
3468 if (opts.unescape === true) {
3469 value = advance();
3470 } else {
3471 value += advance();
3472 }
3473
3474 if (state.brackets === 0) {
3475 push({ type: 'text', value });
3476 continue;
3477 }
3478 }
3479
3480 /**
3481 * If we're inside a regex character class, continue
3482 * until we reach the closing bracket.
3483 */
3484
3485 if (state.brackets > 0 && (value !== ']' || prev.value === '[' || prev.value === '[^')) {
3486 if (opts.posix !== false && value === ':') {
3487 const inner = prev.value.slice(1);
3488 if (inner.includes('[')) {
3489 prev.posix = true;
3490
3491 if (inner.includes(':')) {
3492 const idx = prev.value.lastIndexOf('[');
3493 const pre = prev.value.slice(0, idx);
3494 const rest = prev.value.slice(idx + 2);
3495 const posix = POSIX_REGEX_SOURCE[rest];
3496 if (posix) {
3497 prev.value = pre + posix;
3498 state.backtrack = true;
3499 advance();
3500
3501 if (!bos.output && tokens.indexOf(prev) === 1) {
3502 bos.output = ONE_CHAR;
3503 }
3504 continue;
3505 }
3506 }
3507 }
3508 }
3509
3510 if ((value === '[' && peek() !== ':') || (value === '-' && peek() === ']')) {
3511 value = `\\${value}`;
3512 }
3513
3514 if (value === ']' && (prev.value === '[' || prev.value === '[^')) {
3515 value = `\\${value}`;
3516 }
3517
3518 if (opts.posix === true && value === '!' && prev.value === '[') {
3519 value = '^';
3520 }
3521
3522 prev.value += value;
3523 append({ value });
3524 continue;
3525 }
3526
3527 /**
3528 * If we're inside a quoted string, continue
3529 * until we reach the closing double quote.
3530 */
3531
3532 if (state.quotes === 1 && value !== '"') {
3533 value = utils.escapeRegex(value);
3534 prev.value += value;
3535 append({ value });
3536 continue;
3537 }
3538
3539 /**
3540 * Double quotes
3541 */
3542
3543 if (value === '"') {
3544 state.quotes = state.quotes === 1 ? 0 : 1;
3545 if (opts.keepQuotes === true) {
3546 push({ type: 'text', value });
3547 }
3548 continue;
3549 }
3550
3551 /**
3552 * Parentheses
3553 */
3554
3555 if (value === '(') {
3556 increment('parens');
3557 push({ type: 'paren', value });
3558 continue;
3559 }
3560
3561 if (value === ')') {
3562 if (state.parens === 0 && opts.strictBrackets === true) {
3563 throw new SyntaxError(syntaxError('opening', '('));
3564 }
3565
3566 const extglob = extglobs[extglobs.length - 1];
3567 if (extglob && state.parens === extglob.parens + 1) {
3568 extglobClose(extglobs.pop());
3569 continue;
3570 }
3571
3572 push({ type: 'paren', value, output: state.parens ? ')' : '\\)' });
3573 decrement('parens');
3574 continue;
3575 }
3576
3577 /**
3578 * Square brackets
3579 */
3580
3581 if (value === '[') {
3582 if (opts.nobracket === true || !remaining().includes(']')) {
3583 if (opts.nobracket !== true && opts.strictBrackets === true) {
3584 throw new SyntaxError(syntaxError('closing', ']'));
3585 }
3586
3587 value = `\\${value}`;
3588 } else {
3589 increment('brackets');
3590 }
3591
3592 push({ type: 'bracket', value });
3593 continue;
3594 }
3595
3596 if (value === ']') {
3597 if (opts.nobracket === true || (prev && prev.type === 'bracket' && prev.value.length === 1)) {
3598 push({ type: 'text', value, output: `\\${value}` });
3599 continue;
3600 }
3601
3602 if (state.brackets === 0) {
3603 if (opts.strictBrackets === true) {
3604 throw new SyntaxError(syntaxError('opening', '['));
3605 }
3606
3607 push({ type: 'text', value, output: `\\${value}` });
3608 continue;
3609 }
3610
3611 decrement('brackets');
3612
3613 const prevValue = prev.value.slice(1);
3614 if (prev.posix !== true && prevValue[0] === '^' && !prevValue.includes('/')) {
3615 value = `/${value}`;
3616 }
3617
3618 prev.value += value;
3619 append({ value });
3620
3621 // when literal brackets are explicitly disabled
3622 // assume we should match with a regex character class
3623 if (opts.literalBrackets === false || utils.hasRegexChars(prevValue)) {
3624 continue;
3625 }
3626
3627 const escaped = utils.escapeRegex(prev.value);
3628 state.output = state.output.slice(0, -prev.value.length);
3629
3630 // when literal brackets are explicitly enabled
3631 // assume we should escape the brackets to match literal characters
3632 if (opts.literalBrackets === true) {
3633 state.output += escaped;
3634 prev.value = escaped;
3635 continue;
3636 }
3637
3638 // when the user specifies nothing, try to match both
3639 prev.value = `(${capture}${escaped}|${prev.value})`;
3640 state.output += prev.value;
3641 continue;
3642 }
3643
3644 /**
3645 * Braces
3646 */
3647
3648 if (value === '{' && opts.nobrace !== true) {
3649 increment('braces');
3650
3651 const open = {
3652 type: 'brace',
3653 value,
3654 output: '(',
3655 outputIndex: state.output.length,
3656 tokensIndex: state.tokens.length
3657 };
3658
3659 braces.push(open);
3660 push(open);
3661 continue;
3662 }
3663
3664 if (value === '}') {
3665 const brace = braces[braces.length - 1];
3666
3667 if (opts.nobrace === true || !brace) {
3668 push({ type: 'text', value, output: value });
3669 continue;
3670 }
3671
3672 let output = ')';
3673
3674 if (brace.dots === true) {
3675 const arr = tokens.slice();
3676 const range = [];
3677
3678 for (let i = arr.length - 1; i >= 0; i--) {
3679 tokens.pop();
3680 if (arr[i].type === 'brace') {
3681 break;
3682 }
3683 if (arr[i].type !== 'dots') {
3684 range.unshift(arr[i].value);
3685 }
3686 }
3687
3688 output = expandRange(range, opts);
3689 state.backtrack = true;
3690 }
3691
3692 if (brace.comma !== true && brace.dots !== true) {
3693 const out = state.output.slice(0, brace.outputIndex);
3694 const toks = state.tokens.slice(brace.tokensIndex);
3695 brace.value = brace.output = '\\{';
3696 value = output = '\\}';
3697 state.output = out;
3698 for (const t of toks) {
3699 state.output += (t.output || t.value);
3700 }
3701 }
3702
3703 push({ type: 'brace', value, output });
3704 decrement('braces');
3705 braces.pop();
3706 continue;
3707 }
3708
3709 /**
3710 * Pipes
3711 */
3712
3713 if (value === '|') {
3714 if (extglobs.length > 0) {
3715 extglobs[extglobs.length - 1].conditions++;
3716 }
3717 push({ type: 'text', value });
3718 continue;
3719 }
3720
3721 /**
3722 * Commas
3723 */
3724
3725 if (value === ',') {
3726 let output = value;
3727
3728 const brace = braces[braces.length - 1];
3729 if (brace && stack[stack.length - 1] === 'braces') {
3730 brace.comma = true;
3731 output = '|';
3732 }
3733
3734 push({ type: 'comma', value, output });
3735 continue;
3736 }
3737
3738 /**
3739 * Slashes
3740 */
3741
3742 if (value === '/') {
3743 // if the beginning of the glob is "./", advance the start
3744 // to the current index, and don't add the "./" characters
3745 // to the state. This greatly simplifies lookbehinds when
3746 // checking for BOS characters like "!" and "." (not "./")
3747 if (prev.type === 'dot' && state.index === state.start + 1) {
3748 state.start = state.index + 1;
3749 state.consumed = '';
3750 state.output = '';
3751 tokens.pop();
3752 prev = bos; // reset "prev" to the first token
3753 continue;
3754 }
3755
3756 push({ type: 'slash', value, output: SLASH_LITERAL });
3757 continue;
3758 }
3759
3760 /**
3761 * Dots
3762 */
3763
3764 if (value === '.') {
3765 if (state.braces > 0 && prev.type === 'dot') {
3766 if (prev.value === '.') prev.output = DOT_LITERAL;
3767 const brace = braces[braces.length - 1];
3768 prev.type = 'dots';
3769 prev.output += value;
3770 prev.value += value;
3771 brace.dots = true;
3772 continue;
3773 }
3774
3775 if ((state.braces + state.parens) === 0 && prev.type !== 'bos' && prev.type !== 'slash') {
3776 push({ type: 'text', value, output: DOT_LITERAL });
3777 continue;
3778 }
3779
3780 push({ type: 'dot', value, output: DOT_LITERAL });
3781 continue;
3782 }
3783
3784 /**
3785 * Question marks
3786 */
3787
3788 if (value === '?') {
3789 const isGroup = prev && prev.value === '(';
3790 if (!isGroup && opts.noextglob !== true && peek() === '(' && peek(2) !== '?') {
3791 extglobOpen('qmark', value);
3792 continue;
3793 }
3794
3795 if (prev && prev.type === 'paren') {
3796 const next = peek();
3797 let output = value;
3798
3799 if (next === '<' && !utils.supportsLookbehinds()) {
3800 throw new Error('Node.js v10 or higher is required for regex lookbehinds');
3801 }
3802
3803 if ((prev.value === '(' && !/[!=<:]/.test(next)) || (next === '<' && !/<([!=]|\w+>)/.test(remaining()))) {
3804 output = `\\${value}`;
3805 }
3806
3807 push({ type: 'text', value, output });
3808 continue;
3809 }
3810
3811 if (opts.dot !== true && (prev.type === 'slash' || prev.type === 'bos')) {
3812 push({ type: 'qmark', value, output: QMARK_NO_DOT });
3813 continue;
3814 }
3815
3816 push({ type: 'qmark', value, output: QMARK });
3817 continue;
3818 }
3819
3820 /**
3821 * Exclamation
3822 */
3823
3824 if (value === '!') {
3825 if (opts.noextglob !== true && peek() === '(') {
3826 if (peek(2) !== '?' || !/[!=<:]/.test(peek(3))) {
3827 extglobOpen('negate', value);
3828 continue;
3829 }
3830 }
3831
3832 if (opts.nonegate !== true && state.index === 0) {
3833 negate();
3834 continue;
3835 }
3836 }
3837
3838 /**
3839 * Plus
3840 */
3841
3842 if (value === '+') {
3843 if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') {
3844 extglobOpen('plus', value);
3845 continue;
3846 }
3847
3848 if ((prev && prev.value === '(') || opts.regex === false) {
3849 push({ type: 'plus', value, output: PLUS_LITERAL });
3850 continue;
3851 }
3852
3853 if ((prev && (prev.type === 'bracket' || prev.type === 'paren' || prev.type === 'brace')) || state.parens > 0) {
3854 push({ type: 'plus', value });
3855 continue;
3856 }
3857
3858 push({ type: 'plus', value: PLUS_LITERAL });
3859 continue;
3860 }
3861
3862 /**
3863 * Plain text
3864 */
3865
3866 if (value === '@') {
3867 if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') {
3868 push({ type: 'at', extglob: true, value, output: '' });
3869 continue;
3870 }
3871
3872 push({ type: 'text', value });
3873 continue;
3874 }
3875
3876 /**
3877 * Plain text
3878 */
3879
3880 if (value !== '*') {
3881 if (value === '$' || value === '^') {
3882 value = `\\${value}`;
3883 }
3884
3885 const match = REGEX_NON_SPECIAL_CHARS.exec(remaining());
3886 if (match) {
3887 value += match[0];
3888 state.index += match[0].length;
3889 }
3890
3891 push({ type: 'text', value });
3892 continue;
3893 }
3894
3895 /**
3896 * Stars
3897 */
3898
3899 if (prev && (prev.type === 'globstar' || prev.star === true)) {
3900 prev.type = 'star';
3901 prev.star = true;
3902 prev.value += value;
3903 prev.output = star;
3904 state.backtrack = true;
3905 state.globstar = true;
3906 consume(value);
3907 continue;
3908 }
3909
3910 let rest = remaining();
3911 if (opts.noextglob !== true && /^\([^?]/.test(rest)) {
3912 extglobOpen('star', value);
3913 continue;
3914 }
3915
3916 if (prev.type === 'star') {
3917 if (opts.noglobstar === true) {
3918 consume(value);
3919 continue;
3920 }
3921
3922 const prior = prev.prev;
3923 const before = prior.prev;
3924 const isStart = prior.type === 'slash' || prior.type === 'bos';
3925 const afterStar = before && (before.type === 'star' || before.type === 'globstar');
3926
3927 if (opts.bash === true && (!isStart || (rest[0] && rest[0] !== '/'))) {
3928 push({ type: 'star', value, output: '' });
3929 continue;
3930 }
3931
3932 const isBrace = state.braces > 0 && (prior.type === 'comma' || prior.type === 'brace');
3933 const isExtglob = extglobs.length && (prior.type === 'pipe' || prior.type === 'paren');
3934 if (!isStart && prior.type !== 'paren' && !isBrace && !isExtglob) {
3935 push({ type: 'star', value, output: '' });
3936 continue;
3937 }
3938
3939 // strip consecutive `/**/`
3940 while (rest.slice(0, 3) === '/**') {
3941 const after = input[state.index + 4];
3942 if (after && after !== '/') {
3943 break;
3944 }
3945 rest = rest.slice(3);
3946 consume('/**', 3);
3947 }
3948
3949 if (prior.type === 'bos' && eos()) {
3950 prev.type = 'globstar';
3951 prev.value += value;
3952 prev.output = globstar(opts);
3953 state.output = prev.output;
3954 state.globstar = true;
3955 consume(value);
3956 continue;
3957 }
3958
3959 if (prior.type === 'slash' && prior.prev.type !== 'bos' && !afterStar && eos()) {
3960 state.output = state.output.slice(0, -(prior.output + prev.output).length);
3961 prior.output = `(?:${prior.output}`;
3962
3963 prev.type = 'globstar';
3964 prev.output = globstar(opts) + (opts.strictSlashes ? ')' : '|$)');
3965 prev.value += value;
3966 state.globstar = true;
3967 state.output += prior.output + prev.output;
3968 consume(value);
3969 continue;
3970 }
3971
3972 if (prior.type === 'slash' && prior.prev.type !== 'bos' && rest[0] === '/') {
3973 const end = rest[1] !== void 0 ? '|$' : '';
3974
3975 state.output = state.output.slice(0, -(prior.output + prev.output).length);
3976 prior.output = `(?:${prior.output}`;
3977
3978 prev.type = 'globstar';
3979 prev.output = `${globstar(opts)}${SLASH_LITERAL}|${SLASH_LITERAL}${end})`;
3980 prev.value += value;
3981
3982 state.output += prior.output + prev.output;
3983 state.globstar = true;
3984
3985 consume(value + advance());
3986
3987 push({ type: 'slash', value: '/', output: '' });
3988 continue;
3989 }
3990
3991 if (prior.type === 'bos' && rest[0] === '/') {
3992 prev.type = 'globstar';
3993 prev.value += value;
3994 prev.output = `(?:^|${SLASH_LITERAL}|${globstar(opts)}${SLASH_LITERAL})`;
3995 state.output = prev.output;
3996 state.globstar = true;
3997 consume(value + advance());
3998 push({ type: 'slash', value: '/', output: '' });
3999 continue;
4000 }
4001
4002 // remove single star from output
4003 state.output = state.output.slice(0, -prev.output.length);
4004
4005 // reset previous token to globstar
4006 prev.type = 'globstar';
4007 prev.output = globstar(opts);
4008 prev.value += value;
4009
4010 // reset output with globstar
4011 state.output += prev.output;
4012 state.globstar = true;
4013 consume(value);
4014 continue;
4015 }
4016
4017 const token = { type: 'star', value, output: star };
4018
4019 if (opts.bash === true) {
4020 token.output = '.*?';
4021 if (prev.type === 'bos' || prev.type === 'slash') {
4022 token.output = nodot + token.output;
4023 }
4024 push(token);
4025 continue;
4026 }
4027
4028 if (prev && (prev.type === 'bracket' || prev.type === 'paren') && opts.regex === true) {
4029 token.output = value;
4030 push(token);
4031 continue;
4032 }
4033
4034 if (state.index === state.start || prev.type === 'slash' || prev.type === 'dot') {
4035 if (prev.type === 'dot') {
4036 state.output += NO_DOT_SLASH;
4037 prev.output += NO_DOT_SLASH;
4038
4039 } else if (opts.dot === true) {
4040 state.output += NO_DOTS_SLASH;
4041 prev.output += NO_DOTS_SLASH;
4042
4043 } else {
4044 state.output += nodot;
4045 prev.output += nodot;
4046 }
4047
4048 if (peek() !== '*') {
4049 state.output += ONE_CHAR;
4050 prev.output += ONE_CHAR;
4051 }
4052 }
4053
4054 push(token);
4055 }
4056
4057 while (state.brackets > 0) {
4058 if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', ']'));
4059 state.output = utils.escapeLast(state.output, '[');
4060 decrement('brackets');
4061 }
4062
4063 while (state.parens > 0) {
4064 if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', ')'));
4065 state.output = utils.escapeLast(state.output, '(');
4066 decrement('parens');
4067 }
4068
4069 while (state.braces > 0) {
4070 if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', '}'));
4071 state.output = utils.escapeLast(state.output, '{');
4072 decrement('braces');
4073 }
4074
4075 if (opts.strictSlashes !== true && (prev.type === 'star' || prev.type === 'bracket')) {
4076 push({ type: 'maybe_slash', value: '', output: `${SLASH_LITERAL}?` });
4077 }
4078
4079 // rebuild the output if we had to backtrack at any point
4080 if (state.backtrack === true) {
4081 state.output = '';
4082
4083 for (const token of state.tokens) {
4084 state.output += token.output != null ? token.output : token.value;
4085
4086 if (token.suffix) {
4087 state.output += token.suffix;
4088 }
4089 }
4090 }
4091
4092 return state;
4093 };
4094
4095 /**
4096 * Fast paths for creating regular expressions for common glob patterns.
4097 * This can significantly speed up processing and has very little downside
4098 * impact when none of the fast paths match.
4099 */
4100
4101 parse.fastpaths = (input, options) => {
4102 const opts = { ...options };
4103 const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH;
4104 const len = input.length;
4105 if (len > max) {
4106 throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`);
4107 }
4108
4109 input = REPLACEMENTS[input] || input;
4110 const win32 = utils.isWindows(options);
4111
4112 // create constants based on platform, for windows or posix
4113 const {
4114 DOT_LITERAL,
4115 SLASH_LITERAL,
4116 ONE_CHAR,
4117 DOTS_SLASH,
4118 NO_DOT,
4119 NO_DOTS,
4120 NO_DOTS_SLASH,
4121 STAR,
4122 START_ANCHOR
4123 } = constants.globChars(win32);
4124
4125 const nodot = opts.dot ? NO_DOTS : NO_DOT;
4126 const slashDot = opts.dot ? NO_DOTS_SLASH : NO_DOT;
4127 const capture = opts.capture ? '' : '?:';
4128 const state = { negated: false, prefix: '' };
4129 let star = opts.bash === true ? '.*?' : STAR;
4130
4131 if (opts.capture) {
4132 star = `(${star})`;
4133 }
4134
4135 const globstar = opts => {
4136 if (opts.noglobstar === true) return star;
4137 return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`;
4138 };
4139
4140 const create = str => {
4141 switch (str) {
4142 case '*':
4143 return `${nodot}${ONE_CHAR}${star}`;
4144
4145 case '.*':
4146 return `${DOT_LITERAL}${ONE_CHAR}${star}`;
4147
4148 case '*.*':
4149 return `${nodot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`;
4150
4151 case '*/*':
4152 return `${nodot}${star}${SLASH_LITERAL}${ONE_CHAR}${slashDot}${star}`;
4153
4154 case '**':
4155 return nodot + globstar(opts);
4156
4157 case '**/*':
4158 return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${ONE_CHAR}${star}`;
4159
4160 case '**/*.*':
4161 return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`;
4162
4163 case '**/.*':
4164 return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${DOT_LITERAL}${ONE_CHAR}${star}`;
4165
4166 default: {
4167 const match = /^(.*?)\.(\w+)$/.exec(str);
4168 if (!match) return;
4169
4170 const source = create(match[1]);
4171 if (!source) return;
4172
4173 return source + DOT_LITERAL + match[2];
4174 }
4175 }
4176 };
4177
4178 const output = utils.removePrefix(input, state);
4179 let source = create(output);
4180
4181 if (source && opts.strictSlashes !== true) {
4182 source += `${SLASH_LITERAL}?`;
4183 }
4184
4185 return source;
4186 };
4187
4188 parse_1$1 = parse;
4189 return parse_1$1;
4190}
4191
4192var picomatch_1;
4193var hasRequiredPicomatch$1;
4194
4195function requirePicomatch$1 () {
4196 if (hasRequiredPicomatch$1) return picomatch_1;
4197 hasRequiredPicomatch$1 = 1;
4198
4199 const path = require$$0$1;
4200 const scan = /*@__PURE__*/ requireScan();
4201 const parse = /*@__PURE__*/ requireParse$1();
4202 const utils = /*@__PURE__*/ requireUtils$1();
4203 const constants = /*@__PURE__*/ requireConstants$2();
4204 const isObject = val => val && typeof val === 'object' && !Array.isArray(val);
4205
4206 /**
4207 * Creates a matcher function from one or more glob patterns. The
4208 * returned function takes a string to match as its first argument,
4209 * and returns true if the string is a match. The returned matcher
4210 * function also takes a boolean as the second argument that, when true,
4211 * returns an object with additional information.
4212 *
4213 * ```js
4214 * const picomatch = require('picomatch');
4215 * // picomatch(glob[, options]);
4216 *
4217 * const isMatch = picomatch('*.!(*a)');
4218 * console.log(isMatch('a.a')); //=> false
4219 * console.log(isMatch('a.b')); //=> true
4220 * ```
4221 * @name picomatch
4222 * @param {String|Array} `globs` One or more glob patterns.
4223 * @param {Object=} `options`
4224 * @return {Function=} Returns a matcher function.
4225 * @api public
4226 */
4227
4228 const picomatch = (glob, options, returnState = false) => {
4229 if (Array.isArray(glob)) {
4230 const fns = glob.map(input => picomatch(input, options, returnState));
4231 const arrayMatcher = str => {
4232 for (const isMatch of fns) {
4233 const state = isMatch(str);
4234 if (state) return state;
4235 }
4236 return false;
4237 };
4238 return arrayMatcher;
4239 }
4240
4241 const isState = isObject(glob) && glob.tokens && glob.input;
4242
4243 if (glob === '' || (typeof glob !== 'string' && !isState)) {
4244 throw new TypeError('Expected pattern to be a non-empty string');
4245 }
4246
4247 const opts = options || {};
4248 const posix = utils.isWindows(options);
4249 const regex = isState
4250 ? picomatch.compileRe(glob, options)
4251 : picomatch.makeRe(glob, options, false, true);
4252
4253 const state = regex.state;
4254 delete regex.state;
4255
4256 let isIgnored = () => false;
4257 if (opts.ignore) {
4258 const ignoreOpts = { ...options, ignore: null, onMatch: null, onResult: null };
4259 isIgnored = picomatch(opts.ignore, ignoreOpts, returnState);
4260 }
4261
4262 const matcher = (input, returnObject = false) => {
4263 const { isMatch, match, output } = picomatch.test(input, regex, options, { glob, posix });
4264 const result = { glob, state, regex, posix, input, output, match, isMatch };
4265
4266 if (typeof opts.onResult === 'function') {
4267 opts.onResult(result);
4268 }
4269
4270 if (isMatch === false) {
4271 result.isMatch = false;
4272 return returnObject ? result : false;
4273 }
4274
4275 if (isIgnored(input)) {
4276 if (typeof opts.onIgnore === 'function') {
4277 opts.onIgnore(result);
4278 }
4279 result.isMatch = false;
4280 return returnObject ? result : false;
4281 }
4282
4283 if (typeof opts.onMatch === 'function') {
4284 opts.onMatch(result);
4285 }
4286 return returnObject ? result : true;
4287 };
4288
4289 if (returnState) {
4290 matcher.state = state;
4291 }
4292
4293 return matcher;
4294 };
4295
4296 /**
4297 * Test `input` with the given `regex`. This is used by the main
4298 * `picomatch()` function to test the input string.
4299 *
4300 * ```js
4301 * const picomatch = require('picomatch');
4302 * // picomatch.test(input, regex[, options]);
4303 *
4304 * console.log(picomatch.test('foo/bar', /^(?:([^/]*?)\/([^/]*?))$/));
4305 * // { isMatch: true, match: [ 'foo/', 'foo', 'bar' ], output: 'foo/bar' }
4306 * ```
4307 * @param {String} `input` String to test.
4308 * @param {RegExp} `regex`
4309 * @return {Object} Returns an object with matching info.
4310 * @api public
4311 */
4312
4313 picomatch.test = (input, regex, options, { glob, posix } = {}) => {
4314 if (typeof input !== 'string') {
4315 throw new TypeError('Expected input to be a string');
4316 }
4317
4318 if (input === '') {
4319 return { isMatch: false, output: '' };
4320 }
4321
4322 const opts = options || {};
4323 const format = opts.format || (posix ? utils.toPosixSlashes : null);
4324 let match = input === glob;
4325 let output = (match && format) ? format(input) : input;
4326
4327 if (match === false) {
4328 output = format ? format(input) : input;
4329 match = output === glob;
4330 }
4331
4332 if (match === false || opts.capture === true) {
4333 if (opts.matchBase === true || opts.basename === true) {
4334 match = picomatch.matchBase(input, regex, options, posix);
4335 } else {
4336 match = regex.exec(output);
4337 }
4338 }
4339
4340 return { isMatch: Boolean(match), match, output };
4341 };
4342
4343 /**
4344 * Match the basename of a filepath.
4345 *
4346 * ```js
4347 * const picomatch = require('picomatch');
4348 * // picomatch.matchBase(input, glob[, options]);
4349 * console.log(picomatch.matchBase('foo/bar.js', '*.js'); // true
4350 * ```
4351 * @param {String} `input` String to test.
4352 * @param {RegExp|String} `glob` Glob pattern or regex created by [.makeRe](#makeRe).
4353 * @return {Boolean}
4354 * @api public
4355 */
4356
4357 picomatch.matchBase = (input, glob, options, posix = utils.isWindows(options)) => {
4358 const regex = glob instanceof RegExp ? glob : picomatch.makeRe(glob, options);
4359 return regex.test(path.basename(input));
4360 };
4361
4362 /**
4363 * Returns true if **any** of the given glob `patterns` match the specified `string`.
4364 *
4365 * ```js
4366 * const picomatch = require('picomatch');
4367 * // picomatch.isMatch(string, patterns[, options]);
4368 *
4369 * console.log(picomatch.isMatch('a.a', ['b.*', '*.a'])); //=> true
4370 * console.log(picomatch.isMatch('a.a', 'b.*')); //=> false
4371 * ```
4372 * @param {String|Array} str The string to test.
4373 * @param {String|Array} patterns One or more glob patterns to use for matching.
4374 * @param {Object} [options] See available [options](#options).
4375 * @return {Boolean} Returns true if any patterns match `str`
4376 * @api public
4377 */
4378
4379 picomatch.isMatch = (str, patterns, options) => picomatch(patterns, options)(str);
4380
4381 /**
4382 * Parse a glob pattern to create the source string for a regular
4383 * expression.
4384 *
4385 * ```js
4386 * const picomatch = require('picomatch');
4387 * const result = picomatch.parse(pattern[, options]);
4388 * ```
4389 * @param {String} `pattern`
4390 * @param {Object} `options`
4391 * @return {Object} Returns an object with useful properties and output to be used as a regex source string.
4392 * @api public
4393 */
4394
4395 picomatch.parse = (pattern, options) => {
4396 if (Array.isArray(pattern)) return pattern.map(p => picomatch.parse(p, options));
4397 return parse(pattern, { ...options, fastpaths: false });
4398 };
4399
4400 /**
4401 * Scan a glob pattern to separate the pattern into segments.
4402 *
4403 * ```js
4404 * const picomatch = require('picomatch');
4405 * // picomatch.scan(input[, options]);
4406 *
4407 * const result = picomatch.scan('!./foo/*.js');
4408 * console.log(result);
4409 * { prefix: '!./',
4410 * input: '!./foo/*.js',
4411 * start: 3,
4412 * base: 'foo',
4413 * glob: '*.js',
4414 * isBrace: false,
4415 * isBracket: false,
4416 * isGlob: true,
4417 * isExtglob: false,
4418 * isGlobstar: false,
4419 * negated: true }
4420 * ```
4421 * @param {String} `input` Glob pattern to scan.
4422 * @param {Object} `options`
4423 * @return {Object} Returns an object with
4424 * @api public
4425 */
4426
4427 picomatch.scan = (input, options) => scan(input, options);
4428
4429 /**
4430 * Compile a regular expression from the `state` object returned by the
4431 * [parse()](#parse) method.
4432 *
4433 * @param {Object} `state`
4434 * @param {Object} `options`
4435 * @param {Boolean} `returnOutput` Intended for implementors, this argument allows you to return the raw output from the parser.
4436 * @param {Boolean} `returnState` Adds the state to a `state` property on the returned regex. Useful for implementors and debugging.
4437 * @return {RegExp}
4438 * @api public
4439 */
4440
4441 picomatch.compileRe = (state, options, returnOutput = false, returnState = false) => {
4442 if (returnOutput === true) {
4443 return state.output;
4444 }
4445
4446 const opts = options || {};
4447 const prepend = opts.contains ? '' : '^';
4448 const append = opts.contains ? '' : '$';
4449
4450 let source = `${prepend}(?:${state.output})${append}`;
4451 if (state && state.negated === true) {
4452 source = `^(?!${source}).*$`;
4453 }
4454
4455 const regex = picomatch.toRegex(source, options);
4456 if (returnState === true) {
4457 regex.state = state;
4458 }
4459
4460 return regex;
4461 };
4462
4463 /**
4464 * Create a regular expression from a parsed glob pattern.
4465 *
4466 * ```js
4467 * const picomatch = require('picomatch');
4468 * const state = picomatch.parse('*.js');
4469 * // picomatch.compileRe(state[, options]);
4470 *
4471 * console.log(picomatch.compileRe(state));
4472 * //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/
4473 * ```
4474 * @param {String} `state` The object returned from the `.parse` method.
4475 * @param {Object} `options`
4476 * @param {Boolean} `returnOutput` Implementors may use this argument to return the compiled output, instead of a regular expression. This is not exposed on the options to prevent end-users from mutating the result.
4477 * @param {Boolean} `returnState` Implementors may use this argument to return the state from the parsed glob with the returned regular expression.
4478 * @return {RegExp} Returns a regex created from the given pattern.
4479 * @api public
4480 */
4481
4482 picomatch.makeRe = (input, options = {}, returnOutput = false, returnState = false) => {
4483 if (!input || typeof input !== 'string') {
4484 throw new TypeError('Expected a non-empty string');
4485 }
4486
4487 let parsed = { negated: false, fastpaths: true };
4488
4489 if (options.fastpaths !== false && (input[0] === '.' || input[0] === '*')) {
4490 parsed.output = parse.fastpaths(input, options);
4491 }
4492
4493 if (!parsed.output) {
4494 parsed = parse(input, options);
4495 }
4496
4497 return picomatch.compileRe(parsed, options, returnOutput, returnState);
4498 };
4499
4500 /**
4501 * Create a regular expression from the given regex source string.
4502 *
4503 * ```js
4504 * const picomatch = require('picomatch');
4505 * // picomatch.toRegex(source[, options]);
4506 *
4507 * const { output } = picomatch.parse('*.js');
4508 * console.log(picomatch.toRegex(output));
4509 * //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/
4510 * ```
4511 * @param {String} `source` Regular expression source string.
4512 * @param {Object} `options`
4513 * @return {RegExp}
4514 * @api public
4515 */
4516
4517 picomatch.toRegex = (source, options) => {
4518 try {
4519 const opts = options || {};
4520 return new RegExp(source, opts.flags || (opts.nocase ? 'i' : ''));
4521 } catch (err) {
4522 if (options && options.debug === true) throw err;
4523 return /$^/;
4524 }
4525 };
4526
4527 /**
4528 * Picomatch constants.
4529 * @return {Object}
4530 */
4531
4532 picomatch.constants = constants;
4533
4534 /**
4535 * Expose "picomatch"
4536 */
4537
4538 picomatch_1 = picomatch;
4539 return picomatch_1;
4540}
4541
4542var picomatch;
4543var hasRequiredPicomatch;
4544
4545function requirePicomatch () {
4546 if (hasRequiredPicomatch) return picomatch;
4547 hasRequiredPicomatch = 1;
4548
4549 picomatch = /*@__PURE__*/ requirePicomatch$1();
4550 return picomatch;
4551}
4552
4553/*!
4554 * normalize-path <https://github.com/jonschlinkert/normalize-path>
4555 *
4556 * Copyright (c) 2014-2018, Jon Schlinkert.
4557 * Released under the MIT License.
4558 */
4559
4560var normalizePath;
4561var hasRequiredNormalizePath;
4562
4563function requireNormalizePath () {
4564 if (hasRequiredNormalizePath) return normalizePath;
4565 hasRequiredNormalizePath = 1;
4566 normalizePath = function(path, stripTrailing) {
4567 if (typeof path !== 'string') {
4568 throw new TypeError('expected path to be a string');
4569 }
4570
4571 if (path === '\\' || path === '/') return '/';
4572
4573 var len = path.length;
4574 if (len <= 1) return path;
4575
4576 // ensure that win32 namespaces has two leading slashes, so that the path is
4577 // handled properly by the win32 version of path.parse() after being normalized
4578 // https://msdn.microsoft.com/library/windows/desktop/aa365247(v=vs.85).aspx#namespaces
4579 var prefix = '';
4580 if (len > 4 && path[3] === '\\') {
4581 var ch = path[2];
4582 if ((ch === '?' || ch === '.') && path.slice(0, 2) === '\\\\') {
4583 path = path.slice(2);
4584 prefix = '//';
4585 }
4586 }
4587
4588 var segs = path.split(/[/\\]+/);
4589 if (stripTrailing !== false && segs[segs.length - 1] === '') {
4590 segs.pop();
4591 }
4592 return prefix + segs.join('/');
4593 };
4594 return normalizePath;
4595}
4596
4597var anymatch_1 = anymatch.exports;
4598
4599var hasRequiredAnymatch;
4600
4601function requireAnymatch () {
4602 if (hasRequiredAnymatch) return anymatch.exports;
4603 hasRequiredAnymatch = 1;
4604
4605 Object.defineProperty(anymatch_1, "__esModule", { value: true });
4606
4607 const picomatch = /*@__PURE__*/ requirePicomatch();
4608 const normalizePath = /*@__PURE__*/ requireNormalizePath();
4609
4610 /**
4611 * @typedef {(testString: string) => boolean} AnymatchFn
4612 * @typedef {string|RegExp|AnymatchFn} AnymatchPattern
4613 * @typedef {AnymatchPattern|AnymatchPattern[]} AnymatchMatcher
4614 */
4615 const BANG = '!';
4616 const DEFAULT_OPTIONS = {returnIndex: false};
4617 const arrify = (item) => Array.isArray(item) ? item : [item];
4618
4619 /**
4620 * @param {AnymatchPattern} matcher
4621 * @param {object} options
4622 * @returns {AnymatchFn}
4623 */
4624 const createPattern = (matcher, options) => {
4625 if (typeof matcher === 'function') {
4626 return matcher;
4627 }
4628 if (typeof matcher === 'string') {
4629 const glob = picomatch(matcher, options);
4630 return (string) => matcher === string || glob(string);
4631 }
4632 if (matcher instanceof RegExp) {
4633 return (string) => matcher.test(string);
4634 }
4635 return (string) => false;
4636 };
4637
4638 /**
4639 * @param {Array<Function>} patterns
4640 * @param {Array<Function>} negPatterns
4641 * @param {String|Array} args
4642 * @param {Boolean} returnIndex
4643 * @returns {boolean|number}
4644 */
4645 const matchPatterns = (patterns, negPatterns, args, returnIndex) => {
4646 const isList = Array.isArray(args);
4647 const _path = isList ? args[0] : args;
4648 if (!isList && typeof _path !== 'string') {
4649 throw new TypeError('anymatch: second argument must be a string: got ' +
4650 Object.prototype.toString.call(_path))
4651 }
4652 const path = normalizePath(_path, false);
4653
4654 for (let index = 0; index < negPatterns.length; index++) {
4655 const nglob = negPatterns[index];
4656 if (nglob(path)) {
4657 return returnIndex ? -1 : false;
4658 }
4659 }
4660
4661 const applied = isList && [path].concat(args.slice(1));
4662 for (let index = 0; index < patterns.length; index++) {
4663 const pattern = patterns[index];
4664 if (isList ? pattern(...applied) : pattern(path)) {
4665 return returnIndex ? index : true;
4666 }
4667 }
4668
4669 return returnIndex ? -1 : false;
4670 };
4671
4672 /**
4673 * @param {AnymatchMatcher} matchers
4674 * @param {Array|string} testString
4675 * @param {object} options
4676 * @returns {boolean|number|Function}
4677 */
4678 const anymatch$1 = (matchers, testString, options = DEFAULT_OPTIONS) => {
4679 if (matchers == null) {
4680 throw new TypeError('anymatch: specify first argument');
4681 }
4682 const opts = typeof options === 'boolean' ? {returnIndex: options} : options;
4683 const returnIndex = opts.returnIndex || false;
4684
4685 // Early cache for matchers.
4686 const mtchers = arrify(matchers);
4687 const negatedGlobs = mtchers
4688 .filter(item => typeof item === 'string' && item.charAt(0) === BANG)
4689 .map(item => item.slice(1))
4690 .map(item => picomatch(item, opts));
4691 const patterns = mtchers
4692 .filter(item => typeof item !== 'string' || (typeof item === 'string' && item.charAt(0) !== BANG))
4693 .map(matcher => createPattern(matcher, opts));
4694
4695 if (testString == null) {
4696 return (testString, ri = false) => {
4697 const returnIndex = typeof ri === 'boolean' ? ri : false;
4698 return matchPatterns(patterns, negatedGlobs, testString, returnIndex);
4699 }
4700 }
4701
4702 return matchPatterns(patterns, negatedGlobs, testString, returnIndex);
4703 };
4704
4705 anymatch$1.default = anymatch$1;
4706 anymatch.exports = anymatch$1;
4707 return anymatch.exports;
4708}
4709
4710/*!
4711 * is-extglob <https://github.com/jonschlinkert/is-extglob>
4712 *
4713 * Copyright (c) 2014-2016, Jon Schlinkert.
4714 * Licensed under the MIT License.
4715 */
4716
4717var isExtglob;
4718var hasRequiredIsExtglob;
4719
4720function requireIsExtglob () {
4721 if (hasRequiredIsExtglob) return isExtglob;
4722 hasRequiredIsExtglob = 1;
4723 isExtglob = function isExtglob(str) {
4724 if (typeof str !== 'string' || str === '') {
4725 return false;
4726 }
4727
4728 var match;
4729 while ((match = /(\\).|([@?!+*]\(.*\))/g.exec(str))) {
4730 if (match[2]) return true;
4731 str = str.slice(match.index + match[0].length);
4732 }
4733
4734 return false;
4735 };
4736 return isExtglob;
4737}
4738
4739/*!
4740 * is-glob <https://github.com/jonschlinkert/is-glob>
4741 *
4742 * Copyright (c) 2014-2017, Jon Schlinkert.
4743 * Released under the MIT License.
4744 */
4745
4746var isGlob;
4747var hasRequiredIsGlob;
4748
4749function requireIsGlob () {
4750 if (hasRequiredIsGlob) return isGlob;
4751 hasRequiredIsGlob = 1;
4752 var isExtglob = /*@__PURE__*/ requireIsExtglob();
4753 var chars = { '{': '}', '(': ')', '[': ']'};
4754 var strictCheck = function(str) {
4755 if (str[0] === '!') {
4756 return true;
4757 }
4758 var index = 0;
4759 var pipeIndex = -2;
4760 var closeSquareIndex = -2;
4761 var closeCurlyIndex = -2;
4762 var closeParenIndex = -2;
4763 var backSlashIndex = -2;
4764 while (index < str.length) {
4765 if (str[index] === '*') {
4766 return true;
4767 }
4768
4769 if (str[index + 1] === '?' && /[\].+)]/.test(str[index])) {
4770 return true;
4771 }
4772
4773 if (closeSquareIndex !== -1 && str[index] === '[' && str[index + 1] !== ']') {
4774 if (closeSquareIndex < index) {
4775 closeSquareIndex = str.indexOf(']', index);
4776 }
4777 if (closeSquareIndex > index) {
4778 if (backSlashIndex === -1 || backSlashIndex > closeSquareIndex) {
4779 return true;
4780 }
4781 backSlashIndex = str.indexOf('\\', index);
4782 if (backSlashIndex === -1 || backSlashIndex > closeSquareIndex) {
4783 return true;
4784 }
4785 }
4786 }
4787
4788 if (closeCurlyIndex !== -1 && str[index] === '{' && str[index + 1] !== '}') {
4789 closeCurlyIndex = str.indexOf('}', index);
4790 if (closeCurlyIndex > index) {
4791 backSlashIndex = str.indexOf('\\', index);
4792 if (backSlashIndex === -1 || backSlashIndex > closeCurlyIndex) {
4793 return true;
4794 }
4795 }
4796 }
4797
4798 if (closeParenIndex !== -1 && str[index] === '(' && str[index + 1] === '?' && /[:!=]/.test(str[index + 2]) && str[index + 3] !== ')') {
4799 closeParenIndex = str.indexOf(')', index);
4800 if (closeParenIndex > index) {
4801 backSlashIndex = str.indexOf('\\', index);
4802 if (backSlashIndex === -1 || backSlashIndex > closeParenIndex) {
4803 return true;
4804 }
4805 }
4806 }
4807
4808 if (pipeIndex !== -1 && str[index] === '(' && str[index + 1] !== '|') {
4809 if (pipeIndex < index) {
4810 pipeIndex = str.indexOf('|', index);
4811 }
4812 if (pipeIndex !== -1 && str[pipeIndex + 1] !== ')') {
4813 closeParenIndex = str.indexOf(')', pipeIndex);
4814 if (closeParenIndex > pipeIndex) {
4815 backSlashIndex = str.indexOf('\\', pipeIndex);
4816 if (backSlashIndex === -1 || backSlashIndex > closeParenIndex) {
4817 return true;
4818 }
4819 }
4820 }
4821 }
4822
4823 if (str[index] === '\\') {
4824 var open = str[index + 1];
4825 index += 2;
4826 var close = chars[open];
4827
4828 if (close) {
4829 var n = str.indexOf(close, index);
4830 if (n !== -1) {
4831 index = n + 1;
4832 }
4833 }
4834
4835 if (str[index] === '!') {
4836 return true;
4837 }
4838 } else {
4839 index++;
4840 }
4841 }
4842 return false;
4843 };
4844
4845 var relaxedCheck = function(str) {
4846 if (str[0] === '!') {
4847 return true;
4848 }
4849 var index = 0;
4850 while (index < str.length) {
4851 if (/[*?{}()[\]]/.test(str[index])) {
4852 return true;
4853 }
4854
4855 if (str[index] === '\\') {
4856 var open = str[index + 1];
4857 index += 2;
4858 var close = chars[open];
4859
4860 if (close) {
4861 var n = str.indexOf(close, index);
4862 if (n !== -1) {
4863 index = n + 1;
4864 }
4865 }
4866
4867 if (str[index] === '!') {
4868 return true;
4869 }
4870 } else {
4871 index++;
4872 }
4873 }
4874 return false;
4875 };
4876
4877 isGlob = function isGlob(str, options) {
4878 if (typeof str !== 'string' || str === '') {
4879 return false;
4880 }
4881
4882 if (isExtglob(str)) {
4883 return true;
4884 }
4885
4886 var check = strictCheck;
4887
4888 // optionally relax check
4889 if (options && options.strict === false) {
4890 check = relaxedCheck;
4891 }
4892
4893 return check(str);
4894 };
4895 return isGlob;
4896}
4897
4898var globParent;
4899var hasRequiredGlobParent;
4900
4901function requireGlobParent () {
4902 if (hasRequiredGlobParent) return globParent;
4903 hasRequiredGlobParent = 1;
4904
4905 var isGlob = /*@__PURE__*/ requireIsGlob();
4906 var pathPosixDirname = require$$0$1.posix.dirname;
4907 var isWin32 = require$$2$1.platform() === 'win32';
4908
4909 var slash = '/';
4910 var backslash = /\\/g;
4911 var enclosure = /[\{\[].*[\}\]]$/;
4912 var globby = /(^|[^\\])([\{\[]|\([^\)]+$)/;
4913 var escaped = /\\([\!\*\?\|\[\]\(\)\{\}])/g;
4914
4915 /**
4916 * @param {string} str
4917 * @param {Object} opts
4918 * @param {boolean} [opts.flipBackslashes=true]
4919 * @returns {string}
4920 */
4921 globParent = function globParent(str, opts) {
4922 var options = Object.assign({ flipBackslashes: true }, opts);
4923
4924 // flip windows path separators
4925 if (options.flipBackslashes && isWin32 && str.indexOf(slash) < 0) {
4926 str = str.replace(backslash, slash);
4927 }
4928
4929 // special case for strings ending in enclosure containing path separator
4930 if (enclosure.test(str)) {
4931 str += slash;
4932 }
4933
4934 // preserves full path in case of trailing path separator
4935 str += 'a';
4936
4937 // remove path parts that are globby
4938 do {
4939 str = pathPosixDirname(str);
4940 } while (isGlob(str) || globby.test(str));
4941
4942 // remove escape chars and return result
4943 return str.replace(escaped, '$1');
4944 };
4945 return globParent;
4946}
4947
4948var utils = {};
4949
4950var hasRequiredUtils;
4951
4952function requireUtils () {
4953 if (hasRequiredUtils) return utils;
4954 hasRequiredUtils = 1;
4955 (function (exports) {
4956
4957 exports.isInteger = num => {
4958 if (typeof num === 'number') {
4959 return Number.isInteger(num);
4960 }
4961 if (typeof num === 'string' && num.trim() !== '') {
4962 return Number.isInteger(Number(num));
4963 }
4964 return false;
4965 };
4966
4967 /**
4968 * Find a node of the given type
4969 */
4970
4971 exports.find = (node, type) => node.nodes.find(node => node.type === type);
4972
4973 /**
4974 * Find a node of the given type
4975 */
4976
4977 exports.exceedsLimit = (min, max, step = 1, limit) => {
4978 if (limit === false) return false;
4979 if (!exports.isInteger(min) || !exports.isInteger(max)) return false;
4980 return ((Number(max) - Number(min)) / Number(step)) >= limit;
4981 };
4982
4983 /**
4984 * Escape the given node with '\\' before node.value
4985 */
4986
4987 exports.escapeNode = (block, n = 0, type) => {
4988 const node = block.nodes[n];
4989 if (!node) return;
4990
4991 if ((type && node.type === type) || node.type === 'open' || node.type === 'close') {
4992 if (node.escaped !== true) {
4993 node.value = '\\' + node.value;
4994 node.escaped = true;
4995 }
4996 }
4997 };
4998
4999 /**
5000 * Returns true if the given brace node should be enclosed in literal braces
5001 */
5002
5003 exports.encloseBrace = node => {
5004 if (node.type !== 'brace') return false;
5005 if ((node.commas >> 0 + node.ranges >> 0) === 0) {
5006 node.invalid = true;
5007 return true;
5008 }
5009 return false;
5010 };
5011
5012 /**
5013 * Returns true if a brace node is invalid.
5014 */
5015
5016 exports.isInvalidBrace = block => {
5017 if (block.type !== 'brace') return false;
5018 if (block.invalid === true || block.dollar) return true;
5019 if ((block.commas >> 0 + block.ranges >> 0) === 0) {
5020 block.invalid = true;
5021 return true;
5022 }
5023 if (block.open !== true || block.close !== true) {
5024 block.invalid = true;
5025 return true;
5026 }
5027 return false;
5028 };
5029
5030 /**
5031 * Returns true if a node is an open or close node
5032 */
5033
5034 exports.isOpenOrClose = node => {
5035 if (node.type === 'open' || node.type === 'close') {
5036 return true;
5037 }
5038 return node.open === true || node.close === true;
5039 };
5040
5041 /**
5042 * Reduce an array of text nodes.
5043 */
5044
5045 exports.reduce = nodes => nodes.reduce((acc, node) => {
5046 if (node.type === 'text') acc.push(node.value);
5047 if (node.type === 'range') node.type = 'text';
5048 return acc;
5049 }, []);
5050
5051 /**
5052 * Flatten an array
5053 */
5054
5055 exports.flatten = (...args) => {
5056 const result = [];
5057
5058 const flat = arr => {
5059 for (let i = 0; i < arr.length; i++) {
5060 const ele = arr[i];
5061
5062 if (Array.isArray(ele)) {
5063 flat(ele);
5064 continue;
5065 }
5066
5067 if (ele !== undefined) {
5068 result.push(ele);
5069 }
5070 }
5071 return result;
5072 };
5073
5074 flat(args);
5075 return result;
5076 };
5077 } (utils));
5078 return utils;
5079}
5080
5081var stringify;
5082var hasRequiredStringify;
5083
5084function requireStringify () {
5085 if (hasRequiredStringify) return stringify;
5086 hasRequiredStringify = 1;
5087
5088 const utils = /*@__PURE__*/ requireUtils();
5089
5090 stringify = (ast, options = {}) => {
5091 const stringify = (node, parent = {}) => {
5092 const invalidBlock = options.escapeInvalid && utils.isInvalidBrace(parent);
5093 const invalidNode = node.invalid === true && options.escapeInvalid === true;
5094 let output = '';
5095
5096 if (node.value) {
5097 if ((invalidBlock || invalidNode) && utils.isOpenOrClose(node)) {
5098 return '\\' + node.value;
5099 }
5100 return node.value;
5101 }
5102
5103 if (node.value) {
5104 return node.value;
5105 }
5106
5107 if (node.nodes) {
5108 for (const child of node.nodes) {
5109 output += stringify(child);
5110 }
5111 }
5112 return output;
5113 };
5114
5115 return stringify(ast);
5116 };
5117 return stringify;
5118}
5119
5120/*!
5121 * is-number <https://github.com/jonschlinkert/is-number>
5122 *
5123 * Copyright (c) 2014-present, Jon Schlinkert.
5124 * Released under the MIT License.
5125 */
5126
5127var isNumber;
5128var hasRequiredIsNumber;
5129
5130function requireIsNumber () {
5131 if (hasRequiredIsNumber) return isNumber;
5132 hasRequiredIsNumber = 1;
5133
5134 isNumber = function(num) {
5135 if (typeof num === 'number') {
5136 return num - num === 0;
5137 }
5138 if (typeof num === 'string' && num.trim() !== '') {
5139 return Number.isFinite ? Number.isFinite(+num) : isFinite(+num);
5140 }
5141 return false;
5142 };
5143 return isNumber;
5144}
5145
5146/*!
5147 * to-regex-range <https://github.com/micromatch/to-regex-range>
5148 *
5149 * Copyright (c) 2015-present, Jon Schlinkert.
5150 * Released under the MIT License.
5151 */
5152
5153var toRegexRange_1;
5154var hasRequiredToRegexRange;
5155
5156function requireToRegexRange () {
5157 if (hasRequiredToRegexRange) return toRegexRange_1;
5158 hasRequiredToRegexRange = 1;
5159
5160 const isNumber = /*@__PURE__*/ requireIsNumber();
5161
5162 const toRegexRange = (min, max, options) => {
5163 if (isNumber(min) === false) {
5164 throw new TypeError('toRegexRange: expected the first argument to be a number');
5165 }
5166
5167 if (max === void 0 || min === max) {
5168 return String(min);
5169 }
5170
5171 if (isNumber(max) === false) {
5172 throw new TypeError('toRegexRange: expected the second argument to be a number.');
5173 }
5174
5175 let opts = { relaxZeros: true, ...options };
5176 if (typeof opts.strictZeros === 'boolean') {
5177 opts.relaxZeros = opts.strictZeros === false;
5178 }
5179
5180 let relax = String(opts.relaxZeros);
5181 let shorthand = String(opts.shorthand);
5182 let capture = String(opts.capture);
5183 let wrap = String(opts.wrap);
5184 let cacheKey = min + ':' + max + '=' + relax + shorthand + capture + wrap;
5185
5186 if (toRegexRange.cache.hasOwnProperty(cacheKey)) {
5187 return toRegexRange.cache[cacheKey].result;
5188 }
5189
5190 let a = Math.min(min, max);
5191 let b = Math.max(min, max);
5192
5193 if (Math.abs(a - b) === 1) {
5194 let result = min + '|' + max;
5195 if (opts.capture) {
5196 return `(${result})`;
5197 }
5198 if (opts.wrap === false) {
5199 return result;
5200 }
5201 return `(?:${result})`;
5202 }
5203
5204 let isPadded = hasPadding(min) || hasPadding(max);
5205 let state = { min, max, a, b };
5206 let positives = [];
5207 let negatives = [];
5208
5209 if (isPadded) {
5210 state.isPadded = isPadded;
5211 state.maxLen = String(state.max).length;
5212 }
5213
5214 if (a < 0) {
5215 let newMin = b < 0 ? Math.abs(b) : 1;
5216 negatives = splitToPatterns(newMin, Math.abs(a), state, opts);
5217 a = state.a = 0;
5218 }
5219
5220 if (b >= 0) {
5221 positives = splitToPatterns(a, b, state, opts);
5222 }
5223
5224 state.negatives = negatives;
5225 state.positives = positives;
5226 state.result = collatePatterns(negatives, positives);
5227
5228 if (opts.capture === true) {
5229 state.result = `(${state.result})`;
5230 } else if (opts.wrap !== false && (positives.length + negatives.length) > 1) {
5231 state.result = `(?:${state.result})`;
5232 }
5233
5234 toRegexRange.cache[cacheKey] = state;
5235 return state.result;
5236 };
5237
5238 function collatePatterns(neg, pos, options) {
5239 let onlyNegative = filterPatterns(neg, pos, '-', false) || [];
5240 let onlyPositive = filterPatterns(pos, neg, '', false) || [];
5241 let intersected = filterPatterns(neg, pos, '-?', true) || [];
5242 let subpatterns = onlyNegative.concat(intersected).concat(onlyPositive);
5243 return subpatterns.join('|');
5244 }
5245
5246 function splitToRanges(min, max) {
5247 let nines = 1;
5248 let zeros = 1;
5249
5250 let stop = countNines(min, nines);
5251 let stops = new Set([max]);
5252
5253 while (min <= stop && stop <= max) {
5254 stops.add(stop);
5255 nines += 1;
5256 stop = countNines(min, nines);
5257 }
5258
5259 stop = countZeros(max + 1, zeros) - 1;
5260
5261 while (min < stop && stop <= max) {
5262 stops.add(stop);
5263 zeros += 1;
5264 stop = countZeros(max + 1, zeros) - 1;
5265 }
5266
5267 stops = [...stops];
5268 stops.sort(compare);
5269 return stops;
5270 }
5271
5272 /**
5273 * Convert a range to a regex pattern
5274 * @param {Number} `start`
5275 * @param {Number} `stop`
5276 * @return {String}
5277 */
5278
5279 function rangeToPattern(start, stop, options) {
5280 if (start === stop) {
5281 return { pattern: start, count: [], digits: 0 };
5282 }
5283
5284 let zipped = zip(start, stop);
5285 let digits = zipped.length;
5286 let pattern = '';
5287 let count = 0;
5288
5289 for (let i = 0; i < digits; i++) {
5290 let [startDigit, stopDigit] = zipped[i];
5291
5292 if (startDigit === stopDigit) {
5293 pattern += startDigit;
5294
5295 } else if (startDigit !== '0' || stopDigit !== '9') {
5296 pattern += toCharacterClass(startDigit, stopDigit);
5297
5298 } else {
5299 count++;
5300 }
5301 }
5302
5303 if (count) {
5304 pattern += options.shorthand === true ? '\\d' : '[0-9]';
5305 }
5306
5307 return { pattern, count: [count], digits };
5308 }
5309
5310 function splitToPatterns(min, max, tok, options) {
5311 let ranges = splitToRanges(min, max);
5312 let tokens = [];
5313 let start = min;
5314 let prev;
5315
5316 for (let i = 0; i < ranges.length; i++) {
5317 let max = ranges[i];
5318 let obj = rangeToPattern(String(start), String(max), options);
5319 let zeros = '';
5320
5321 if (!tok.isPadded && prev && prev.pattern === obj.pattern) {
5322 if (prev.count.length > 1) {
5323 prev.count.pop();
5324 }
5325
5326 prev.count.push(obj.count[0]);
5327 prev.string = prev.pattern + toQuantifier(prev.count);
5328 start = max + 1;
5329 continue;
5330 }
5331
5332 if (tok.isPadded) {
5333 zeros = padZeros(max, tok, options);
5334 }
5335
5336 obj.string = zeros + obj.pattern + toQuantifier(obj.count);
5337 tokens.push(obj);
5338 start = max + 1;
5339 prev = obj;
5340 }
5341
5342 return tokens;
5343 }
5344
5345 function filterPatterns(arr, comparison, prefix, intersection, options) {
5346 let result = [];
5347
5348 for (let ele of arr) {
5349 let { string } = ele;
5350
5351 // only push if _both_ are negative...
5352 if (!intersection && !contains(comparison, 'string', string)) {
5353 result.push(prefix + string);
5354 }
5355
5356 // or _both_ are positive
5357 if (intersection && contains(comparison, 'string', string)) {
5358 result.push(prefix + string);
5359 }
5360 }
5361 return result;
5362 }
5363
5364 /**
5365 * Zip strings
5366 */
5367
5368 function zip(a, b) {
5369 let arr = [];
5370 for (let i = 0; i < a.length; i++) arr.push([a[i], b[i]]);
5371 return arr;
5372 }
5373
5374 function compare(a, b) {
5375 return a > b ? 1 : b > a ? -1 : 0;
5376 }
5377
5378 function contains(arr, key, val) {
5379 return arr.some(ele => ele[key] === val);
5380 }
5381
5382 function countNines(min, len) {
5383 return Number(String(min).slice(0, -len) + '9'.repeat(len));
5384 }
5385
5386 function countZeros(integer, zeros) {
5387 return integer - (integer % Math.pow(10, zeros));
5388 }
5389
5390 function toQuantifier(digits) {
5391 let [start = 0, stop = ''] = digits;
5392 if (stop || start > 1) {
5393 return `{${start + (stop ? ',' + stop : '')}}`;
5394 }
5395 return '';
5396 }
5397
5398 function toCharacterClass(a, b, options) {
5399 return `[${a}${(b - a === 1) ? '' : '-'}${b}]`;
5400 }
5401
5402 function hasPadding(str) {
5403 return /^-?(0+)\d/.test(str);
5404 }
5405
5406 function padZeros(value, tok, options) {
5407 if (!tok.isPadded) {
5408 return value;
5409 }
5410
5411 let diff = Math.abs(tok.maxLen - String(value).length);
5412 let relax = options.relaxZeros !== false;
5413
5414 switch (diff) {
5415 case 0:
5416 return '';
5417 case 1:
5418 return relax ? '0?' : '0';
5419 case 2:
5420 return relax ? '0{0,2}' : '00';
5421 default: {
5422 return relax ? `0{0,${diff}}` : `0{${diff}}`;
5423 }
5424 }
5425 }
5426
5427 /**
5428 * Cache
5429 */
5430
5431 toRegexRange.cache = {};
5432 toRegexRange.clearCache = () => (toRegexRange.cache = {});
5433
5434 /**
5435 * Expose `toRegexRange`
5436 */
5437
5438 toRegexRange_1 = toRegexRange;
5439 return toRegexRange_1;
5440}
5441
5442/*!
5443 * fill-range <https://github.com/jonschlinkert/fill-range>
5444 *
5445 * Copyright (c) 2014-present, Jon Schlinkert.
5446 * Licensed under the MIT License.
5447 */
5448
5449var fillRange;
5450var hasRequiredFillRange;
5451
5452function requireFillRange () {
5453 if (hasRequiredFillRange) return fillRange;
5454 hasRequiredFillRange = 1;
5455
5456 const util = require$$2;
5457 const toRegexRange = /*@__PURE__*/ requireToRegexRange();
5458
5459 const isObject = val => val !== null && typeof val === 'object' && !Array.isArray(val);
5460
5461 const transform = toNumber => {
5462 return value => toNumber === true ? Number(value) : String(value);
5463 };
5464
5465 const isValidValue = value => {
5466 return typeof value === 'number' || (typeof value === 'string' && value !== '');
5467 };
5468
5469 const isNumber = num => Number.isInteger(+num);
5470
5471 const zeros = input => {
5472 let value = `${input}`;
5473 let index = -1;
5474 if (value[0] === '-') value = value.slice(1);
5475 if (value === '0') return false;
5476 while (value[++index] === '0');
5477 return index > 0;
5478 };
5479
5480 const stringify = (start, end, options) => {
5481 if (typeof start === 'string' || typeof end === 'string') {
5482 return true;
5483 }
5484 return options.stringify === true;
5485 };
5486
5487 const pad = (input, maxLength, toNumber) => {
5488 if (maxLength > 0) {
5489 let dash = input[0] === '-' ? '-' : '';
5490 if (dash) input = input.slice(1);
5491 input = (dash + input.padStart(dash ? maxLength - 1 : maxLength, '0'));
5492 }
5493 if (toNumber === false) {
5494 return String(input);
5495 }
5496 return input;
5497 };
5498
5499 const toMaxLen = (input, maxLength) => {
5500 let negative = input[0] === '-' ? '-' : '';
5501 if (negative) {
5502 input = input.slice(1);
5503 maxLength--;
5504 }
5505 while (input.length < maxLength) input = '0' + input;
5506 return negative ? ('-' + input) : input;
5507 };
5508
5509 const toSequence = (parts, options, maxLen) => {
5510 parts.negatives.sort((a, b) => a < b ? -1 : a > b ? 1 : 0);
5511 parts.positives.sort((a, b) => a < b ? -1 : a > b ? 1 : 0);
5512
5513 let prefix = options.capture ? '' : '?:';
5514 let positives = '';
5515 let negatives = '';
5516 let result;
5517
5518 if (parts.positives.length) {
5519 positives = parts.positives.map(v => toMaxLen(String(v), maxLen)).join('|');
5520 }
5521
5522 if (parts.negatives.length) {
5523 negatives = `-(${prefix}${parts.negatives.map(v => toMaxLen(String(v), maxLen)).join('|')})`;
5524 }
5525
5526 if (positives && negatives) {
5527 result = `${positives}|${negatives}`;
5528 } else {
5529 result = positives || negatives;
5530 }
5531
5532 if (options.wrap) {
5533 return `(${prefix}${result})`;
5534 }
5535
5536 return result;
5537 };
5538
5539 const toRange = (a, b, isNumbers, options) => {
5540 if (isNumbers) {
5541 return toRegexRange(a, b, { wrap: false, ...options });
5542 }
5543
5544 let start = String.fromCharCode(a);
5545 if (a === b) return start;
5546
5547 let stop = String.fromCharCode(b);
5548 return `[${start}-${stop}]`;
5549 };
5550
5551 const toRegex = (start, end, options) => {
5552 if (Array.isArray(start)) {
5553 let wrap = options.wrap === true;
5554 let prefix = options.capture ? '' : '?:';
5555 return wrap ? `(${prefix}${start.join('|')})` : start.join('|');
5556 }
5557 return toRegexRange(start, end, options);
5558 };
5559
5560 const rangeError = (...args) => {
5561 return new RangeError('Invalid range arguments: ' + util.inspect(...args));
5562 };
5563
5564 const invalidRange = (start, end, options) => {
5565 if (options.strictRanges === true) throw rangeError([start, end]);
5566 return [];
5567 };
5568
5569 const invalidStep = (step, options) => {
5570 if (options.strictRanges === true) {
5571 throw new TypeError(`Expected step "${step}" to be a number`);
5572 }
5573 return [];
5574 };
5575
5576 const fillNumbers = (start, end, step = 1, options = {}) => {
5577 let a = Number(start);
5578 let b = Number(end);
5579
5580 if (!Number.isInteger(a) || !Number.isInteger(b)) {
5581 if (options.strictRanges === true) throw rangeError([start, end]);
5582 return [];
5583 }
5584
5585 // fix negative zero
5586 if (a === 0) a = 0;
5587 if (b === 0) b = 0;
5588
5589 let descending = a > b;
5590 let startString = String(start);
5591 let endString = String(end);
5592 let stepString = String(step);
5593 step = Math.max(Math.abs(step), 1);
5594
5595 let padded = zeros(startString) || zeros(endString) || zeros(stepString);
5596 let maxLen = padded ? Math.max(startString.length, endString.length, stepString.length) : 0;
5597 let toNumber = padded === false && stringify(start, end, options) === false;
5598 let format = options.transform || transform(toNumber);
5599
5600 if (options.toRegex && step === 1) {
5601 return toRange(toMaxLen(start, maxLen), toMaxLen(end, maxLen), true, options);
5602 }
5603
5604 let parts = { negatives: [], positives: [] };
5605 let push = num => parts[num < 0 ? 'negatives' : 'positives'].push(Math.abs(num));
5606 let range = [];
5607 let index = 0;
5608
5609 while (descending ? a >= b : a <= b) {
5610 if (options.toRegex === true && step > 1) {
5611 push(a);
5612 } else {
5613 range.push(pad(format(a, index), maxLen, toNumber));
5614 }
5615 a = descending ? a - step : a + step;
5616 index++;
5617 }
5618
5619 if (options.toRegex === true) {
5620 return step > 1
5621 ? toSequence(parts, options, maxLen)
5622 : toRegex(range, null, { wrap: false, ...options });
5623 }
5624
5625 return range;
5626 };
5627
5628 const fillLetters = (start, end, step = 1, options = {}) => {
5629 if ((!isNumber(start) && start.length > 1) || (!isNumber(end) && end.length > 1)) {
5630 return invalidRange(start, end, options);
5631 }
5632
5633 let format = options.transform || (val => String.fromCharCode(val));
5634 let a = `${start}`.charCodeAt(0);
5635 let b = `${end}`.charCodeAt(0);
5636
5637 let descending = a > b;
5638 let min = Math.min(a, b);
5639 let max = Math.max(a, b);
5640
5641 if (options.toRegex && step === 1) {
5642 return toRange(min, max, false, options);
5643 }
5644
5645 let range = [];
5646 let index = 0;
5647
5648 while (descending ? a >= b : a <= b) {
5649 range.push(format(a, index));
5650 a = descending ? a - step : a + step;
5651 index++;
5652 }
5653
5654 if (options.toRegex === true) {
5655 return toRegex(range, null, { wrap: false, options });
5656 }
5657
5658 return range;
5659 };
5660
5661 const fill = (start, end, step, options = {}) => {
5662 if (end == null && isValidValue(start)) {
5663 return [start];
5664 }
5665
5666 if (!isValidValue(start) || !isValidValue(end)) {
5667 return invalidRange(start, end, options);
5668 }
5669
5670 if (typeof step === 'function') {
5671 return fill(start, end, 1, { transform: step });
5672 }
5673
5674 if (isObject(step)) {
5675 return fill(start, end, 0, step);
5676 }
5677
5678 let opts = { ...options };
5679 if (opts.capture === true) opts.wrap = true;
5680 step = step || opts.step || 1;
5681
5682 if (!isNumber(step)) {
5683 if (step != null && !isObject(step)) return invalidStep(step, opts);
5684 return fill(start, end, 1, step);
5685 }
5686
5687 if (isNumber(start) && isNumber(end)) {
5688 return fillNumbers(start, end, step, opts);
5689 }
5690
5691 return fillLetters(start, end, Math.max(Math.abs(step), 1), opts);
5692 };
5693
5694 fillRange = fill;
5695 return fillRange;
5696}
5697
5698var compile_1;
5699var hasRequiredCompile;
5700
5701function requireCompile () {
5702 if (hasRequiredCompile) return compile_1;
5703 hasRequiredCompile = 1;
5704
5705 const fill = /*@__PURE__*/ requireFillRange();
5706 const utils = /*@__PURE__*/ requireUtils();
5707
5708 const compile = (ast, options = {}) => {
5709 const walk = (node, parent = {}) => {
5710 const invalidBlock = utils.isInvalidBrace(parent);
5711 const invalidNode = node.invalid === true && options.escapeInvalid === true;
5712 const invalid = invalidBlock === true || invalidNode === true;
5713 const prefix = options.escapeInvalid === true ? '\\' : '';
5714 let output = '';
5715
5716 if (node.isOpen === true) {
5717 return prefix + node.value;
5718 }
5719
5720 if (node.isClose === true) {
5721 console.log('node.isClose', prefix, node.value);
5722 return prefix + node.value;
5723 }
5724
5725 if (node.type === 'open') {
5726 return invalid ? prefix + node.value : '(';
5727 }
5728
5729 if (node.type === 'close') {
5730 return invalid ? prefix + node.value : ')';
5731 }
5732
5733 if (node.type === 'comma') {
5734 return node.prev.type === 'comma' ? '' : invalid ? node.value : '|';
5735 }
5736
5737 if (node.value) {
5738 return node.value;
5739 }
5740
5741 if (node.nodes && node.ranges > 0) {
5742 const args = utils.reduce(node.nodes);
5743 const range = fill(...args, { ...options, wrap: false, toRegex: true, strictZeros: true });
5744
5745 if (range.length !== 0) {
5746 return args.length > 1 && range.length > 1 ? `(${range})` : range;
5747 }
5748 }
5749
5750 if (node.nodes) {
5751 for (const child of node.nodes) {
5752 output += walk(child, node);
5753 }
5754 }
5755
5756 return output;
5757 };
5758
5759 return walk(ast);
5760 };
5761
5762 compile_1 = compile;
5763 return compile_1;
5764}
5765
5766var expand_1;
5767var hasRequiredExpand;
5768
5769function requireExpand () {
5770 if (hasRequiredExpand) return expand_1;
5771 hasRequiredExpand = 1;
5772
5773 const fill = /*@__PURE__*/ requireFillRange();
5774 const stringify = /*@__PURE__*/ requireStringify();
5775 const utils = /*@__PURE__*/ requireUtils();
5776
5777 const append = (queue = '', stash = '', enclose = false) => {
5778 const result = [];
5779
5780 queue = [].concat(queue);
5781 stash = [].concat(stash);
5782
5783 if (!stash.length) return queue;
5784 if (!queue.length) {
5785 return enclose ? utils.flatten(stash).map(ele => `{${ele}}`) : stash;
5786 }
5787
5788 for (const item of queue) {
5789 if (Array.isArray(item)) {
5790 for (const value of item) {
5791 result.push(append(value, stash, enclose));
5792 }
5793 } else {
5794 for (let ele of stash) {
5795 if (enclose === true && typeof ele === 'string') ele = `{${ele}}`;
5796 result.push(Array.isArray(ele) ? append(item, ele, enclose) : item + ele);
5797 }
5798 }
5799 }
5800 return utils.flatten(result);
5801 };
5802
5803 const expand = (ast, options = {}) => {
5804 const rangeLimit = options.rangeLimit === undefined ? 1000 : options.rangeLimit;
5805
5806 const walk = (node, parent = {}) => {
5807 node.queue = [];
5808
5809 let p = parent;
5810 let q = parent.queue;
5811
5812 while (p.type !== 'brace' && p.type !== 'root' && p.parent) {
5813 p = p.parent;
5814 q = p.queue;
5815 }
5816
5817 if (node.invalid || node.dollar) {
5818 q.push(append(q.pop(), stringify(node, options)));
5819 return;
5820 }
5821
5822 if (node.type === 'brace' && node.invalid !== true && node.nodes.length === 2) {
5823 q.push(append(q.pop(), ['{}']));
5824 return;
5825 }
5826
5827 if (node.nodes && node.ranges > 0) {
5828 const args = utils.reduce(node.nodes);
5829
5830 if (utils.exceedsLimit(...args, options.step, rangeLimit)) {
5831 throw new RangeError('expanded array length exceeds range limit. Use options.rangeLimit to increase or disable the limit.');
5832 }
5833
5834 let range = fill(...args, options);
5835 if (range.length === 0) {
5836 range = stringify(node, options);
5837 }
5838
5839 q.push(append(q.pop(), range));
5840 node.nodes = [];
5841 return;
5842 }
5843
5844 const enclose = utils.encloseBrace(node);
5845 let queue = node.queue;
5846 let block = node;
5847
5848 while (block.type !== 'brace' && block.type !== 'root' && block.parent) {
5849 block = block.parent;
5850 queue = block.queue;
5851 }
5852
5853 for (let i = 0; i < node.nodes.length; i++) {
5854 const child = node.nodes[i];
5855
5856 if (child.type === 'comma' && node.type === 'brace') {
5857 if (i === 1) queue.push('');
5858 queue.push('');
5859 continue;
5860 }
5861
5862 if (child.type === 'close') {
5863 q.push(append(q.pop(), queue, enclose));
5864 continue;
5865 }
5866
5867 if (child.value && child.type !== 'open') {
5868 queue.push(append(queue.pop(), child.value));
5869 continue;
5870 }
5871
5872 if (child.nodes) {
5873 walk(child, node);
5874 }
5875 }
5876
5877 return queue;
5878 };
5879
5880 return utils.flatten(walk(ast));
5881 };
5882
5883 expand_1 = expand;
5884 return expand_1;
5885}
5886
5887var constants$1;
5888var hasRequiredConstants$1;
5889
5890function requireConstants$1 () {
5891 if (hasRequiredConstants$1) return constants$1;
5892 hasRequiredConstants$1 = 1;
5893
5894 constants$1 = {
5895 MAX_LENGTH: 10000,
5896
5897 // Digits
5898 CHAR_0: '0', /* 0 */
5899 CHAR_9: '9', /* 9 */
5900
5901 // Alphabet chars.
5902 CHAR_UPPERCASE_A: 'A', /* A */
5903 CHAR_LOWERCASE_A: 'a', /* a */
5904 CHAR_UPPERCASE_Z: 'Z', /* Z */
5905 CHAR_LOWERCASE_Z: 'z', /* z */
5906
5907 CHAR_LEFT_PARENTHESES: '(', /* ( */
5908 CHAR_RIGHT_PARENTHESES: ')', /* ) */
5909
5910 CHAR_ASTERISK: '*', /* * */
5911
5912 // Non-alphabetic chars.
5913 CHAR_AMPERSAND: '&', /* & */
5914 CHAR_AT: '@', /* @ */
5915 CHAR_BACKSLASH: '\\', /* \ */
5916 CHAR_BACKTICK: '`', /* ` */
5917 CHAR_CARRIAGE_RETURN: '\r', /* \r */
5918 CHAR_CIRCUMFLEX_ACCENT: '^', /* ^ */
5919 CHAR_COLON: ':', /* : */
5920 CHAR_COMMA: ',', /* , */
5921 CHAR_DOLLAR: '$', /* . */
5922 CHAR_DOT: '.', /* . */
5923 CHAR_DOUBLE_QUOTE: '"', /* " */
5924 CHAR_EQUAL: '=', /* = */
5925 CHAR_EXCLAMATION_MARK: '!', /* ! */
5926 CHAR_FORM_FEED: '\f', /* \f */
5927 CHAR_FORWARD_SLASH: '/', /* / */
5928 CHAR_HASH: '#', /* # */
5929 CHAR_HYPHEN_MINUS: '-', /* - */
5930 CHAR_LEFT_ANGLE_BRACKET: '<', /* < */
5931 CHAR_LEFT_CURLY_BRACE: '{', /* { */
5932 CHAR_LEFT_SQUARE_BRACKET: '[', /* [ */
5933 CHAR_LINE_FEED: '\n', /* \n */
5934 CHAR_NO_BREAK_SPACE: '\u00A0', /* \u00A0 */
5935 CHAR_PERCENT: '%', /* % */
5936 CHAR_PLUS: '+', /* + */
5937 CHAR_QUESTION_MARK: '?', /* ? */
5938 CHAR_RIGHT_ANGLE_BRACKET: '>', /* > */
5939 CHAR_RIGHT_CURLY_BRACE: '}', /* } */
5940 CHAR_RIGHT_SQUARE_BRACKET: ']', /* ] */
5941 CHAR_SEMICOLON: ';', /* ; */
5942 CHAR_SINGLE_QUOTE: '\'', /* ' */
5943 CHAR_SPACE: ' ', /* */
5944 CHAR_TAB: '\t', /* \t */
5945 CHAR_UNDERSCORE: '_', /* _ */
5946 CHAR_VERTICAL_LINE: '|', /* | */
5947 CHAR_ZERO_WIDTH_NOBREAK_SPACE: '\uFEFF' /* \uFEFF */
5948 };
5949 return constants$1;
5950}
5951
5952var parse_1;
5953var hasRequiredParse;
5954
5955function requireParse () {
5956 if (hasRequiredParse) return parse_1;
5957 hasRequiredParse = 1;
5958
5959 const stringify = /*@__PURE__*/ requireStringify();
5960
5961 /**
5962 * Constants
5963 */
5964
5965 const {
5966 MAX_LENGTH,
5967 CHAR_BACKSLASH, /* \ */
5968 CHAR_BACKTICK, /* ` */
5969 CHAR_COMMA, /* , */
5970 CHAR_DOT, /* . */
5971 CHAR_LEFT_PARENTHESES, /* ( */
5972 CHAR_RIGHT_PARENTHESES, /* ) */
5973 CHAR_LEFT_CURLY_BRACE, /* { */
5974 CHAR_RIGHT_CURLY_BRACE, /* } */
5975 CHAR_LEFT_SQUARE_BRACKET, /* [ */
5976 CHAR_RIGHT_SQUARE_BRACKET, /* ] */
5977 CHAR_DOUBLE_QUOTE, /* " */
5978 CHAR_SINGLE_QUOTE, /* ' */
5979 CHAR_NO_BREAK_SPACE,
5980 CHAR_ZERO_WIDTH_NOBREAK_SPACE
5981 } = /*@__PURE__*/ requireConstants$1();
5982
5983 /**
5984 * parse
5985 */
5986
5987 const parse = (input, options = {}) => {
5988 if (typeof input !== 'string') {
5989 throw new TypeError('Expected a string');
5990 }
5991
5992 const opts = options || {};
5993 const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH;
5994 if (input.length > max) {
5995 throw new SyntaxError(`Input length (${input.length}), exceeds max characters (${max})`);
5996 }
5997
5998 const ast = { type: 'root', input, nodes: [] };
5999 const stack = [ast];
6000 let block = ast;
6001 let prev = ast;
6002 let brackets = 0;
6003 const length = input.length;
6004 let index = 0;
6005 let depth = 0;
6006 let value;
6007
6008 /**
6009 * Helpers
6010 */
6011
6012 const advance = () => input[index++];
6013 const push = node => {
6014 if (node.type === 'text' && prev.type === 'dot') {
6015 prev.type = 'text';
6016 }
6017
6018 if (prev && prev.type === 'text' && node.type === 'text') {
6019 prev.value += node.value;
6020 return;
6021 }
6022
6023 block.nodes.push(node);
6024 node.parent = block;
6025 node.prev = prev;
6026 prev = node;
6027 return node;
6028 };
6029
6030 push({ type: 'bos' });
6031
6032 while (index < length) {
6033 block = stack[stack.length - 1];
6034 value = advance();
6035
6036 /**
6037 * Invalid chars
6038 */
6039
6040 if (value === CHAR_ZERO_WIDTH_NOBREAK_SPACE || value === CHAR_NO_BREAK_SPACE) {
6041 continue;
6042 }
6043
6044 /**
6045 * Escaped chars
6046 */
6047
6048 if (value === CHAR_BACKSLASH) {
6049 push({ type: 'text', value: (options.keepEscaping ? value : '') + advance() });
6050 continue;
6051 }
6052
6053 /**
6054 * Right square bracket (literal): ']'
6055 */
6056
6057 if (value === CHAR_RIGHT_SQUARE_BRACKET) {
6058 push({ type: 'text', value: '\\' + value });
6059 continue;
6060 }
6061
6062 /**
6063 * Left square bracket: '['
6064 */
6065
6066 if (value === CHAR_LEFT_SQUARE_BRACKET) {
6067 brackets++;
6068
6069 let next;
6070
6071 while (index < length && (next = advance())) {
6072 value += next;
6073
6074 if (next === CHAR_LEFT_SQUARE_BRACKET) {
6075 brackets++;
6076 continue;
6077 }
6078
6079 if (next === CHAR_BACKSLASH) {
6080 value += advance();
6081 continue;
6082 }
6083
6084 if (next === CHAR_RIGHT_SQUARE_BRACKET) {
6085 brackets--;
6086
6087 if (brackets === 0) {
6088 break;
6089 }
6090 }
6091 }
6092
6093 push({ type: 'text', value });
6094 continue;
6095 }
6096
6097 /**
6098 * Parentheses
6099 */
6100
6101 if (value === CHAR_LEFT_PARENTHESES) {
6102 block = push({ type: 'paren', nodes: [] });
6103 stack.push(block);
6104 push({ type: 'text', value });
6105 continue;
6106 }
6107
6108 if (value === CHAR_RIGHT_PARENTHESES) {
6109 if (block.type !== 'paren') {
6110 push({ type: 'text', value });
6111 continue;
6112 }
6113 block = stack.pop();
6114 push({ type: 'text', value });
6115 block = stack[stack.length - 1];
6116 continue;
6117 }
6118
6119 /**
6120 * Quotes: '|"|`
6121 */
6122
6123 if (value === CHAR_DOUBLE_QUOTE || value === CHAR_SINGLE_QUOTE || value === CHAR_BACKTICK) {
6124 const open = value;
6125 let next;
6126
6127 if (options.keepQuotes !== true) {
6128 value = '';
6129 }
6130
6131 while (index < length && (next = advance())) {
6132 if (next === CHAR_BACKSLASH) {
6133 value += next + advance();
6134 continue;
6135 }
6136
6137 if (next === open) {
6138 if (options.keepQuotes === true) value += next;
6139 break;
6140 }
6141
6142 value += next;
6143 }
6144
6145 push({ type: 'text', value });
6146 continue;
6147 }
6148
6149 /**
6150 * Left curly brace: '{'
6151 */
6152
6153 if (value === CHAR_LEFT_CURLY_BRACE) {
6154 depth++;
6155
6156 const dollar = prev.value && prev.value.slice(-1) === '$' || block.dollar === true;
6157 const brace = {
6158 type: 'brace',
6159 open: true,
6160 close: false,
6161 dollar,
6162 depth,
6163 commas: 0,
6164 ranges: 0,
6165 nodes: []
6166 };
6167
6168 block = push(brace);
6169 stack.push(block);
6170 push({ type: 'open', value });
6171 continue;
6172 }
6173
6174 /**
6175 * Right curly brace: '}'
6176 */
6177
6178 if (value === CHAR_RIGHT_CURLY_BRACE) {
6179 if (block.type !== 'brace') {
6180 push({ type: 'text', value });
6181 continue;
6182 }
6183
6184 const type = 'close';
6185 block = stack.pop();
6186 block.close = true;
6187
6188 push({ type, value });
6189 depth--;
6190
6191 block = stack[stack.length - 1];
6192 continue;
6193 }
6194
6195 /**
6196 * Comma: ','
6197 */
6198
6199 if (value === CHAR_COMMA && depth > 0) {
6200 if (block.ranges > 0) {
6201 block.ranges = 0;
6202 const open = block.nodes.shift();
6203 block.nodes = [open, { type: 'text', value: stringify(block) }];
6204 }
6205
6206 push({ type: 'comma', value });
6207 block.commas++;
6208 continue;
6209 }
6210
6211 /**
6212 * Dot: '.'
6213 */
6214
6215 if (value === CHAR_DOT && depth > 0 && block.commas === 0) {
6216 const siblings = block.nodes;
6217
6218 if (depth === 0 || siblings.length === 0) {
6219 push({ type: 'text', value });
6220 continue;
6221 }
6222
6223 if (prev.type === 'dot') {
6224 block.range = [];
6225 prev.value += value;
6226 prev.type = 'range';
6227
6228 if (block.nodes.length !== 3 && block.nodes.length !== 5) {
6229 block.invalid = true;
6230 block.ranges = 0;
6231 prev.type = 'text';
6232 continue;
6233 }
6234
6235 block.ranges++;
6236 block.args = [];
6237 continue;
6238 }
6239
6240 if (prev.type === 'range') {
6241 siblings.pop();
6242
6243 const before = siblings[siblings.length - 1];
6244 before.value += prev.value + value;
6245 prev = before;
6246 block.ranges--;
6247 continue;
6248 }
6249
6250 push({ type: 'dot', value });
6251 continue;
6252 }
6253
6254 /**
6255 * Text
6256 */
6257
6258 push({ type: 'text', value });
6259 }
6260
6261 // Mark imbalanced braces and brackets as invalid
6262 do {
6263 block = stack.pop();
6264
6265 if (block.type !== 'root') {
6266 block.nodes.forEach(node => {
6267 if (!node.nodes) {
6268 if (node.type === 'open') node.isOpen = true;
6269 if (node.type === 'close') node.isClose = true;
6270 if (!node.nodes) node.type = 'text';
6271 node.invalid = true;
6272 }
6273 });
6274
6275 // get the location of the block on parent.nodes (block's siblings)
6276 const parent = stack[stack.length - 1];
6277 const index = parent.nodes.indexOf(block);
6278 // replace the (invalid) block with it's nodes
6279 parent.nodes.splice(index, 1, ...block.nodes);
6280 }
6281 } while (stack.length > 0);
6282
6283 push({ type: 'eos' });
6284 return ast;
6285 };
6286
6287 parse_1 = parse;
6288 return parse_1;
6289}
6290
6291var braces_1;
6292var hasRequiredBraces;
6293
6294function requireBraces () {
6295 if (hasRequiredBraces) return braces_1;
6296 hasRequiredBraces = 1;
6297
6298 const stringify = /*@__PURE__*/ requireStringify();
6299 const compile = /*@__PURE__*/ requireCompile();
6300 const expand = /*@__PURE__*/ requireExpand();
6301 const parse = /*@__PURE__*/ requireParse();
6302
6303 /**
6304 * Expand the given pattern or create a regex-compatible string.
6305 *
6306 * ```js
6307 * const braces = require('braces');
6308 * console.log(braces('{a,b,c}', { compile: true })); //=> ['(a|b|c)']
6309 * console.log(braces('{a,b,c}')); //=> ['a', 'b', 'c']
6310 * ```
6311 * @param {String} `str`
6312 * @param {Object} `options`
6313 * @return {String}
6314 * @api public
6315 */
6316
6317 const braces = (input, options = {}) => {
6318 let output = [];
6319
6320 if (Array.isArray(input)) {
6321 for (const pattern of input) {
6322 const result = braces.create(pattern, options);
6323 if (Array.isArray(result)) {
6324 output.push(...result);
6325 } else {
6326 output.push(result);
6327 }
6328 }
6329 } else {
6330 output = [].concat(braces.create(input, options));
6331 }
6332
6333 if (options && options.expand === true && options.nodupes === true) {
6334 output = [...new Set(output)];
6335 }
6336 return output;
6337 };
6338
6339 /**
6340 * Parse the given `str` with the given `options`.
6341 *
6342 * ```js
6343 * // braces.parse(pattern, [, options]);
6344 * const ast = braces.parse('a/{b,c}/d');
6345 * console.log(ast);
6346 * ```
6347 * @param {String} pattern Brace pattern to parse
6348 * @param {Object} options
6349 * @return {Object} Returns an AST
6350 * @api public
6351 */
6352
6353 braces.parse = (input, options = {}) => parse(input, options);
6354
6355 /**
6356 * Creates a braces string from an AST, or an AST node.
6357 *
6358 * ```js
6359 * const braces = require('braces');
6360 * let ast = braces.parse('foo/{a,b}/bar');
6361 * console.log(stringify(ast.nodes[2])); //=> '{a,b}'
6362 * ```
6363 * @param {String} `input` Brace pattern or AST.
6364 * @param {Object} `options`
6365 * @return {Array} Returns an array of expanded values.
6366 * @api public
6367 */
6368
6369 braces.stringify = (input, options = {}) => {
6370 if (typeof input === 'string') {
6371 return stringify(braces.parse(input, options), options);
6372 }
6373 return stringify(input, options);
6374 };
6375
6376 /**
6377 * Compiles a brace pattern into a regex-compatible, optimized string.
6378 * This method is called by the main [braces](#braces) function by default.
6379 *
6380 * ```js
6381 * const braces = require('braces');
6382 * console.log(braces.compile('a/{b,c}/d'));
6383 * //=> ['a/(b|c)/d']
6384 * ```
6385 * @param {String} `input` Brace pattern or AST.
6386 * @param {Object} `options`
6387 * @return {Array} Returns an array of expanded values.
6388 * @api public
6389 */
6390
6391 braces.compile = (input, options = {}) => {
6392 if (typeof input === 'string') {
6393 input = braces.parse(input, options);
6394 }
6395 return compile(input, options);
6396 };
6397
6398 /**
6399 * Expands a brace pattern into an array. This method is called by the
6400 * main [braces](#braces) function when `options.expand` is true. Before
6401 * using this method it's recommended that you read the [performance notes](#performance))
6402 * and advantages of using [.compile](#compile) instead.
6403 *
6404 * ```js
6405 * const braces = require('braces');
6406 * console.log(braces.expand('a/{b,c}/d'));
6407 * //=> ['a/b/d', 'a/c/d'];
6408 * ```
6409 * @param {String} `pattern` Brace pattern
6410 * @param {Object} `options`
6411 * @return {Array} Returns an array of expanded values.
6412 * @api public
6413 */
6414
6415 braces.expand = (input, options = {}) => {
6416 if (typeof input === 'string') {
6417 input = braces.parse(input, options);
6418 }
6419
6420 let result = expand(input, options);
6421
6422 // filter out empty strings if specified
6423 if (options.noempty === true) {
6424 result = result.filter(Boolean);
6425 }
6426
6427 // filter out duplicates if specified
6428 if (options.nodupes === true) {
6429 result = [...new Set(result)];
6430 }
6431
6432 return result;
6433 };
6434
6435 /**
6436 * Processes a brace pattern and returns either an expanded array
6437 * (if `options.expand` is true), a highly optimized regex-compatible string.
6438 * This method is called by the main [braces](#braces) function.
6439 *
6440 * ```js
6441 * const braces = require('braces');
6442 * console.log(braces.create('user-{200..300}/project-{a,b,c}-{1..10}'))
6443 * //=> 'user-(20[0-9]|2[1-9][0-9]|300)/project-(a|b|c)-([1-9]|10)'
6444 * ```
6445 * @param {String} `pattern` Brace pattern
6446 * @param {Object} `options`
6447 * @return {Array} Returns an array of expanded values.
6448 * @api public
6449 */
6450
6451 braces.create = (input, options = {}) => {
6452 if (input === '' || input.length < 3) {
6453 return [input];
6454 }
6455
6456 return options.expand !== true
6457 ? braces.compile(input, options)
6458 : braces.expand(input, options);
6459 };
6460
6461 /**
6462 * Expose "braces"
6463 */
6464
6465 braces_1 = braces;
6466 return braces_1;
6467}
6468
6469const require$$0 = [
6470 "3dm",
6471 "3ds",
6472 "3g2",
6473 "3gp",
6474 "7z",
6475 "a",
6476 "aac",
6477 "adp",
6478 "afdesign",
6479 "afphoto",
6480 "afpub",
6481 "ai",
6482 "aif",
6483 "aiff",
6484 "alz",
6485 "ape",
6486 "apk",
6487 "appimage",
6488 "ar",
6489 "arj",
6490 "asf",
6491 "au",
6492 "avi",
6493 "bak",
6494 "baml",
6495 "bh",
6496 "bin",
6497 "bk",
6498 "bmp",
6499 "btif",
6500 "bz2",
6501 "bzip2",
6502 "cab",
6503 "caf",
6504 "cgm",
6505 "class",
6506 "cmx",
6507 "cpio",
6508 "cr2",
6509 "cur",
6510 "dat",
6511 "dcm",
6512 "deb",
6513 "dex",
6514 "djvu",
6515 "dll",
6516 "dmg",
6517 "dng",
6518 "doc",
6519 "docm",
6520 "docx",
6521 "dot",
6522 "dotm",
6523 "dra",
6524 "DS_Store",
6525 "dsk",
6526 "dts",
6527 "dtshd",
6528 "dvb",
6529 "dwg",
6530 "dxf",
6531 "ecelp4800",
6532 "ecelp7470",
6533 "ecelp9600",
6534 "egg",
6535 "eol",
6536 "eot",
6537 "epub",
6538 "exe",
6539 "f4v",
6540 "fbs",
6541 "fh",
6542 "fla",
6543 "flac",
6544 "flatpak",
6545 "fli",
6546 "flv",
6547 "fpx",
6548 "fst",
6549 "fvt",
6550 "g3",
6551 "gh",
6552 "gif",
6553 "graffle",
6554 "gz",
6555 "gzip",
6556 "h261",
6557 "h263",
6558 "h264",
6559 "icns",
6560 "ico",
6561 "ief",
6562 "img",
6563 "ipa",
6564 "iso",
6565 "jar",
6566 "jpeg",
6567 "jpg",
6568 "jpgv",
6569 "jpm",
6570 "jxr",
6571 "key",
6572 "ktx",
6573 "lha",
6574 "lib",
6575 "lvp",
6576 "lz",
6577 "lzh",
6578 "lzma",
6579 "lzo",
6580 "m3u",
6581 "m4a",
6582 "m4v",
6583 "mar",
6584 "mdi",
6585 "mht",
6586 "mid",
6587 "midi",
6588 "mj2",
6589 "mka",
6590 "mkv",
6591 "mmr",
6592 "mng",
6593 "mobi",
6594 "mov",
6595 "movie",
6596 "mp3",
6597 "mp4",
6598 "mp4a",
6599 "mpeg",
6600 "mpg",
6601 "mpga",
6602 "mxu",
6603 "nef",
6604 "npx",
6605 "numbers",
6606 "nupkg",
6607 "o",
6608 "odp",
6609 "ods",
6610 "odt",
6611 "oga",
6612 "ogg",
6613 "ogv",
6614 "otf",
6615 "ott",
6616 "pages",
6617 "pbm",
6618 "pcx",
6619 "pdb",
6620 "pdf",
6621 "pea",
6622 "pgm",
6623 "pic",
6624 "png",
6625 "pnm",
6626 "pot",
6627 "potm",
6628 "potx",
6629 "ppa",
6630 "ppam",
6631 "ppm",
6632 "pps",
6633 "ppsm",
6634 "ppsx",
6635 "ppt",
6636 "pptm",
6637 "pptx",
6638 "psd",
6639 "pya",
6640 "pyc",
6641 "pyo",
6642 "pyv",
6643 "qt",
6644 "rar",
6645 "ras",
6646 "raw",
6647 "resources",
6648 "rgb",
6649 "rip",
6650 "rlc",
6651 "rmf",
6652 "rmvb",
6653 "rpm",
6654 "rtf",
6655 "rz",
6656 "s3m",
6657 "s7z",
6658 "scpt",
6659 "sgi",
6660 "shar",
6661 "snap",
6662 "sil",
6663 "sketch",
6664 "slk",
6665 "smv",
6666 "snk",
6667 "so",
6668 "stl",
6669 "suo",
6670 "sub",
6671 "swf",
6672 "tar",
6673 "tbz",
6674 "tbz2",
6675 "tga",
6676 "tgz",
6677 "thmx",
6678 "tif",
6679 "tiff",
6680 "tlz",
6681 "ttc",
6682 "ttf",
6683 "txz",
6684 "udf",
6685 "uvh",
6686 "uvi",
6687 "uvm",
6688 "uvp",
6689 "uvs",
6690 "uvu",
6691 "viv",
6692 "vob",
6693 "war",
6694 "wav",
6695 "wax",
6696 "wbmp",
6697 "wdp",
6698 "weba",
6699 "webm",
6700 "webp",
6701 "whl",
6702 "wim",
6703 "wm",
6704 "wma",
6705 "wmv",
6706 "wmx",
6707 "woff",
6708 "woff2",
6709 "wrm",
6710 "wvx",
6711 "xbm",
6712 "xif",
6713 "xla",
6714 "xlam",
6715 "xls",
6716 "xlsb",
6717 "xlsm",
6718 "xlsx",
6719 "xlt",
6720 "xltm",
6721 "xltx",
6722 "xm",
6723 "xmind",
6724 "xpi",
6725 "xpm",
6726 "xwd",
6727 "xz",
6728 "z",
6729 "zip",
6730 "zipx"
6731];
6732
6733var binaryExtensions;
6734var hasRequiredBinaryExtensions;
6735
6736function requireBinaryExtensions () {
6737 if (hasRequiredBinaryExtensions) return binaryExtensions;
6738 hasRequiredBinaryExtensions = 1;
6739 binaryExtensions = require$$0;
6740 return binaryExtensions;
6741}
6742
6743var isBinaryPath;
6744var hasRequiredIsBinaryPath;
6745
6746function requireIsBinaryPath () {
6747 if (hasRequiredIsBinaryPath) return isBinaryPath;
6748 hasRequiredIsBinaryPath = 1;
6749 const path = require$$0$1;
6750 const binaryExtensions = /*@__PURE__*/ requireBinaryExtensions();
6751
6752 const extensions = new Set(binaryExtensions);
6753
6754 isBinaryPath = filePath => extensions.has(path.extname(filePath).slice(1).toLowerCase());
6755 return isBinaryPath;
6756}
6757
6758var constants = {};
6759
6760var hasRequiredConstants;
6761
6762function requireConstants () {
6763 if (hasRequiredConstants) return constants;
6764 hasRequiredConstants = 1;
6765 (function (exports) {
6766
6767 const {sep} = require$$0$1;
6768 const {platform} = process;
6769 const os = require$$2$1;
6770
6771 exports.EV_ALL = 'all';
6772 exports.EV_READY = 'ready';
6773 exports.EV_ADD = 'add';
6774 exports.EV_CHANGE = 'change';
6775 exports.EV_ADD_DIR = 'addDir';
6776 exports.EV_UNLINK = 'unlink';
6777 exports.EV_UNLINK_DIR = 'unlinkDir';
6778 exports.EV_RAW = 'raw';
6779 exports.EV_ERROR = 'error';
6780
6781 exports.STR_DATA = 'data';
6782 exports.STR_END = 'end';
6783 exports.STR_CLOSE = 'close';
6784
6785 exports.FSEVENT_CREATED = 'created';
6786 exports.FSEVENT_MODIFIED = 'modified';
6787 exports.FSEVENT_DELETED = 'deleted';
6788 exports.FSEVENT_MOVED = 'moved';
6789 exports.FSEVENT_CLONED = 'cloned';
6790 exports.FSEVENT_UNKNOWN = 'unknown';
6791 exports.FSEVENT_FLAG_MUST_SCAN_SUBDIRS = 1;
6792 exports.FSEVENT_TYPE_FILE = 'file';
6793 exports.FSEVENT_TYPE_DIRECTORY = 'directory';
6794 exports.FSEVENT_TYPE_SYMLINK = 'symlink';
6795
6796 exports.KEY_LISTENERS = 'listeners';
6797 exports.KEY_ERR = 'errHandlers';
6798 exports.KEY_RAW = 'rawEmitters';
6799 exports.HANDLER_KEYS = [exports.KEY_LISTENERS, exports.KEY_ERR, exports.KEY_RAW];
6800
6801 exports.DOT_SLASH = `.${sep}`;
6802
6803 exports.BACK_SLASH_RE = /\\/g;
6804 exports.DOUBLE_SLASH_RE = /\/\//;
6805 exports.SLASH_OR_BACK_SLASH_RE = /[/\\]/;
6806 exports.DOT_RE = /\..*\.(sw[px])$|~$|\.subl.*\.tmp/;
6807 exports.REPLACER_RE = /^\.[/\\]/;
6808
6809 exports.SLASH = '/';
6810 exports.SLASH_SLASH = '//';
6811 exports.BRACE_START = '{';
6812 exports.BANG = '!';
6813 exports.ONE_DOT = '.';
6814 exports.TWO_DOTS = '..';
6815 exports.STAR = '*';
6816 exports.GLOBSTAR = '**';
6817 exports.ROOT_GLOBSTAR = '/**/*';
6818 exports.SLASH_GLOBSTAR = '/**';
6819 exports.DIR_SUFFIX = 'Dir';
6820 exports.ANYMATCH_OPTS = {dot: true};
6821 exports.STRING_TYPE = 'string';
6822 exports.FUNCTION_TYPE = 'function';
6823 exports.EMPTY_STR = '';
6824 exports.EMPTY_FN = () => {};
6825 exports.IDENTITY_FN = val => val;
6826
6827 exports.isWindows = platform === 'win32';
6828 exports.isMacos = platform === 'darwin';
6829 exports.isLinux = platform === 'linux';
6830 exports.isIBMi = os.type() === 'OS400';
6831 } (constants));
6832 return constants;
6833}
6834
6835var nodefsHandler;
6836var hasRequiredNodefsHandler;
6837
6838function requireNodefsHandler () {
6839 if (hasRequiredNodefsHandler) return nodefsHandler;
6840 hasRequiredNodefsHandler = 1;
6841
6842 const fs = require$$0$2;
6843 const sysPath = require$$0$1;
6844 const { promisify } = require$$2;
6845 const isBinaryPath = /*@__PURE__*/ requireIsBinaryPath();
6846 const {
6847 isWindows,
6848 isLinux,
6849 EMPTY_FN,
6850 EMPTY_STR,
6851 KEY_LISTENERS,
6852 KEY_ERR,
6853 KEY_RAW,
6854 HANDLER_KEYS,
6855 EV_CHANGE,
6856 EV_ADD,
6857 EV_ADD_DIR,
6858 EV_ERROR,
6859 STR_DATA,
6860 STR_END,
6861 BRACE_START,
6862 STAR
6863 } = /*@__PURE__*/ requireConstants();
6864
6865 const THROTTLE_MODE_WATCH = 'watch';
6866
6867 const open = promisify(fs.open);
6868 const stat = promisify(fs.stat);
6869 const lstat = promisify(fs.lstat);
6870 const close = promisify(fs.close);
6871 const fsrealpath = promisify(fs.realpath);
6872
6873 const statMethods = { lstat, stat };
6874
6875 // TODO: emit errors properly. Example: EMFILE on Macos.
6876 const foreach = (val, fn) => {
6877 if (val instanceof Set) {
6878 val.forEach(fn);
6879 } else {
6880 fn(val);
6881 }
6882 };
6883
6884 const addAndConvert = (main, prop, item) => {
6885 let container = main[prop];
6886 if (!(container instanceof Set)) {
6887 main[prop] = container = new Set([container]);
6888 }
6889 container.add(item);
6890 };
6891
6892 const clearItem = cont => key => {
6893 const set = cont[key];
6894 if (set instanceof Set) {
6895 set.clear();
6896 } else {
6897 delete cont[key];
6898 }
6899 };
6900
6901 const delFromSet = (main, prop, item) => {
6902 const container = main[prop];
6903 if (container instanceof Set) {
6904 container.delete(item);
6905 } else if (container === item) {
6906 delete main[prop];
6907 }
6908 };
6909
6910 const isEmptySet = (val) => val instanceof Set ? val.size === 0 : !val;
6911
6912 /**
6913 * @typedef {String} Path
6914 */
6915
6916 // fs_watch helpers
6917
6918 // object to hold per-process fs_watch instances
6919 // (may be shared across chokidar FSWatcher instances)
6920
6921 /**
6922 * @typedef {Object} FsWatchContainer
6923 * @property {Set} listeners
6924 * @property {Set} errHandlers
6925 * @property {Set} rawEmitters
6926 * @property {fs.FSWatcher=} watcher
6927 * @property {Boolean=} watcherUnusable
6928 */
6929
6930 /**
6931 * @type {Map<String,FsWatchContainer>}
6932 */
6933 const FsWatchInstances = new Map();
6934
6935 /**
6936 * Instantiates the fs_watch interface
6937 * @param {String} path to be watched
6938 * @param {Object} options to be passed to fs_watch
6939 * @param {Function} listener main event handler
6940 * @param {Function} errHandler emits info about errors
6941 * @param {Function} emitRaw emits raw event data
6942 * @returns {fs.FSWatcher} new fsevents instance
6943 */
6944 function createFsWatchInstance(path, options, listener, errHandler, emitRaw) {
6945 const handleEvent = (rawEvent, evPath) => {
6946 listener(path);
6947 emitRaw(rawEvent, evPath, {watchedPath: path});
6948
6949 // emit based on events occurring for files from a directory's watcher in
6950 // case the file's watcher misses it (and rely on throttling to de-dupe)
6951 if (evPath && path !== evPath) {
6952 fsWatchBroadcast(
6953 sysPath.resolve(path, evPath), KEY_LISTENERS, sysPath.join(path, evPath)
6954 );
6955 }
6956 };
6957 try {
6958 return fs.watch(path, options, handleEvent);
6959 } catch (error) {
6960 errHandler(error);
6961 }
6962 }
6963
6964 /**
6965 * Helper for passing fs_watch event data to a collection of listeners
6966 * @param {Path} fullPath absolute path bound to fs_watch instance
6967 * @param {String} type listener type
6968 * @param {*=} val1 arguments to be passed to listeners
6969 * @param {*=} val2
6970 * @param {*=} val3
6971 */
6972 const fsWatchBroadcast = (fullPath, type, val1, val2, val3) => {
6973 const cont = FsWatchInstances.get(fullPath);
6974 if (!cont) return;
6975 foreach(cont[type], (listener) => {
6976 listener(val1, val2, val3);
6977 });
6978 };
6979
6980 /**
6981 * Instantiates the fs_watch interface or binds listeners
6982 * to an existing one covering the same file system entry
6983 * @param {String} path
6984 * @param {String} fullPath absolute path
6985 * @param {Object} options to be passed to fs_watch
6986 * @param {Object} handlers container for event listener functions
6987 */
6988 const setFsWatchListener = (path, fullPath, options, handlers) => {
6989 const {listener, errHandler, rawEmitter} = handlers;
6990 let cont = FsWatchInstances.get(fullPath);
6991
6992 /** @type {fs.FSWatcher=} */
6993 let watcher;
6994 if (!options.persistent) {
6995 watcher = createFsWatchInstance(
6996 path, options, listener, errHandler, rawEmitter
6997 );
6998 return watcher.close.bind(watcher);
6999 }
7000 if (cont) {
7001 addAndConvert(cont, KEY_LISTENERS, listener);
7002 addAndConvert(cont, KEY_ERR, errHandler);
7003 addAndConvert(cont, KEY_RAW, rawEmitter);
7004 } else {
7005 watcher = createFsWatchInstance(
7006 path,
7007 options,
7008 fsWatchBroadcast.bind(null, fullPath, KEY_LISTENERS),
7009 errHandler, // no need to use broadcast here
7010 fsWatchBroadcast.bind(null, fullPath, KEY_RAW)
7011 );
7012 if (!watcher) return;
7013 watcher.on(EV_ERROR, async (error) => {
7014 const broadcastErr = fsWatchBroadcast.bind(null, fullPath, KEY_ERR);
7015 cont.watcherUnusable = true; // documented since Node 10.4.1
7016 // Workaround for https://github.com/joyent/node/issues/4337
7017 if (isWindows && error.code === 'EPERM') {
7018 try {
7019 const fd = await open(path, 'r');
7020 await close(fd);
7021 broadcastErr(error);
7022 } catch (err) {}
7023 } else {
7024 broadcastErr(error);
7025 }
7026 });
7027 cont = {
7028 listeners: listener,
7029 errHandlers: errHandler,
7030 rawEmitters: rawEmitter,
7031 watcher
7032 };
7033 FsWatchInstances.set(fullPath, cont);
7034 }
7035 // const index = cont.listeners.indexOf(listener);
7036
7037 // removes this instance's listeners and closes the underlying fs_watch
7038 // instance if there are no more listeners left
7039 return () => {
7040 delFromSet(cont, KEY_LISTENERS, listener);
7041 delFromSet(cont, KEY_ERR, errHandler);
7042 delFromSet(cont, KEY_RAW, rawEmitter);
7043 if (isEmptySet(cont.listeners)) {
7044 // Check to protect against issue gh-730.
7045 // if (cont.watcherUnusable) {
7046 cont.watcher.close();
7047 // }
7048 FsWatchInstances.delete(fullPath);
7049 HANDLER_KEYS.forEach(clearItem(cont));
7050 cont.watcher = undefined;
7051 Object.freeze(cont);
7052 }
7053 };
7054 };
7055
7056 // fs_watchFile helpers
7057
7058 // object to hold per-process fs_watchFile instances
7059 // (may be shared across chokidar FSWatcher instances)
7060 const FsWatchFileInstances = new Map();
7061
7062 /**
7063 * Instantiates the fs_watchFile interface or binds listeners
7064 * to an existing one covering the same file system entry
7065 * @param {String} path to be watched
7066 * @param {String} fullPath absolute path
7067 * @param {Object} options options to be passed to fs_watchFile
7068 * @param {Object} handlers container for event listener functions
7069 * @returns {Function} closer
7070 */
7071 const setFsWatchFileListener = (path, fullPath, options, handlers) => {
7072 const {listener, rawEmitter} = handlers;
7073 let cont = FsWatchFileInstances.get(fullPath);
7074
7075 const copts = cont && cont.options;
7076 if (copts && (copts.persistent < options.persistent || copts.interval > options.interval)) {
7077 fs.unwatchFile(fullPath);
7078 cont = undefined;
7079 }
7080
7081 /* eslint-enable no-unused-vars, prefer-destructuring */
7082
7083 if (cont) {
7084 addAndConvert(cont, KEY_LISTENERS, listener);
7085 addAndConvert(cont, KEY_RAW, rawEmitter);
7086 } else {
7087 // TODO
7088 // listeners.add(listener);
7089 // rawEmitters.add(rawEmitter);
7090 cont = {
7091 listeners: listener,
7092 rawEmitters: rawEmitter,
7093 options,
7094 watcher: fs.watchFile(fullPath, options, (curr, prev) => {
7095 foreach(cont.rawEmitters, (rawEmitter) => {
7096 rawEmitter(EV_CHANGE, fullPath, {curr, prev});
7097 });
7098 const currmtime = curr.mtimeMs;
7099 if (curr.size !== prev.size || currmtime > prev.mtimeMs || currmtime === 0) {
7100 foreach(cont.listeners, (listener) => listener(path, curr));
7101 }
7102 })
7103 };
7104 FsWatchFileInstances.set(fullPath, cont);
7105 }
7106 // const index = cont.listeners.indexOf(listener);
7107
7108 // Removes this instance's listeners and closes the underlying fs_watchFile
7109 // instance if there are no more listeners left.
7110 return () => {
7111 delFromSet(cont, KEY_LISTENERS, listener);
7112 delFromSet(cont, KEY_RAW, rawEmitter);
7113 if (isEmptySet(cont.listeners)) {
7114 FsWatchFileInstances.delete(fullPath);
7115 fs.unwatchFile(fullPath);
7116 cont.options = cont.watcher = undefined;
7117 Object.freeze(cont);
7118 }
7119 };
7120 };
7121
7122 /**
7123 * @mixin
7124 */
7125 class NodeFsHandler {
7126
7127 /**
7128 * @param {import("../index").FSWatcher} fsW
7129 */
7130 constructor(fsW) {
7131 this.fsw = fsW;
7132 this._boundHandleError = (error) => fsW._handleError(error);
7133 }
7134
7135 /**
7136 * Watch file for changes with fs_watchFile or fs_watch.
7137 * @param {String} path to file or dir
7138 * @param {Function} listener on fs change
7139 * @returns {Function} closer for the watcher instance
7140 */
7141 _watchWithNodeFs(path, listener) {
7142 const opts = this.fsw.options;
7143 const directory = sysPath.dirname(path);
7144 const basename = sysPath.basename(path);
7145 const parent = this.fsw._getWatchedDir(directory);
7146 parent.add(basename);
7147 const absolutePath = sysPath.resolve(path);
7148 const options = {persistent: opts.persistent};
7149 if (!listener) listener = EMPTY_FN;
7150
7151 let closer;
7152 if (opts.usePolling) {
7153 options.interval = opts.enableBinaryInterval && isBinaryPath(basename) ?
7154 opts.binaryInterval : opts.interval;
7155 closer = setFsWatchFileListener(path, absolutePath, options, {
7156 listener,
7157 rawEmitter: this.fsw._emitRaw
7158 });
7159 } else {
7160 closer = setFsWatchListener(path, absolutePath, options, {
7161 listener,
7162 errHandler: this._boundHandleError,
7163 rawEmitter: this.fsw._emitRaw
7164 });
7165 }
7166 return closer;
7167 }
7168
7169 /**
7170 * Watch a file and emit add event if warranted.
7171 * @param {Path} file Path
7172 * @param {fs.Stats} stats result of fs_stat
7173 * @param {Boolean} initialAdd was the file added at watch instantiation?
7174 * @returns {Function} closer for the watcher instance
7175 */
7176 _handleFile(file, stats, initialAdd) {
7177 if (this.fsw.closed) {
7178 return;
7179 }
7180 const dirname = sysPath.dirname(file);
7181 const basename = sysPath.basename(file);
7182 const parent = this.fsw._getWatchedDir(dirname);
7183 // stats is always present
7184 let prevStats = stats;
7185
7186 // if the file is already being watched, do nothing
7187 if (parent.has(basename)) return;
7188
7189 const listener = async (path, newStats) => {
7190 if (!this.fsw._throttle(THROTTLE_MODE_WATCH, file, 5)) return;
7191 if (!newStats || newStats.mtimeMs === 0) {
7192 try {
7193 const newStats = await stat(file);
7194 if (this.fsw.closed) return;
7195 // Check that change event was not fired because of changed only accessTime.
7196 const at = newStats.atimeMs;
7197 const mt = newStats.mtimeMs;
7198 if (!at || at <= mt || mt !== prevStats.mtimeMs) {
7199 this.fsw._emit(EV_CHANGE, file, newStats);
7200 }
7201 if (isLinux && prevStats.ino !== newStats.ino) {
7202 this.fsw._closeFile(path);
7203 prevStats = newStats;
7204 this.fsw._addPathCloser(path, this._watchWithNodeFs(file, listener));
7205 } else {
7206 prevStats = newStats;
7207 }
7208 } catch (error) {
7209 // Fix issues where mtime is null but file is still present
7210 this.fsw._remove(dirname, basename);
7211 }
7212 // add is about to be emitted if file not already tracked in parent
7213 } else if (parent.has(basename)) {
7214 // Check that change event was not fired because of changed only accessTime.
7215 const at = newStats.atimeMs;
7216 const mt = newStats.mtimeMs;
7217 if (!at || at <= mt || mt !== prevStats.mtimeMs) {
7218 this.fsw._emit(EV_CHANGE, file, newStats);
7219 }
7220 prevStats = newStats;
7221 }
7222 };
7223 // kick off the watcher
7224 const closer = this._watchWithNodeFs(file, listener);
7225
7226 // emit an add event if we're supposed to
7227 if (!(initialAdd && this.fsw.options.ignoreInitial) && this.fsw._isntIgnored(file)) {
7228 if (!this.fsw._throttle(EV_ADD, file, 0)) return;
7229 this.fsw._emit(EV_ADD, file, stats);
7230 }
7231
7232 return closer;
7233 }
7234
7235 /**
7236 * Handle symlinks encountered while reading a dir.
7237 * @param {Object} entry returned by readdirp
7238 * @param {String} directory path of dir being read
7239 * @param {String} path of this item
7240 * @param {String} item basename of this item
7241 * @returns {Promise<Boolean>} true if no more processing is needed for this entry.
7242 */
7243 async _handleSymlink(entry, directory, path, item) {
7244 if (this.fsw.closed) {
7245 return;
7246 }
7247 const full = entry.fullPath;
7248 const dir = this.fsw._getWatchedDir(directory);
7249
7250 if (!this.fsw.options.followSymlinks) {
7251 // watch symlink directly (don't follow) and detect changes
7252 this.fsw._incrReadyCount();
7253
7254 let linkPath;
7255 try {
7256 linkPath = await fsrealpath(path);
7257 } catch (e) {
7258 this.fsw._emitReady();
7259 return true;
7260 }
7261
7262 if (this.fsw.closed) return;
7263 if (dir.has(item)) {
7264 if (this.fsw._symlinkPaths.get(full) !== linkPath) {
7265 this.fsw._symlinkPaths.set(full, linkPath);
7266 this.fsw._emit(EV_CHANGE, path, entry.stats);
7267 }
7268 } else {
7269 dir.add(item);
7270 this.fsw._symlinkPaths.set(full, linkPath);
7271 this.fsw._emit(EV_ADD, path, entry.stats);
7272 }
7273 this.fsw._emitReady();
7274 return true;
7275 }
7276
7277 // don't follow the same symlink more than once
7278 if (this.fsw._symlinkPaths.has(full)) {
7279 return true;
7280 }
7281
7282 this.fsw._symlinkPaths.set(full, true);
7283 }
7284
7285 _handleRead(directory, initialAdd, wh, target, dir, depth, throttler) {
7286 // Normalize the directory name on Windows
7287 directory = sysPath.join(directory, EMPTY_STR);
7288
7289 if (!wh.hasGlob) {
7290 throttler = this.fsw._throttle('readdir', directory, 1000);
7291 if (!throttler) return;
7292 }
7293
7294 const previous = this.fsw._getWatchedDir(wh.path);
7295 const current = new Set();
7296
7297 let stream = this.fsw._readdirp(directory, {
7298 fileFilter: entry => wh.filterPath(entry),
7299 directoryFilter: entry => wh.filterDir(entry),
7300 depth: 0
7301 }).on(STR_DATA, async (entry) => {
7302 if (this.fsw.closed) {
7303 stream = undefined;
7304 return;
7305 }
7306 const item = entry.path;
7307 let path = sysPath.join(directory, item);
7308 current.add(item);
7309
7310 if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path, item)) {
7311 return;
7312 }
7313
7314 if (this.fsw.closed) {
7315 stream = undefined;
7316 return;
7317 }
7318 // Files that present in current directory snapshot
7319 // but absent in previous are added to watch list and
7320 // emit `add` event.
7321 if (item === target || !target && !previous.has(item)) {
7322 this.fsw._incrReadyCount();
7323
7324 // ensure relativeness of path is preserved in case of watcher reuse
7325 path = sysPath.join(dir, sysPath.relative(dir, path));
7326
7327 this._addToNodeFs(path, initialAdd, wh, depth + 1);
7328 }
7329 }).on(EV_ERROR, this._boundHandleError);
7330
7331 return new Promise(resolve =>
7332 stream.once(STR_END, () => {
7333 if (this.fsw.closed) {
7334 stream = undefined;
7335 return;
7336 }
7337 const wasThrottled = throttler ? throttler.clear() : false;
7338
7339 resolve();
7340
7341 // Files that absent in current directory snapshot
7342 // but present in previous emit `remove` event
7343 // and are removed from @watched[directory].
7344 previous.getChildren().filter((item) => {
7345 return item !== directory &&
7346 !current.has(item) &&
7347 // in case of intersecting globs;
7348 // a path may have been filtered out of this readdir, but
7349 // shouldn't be removed because it matches a different glob
7350 (!wh.hasGlob || wh.filterPath({
7351 fullPath: sysPath.resolve(directory, item)
7352 }));
7353 }).forEach((item) => {
7354 this.fsw._remove(directory, item);
7355 });
7356
7357 stream = undefined;
7358
7359 // one more time for any missed in case changes came in extremely quickly
7360 if (wasThrottled) this._handleRead(directory, false, wh, target, dir, depth, throttler);
7361 })
7362 );
7363 }
7364
7365 /**
7366 * Read directory to add / remove files from `@watched` list and re-read it on change.
7367 * @param {String} dir fs path
7368 * @param {fs.Stats} stats
7369 * @param {Boolean} initialAdd
7370 * @param {Number} depth relative to user-supplied path
7371 * @param {String} target child path targeted for watch
7372 * @param {Object} wh Common watch helpers for this path
7373 * @param {String} realpath
7374 * @returns {Promise<Function>} closer for the watcher instance.
7375 */
7376 async _handleDir(dir, stats, initialAdd, depth, target, wh, realpath) {
7377 const parentDir = this.fsw._getWatchedDir(sysPath.dirname(dir));
7378 const tracked = parentDir.has(sysPath.basename(dir));
7379 if (!(initialAdd && this.fsw.options.ignoreInitial) && !target && !tracked) {
7380 if (!wh.hasGlob || wh.globFilter(dir)) this.fsw._emit(EV_ADD_DIR, dir, stats);
7381 }
7382
7383 // ensure dir is tracked (harmless if redundant)
7384 parentDir.add(sysPath.basename(dir));
7385 this.fsw._getWatchedDir(dir);
7386 let throttler;
7387 let closer;
7388
7389 const oDepth = this.fsw.options.depth;
7390 if ((oDepth == null || depth <= oDepth) && !this.fsw._symlinkPaths.has(realpath)) {
7391 if (!target) {
7392 await this._handleRead(dir, initialAdd, wh, target, dir, depth, throttler);
7393 if (this.fsw.closed) return;
7394 }
7395
7396 closer = this._watchWithNodeFs(dir, (dirPath, stats) => {
7397 // if current directory is removed, do nothing
7398 if (stats && stats.mtimeMs === 0) return;
7399
7400 this._handleRead(dirPath, false, wh, target, dir, depth, throttler);
7401 });
7402 }
7403 return closer;
7404 }
7405
7406 /**
7407 * Handle added file, directory, or glob pattern.
7408 * Delegates call to _handleFile / _handleDir after checks.
7409 * @param {String} path to file or ir
7410 * @param {Boolean} initialAdd was the file added at watch instantiation?
7411 * @param {Object} priorWh depth relative to user-supplied path
7412 * @param {Number} depth Child path actually targeted for watch
7413 * @param {String=} target Child path actually targeted for watch
7414 * @returns {Promise}
7415 */
7416 async _addToNodeFs(path, initialAdd, priorWh, depth, target) {
7417 const ready = this.fsw._emitReady;
7418 if (this.fsw._isIgnored(path) || this.fsw.closed) {
7419 ready();
7420 return false;
7421 }
7422
7423 const wh = this.fsw._getWatchHelpers(path, depth);
7424 if (!wh.hasGlob && priorWh) {
7425 wh.hasGlob = priorWh.hasGlob;
7426 wh.globFilter = priorWh.globFilter;
7427 wh.filterPath = entry => priorWh.filterPath(entry);
7428 wh.filterDir = entry => priorWh.filterDir(entry);
7429 }
7430
7431 // evaluate what is at the path we're being asked to watch
7432 try {
7433 const stats = await statMethods[wh.statMethod](wh.watchPath);
7434 if (this.fsw.closed) return;
7435 if (this.fsw._isIgnored(wh.watchPath, stats)) {
7436 ready();
7437 return false;
7438 }
7439
7440 const follow = this.fsw.options.followSymlinks && !path.includes(STAR) && !path.includes(BRACE_START);
7441 let closer;
7442 if (stats.isDirectory()) {
7443 const absPath = sysPath.resolve(path);
7444 const targetPath = follow ? await fsrealpath(path) : path;
7445 if (this.fsw.closed) return;
7446 closer = await this._handleDir(wh.watchPath, stats, initialAdd, depth, target, wh, targetPath);
7447 if (this.fsw.closed) return;
7448 // preserve this symlink's target path
7449 if (absPath !== targetPath && targetPath !== undefined) {
7450 this.fsw._symlinkPaths.set(absPath, targetPath);
7451 }
7452 } else if (stats.isSymbolicLink()) {
7453 const targetPath = follow ? await fsrealpath(path) : path;
7454 if (this.fsw.closed) return;
7455 const parent = sysPath.dirname(wh.watchPath);
7456 this.fsw._getWatchedDir(parent).add(wh.watchPath);
7457 this.fsw._emit(EV_ADD, wh.watchPath, stats);
7458 closer = await this._handleDir(parent, stats, initialAdd, depth, path, wh, targetPath);
7459 if (this.fsw.closed) return;
7460
7461 // preserve this symlink's target path
7462 if (targetPath !== undefined) {
7463 this.fsw._symlinkPaths.set(sysPath.resolve(path), targetPath);
7464 }
7465 } else {
7466 closer = this._handleFile(wh.watchPath, stats, initialAdd);
7467 }
7468 ready();
7469
7470 this.fsw._addPathCloser(path, closer);
7471 return false;
7472
7473 } catch (error) {
7474 if (this.fsw._handleError(error)) {
7475 ready();
7476 return path;
7477 }
7478 }
7479 }
7480
7481 }
7482
7483 nodefsHandler = NodeFsHandler;
7484 return nodefsHandler;
7485}
7486
7487var fseventsHandler = {exports: {}};
7488
7489const require$$3 = /*@__PURE__*/getAugmentedNamespace(fseventsImporter);
7490
7491var hasRequiredFseventsHandler;
7492
7493function requireFseventsHandler () {
7494 if (hasRequiredFseventsHandler) return fseventsHandler.exports;
7495 hasRequiredFseventsHandler = 1;
7496
7497 const fs = require$$0$2;
7498 const sysPath = require$$0$1;
7499 const { promisify } = require$$2;
7500
7501 let fsevents;
7502 try {
7503 fsevents = require$$3.getFsEvents();
7504 } catch (error) {
7505 if (process.env.CHOKIDAR_PRINT_FSEVENTS_REQUIRE_ERROR) console.error(error);
7506 }
7507
7508 if (fsevents) {
7509 // TODO: real check
7510 const mtch = process.version.match(/v(\d+)\.(\d+)/);
7511 if (mtch && mtch[1] && mtch[2]) {
7512 const maj = Number.parseInt(mtch[1], 10);
7513 const min = Number.parseInt(mtch[2], 10);
7514 if (maj === 8 && min < 16) {
7515 fsevents = undefined;
7516 }
7517 }
7518 }
7519
7520 const {
7521 EV_ADD,
7522 EV_CHANGE,
7523 EV_ADD_DIR,
7524 EV_UNLINK,
7525 EV_ERROR,
7526 STR_DATA,
7527 STR_END,
7528 FSEVENT_CREATED,
7529 FSEVENT_MODIFIED,
7530 FSEVENT_DELETED,
7531 FSEVENT_MOVED,
7532 // FSEVENT_CLONED,
7533 FSEVENT_UNKNOWN,
7534 FSEVENT_FLAG_MUST_SCAN_SUBDIRS,
7535 FSEVENT_TYPE_FILE,
7536 FSEVENT_TYPE_DIRECTORY,
7537 FSEVENT_TYPE_SYMLINK,
7538
7539 ROOT_GLOBSTAR,
7540 DIR_SUFFIX,
7541 DOT_SLASH,
7542 FUNCTION_TYPE,
7543 EMPTY_FN,
7544 IDENTITY_FN
7545 } = /*@__PURE__*/ requireConstants();
7546
7547 const Depth = (value) => isNaN(value) ? {} : {depth: value};
7548
7549 const stat = promisify(fs.stat);
7550 const lstat = promisify(fs.lstat);
7551 const realpath = promisify(fs.realpath);
7552
7553 const statMethods = { stat, lstat };
7554
7555 /**
7556 * @typedef {String} Path
7557 */
7558
7559 /**
7560 * @typedef {Object} FsEventsWatchContainer
7561 * @property {Set<Function>} listeners
7562 * @property {Function} rawEmitter
7563 * @property {{stop: Function}} watcher
7564 */
7565
7566 // fsevents instance helper functions
7567 /**
7568 * Object to hold per-process fsevents instances (may be shared across chokidar FSWatcher instances)
7569 * @type {Map<Path,FsEventsWatchContainer>}
7570 */
7571 const FSEventsWatchers = new Map();
7572
7573 // Threshold of duplicate path prefixes at which to start
7574 // consolidating going forward
7575 const consolidateThreshhold = 10;
7576
7577 const wrongEventFlags = new Set([
7578 69888, 70400, 71424, 72704, 73472, 131328, 131840, 262912
7579 ]);
7580
7581 /**
7582 * Instantiates the fsevents interface
7583 * @param {Path} path path to be watched
7584 * @param {Function} callback called when fsevents is bound and ready
7585 * @returns {{stop: Function}} new fsevents instance
7586 */
7587 const createFSEventsInstance = (path, callback) => {
7588 const stop = fsevents.watch(path, callback);
7589 return {stop};
7590 };
7591
7592 /**
7593 * Instantiates the fsevents interface or binds listeners to an existing one covering
7594 * the same file tree.
7595 * @param {Path} path - to be watched
7596 * @param {Path} realPath - real path for symlinks
7597 * @param {Function} listener - called when fsevents emits events
7598 * @param {Function} rawEmitter - passes data to listeners of the 'raw' event
7599 * @returns {Function} closer
7600 */
7601 function setFSEventsListener(path, realPath, listener, rawEmitter) {
7602 let watchPath = sysPath.extname(realPath) ? sysPath.dirname(realPath) : realPath;
7603
7604 const parentPath = sysPath.dirname(watchPath);
7605 let cont = FSEventsWatchers.get(watchPath);
7606
7607 // If we've accumulated a substantial number of paths that
7608 // could have been consolidated by watching one directory
7609 // above the current one, create a watcher on the parent
7610 // path instead, so that we do consolidate going forward.
7611 if (couldConsolidate(parentPath)) {
7612 watchPath = parentPath;
7613 }
7614
7615 const resolvedPath = sysPath.resolve(path);
7616 const hasSymlink = resolvedPath !== realPath;
7617
7618 const filteredListener = (fullPath, flags, info) => {
7619 if (hasSymlink) fullPath = fullPath.replace(realPath, resolvedPath);
7620 if (
7621 fullPath === resolvedPath ||
7622 !fullPath.indexOf(resolvedPath + sysPath.sep)
7623 ) listener(fullPath, flags, info);
7624 };
7625
7626 // check if there is already a watcher on a parent path
7627 // modifies `watchPath` to the parent path when it finds a match
7628 let watchedParent = false;
7629 for (const watchedPath of FSEventsWatchers.keys()) {
7630 if (realPath.indexOf(sysPath.resolve(watchedPath) + sysPath.sep) === 0) {
7631 watchPath = watchedPath;
7632 cont = FSEventsWatchers.get(watchPath);
7633 watchedParent = true;
7634 break;
7635 }
7636 }
7637
7638 if (cont || watchedParent) {
7639 cont.listeners.add(filteredListener);
7640 } else {
7641 cont = {
7642 listeners: new Set([filteredListener]),
7643 rawEmitter,
7644 watcher: createFSEventsInstance(watchPath, (fullPath, flags) => {
7645 if (!cont.listeners.size) return;
7646 if (flags & FSEVENT_FLAG_MUST_SCAN_SUBDIRS) return;
7647 const info = fsevents.getInfo(fullPath, flags);
7648 cont.listeners.forEach(list => {
7649 list(fullPath, flags, info);
7650 });
7651
7652 cont.rawEmitter(info.event, fullPath, info);
7653 })
7654 };
7655 FSEventsWatchers.set(watchPath, cont);
7656 }
7657
7658 // removes this instance's listeners and closes the underlying fsevents
7659 // instance if there are no more listeners left
7660 return () => {
7661 const lst = cont.listeners;
7662
7663 lst.delete(filteredListener);
7664 if (!lst.size) {
7665 FSEventsWatchers.delete(watchPath);
7666 if (cont.watcher) return cont.watcher.stop().then(() => {
7667 cont.rawEmitter = cont.watcher = undefined;
7668 Object.freeze(cont);
7669 });
7670 }
7671 };
7672 }
7673
7674 // Decide whether or not we should start a new higher-level
7675 // parent watcher
7676 const couldConsolidate = (path) => {
7677 let count = 0;
7678 for (const watchPath of FSEventsWatchers.keys()) {
7679 if (watchPath.indexOf(path) === 0) {
7680 count++;
7681 if (count >= consolidateThreshhold) {
7682 return true;
7683 }
7684 }
7685 }
7686
7687 return false;
7688 };
7689
7690 // returns boolean indicating whether fsevents can be used
7691 const canUse = () => fsevents && FSEventsWatchers.size < 128;
7692
7693 // determines subdirectory traversal levels from root to path
7694 const calcDepth = (path, root) => {
7695 let i = 0;
7696 while (!path.indexOf(root) && (path = sysPath.dirname(path)) !== root) i++;
7697 return i;
7698 };
7699
7700 // returns boolean indicating whether the fsevents' event info has the same type
7701 // as the one returned by fs.stat
7702 const sameTypes = (info, stats) => (
7703 info.type === FSEVENT_TYPE_DIRECTORY && stats.isDirectory() ||
7704 info.type === FSEVENT_TYPE_SYMLINK && stats.isSymbolicLink() ||
7705 info.type === FSEVENT_TYPE_FILE && stats.isFile()
7706 );
7707
7708 /**
7709 * @mixin
7710 */
7711 class FsEventsHandler {
7712
7713 /**
7714 * @param {import('../index').FSWatcher} fsw
7715 */
7716 constructor(fsw) {
7717 this.fsw = fsw;
7718 }
7719 checkIgnored(path, stats) {
7720 const ipaths = this.fsw._ignoredPaths;
7721 if (this.fsw._isIgnored(path, stats)) {
7722 ipaths.add(path);
7723 if (stats && stats.isDirectory()) {
7724 ipaths.add(path + ROOT_GLOBSTAR);
7725 }
7726 return true;
7727 }
7728
7729 ipaths.delete(path);
7730 ipaths.delete(path + ROOT_GLOBSTAR);
7731 }
7732
7733 addOrChange(path, fullPath, realPath, parent, watchedDir, item, info, opts) {
7734 const event = watchedDir.has(item) ? EV_CHANGE : EV_ADD;
7735 this.handleEvent(event, path, fullPath, realPath, parent, watchedDir, item, info, opts);
7736 }
7737
7738 async checkExists(path, fullPath, realPath, parent, watchedDir, item, info, opts) {
7739 try {
7740 const stats = await stat(path);
7741 if (this.fsw.closed) return;
7742 if (sameTypes(info, stats)) {
7743 this.addOrChange(path, fullPath, realPath, parent, watchedDir, item, info, opts);
7744 } else {
7745 this.handleEvent(EV_UNLINK, path, fullPath, realPath, parent, watchedDir, item, info, opts);
7746 }
7747 } catch (error) {
7748 if (error.code === 'EACCES') {
7749 this.addOrChange(path, fullPath, realPath, parent, watchedDir, item, info, opts);
7750 } else {
7751 this.handleEvent(EV_UNLINK, path, fullPath, realPath, parent, watchedDir, item, info, opts);
7752 }
7753 }
7754 }
7755
7756 handleEvent(event, path, fullPath, realPath, parent, watchedDir, item, info, opts) {
7757 if (this.fsw.closed || this.checkIgnored(path)) return;
7758
7759 if (event === EV_UNLINK) {
7760 const isDirectory = info.type === FSEVENT_TYPE_DIRECTORY;
7761 // suppress unlink events on never before seen files
7762 if (isDirectory || watchedDir.has(item)) {
7763 this.fsw._remove(parent, item, isDirectory);
7764 }
7765 } else {
7766 if (event === EV_ADD) {
7767 // track new directories
7768 if (info.type === FSEVENT_TYPE_DIRECTORY) this.fsw._getWatchedDir(path);
7769
7770 if (info.type === FSEVENT_TYPE_SYMLINK && opts.followSymlinks) {
7771 // push symlinks back to the top of the stack to get handled
7772 const curDepth = opts.depth === undefined ?
7773 undefined : calcDepth(fullPath, realPath) + 1;
7774 return this._addToFsEvents(path, false, true, curDepth);
7775 }
7776
7777 // track new paths
7778 // (other than symlinks being followed, which will be tracked soon)
7779 this.fsw._getWatchedDir(parent).add(item);
7780 }
7781 /**
7782 * @type {'add'|'addDir'|'unlink'|'unlinkDir'}
7783 */
7784 const eventName = info.type === FSEVENT_TYPE_DIRECTORY ? event + DIR_SUFFIX : event;
7785 this.fsw._emit(eventName, path);
7786 if (eventName === EV_ADD_DIR) this._addToFsEvents(path, false, true);
7787 }
7788 }
7789
7790 /**
7791 * Handle symlinks encountered during directory scan
7792 * @param {String} watchPath - file/dir path to be watched with fsevents
7793 * @param {String} realPath - real path (in case of symlinks)
7794 * @param {Function} transform - path transformer
7795 * @param {Function} globFilter - path filter in case a glob pattern was provided
7796 * @returns {Function} closer for the watcher instance
7797 */
7798 _watchWithFsEvents(watchPath, realPath, transform, globFilter) {
7799 if (this.fsw.closed || this.fsw._isIgnored(watchPath)) return;
7800 const opts = this.fsw.options;
7801 const watchCallback = async (fullPath, flags, info) => {
7802 if (this.fsw.closed) return;
7803 if (
7804 opts.depth !== undefined &&
7805 calcDepth(fullPath, realPath) > opts.depth
7806 ) return;
7807 const path = transform(sysPath.join(
7808 watchPath, sysPath.relative(watchPath, fullPath)
7809 ));
7810 if (globFilter && !globFilter(path)) return;
7811 // ensure directories are tracked
7812 const parent = sysPath.dirname(path);
7813 const item = sysPath.basename(path);
7814 const watchedDir = this.fsw._getWatchedDir(
7815 info.type === FSEVENT_TYPE_DIRECTORY ? path : parent
7816 );
7817
7818 // correct for wrong events emitted
7819 if (wrongEventFlags.has(flags) || info.event === FSEVENT_UNKNOWN) {
7820 if (typeof opts.ignored === FUNCTION_TYPE) {
7821 let stats;
7822 try {
7823 stats = await stat(path);
7824 } catch (error) {}
7825 if (this.fsw.closed) return;
7826 if (this.checkIgnored(path, stats)) return;
7827 if (sameTypes(info, stats)) {
7828 this.addOrChange(path, fullPath, realPath, parent, watchedDir, item, info, opts);
7829 } else {
7830 this.handleEvent(EV_UNLINK, path, fullPath, realPath, parent, watchedDir, item, info, opts);
7831 }
7832 } else {
7833 this.checkExists(path, fullPath, realPath, parent, watchedDir, item, info, opts);
7834 }
7835 } else {
7836 switch (info.event) {
7837 case FSEVENT_CREATED:
7838 case FSEVENT_MODIFIED:
7839 return this.addOrChange(path, fullPath, realPath, parent, watchedDir, item, info, opts);
7840 case FSEVENT_DELETED:
7841 case FSEVENT_MOVED:
7842 return this.checkExists(path, fullPath, realPath, parent, watchedDir, item, info, opts);
7843 }
7844 }
7845 };
7846
7847 const closer = setFSEventsListener(
7848 watchPath,
7849 realPath,
7850 watchCallback,
7851 this.fsw._emitRaw
7852 );
7853
7854 this.fsw._emitReady();
7855 return closer;
7856 }
7857
7858 /**
7859 * Handle symlinks encountered during directory scan
7860 * @param {String} linkPath path to symlink
7861 * @param {String} fullPath absolute path to the symlink
7862 * @param {Function} transform pre-existing path transformer
7863 * @param {Number} curDepth level of subdirectories traversed to where symlink is
7864 * @returns {Promise<void>}
7865 */
7866 async _handleFsEventsSymlink(linkPath, fullPath, transform, curDepth) {
7867 // don't follow the same symlink more than once
7868 if (this.fsw.closed || this.fsw._symlinkPaths.has(fullPath)) return;
7869
7870 this.fsw._symlinkPaths.set(fullPath, true);
7871 this.fsw._incrReadyCount();
7872
7873 try {
7874 const linkTarget = await realpath(linkPath);
7875 if (this.fsw.closed) return;
7876 if (this.fsw._isIgnored(linkTarget)) {
7877 return this.fsw._emitReady();
7878 }
7879
7880 this.fsw._incrReadyCount();
7881
7882 // add the linkTarget for watching with a wrapper for transform
7883 // that causes emitted paths to incorporate the link's path
7884 this._addToFsEvents(linkTarget || linkPath, (path) => {
7885 let aliasedPath = linkPath;
7886 if (linkTarget && linkTarget !== DOT_SLASH) {
7887 aliasedPath = path.replace(linkTarget, linkPath);
7888 } else if (path !== DOT_SLASH) {
7889 aliasedPath = sysPath.join(linkPath, path);
7890 }
7891 return transform(aliasedPath);
7892 }, false, curDepth);
7893 } catch(error) {
7894 if (this.fsw._handleError(error)) {
7895 return this.fsw._emitReady();
7896 }
7897 }
7898 }
7899
7900 /**
7901 *
7902 * @param {Path} newPath
7903 * @param {fs.Stats} stats
7904 */
7905 emitAdd(newPath, stats, processPath, opts, forceAdd) {
7906 const pp = processPath(newPath);
7907 const isDir = stats.isDirectory();
7908 const dirObj = this.fsw._getWatchedDir(sysPath.dirname(pp));
7909 const base = sysPath.basename(pp);
7910
7911 // ensure empty dirs get tracked
7912 if (isDir) this.fsw._getWatchedDir(pp);
7913 if (dirObj.has(base)) return;
7914 dirObj.add(base);
7915
7916 if (!opts.ignoreInitial || forceAdd === true) {
7917 this.fsw._emit(isDir ? EV_ADD_DIR : EV_ADD, pp, stats);
7918 }
7919 }
7920
7921 initWatch(realPath, path, wh, processPath) {
7922 if (this.fsw.closed) return;
7923 const closer = this._watchWithFsEvents(
7924 wh.watchPath,
7925 sysPath.resolve(realPath || wh.watchPath),
7926 processPath,
7927 wh.globFilter
7928 );
7929 this.fsw._addPathCloser(path, closer);
7930 }
7931
7932 /**
7933 * Handle added path with fsevents
7934 * @param {String} path file/dir path or glob pattern
7935 * @param {Function|Boolean=} transform converts working path to what the user expects
7936 * @param {Boolean=} forceAdd ensure add is emitted
7937 * @param {Number=} priorDepth Level of subdirectories already traversed.
7938 * @returns {Promise<void>}
7939 */
7940 async _addToFsEvents(path, transform, forceAdd, priorDepth) {
7941 if (this.fsw.closed) {
7942 return;
7943 }
7944 const opts = this.fsw.options;
7945 const processPath = typeof transform === FUNCTION_TYPE ? transform : IDENTITY_FN;
7946
7947 const wh = this.fsw._getWatchHelpers(path);
7948
7949 // evaluate what is at the path we're being asked to watch
7950 try {
7951 const stats = await statMethods[wh.statMethod](wh.watchPath);
7952 if (this.fsw.closed) return;
7953 if (this.fsw._isIgnored(wh.watchPath, stats)) {
7954 throw null;
7955 }
7956 if (stats.isDirectory()) {
7957 // emit addDir unless this is a glob parent
7958 if (!wh.globFilter) this.emitAdd(processPath(path), stats, processPath, opts, forceAdd);
7959
7960 // don't recurse further if it would exceed depth setting
7961 if (priorDepth && priorDepth > opts.depth) return;
7962
7963 // scan the contents of the dir
7964 this.fsw._readdirp(wh.watchPath, {
7965 fileFilter: entry => wh.filterPath(entry),
7966 directoryFilter: entry => wh.filterDir(entry),
7967 ...Depth(opts.depth - (priorDepth || 0))
7968 }).on(STR_DATA, (entry) => {
7969 // need to check filterPath on dirs b/c filterDir is less restrictive
7970 if (this.fsw.closed) {
7971 return;
7972 }
7973 if (entry.stats.isDirectory() && !wh.filterPath(entry)) return;
7974
7975 const joinedPath = sysPath.join(wh.watchPath, entry.path);
7976 const {fullPath} = entry;
7977
7978 if (wh.followSymlinks && entry.stats.isSymbolicLink()) {
7979 // preserve the current depth here since it can't be derived from
7980 // real paths past the symlink
7981 const curDepth = opts.depth === undefined ?
7982 undefined : calcDepth(joinedPath, sysPath.resolve(wh.watchPath)) + 1;
7983
7984 this._handleFsEventsSymlink(joinedPath, fullPath, processPath, curDepth);
7985 } else {
7986 this.emitAdd(joinedPath, entry.stats, processPath, opts, forceAdd);
7987 }
7988 }).on(EV_ERROR, EMPTY_FN).on(STR_END, () => {
7989 this.fsw._emitReady();
7990 });
7991 } else {
7992 this.emitAdd(wh.watchPath, stats, processPath, opts, forceAdd);
7993 this.fsw._emitReady();
7994 }
7995 } catch (error) {
7996 if (!error || this.fsw._handleError(error)) {
7997 // TODO: Strange thing: "should not choke on an ignored watch path" will be failed without 2 ready calls -__-
7998 this.fsw._emitReady();
7999 this.fsw._emitReady();
8000 }
8001 }
8002
8003 if (opts.persistent && forceAdd !== true) {
8004 if (typeof transform === FUNCTION_TYPE) {
8005 // realpath has already been resolved
8006 this.initWatch(undefined, path, wh, processPath);
8007 } else {
8008 let realPath;
8009 try {
8010 realPath = await realpath(wh.watchPath);
8011 } catch (e) {}
8012 this.initWatch(realPath, path, wh, processPath);
8013 }
8014 }
8015 }
8016
8017 }
8018
8019 fseventsHandler.exports = FsEventsHandler;
8020 fseventsHandler.exports.canUse = canUse;
8021 return fseventsHandler.exports;
8022}
8023
8024var hasRequiredChokidar;
8025
8026function requireChokidar () {
8027 if (hasRequiredChokidar) return chokidar$1;
8028 hasRequiredChokidar = 1;
8029
8030 const { EventEmitter } = require$$0$3;
8031 const fs = require$$0$2;
8032 const sysPath = require$$0$1;
8033 const { promisify } = require$$2;
8034 const readdirp = /*@__PURE__*/ requireReaddirp();
8035 const anymatch = /*@__PURE__*/ requireAnymatch().default;
8036 const globParent = /*@__PURE__*/ requireGlobParent();
8037 const isGlob = /*@__PURE__*/ requireIsGlob();
8038 const braces = /*@__PURE__*/ requireBraces();
8039 const normalizePath = /*@__PURE__*/ requireNormalizePath();
8040
8041 const NodeFsHandler = /*@__PURE__*/ requireNodefsHandler();
8042 const FsEventsHandler = /*@__PURE__*/ requireFseventsHandler();
8043 const {
8044 EV_ALL,
8045 EV_READY,
8046 EV_ADD,
8047 EV_CHANGE,
8048 EV_UNLINK,
8049 EV_ADD_DIR,
8050 EV_UNLINK_DIR,
8051 EV_RAW,
8052 EV_ERROR,
8053
8054 STR_CLOSE,
8055 STR_END,
8056
8057 BACK_SLASH_RE,
8058 DOUBLE_SLASH_RE,
8059 SLASH_OR_BACK_SLASH_RE,
8060 DOT_RE,
8061 REPLACER_RE,
8062
8063 SLASH,
8064 SLASH_SLASH,
8065 BRACE_START,
8066 BANG,
8067 ONE_DOT,
8068 TWO_DOTS,
8069 GLOBSTAR,
8070 SLASH_GLOBSTAR,
8071 ANYMATCH_OPTS,
8072 STRING_TYPE,
8073 FUNCTION_TYPE,
8074 EMPTY_STR,
8075 EMPTY_FN,
8076
8077 isWindows,
8078 isMacos,
8079 isIBMi
8080 } = /*@__PURE__*/ requireConstants();
8081
8082 const stat = promisify(fs.stat);
8083 const readdir = promisify(fs.readdir);
8084
8085 /**
8086 * @typedef {String} Path
8087 * @typedef {'all'|'add'|'addDir'|'change'|'unlink'|'unlinkDir'|'raw'|'error'|'ready'} EventName
8088 * @typedef {'readdir'|'watch'|'add'|'remove'|'change'} ThrottleType
8089 */
8090
8091 /**
8092 *
8093 * @typedef {Object} WatchHelpers
8094 * @property {Boolean} followSymlinks
8095 * @property {'stat'|'lstat'} statMethod
8096 * @property {Path} path
8097 * @property {Path} watchPath
8098 * @property {Function} entryPath
8099 * @property {Boolean} hasGlob
8100 * @property {Object} globFilter
8101 * @property {Function} filterPath
8102 * @property {Function} filterDir
8103 */
8104
8105 const arrify = (value = []) => Array.isArray(value) ? value : [value];
8106 const flatten = (list, result = []) => {
8107 list.forEach(item => {
8108 if (Array.isArray(item)) {
8109 flatten(item, result);
8110 } else {
8111 result.push(item);
8112 }
8113 });
8114 return result;
8115 };
8116
8117 const unifyPaths = (paths_) => {
8118 /**
8119 * @type {Array<String>}
8120 */
8121 const paths = flatten(arrify(paths_));
8122 if (!paths.every(p => typeof p === STRING_TYPE)) {
8123 throw new TypeError(`Non-string provided as watch path: ${paths}`);
8124 }
8125 return paths.map(normalizePathToUnix);
8126 };
8127
8128 // If SLASH_SLASH occurs at the beginning of path, it is not replaced
8129 // because "//StoragePC/DrivePool/Movies" is a valid network path
8130 const toUnix = (string) => {
8131 let str = string.replace(BACK_SLASH_RE, SLASH);
8132 let prepend = false;
8133 if (str.startsWith(SLASH_SLASH)) {
8134 prepend = true;
8135 }
8136 while (str.match(DOUBLE_SLASH_RE)) {
8137 str = str.replace(DOUBLE_SLASH_RE, SLASH);
8138 }
8139 if (prepend) {
8140 str = SLASH + str;
8141 }
8142 return str;
8143 };
8144
8145 // Our version of upath.normalize
8146 // TODO: this is not equal to path-normalize module - investigate why
8147 const normalizePathToUnix = (path) => toUnix(sysPath.normalize(toUnix(path)));
8148
8149 const normalizeIgnored = (cwd = EMPTY_STR) => (path) => {
8150 if (typeof path !== STRING_TYPE) return path;
8151 return normalizePathToUnix(sysPath.isAbsolute(path) ? path : sysPath.join(cwd, path));
8152 };
8153
8154 const getAbsolutePath = (path, cwd) => {
8155 if (sysPath.isAbsolute(path)) {
8156 return path;
8157 }
8158 if (path.startsWith(BANG)) {
8159 return BANG + sysPath.join(cwd, path.slice(1));
8160 }
8161 return sysPath.join(cwd, path);
8162 };
8163
8164 const undef = (opts, key) => opts[key] === undefined;
8165
8166 /**
8167 * Directory entry.
8168 * @property {Path} path
8169 * @property {Set<Path>} items
8170 */
8171 class DirEntry {
8172 /**
8173 * @param {Path} dir
8174 * @param {Function} removeWatcher
8175 */
8176 constructor(dir, removeWatcher) {
8177 this.path = dir;
8178 this._removeWatcher = removeWatcher;
8179 /** @type {Set<Path>} */
8180 this.items = new Set();
8181 }
8182
8183 add(item) {
8184 const {items} = this;
8185 if (!items) return;
8186 if (item !== ONE_DOT && item !== TWO_DOTS) items.add(item);
8187 }
8188
8189 async remove(item) {
8190 const {items} = this;
8191 if (!items) return;
8192 items.delete(item);
8193 if (items.size > 0) return;
8194
8195 const dir = this.path;
8196 try {
8197 await readdir(dir);
8198 } catch (err) {
8199 if (this._removeWatcher) {
8200 this._removeWatcher(sysPath.dirname(dir), sysPath.basename(dir));
8201 }
8202 }
8203 }
8204
8205 has(item) {
8206 const {items} = this;
8207 if (!items) return;
8208 return items.has(item);
8209 }
8210
8211 /**
8212 * @returns {Array<String>}
8213 */
8214 getChildren() {
8215 const {items} = this;
8216 if (!items) return;
8217 return [...items.values()];
8218 }
8219
8220 dispose() {
8221 this.items.clear();
8222 delete this.path;
8223 delete this._removeWatcher;
8224 delete this.items;
8225 Object.freeze(this);
8226 }
8227 }
8228
8229 const STAT_METHOD_F = 'stat';
8230 const STAT_METHOD_L = 'lstat';
8231 class WatchHelper {
8232 constructor(path, watchPath, follow, fsw) {
8233 this.fsw = fsw;
8234 this.path = path = path.replace(REPLACER_RE, EMPTY_STR);
8235 this.watchPath = watchPath;
8236 this.fullWatchPath = sysPath.resolve(watchPath);
8237 this.hasGlob = watchPath !== path;
8238 /** @type {object|boolean} */
8239 if (path === EMPTY_STR) this.hasGlob = false;
8240 this.globSymlink = this.hasGlob && follow ? undefined : false;
8241 this.globFilter = this.hasGlob ? anymatch(path, undefined, ANYMATCH_OPTS) : false;
8242 this.dirParts = this.getDirParts(path);
8243 this.dirParts.forEach((parts) => {
8244 if (parts.length > 1) parts.pop();
8245 });
8246 this.followSymlinks = follow;
8247 this.statMethod = follow ? STAT_METHOD_F : STAT_METHOD_L;
8248 }
8249
8250 checkGlobSymlink(entry) {
8251 // only need to resolve once
8252 // first entry should always have entry.parentDir === EMPTY_STR
8253 if (this.globSymlink === undefined) {
8254 this.globSymlink = entry.fullParentDir === this.fullWatchPath ?
8255 false : {realPath: entry.fullParentDir, linkPath: this.fullWatchPath};
8256 }
8257
8258 if (this.globSymlink) {
8259 return entry.fullPath.replace(this.globSymlink.realPath, this.globSymlink.linkPath);
8260 }
8261
8262 return entry.fullPath;
8263 }
8264
8265 entryPath(entry) {
8266 return sysPath.join(this.watchPath,
8267 sysPath.relative(this.watchPath, this.checkGlobSymlink(entry))
8268 );
8269 }
8270
8271 filterPath(entry) {
8272 const {stats} = entry;
8273 if (stats && stats.isSymbolicLink()) return this.filterDir(entry);
8274 const resolvedPath = this.entryPath(entry);
8275 const matchesGlob = this.hasGlob && typeof this.globFilter === FUNCTION_TYPE ?
8276 this.globFilter(resolvedPath) : true;
8277 return matchesGlob &&
8278 this.fsw._isntIgnored(resolvedPath, stats) &&
8279 this.fsw._hasReadPermissions(stats);
8280 }
8281
8282 getDirParts(path) {
8283 if (!this.hasGlob) return [];
8284 const parts = [];
8285 const expandedPath = path.includes(BRACE_START) ? braces.expand(path) : [path];
8286 expandedPath.forEach((path) => {
8287 parts.push(sysPath.relative(this.watchPath, path).split(SLASH_OR_BACK_SLASH_RE));
8288 });
8289 return parts;
8290 }
8291
8292 filterDir(entry) {
8293 if (this.hasGlob) {
8294 const entryParts = this.getDirParts(this.checkGlobSymlink(entry));
8295 let globstar = false;
8296 this.unmatchedGlob = !this.dirParts.some((parts) => {
8297 return parts.every((part, i) => {
8298 if (part === GLOBSTAR) globstar = true;
8299 return globstar || !entryParts[0][i] || anymatch(part, entryParts[0][i], ANYMATCH_OPTS);
8300 });
8301 });
8302 }
8303 return !this.unmatchedGlob && this.fsw._isntIgnored(this.entryPath(entry), entry.stats);
8304 }
8305 }
8306
8307 /**
8308 * Watches files & directories for changes. Emitted events:
8309 * `add`, `addDir`, `change`, `unlink`, `unlinkDir`, `all`, `error`
8310 *
8311 * new FSWatcher()
8312 * .add(directories)
8313 * .on('add', path => log('File', path, 'was added'))
8314 */
8315 class FSWatcher extends EventEmitter {
8316 // Not indenting methods for history sake; for now.
8317 constructor(_opts) {
8318 super();
8319
8320 const opts = {};
8321 if (_opts) Object.assign(opts, _opts); // for frozen objects
8322
8323 /** @type {Map<String, DirEntry>} */
8324 this._watched = new Map();
8325 /** @type {Map<String, Array>} */
8326 this._closers = new Map();
8327 /** @type {Set<String>} */
8328 this._ignoredPaths = new Set();
8329
8330 /** @type {Map<ThrottleType, Map>} */
8331 this._throttled = new Map();
8332
8333 /** @type {Map<Path, String|Boolean>} */
8334 this._symlinkPaths = new Map();
8335
8336 this._streams = new Set();
8337 this.closed = false;
8338
8339 // Set up default options.
8340 if (undef(opts, 'persistent')) opts.persistent = true;
8341 if (undef(opts, 'ignoreInitial')) opts.ignoreInitial = false;
8342 if (undef(opts, 'ignorePermissionErrors')) opts.ignorePermissionErrors = false;
8343 if (undef(opts, 'interval')) opts.interval = 100;
8344 if (undef(opts, 'binaryInterval')) opts.binaryInterval = 300;
8345 if (undef(opts, 'disableGlobbing')) opts.disableGlobbing = false;
8346 opts.enableBinaryInterval = opts.binaryInterval !== opts.interval;
8347
8348 // Enable fsevents on OS X when polling isn't explicitly enabled.
8349 if (undef(opts, 'useFsEvents')) opts.useFsEvents = !opts.usePolling;
8350
8351 // If we can't use fsevents, ensure the options reflect it's disabled.
8352 const canUseFsEvents = FsEventsHandler.canUse();
8353 if (!canUseFsEvents) opts.useFsEvents = false;
8354
8355 // Use polling on Mac if not using fsevents.
8356 // Other platforms use non-polling fs_watch.
8357 if (undef(opts, 'usePolling') && !opts.useFsEvents) {
8358 opts.usePolling = isMacos;
8359 }
8360
8361 // Always default to polling on IBM i because fs.watch() is not available on IBM i.
8362 if(isIBMi) {
8363 opts.usePolling = true;
8364 }
8365
8366 // Global override (useful for end-developers that need to force polling for all
8367 // instances of chokidar, regardless of usage/dependency depth)
8368 const envPoll = process.env.CHOKIDAR_USEPOLLING;
8369 if (envPoll !== undefined) {
8370 const envLower = envPoll.toLowerCase();
8371
8372 if (envLower === 'false' || envLower === '0') {
8373 opts.usePolling = false;
8374 } else if (envLower === 'true' || envLower === '1') {
8375 opts.usePolling = true;
8376 } else {
8377 opts.usePolling = !!envLower;
8378 }
8379 }
8380 const envInterval = process.env.CHOKIDAR_INTERVAL;
8381 if (envInterval) {
8382 opts.interval = Number.parseInt(envInterval, 10);
8383 }
8384
8385 // Editor atomic write normalization enabled by default with fs.watch
8386 if (undef(opts, 'atomic')) opts.atomic = !opts.usePolling && !opts.useFsEvents;
8387 if (opts.atomic) this._pendingUnlinks = new Map();
8388
8389 if (undef(opts, 'followSymlinks')) opts.followSymlinks = true;
8390
8391 if (undef(opts, 'awaitWriteFinish')) opts.awaitWriteFinish = false;
8392 if (opts.awaitWriteFinish === true) opts.awaitWriteFinish = {};
8393 const awf = opts.awaitWriteFinish;
8394 if (awf) {
8395 if (!awf.stabilityThreshold) awf.stabilityThreshold = 2000;
8396 if (!awf.pollInterval) awf.pollInterval = 100;
8397 this._pendingWrites = new Map();
8398 }
8399 if (opts.ignored) opts.ignored = arrify(opts.ignored);
8400
8401 let readyCalls = 0;
8402 this._emitReady = () => {
8403 readyCalls++;
8404 if (readyCalls >= this._readyCount) {
8405 this._emitReady = EMPTY_FN;
8406 this._readyEmitted = true;
8407 // use process.nextTick to allow time for listener to be bound
8408 process.nextTick(() => this.emit(EV_READY));
8409 }
8410 };
8411 this._emitRaw = (...args) => this.emit(EV_RAW, ...args);
8412 this._readyEmitted = false;
8413 this.options = opts;
8414
8415 // Initialize with proper watcher.
8416 if (opts.useFsEvents) {
8417 this._fsEventsHandler = new FsEventsHandler(this);
8418 } else {
8419 this._nodeFsHandler = new NodeFsHandler(this);
8420 }
8421
8422 // You’re frozen when your heart’s not open.
8423 Object.freeze(opts);
8424 }
8425
8426 // Public methods
8427
8428 /**
8429 * Adds paths to be watched on an existing FSWatcher instance
8430 * @param {Path|Array<Path>} paths_
8431 * @param {String=} _origAdd private; for handling non-existent paths to be watched
8432 * @param {Boolean=} _internal private; indicates a non-user add
8433 * @returns {FSWatcher} for chaining
8434 */
8435 add(paths_, _origAdd, _internal) {
8436 const {cwd, disableGlobbing} = this.options;
8437 this.closed = false;
8438 let paths = unifyPaths(paths_);
8439 if (cwd) {
8440 paths = paths.map((path) => {
8441 const absPath = getAbsolutePath(path, cwd);
8442
8443 // Check `path` instead of `absPath` because the cwd portion can't be a glob
8444 if (disableGlobbing || !isGlob(path)) {
8445 return absPath;
8446 }
8447 return normalizePath(absPath);
8448 });
8449 }
8450
8451 // set aside negated glob strings
8452 paths = paths.filter((path) => {
8453 if (path.startsWith(BANG)) {
8454 this._ignoredPaths.add(path.slice(1));
8455 return false;
8456 }
8457
8458 // if a path is being added that was previously ignored, stop ignoring it
8459 this._ignoredPaths.delete(path);
8460 this._ignoredPaths.delete(path + SLASH_GLOBSTAR);
8461
8462 // reset the cached userIgnored anymatch fn
8463 // to make ignoredPaths changes effective
8464 this._userIgnored = undefined;
8465
8466 return true;
8467 });
8468
8469 if (this.options.useFsEvents && this._fsEventsHandler) {
8470 if (!this._readyCount) this._readyCount = paths.length;
8471 if (this.options.persistent) this._readyCount += paths.length;
8472 paths.forEach((path) => this._fsEventsHandler._addToFsEvents(path));
8473 } else {
8474 if (!this._readyCount) this._readyCount = 0;
8475 this._readyCount += paths.length;
8476 Promise.all(
8477 paths.map(async path => {
8478 const res = await this._nodeFsHandler._addToNodeFs(path, !_internal, 0, 0, _origAdd);
8479 if (res) this._emitReady();
8480 return res;
8481 })
8482 ).then(results => {
8483 if (this.closed) return;
8484 results.filter(item => item).forEach(item => {
8485 this.add(sysPath.dirname(item), sysPath.basename(_origAdd || item));
8486 });
8487 });
8488 }
8489
8490 return this;
8491 }
8492
8493 /**
8494 * Close watchers or start ignoring events from specified paths.
8495 * @param {Path|Array<Path>} paths_ - string or array of strings, file/directory paths and/or globs
8496 * @returns {FSWatcher} for chaining
8497 */
8498 unwatch(paths_) {
8499 if (this.closed) return this;
8500 const paths = unifyPaths(paths_);
8501 const {cwd} = this.options;
8502
8503 paths.forEach((path) => {
8504 // convert to absolute path unless relative path already matches
8505 if (!sysPath.isAbsolute(path) && !this._closers.has(path)) {
8506 if (cwd) path = sysPath.join(cwd, path);
8507 path = sysPath.resolve(path);
8508 }
8509
8510 this._closePath(path);
8511
8512 this._ignoredPaths.add(path);
8513 if (this._watched.has(path)) {
8514 this._ignoredPaths.add(path + SLASH_GLOBSTAR);
8515 }
8516
8517 // reset the cached userIgnored anymatch fn
8518 // to make ignoredPaths changes effective
8519 this._userIgnored = undefined;
8520 });
8521
8522 return this;
8523 }
8524
8525 /**
8526 * Close watchers and remove all listeners from watched paths.
8527 * @returns {Promise<void>}.
8528 */
8529 close() {
8530 if (this.closed) return this._closePromise;
8531 this.closed = true;
8532
8533 // Memory management.
8534 this.removeAllListeners();
8535 const closers = [];
8536 this._closers.forEach(closerList => closerList.forEach(closer => {
8537 const promise = closer();
8538 if (promise instanceof Promise) closers.push(promise);
8539 }));
8540 this._streams.forEach(stream => stream.destroy());
8541 this._userIgnored = undefined;
8542 this._readyCount = 0;
8543 this._readyEmitted = false;
8544 this._watched.forEach(dirent => dirent.dispose());
8545 ['closers', 'watched', 'streams', 'symlinkPaths', 'throttled'].forEach(key => {
8546 this[`_${key}`].clear();
8547 });
8548
8549 this._closePromise = closers.length ? Promise.all(closers).then(() => undefined) : Promise.resolve();
8550 return this._closePromise;
8551 }
8552
8553 /**
8554 * Expose list of watched paths
8555 * @returns {Object} for chaining
8556 */
8557 getWatched() {
8558 const watchList = {};
8559 this._watched.forEach((entry, dir) => {
8560 const key = this.options.cwd ? sysPath.relative(this.options.cwd, dir) : dir;
8561 watchList[key || ONE_DOT] = entry.getChildren().sort();
8562 });
8563 return watchList;
8564 }
8565
8566 emitWithAll(event, args) {
8567 this.emit(...args);
8568 if (event !== EV_ERROR) this.emit(EV_ALL, ...args);
8569 }
8570
8571 // Common helpers
8572 // --------------
8573
8574 /**
8575 * Normalize and emit events.
8576 * Calling _emit DOES NOT MEAN emit() would be called!
8577 * @param {EventName} event Type of event
8578 * @param {Path} path File or directory path
8579 * @param {*=} val1 arguments to be passed with event
8580 * @param {*=} val2
8581 * @param {*=} val3
8582 * @returns the error if defined, otherwise the value of the FSWatcher instance's `closed` flag
8583 */
8584 async _emit(event, path, val1, val2, val3) {
8585 if (this.closed) return;
8586
8587 const opts = this.options;
8588 if (isWindows) path = sysPath.normalize(path);
8589 if (opts.cwd) path = sysPath.relative(opts.cwd, path);
8590 /** @type Array<any> */
8591 const args = [event, path];
8592 if (val3 !== undefined) args.push(val1, val2, val3);
8593 else if (val2 !== undefined) args.push(val1, val2);
8594 else if (val1 !== undefined) args.push(val1);
8595
8596 const awf = opts.awaitWriteFinish;
8597 let pw;
8598 if (awf && (pw = this._pendingWrites.get(path))) {
8599 pw.lastChange = new Date();
8600 return this;
8601 }
8602
8603 if (opts.atomic) {
8604 if (event === EV_UNLINK) {
8605 this._pendingUnlinks.set(path, args);
8606 setTimeout(() => {
8607 this._pendingUnlinks.forEach((entry, path) => {
8608 this.emit(...entry);
8609 this.emit(EV_ALL, ...entry);
8610 this._pendingUnlinks.delete(path);
8611 });
8612 }, typeof opts.atomic === 'number' ? opts.atomic : 100);
8613 return this;
8614 }
8615 if (event === EV_ADD && this._pendingUnlinks.has(path)) {
8616 event = args[0] = EV_CHANGE;
8617 this._pendingUnlinks.delete(path);
8618 }
8619 }
8620
8621 if (awf && (event === EV_ADD || event === EV_CHANGE) && this._readyEmitted) {
8622 const awfEmit = (err, stats) => {
8623 if (err) {
8624 event = args[0] = EV_ERROR;
8625 args[1] = err;
8626 this.emitWithAll(event, args);
8627 } else if (stats) {
8628 // if stats doesn't exist the file must have been deleted
8629 if (args.length > 2) {
8630 args[2] = stats;
8631 } else {
8632 args.push(stats);
8633 }
8634 this.emitWithAll(event, args);
8635 }
8636 };
8637
8638 this._awaitWriteFinish(path, awf.stabilityThreshold, event, awfEmit);
8639 return this;
8640 }
8641
8642 if (event === EV_CHANGE) {
8643 const isThrottled = !this._throttle(EV_CHANGE, path, 50);
8644 if (isThrottled) return this;
8645 }
8646
8647 if (opts.alwaysStat && val1 === undefined &&
8648 (event === EV_ADD || event === EV_ADD_DIR || event === EV_CHANGE)
8649 ) {
8650 const fullPath = opts.cwd ? sysPath.join(opts.cwd, path) : path;
8651 let stats;
8652 try {
8653 stats = await stat(fullPath);
8654 } catch (err) {}
8655 // Suppress event when fs_stat fails, to avoid sending undefined 'stat'
8656 if (!stats || this.closed) return;
8657 args.push(stats);
8658 }
8659 this.emitWithAll(event, args);
8660
8661 return this;
8662 }
8663
8664 /**
8665 * Common handler for errors
8666 * @param {Error} error
8667 * @returns {Error|Boolean} The error if defined, otherwise the value of the FSWatcher instance's `closed` flag
8668 */
8669 _handleError(error) {
8670 const code = error && error.code;
8671 if (error && code !== 'ENOENT' && code !== 'ENOTDIR' &&
8672 (!this.options.ignorePermissionErrors || (code !== 'EPERM' && code !== 'EACCES'))
8673 ) {
8674 this.emit(EV_ERROR, error);
8675 }
8676 return error || this.closed;
8677 }
8678
8679 /**
8680 * Helper utility for throttling
8681 * @param {ThrottleType} actionType type being throttled
8682 * @param {Path} path being acted upon
8683 * @param {Number} timeout duration of time to suppress duplicate actions
8684 * @returns {Object|false} tracking object or false if action should be suppressed
8685 */
8686 _throttle(actionType, path, timeout) {
8687 if (!this._throttled.has(actionType)) {
8688 this._throttled.set(actionType, new Map());
8689 }
8690
8691 /** @type {Map<Path, Object>} */
8692 const action = this._throttled.get(actionType);
8693 /** @type {Object} */
8694 const actionPath = action.get(path);
8695
8696 if (actionPath) {
8697 actionPath.count++;
8698 return false;
8699 }
8700
8701 let timeoutObject;
8702 const clear = () => {
8703 const item = action.get(path);
8704 const count = item ? item.count : 0;
8705 action.delete(path);
8706 clearTimeout(timeoutObject);
8707 if (item) clearTimeout(item.timeoutObject);
8708 return count;
8709 };
8710 timeoutObject = setTimeout(clear, timeout);
8711 const thr = {timeoutObject, clear, count: 0};
8712 action.set(path, thr);
8713 return thr;
8714 }
8715
8716 _incrReadyCount() {
8717 return this._readyCount++;
8718 }
8719
8720 /**
8721 * Awaits write operation to finish.
8722 * Polls a newly created file for size variations. When files size does not change for 'threshold' milliseconds calls callback.
8723 * @param {Path} path being acted upon
8724 * @param {Number} threshold Time in milliseconds a file size must be fixed before acknowledging write OP is finished
8725 * @param {EventName} event
8726 * @param {Function} awfEmit Callback to be called when ready for event to be emitted.
8727 */
8728 _awaitWriteFinish(path, threshold, event, awfEmit) {
8729 let timeoutHandler;
8730
8731 let fullPath = path;
8732 if (this.options.cwd && !sysPath.isAbsolute(path)) {
8733 fullPath = sysPath.join(this.options.cwd, path);
8734 }
8735
8736 const now = new Date();
8737
8738 const awaitWriteFinish = (prevStat) => {
8739 fs.stat(fullPath, (err, curStat) => {
8740 if (err || !this._pendingWrites.has(path)) {
8741 if (err && err.code !== 'ENOENT') awfEmit(err);
8742 return;
8743 }
8744
8745 const now = Number(new Date());
8746
8747 if (prevStat && curStat.size !== prevStat.size) {
8748 this._pendingWrites.get(path).lastChange = now;
8749 }
8750 const pw = this._pendingWrites.get(path);
8751 const df = now - pw.lastChange;
8752
8753 if (df >= threshold) {
8754 this._pendingWrites.delete(path);
8755 awfEmit(undefined, curStat);
8756 } else {
8757 timeoutHandler = setTimeout(
8758 awaitWriteFinish,
8759 this.options.awaitWriteFinish.pollInterval,
8760 curStat
8761 );
8762 }
8763 });
8764 };
8765
8766 if (!this._pendingWrites.has(path)) {
8767 this._pendingWrites.set(path, {
8768 lastChange: now,
8769 cancelWait: () => {
8770 this._pendingWrites.delete(path);
8771 clearTimeout(timeoutHandler);
8772 return event;
8773 }
8774 });
8775 timeoutHandler = setTimeout(
8776 awaitWriteFinish,
8777 this.options.awaitWriteFinish.pollInterval
8778 );
8779 }
8780 }
8781
8782 _getGlobIgnored() {
8783 return [...this._ignoredPaths.values()];
8784 }
8785
8786 /**
8787 * Determines whether user has asked to ignore this path.
8788 * @param {Path} path filepath or dir
8789 * @param {fs.Stats=} stats result of fs.stat
8790 * @returns {Boolean}
8791 */
8792 _isIgnored(path, stats) {
8793 if (this.options.atomic && DOT_RE.test(path)) return true;
8794 if (!this._userIgnored) {
8795 const {cwd} = this.options;
8796 const ign = this.options.ignored;
8797
8798 const ignored = ign && ign.map(normalizeIgnored(cwd));
8799 const paths = arrify(ignored)
8800 .filter((path) => typeof path === STRING_TYPE && !isGlob(path))
8801 .map((path) => path + SLASH_GLOBSTAR);
8802 const list = this._getGlobIgnored().map(normalizeIgnored(cwd)).concat(ignored, paths);
8803 this._userIgnored = anymatch(list, undefined, ANYMATCH_OPTS);
8804 }
8805
8806 return this._userIgnored([path, stats]);
8807 }
8808
8809 _isntIgnored(path, stat) {
8810 return !this._isIgnored(path, stat);
8811 }
8812
8813 /**
8814 * Provides a set of common helpers and properties relating to symlink and glob handling.
8815 * @param {Path} path file, directory, or glob pattern being watched
8816 * @param {Number=} depth at any depth > 0, this isn't a glob
8817 * @returns {WatchHelper} object containing helpers for this path
8818 */
8819 _getWatchHelpers(path, depth) {
8820 const watchPath = depth || this.options.disableGlobbing || !isGlob(path) ? path : globParent(path);
8821 const follow = this.options.followSymlinks;
8822
8823 return new WatchHelper(path, watchPath, follow, this);
8824 }
8825
8826 // Directory helpers
8827 // -----------------
8828
8829 /**
8830 * Provides directory tracking objects
8831 * @param {String} directory path of the directory
8832 * @returns {DirEntry} the directory's tracking object
8833 */
8834 _getWatchedDir(directory) {
8835 if (!this._boundRemove) this._boundRemove = this._remove.bind(this);
8836 const dir = sysPath.resolve(directory);
8837 if (!this._watched.has(dir)) this._watched.set(dir, new DirEntry(dir, this._boundRemove));
8838 return this._watched.get(dir);
8839 }
8840
8841 // File helpers
8842 // ------------
8843
8844 /**
8845 * Check for read permissions.
8846 * Based on this answer on SO: https://stackoverflow.com/a/11781404/1358405
8847 * @param {fs.Stats} stats - object, result of fs_stat
8848 * @returns {Boolean} indicates whether the file can be read
8849 */
8850 _hasReadPermissions(stats) {
8851 if (this.options.ignorePermissionErrors) return true;
8852
8853 // stats.mode may be bigint
8854 const md = stats && Number.parseInt(stats.mode, 10);
8855 const st = md & 0o777;
8856 const it = Number.parseInt(st.toString(8)[0], 10);
8857 return Boolean(4 & it);
8858 }
8859
8860 /**
8861 * Handles emitting unlink events for
8862 * files and directories, and via recursion, for
8863 * files and directories within directories that are unlinked
8864 * @param {String} directory within which the following item is located
8865 * @param {String} item base path of item/directory
8866 * @returns {void}
8867 */
8868 _remove(directory, item, isDirectory) {
8869 // if what is being deleted is a directory, get that directory's paths
8870 // for recursive deleting and cleaning of watched object
8871 // if it is not a directory, nestedDirectoryChildren will be empty array
8872 const path = sysPath.join(directory, item);
8873 const fullPath = sysPath.resolve(path);
8874 isDirectory = isDirectory != null
8875 ? isDirectory
8876 : this._watched.has(path) || this._watched.has(fullPath);
8877
8878 // prevent duplicate handling in case of arriving here nearly simultaneously
8879 // via multiple paths (such as _handleFile and _handleDir)
8880 if (!this._throttle('remove', path, 100)) return;
8881
8882 // if the only watched file is removed, watch for its return
8883 if (!isDirectory && !this.options.useFsEvents && this._watched.size === 1) {
8884 this.add(directory, item, true);
8885 }
8886
8887 // This will create a new entry in the watched object in either case
8888 // so we got to do the directory check beforehand
8889 const wp = this._getWatchedDir(path);
8890 const nestedDirectoryChildren = wp.getChildren();
8891
8892 // Recursively remove children directories / files.
8893 nestedDirectoryChildren.forEach(nested => this._remove(path, nested));
8894
8895 // Check if item was on the watched list and remove it
8896 const parent = this._getWatchedDir(directory);
8897 const wasTracked = parent.has(item);
8898 parent.remove(item);
8899
8900 // Fixes issue #1042 -> Relative paths were detected and added as symlinks
8901 // (https://github.com/paulmillr/chokidar/blob/e1753ddbc9571bdc33b4a4af172d52cb6e611c10/lib/nodefs-handler.js#L612),
8902 // but never removed from the map in case the path was deleted.
8903 // This leads to an incorrect state if the path was recreated:
8904 // https://github.com/paulmillr/chokidar/blob/e1753ddbc9571bdc33b4a4af172d52cb6e611c10/lib/nodefs-handler.js#L553
8905 if (this._symlinkPaths.has(fullPath)) {
8906 this._symlinkPaths.delete(fullPath);
8907 }
8908
8909 // If we wait for this file to be fully written, cancel the wait.
8910 let relPath = path;
8911 if (this.options.cwd) relPath = sysPath.relative(this.options.cwd, path);
8912 if (this.options.awaitWriteFinish && this._pendingWrites.has(relPath)) {
8913 const event = this._pendingWrites.get(relPath).cancelWait();
8914 if (event === EV_ADD) return;
8915 }
8916
8917 // The Entry will either be a directory that just got removed
8918 // or a bogus entry to a file, in either case we have to remove it
8919 this._watched.delete(path);
8920 this._watched.delete(fullPath);
8921 const eventName = isDirectory ? EV_UNLINK_DIR : EV_UNLINK;
8922 if (wasTracked && !this._isIgnored(path)) this._emit(eventName, path);
8923
8924 // Avoid conflicts if we later create another file with the same name
8925 if (!this.options.useFsEvents) {
8926 this._closePath(path);
8927 }
8928 }
8929
8930 /**
8931 * Closes all watchers for a path
8932 * @param {Path} path
8933 */
8934 _closePath(path) {
8935 this._closeFile(path);
8936 const dir = sysPath.dirname(path);
8937 this._getWatchedDir(dir).remove(sysPath.basename(path));
8938 }
8939
8940 /**
8941 * Closes only file-specific watchers
8942 * @param {Path} path
8943 */
8944 _closeFile(path) {
8945 const closers = this._closers.get(path);
8946 if (!closers) return;
8947 closers.forEach(closer => closer());
8948 this._closers.delete(path);
8949 }
8950
8951 /**
8952 *
8953 * @param {Path} path
8954 * @param {Function} closer
8955 */
8956 _addPathCloser(path, closer) {
8957 if (!closer) return;
8958 let list = this._closers.get(path);
8959 if (!list) {
8960 list = [];
8961 this._closers.set(path, list);
8962 }
8963 list.push(closer);
8964 }
8965
8966 _readdirp(root, opts) {
8967 if (this.closed) return;
8968 const options = {type: EV_ALL, alwaysStat: true, lstat: true, ...opts};
8969 let stream = readdirp(root, options);
8970 this._streams.add(stream);
8971 stream.once(STR_CLOSE, () => {
8972 stream = undefined;
8973 });
8974 stream.once(STR_END, () => {
8975 if (stream) {
8976 this._streams.delete(stream);
8977 stream = undefined;
8978 }
8979 });
8980 return stream;
8981 }
8982
8983 }
8984
8985 // Export FSWatcher class
8986 chokidar$1.FSWatcher = FSWatcher;
8987
8988 /**
8989 * Instantiates watcher with paths to be tracked.
8990 * @param {String|Array<String>} paths file/directory paths and/or globs
8991 * @param {Object=} options chokidar opts
8992 * @returns an instance of FSWatcher for chaining.
8993 */
8994 const watch = (paths, options) => {
8995 const watcher = new FSWatcher(options);
8996 watcher.add(paths);
8997 return watcher;
8998 };
8999
9000 chokidar$1.watch = watch;
9001 return chokidar$1;
9002}
9003
9004var chokidarExports = /*@__PURE__*/ requireChokidar();
9005const chokidar = /*@__PURE__*/getDefaultExportFromCjs(chokidarExports);
9006
9007class FileWatcher {
9008 constructor(task, chokidarOptions) {
9009 this.transformWatchers = new Map();
9010 this.chokidarOptions = chokidarOptions;
9011 this.task = task;
9012 this.watcher = this.createWatcher(null);
9013 }
9014 close() {
9015 this.watcher.close();
9016 for (const watcher of this.transformWatchers.values()) {
9017 watcher.close();
9018 }
9019 }
9020 unwatch(id) {
9021 this.watcher.unwatch(id);
9022 const transformWatcher = this.transformWatchers.get(id);
9023 if (transformWatcher) {
9024 this.transformWatchers.delete(id);
9025 transformWatcher.close();
9026 }
9027 }
9028 watch(id, isTransformDependency) {
9029 if (isTransformDependency) {
9030 const watcher = this.transformWatchers.get(id) ?? this.createWatcher(id);
9031 watcher.add(id);
9032 this.transformWatchers.set(id, watcher);
9033 }
9034 else {
9035 this.watcher.add(id);
9036 }
9037 }
9038 createWatcher(transformWatcherId) {
9039 const task = this.task;
9040 const isLinux = platform() === 'linux';
9041 const isFreeBSD = platform() === 'freebsd';
9042 const isTransformDependency = transformWatcherId !== null;
9043 const handleChange = (id, event) => {
9044 const changedId = transformWatcherId || id;
9045 if (isLinux || isFreeBSD) {
9046 // unwatching and watching fixes an issue with chokidar where on certain systems,
9047 // a file that was unlinked and immediately recreated would create a change event
9048 // but then no longer any further events
9049 watcher.unwatch(changedId);
9050 watcher.add(changedId);
9051 }
9052 task.invalidate(changedId, { event, isTransformDependency });
9053 };
9054 const watcher = chokidar
9055 .watch([], this.chokidarOptions)
9056 .on('add', id => handleChange(id, 'create'))
9057 .on('change', id => handleChange(id, 'update'))
9058 .on('unlink', id => handleChange(id, 'delete'));
9059 return watcher;
9060 }
9061}
9062
9063const eventsRewrites = {
9064 create: {
9065 create: 'buggy',
9066 delete: null, //delete file from map
9067 update: 'create'
9068 },
9069 delete: {
9070 create: 'update',
9071 delete: 'buggy',
9072 update: 'buggy'
9073 },
9074 update: {
9075 create: 'buggy',
9076 delete: 'delete',
9077 update: 'update'
9078 }
9079};
9080class Watcher {
9081 constructor(optionsList, emitter) {
9082 this.buildDelay = 0;
9083 this.buildTimeout = null;
9084 this.closed = false;
9085 this.invalidatedIds = new Map();
9086 this.rerun = false;
9087 this.running = true;
9088 this.emitter = emitter;
9089 emitter.close = this.close.bind(this);
9090 this.tasks = optionsList.map(options => new Task(this, options));
9091 for (const { watch } of optionsList) {
9092 if (watch && typeof watch.buildDelay === 'number') {
9093 this.buildDelay = Math.max(this.buildDelay, watch.buildDelay);
9094 }
9095 }
9096 process$1.nextTick(() => this.run());
9097 }
9098 async close() {
9099 if (this.closed)
9100 return;
9101 this.closed = true;
9102 if (this.buildTimeout)
9103 clearTimeout(this.buildTimeout);
9104 for (const task of this.tasks) {
9105 task.close();
9106 }
9107 await this.emitter.emit('close');
9108 this.emitter.removeAllListeners();
9109 }
9110 invalidate(file) {
9111 if (file) {
9112 const previousEvent = this.invalidatedIds.get(file.id);
9113 const event = previousEvent ? eventsRewrites[previousEvent][file.event] : file.event;
9114 if (event === 'buggy') {
9115 //TODO: throws or warn? Currently just ignore, uses new event
9116 this.invalidatedIds.set(file.id, file.event);
9117 }
9118 else if (event === null) {
9119 this.invalidatedIds.delete(file.id);
9120 }
9121 else {
9122 this.invalidatedIds.set(file.id, event);
9123 }
9124 }
9125 if (this.running) {
9126 this.rerun = true;
9127 return;
9128 }
9129 if (this.buildTimeout)
9130 clearTimeout(this.buildTimeout);
9131 this.buildTimeout = setTimeout(async () => {
9132 this.buildTimeout = null;
9133 try {
9134 await Promise.all([...this.invalidatedIds].map(([id, event]) => this.emitter.emit('change', id, { event })));
9135 this.invalidatedIds.clear();
9136 await this.emitter.emit('restart');
9137 this.emitter.removeListenersForCurrentRun();
9138 this.run();
9139 }
9140 catch (error) {
9141 this.invalidatedIds.clear();
9142 await this.emitter.emit('event', {
9143 code: 'ERROR',
9144 error,
9145 result: null
9146 });
9147 await this.emitter.emit('event', {
9148 code: 'END'
9149 });
9150 }
9151 }, this.buildDelay);
9152 }
9153 async run() {
9154 this.running = true;
9155 await this.emitter.emit('event', {
9156 code: 'START'
9157 });
9158 for (const task of this.tasks) {
9159 await task.run();
9160 }
9161 this.running = false;
9162 await this.emitter.emit('event', {
9163 code: 'END'
9164 });
9165 if (this.rerun) {
9166 this.rerun = false;
9167 this.invalidate();
9168 }
9169 }
9170}
9171class Task {
9172 constructor(watcher, options) {
9173 this.cache = { modules: [] };
9174 this.watchFiles = [];
9175 this.closed = false;
9176 this.invalidated = true;
9177 this.watched = new Set();
9178 this.watcher = watcher;
9179 this.options = options;
9180 this.skipWrite = Boolean(options.watch && options.watch.skipWrite);
9181 this.outputs = this.options.output;
9182 this.outputFiles = this.outputs.map(output => {
9183 if (output.file || output.dir)
9184 return path.resolve(output.file || output.dir);
9185 return undefined;
9186 });
9187 const watchOptions = this.options.watch || {};
9188 this.filter = createFilter(watchOptions.include, watchOptions.exclude);
9189 this.fileWatcher = new FileWatcher(this, {
9190 ...watchOptions.chokidar,
9191 disableGlobbing: true,
9192 ignoreInitial: true
9193 });
9194 }
9195 close() {
9196 this.closed = true;
9197 this.fileWatcher.close();
9198 }
9199 invalidate(id, details) {
9200 this.invalidated = true;
9201 if (details.isTransformDependency) {
9202 for (const module of this.cache.modules) {
9203 if (!module.transformDependencies.includes(id))
9204 continue;
9205 // effective invalidation
9206 module.originalCode = null;
9207 }
9208 }
9209 this.watcher.invalidate({ event: details.event, id });
9210 }
9211 async run() {
9212 if (!this.invalidated)
9213 return;
9214 this.invalidated = false;
9215 const options = {
9216 ...this.options,
9217 cache: this.cache
9218 };
9219 const start = Date.now();
9220 await this.watcher.emitter.emit('event', {
9221 code: 'BUNDLE_START',
9222 input: this.options.input,
9223 output: this.outputFiles
9224 });
9225 let result = null;
9226 try {
9227 result = await rollupInternal(options, this.watcher.emitter);
9228 if (this.closed) {
9229 return;
9230 }
9231 this.updateWatchedFiles(result);
9232 if (!this.skipWrite) {
9233 await Promise.all(this.outputs.map(output => result.write(output)));
9234 if (this.closed) {
9235 return;
9236 }
9237 this.updateWatchedFiles(result);
9238 }
9239 await this.watcher.emitter.emit('event', {
9240 code: 'BUNDLE_END',
9241 duration: Date.now() - start,
9242 input: this.options.input,
9243 output: this.outputFiles,
9244 result
9245 });
9246 }
9247 catch (error) {
9248 if (!this.closed) {
9249 if (Array.isArray(error.watchFiles)) {
9250 for (const id of error.watchFiles) {
9251 this.watchFile(id);
9252 }
9253 }
9254 if (error.id) {
9255 this.cache.modules = this.cache.modules.filter(module => module.id !== error.id);
9256 }
9257 }
9258 await this.watcher.emitter.emit('event', {
9259 code: 'ERROR',
9260 error,
9261 result
9262 });
9263 }
9264 }
9265 updateWatchedFiles(result) {
9266 const previouslyWatched = this.watched;
9267 this.watched = new Set();
9268 this.watchFiles = result.watchFiles;
9269 this.cache = result.cache;
9270 for (const id of this.watchFiles) {
9271 this.watchFile(id);
9272 }
9273 for (const module of this.cache.modules) {
9274 for (const depId of module.transformDependencies) {
9275 this.watchFile(depId, true);
9276 }
9277 }
9278 for (const id of previouslyWatched) {
9279 if (!this.watched.has(id)) {
9280 this.fileWatcher.unwatch(id);
9281 }
9282 }
9283 }
9284 watchFile(id, isTransformDependency = false) {
9285 if (!this.filter(id))
9286 return;
9287 this.watched.add(id);
9288 if (this.outputFiles.includes(id)) {
9289 throw new Error('Cannot import the generated bundle');
9290 }
9291 // this is necessary to ensure that any 'renamed' files
9292 // continue to be watched following an error
9293 this.fileWatcher.watch(id, isTransformDependency);
9294 }
9295}
9296
9297export { Task, Watcher };
Note: See TracBrowser for help on using the repository browser.