11cb0ef41Sopenharmony_ciimport expand from 'brace-expansion';
21cb0ef41Sopenharmony_ciimport { assertValidPattern } from './assert-valid-pattern.js';
31cb0ef41Sopenharmony_ciimport { AST } from './ast.js';
41cb0ef41Sopenharmony_ciimport { escape } from './escape.js';
51cb0ef41Sopenharmony_ciimport { unescape } from './unescape.js';
61cb0ef41Sopenharmony_ciexport const minimatch = (p, pattern, options = {}) => {
71cb0ef41Sopenharmony_ci    assertValidPattern(pattern);
81cb0ef41Sopenharmony_ci    // shortcut: comments match nothing.
91cb0ef41Sopenharmony_ci    if (!options.nocomment && pattern.charAt(0) === '#') {
101cb0ef41Sopenharmony_ci        return false;
111cb0ef41Sopenharmony_ci    }
121cb0ef41Sopenharmony_ci    return new Minimatch(pattern, options).match(p);
131cb0ef41Sopenharmony_ci};
141cb0ef41Sopenharmony_ci// Optimized checking for the most common glob patterns.
151cb0ef41Sopenharmony_ciconst starDotExtRE = /^\*+([^+@!?\*\[\(]*)$/;
161cb0ef41Sopenharmony_ciconst starDotExtTest = (ext) => (f) => !f.startsWith('.') && f.endsWith(ext);
171cb0ef41Sopenharmony_ciconst starDotExtTestDot = (ext) => (f) => f.endsWith(ext);
181cb0ef41Sopenharmony_ciconst starDotExtTestNocase = (ext) => {
191cb0ef41Sopenharmony_ci    ext = ext.toLowerCase();
201cb0ef41Sopenharmony_ci    return (f) => !f.startsWith('.') && f.toLowerCase().endsWith(ext);
211cb0ef41Sopenharmony_ci};
221cb0ef41Sopenharmony_ciconst starDotExtTestNocaseDot = (ext) => {
231cb0ef41Sopenharmony_ci    ext = ext.toLowerCase();
241cb0ef41Sopenharmony_ci    return (f) => f.toLowerCase().endsWith(ext);
251cb0ef41Sopenharmony_ci};
261cb0ef41Sopenharmony_ciconst starDotStarRE = /^\*+\.\*+$/;
271cb0ef41Sopenharmony_ciconst starDotStarTest = (f) => !f.startsWith('.') && f.includes('.');
281cb0ef41Sopenharmony_ciconst starDotStarTestDot = (f) => f !== '.' && f !== '..' && f.includes('.');
291cb0ef41Sopenharmony_ciconst dotStarRE = /^\.\*+$/;
301cb0ef41Sopenharmony_ciconst dotStarTest = (f) => f !== '.' && f !== '..' && f.startsWith('.');
311cb0ef41Sopenharmony_ciconst starRE = /^\*+$/;
321cb0ef41Sopenharmony_ciconst starTest = (f) => f.length !== 0 && !f.startsWith('.');
331cb0ef41Sopenharmony_ciconst starTestDot = (f) => f.length !== 0 && f !== '.' && f !== '..';
341cb0ef41Sopenharmony_ciconst qmarksRE = /^\?+([^+@!?\*\[\(]*)?$/;
351cb0ef41Sopenharmony_ciconst qmarksTestNocase = ([$0, ext = '']) => {
361cb0ef41Sopenharmony_ci    const noext = qmarksTestNoExt([$0]);
371cb0ef41Sopenharmony_ci    if (!ext)
381cb0ef41Sopenharmony_ci        return noext;
391cb0ef41Sopenharmony_ci    ext = ext.toLowerCase();
401cb0ef41Sopenharmony_ci    return (f) => noext(f) && f.toLowerCase().endsWith(ext);
411cb0ef41Sopenharmony_ci};
421cb0ef41Sopenharmony_ciconst qmarksTestNocaseDot = ([$0, ext = '']) => {
431cb0ef41Sopenharmony_ci    const noext = qmarksTestNoExtDot([$0]);
441cb0ef41Sopenharmony_ci    if (!ext)
451cb0ef41Sopenharmony_ci        return noext;
461cb0ef41Sopenharmony_ci    ext = ext.toLowerCase();
471cb0ef41Sopenharmony_ci    return (f) => noext(f) && f.toLowerCase().endsWith(ext);
481cb0ef41Sopenharmony_ci};
491cb0ef41Sopenharmony_ciconst qmarksTestDot = ([$0, ext = '']) => {
501cb0ef41Sopenharmony_ci    const noext = qmarksTestNoExtDot([$0]);
511cb0ef41Sopenharmony_ci    return !ext ? noext : (f) => noext(f) && f.endsWith(ext);
521cb0ef41Sopenharmony_ci};
531cb0ef41Sopenharmony_ciconst qmarksTest = ([$0, ext = '']) => {
541cb0ef41Sopenharmony_ci    const noext = qmarksTestNoExt([$0]);
551cb0ef41Sopenharmony_ci    return !ext ? noext : (f) => noext(f) && f.endsWith(ext);
561cb0ef41Sopenharmony_ci};
571cb0ef41Sopenharmony_ciconst qmarksTestNoExt = ([$0]) => {
581cb0ef41Sopenharmony_ci    const len = $0.length;
591cb0ef41Sopenharmony_ci    return (f) => f.length === len && !f.startsWith('.');
601cb0ef41Sopenharmony_ci};
611cb0ef41Sopenharmony_ciconst qmarksTestNoExtDot = ([$0]) => {
621cb0ef41Sopenharmony_ci    const len = $0.length;
631cb0ef41Sopenharmony_ci    return (f) => f.length === len && f !== '.' && f !== '..';
641cb0ef41Sopenharmony_ci};
651cb0ef41Sopenharmony_ci/* c8 ignore start */
661cb0ef41Sopenharmony_ciconst defaultPlatform = (typeof process === 'object' && process
671cb0ef41Sopenharmony_ci    ? (typeof process.env === 'object' &&
681cb0ef41Sopenharmony_ci        process.env &&
691cb0ef41Sopenharmony_ci        process.env.__MINIMATCH_TESTING_PLATFORM__) ||
701cb0ef41Sopenharmony_ci        process.platform
711cb0ef41Sopenharmony_ci    : 'posix');
721cb0ef41Sopenharmony_ciconst path = {
731cb0ef41Sopenharmony_ci    win32: { sep: '\\' },
741cb0ef41Sopenharmony_ci    posix: { sep: '/' },
751cb0ef41Sopenharmony_ci};
761cb0ef41Sopenharmony_ci/* c8 ignore stop */
771cb0ef41Sopenharmony_ciexport const sep = defaultPlatform === 'win32' ? path.win32.sep : path.posix.sep;
781cb0ef41Sopenharmony_ciminimatch.sep = sep;
791cb0ef41Sopenharmony_ciexport const GLOBSTAR = Symbol('globstar **');
801cb0ef41Sopenharmony_ciminimatch.GLOBSTAR = GLOBSTAR;
811cb0ef41Sopenharmony_ci// any single thing other than /
821cb0ef41Sopenharmony_ci// don't need to escape / when using new RegExp()
831cb0ef41Sopenharmony_ciconst qmark = '[^/]';
841cb0ef41Sopenharmony_ci// * => any number of characters
851cb0ef41Sopenharmony_ciconst star = qmark + '*?';
861cb0ef41Sopenharmony_ci// ** when dots are allowed.  Anything goes, except .. and .
871cb0ef41Sopenharmony_ci// not (^ or / followed by one or two dots followed by $ or /),
881cb0ef41Sopenharmony_ci// followed by anything, any number of times.
891cb0ef41Sopenharmony_ciconst twoStarDot = '(?:(?!(?:\\/|^)(?:\\.{1,2})($|\\/)).)*?';
901cb0ef41Sopenharmony_ci// not a ^ or / followed by a dot,
911cb0ef41Sopenharmony_ci// followed by anything, any number of times.
921cb0ef41Sopenharmony_ciconst twoStarNoDot = '(?:(?!(?:\\/|^)\\.).)*?';
931cb0ef41Sopenharmony_ciexport const filter = (pattern, options = {}) => (p) => minimatch(p, pattern, options);
941cb0ef41Sopenharmony_ciminimatch.filter = filter;
951cb0ef41Sopenharmony_ciconst ext = (a, b = {}) => Object.assign({}, a, b);
961cb0ef41Sopenharmony_ciexport const defaults = (def) => {
971cb0ef41Sopenharmony_ci    if (!def || typeof def !== 'object' || !Object.keys(def).length) {
981cb0ef41Sopenharmony_ci        return minimatch;
991cb0ef41Sopenharmony_ci    }
1001cb0ef41Sopenharmony_ci    const orig = minimatch;
1011cb0ef41Sopenharmony_ci    const m = (p, pattern, options = {}) => orig(p, pattern, ext(def, options));
1021cb0ef41Sopenharmony_ci    return Object.assign(m, {
1031cb0ef41Sopenharmony_ci        Minimatch: class Minimatch extends orig.Minimatch {
1041cb0ef41Sopenharmony_ci            constructor(pattern, options = {}) {
1051cb0ef41Sopenharmony_ci                super(pattern, ext(def, options));
1061cb0ef41Sopenharmony_ci            }
1071cb0ef41Sopenharmony_ci            static defaults(options) {
1081cb0ef41Sopenharmony_ci                return orig.defaults(ext(def, options)).Minimatch;
1091cb0ef41Sopenharmony_ci            }
1101cb0ef41Sopenharmony_ci        },
1111cb0ef41Sopenharmony_ci        AST: class AST extends orig.AST {
1121cb0ef41Sopenharmony_ci            /* c8 ignore start */
1131cb0ef41Sopenharmony_ci            constructor(type, parent, options = {}) {
1141cb0ef41Sopenharmony_ci                super(type, parent, ext(def, options));
1151cb0ef41Sopenharmony_ci            }
1161cb0ef41Sopenharmony_ci            /* c8 ignore stop */
1171cb0ef41Sopenharmony_ci            static fromGlob(pattern, options = {}) {
1181cb0ef41Sopenharmony_ci                return orig.AST.fromGlob(pattern, ext(def, options));
1191cb0ef41Sopenharmony_ci            }
1201cb0ef41Sopenharmony_ci        },
1211cb0ef41Sopenharmony_ci        unescape: (s, options = {}) => orig.unescape(s, ext(def, options)),
1221cb0ef41Sopenharmony_ci        escape: (s, options = {}) => orig.escape(s, ext(def, options)),
1231cb0ef41Sopenharmony_ci        filter: (pattern, options = {}) => orig.filter(pattern, ext(def, options)),
1241cb0ef41Sopenharmony_ci        defaults: (options) => orig.defaults(ext(def, options)),
1251cb0ef41Sopenharmony_ci        makeRe: (pattern, options = {}) => orig.makeRe(pattern, ext(def, options)),
1261cb0ef41Sopenharmony_ci        braceExpand: (pattern, options = {}) => orig.braceExpand(pattern, ext(def, options)),
1271cb0ef41Sopenharmony_ci        match: (list, pattern, options = {}) => orig.match(list, pattern, ext(def, options)),
1281cb0ef41Sopenharmony_ci        sep: orig.sep,
1291cb0ef41Sopenharmony_ci        GLOBSTAR: GLOBSTAR,
1301cb0ef41Sopenharmony_ci    });
1311cb0ef41Sopenharmony_ci};
1321cb0ef41Sopenharmony_ciminimatch.defaults = defaults;
1331cb0ef41Sopenharmony_ci// Brace expansion:
1341cb0ef41Sopenharmony_ci// a{b,c}d -> abd acd
1351cb0ef41Sopenharmony_ci// a{b,}c -> abc ac
1361cb0ef41Sopenharmony_ci// a{0..3}d -> a0d a1d a2d a3d
1371cb0ef41Sopenharmony_ci// a{b,c{d,e}f}g -> abg acdfg acefg
1381cb0ef41Sopenharmony_ci// a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg
1391cb0ef41Sopenharmony_ci//
1401cb0ef41Sopenharmony_ci// Invalid sets are not expanded.
1411cb0ef41Sopenharmony_ci// a{2..}b -> a{2..}b
1421cb0ef41Sopenharmony_ci// a{b}c -> a{b}c
1431cb0ef41Sopenharmony_ciexport const braceExpand = (pattern, options = {}) => {
1441cb0ef41Sopenharmony_ci    assertValidPattern(pattern);
1451cb0ef41Sopenharmony_ci    // Thanks to Yeting Li <https://github.com/yetingli> for
1461cb0ef41Sopenharmony_ci    // improving this regexp to avoid a ReDOS vulnerability.
1471cb0ef41Sopenharmony_ci    if (options.nobrace || !/\{(?:(?!\{).)*\}/.test(pattern)) {
1481cb0ef41Sopenharmony_ci        // shortcut. no need to expand.
1491cb0ef41Sopenharmony_ci        return [pattern];
1501cb0ef41Sopenharmony_ci    }
1511cb0ef41Sopenharmony_ci    return expand(pattern);
1521cb0ef41Sopenharmony_ci};
1531cb0ef41Sopenharmony_ciminimatch.braceExpand = braceExpand;
1541cb0ef41Sopenharmony_ci// parse a component of the expanded set.
1551cb0ef41Sopenharmony_ci// At this point, no pattern may contain "/" in it
1561cb0ef41Sopenharmony_ci// so we're going to return a 2d array, where each entry is the full
1571cb0ef41Sopenharmony_ci// pattern, split on '/', and then turned into a regular expression.
1581cb0ef41Sopenharmony_ci// A regexp is made at the end which joins each array with an
1591cb0ef41Sopenharmony_ci// escaped /, and another full one which joins each regexp with |.
1601cb0ef41Sopenharmony_ci//
1611cb0ef41Sopenharmony_ci// Following the lead of Bash 4.1, note that "**" only has special meaning
1621cb0ef41Sopenharmony_ci// when it is the *only* thing in a path portion.  Otherwise, any series
1631cb0ef41Sopenharmony_ci// of * is equivalent to a single *.  Globstar behavior is enabled by
1641cb0ef41Sopenharmony_ci// default, and can be disabled by setting options.noglobstar.
1651cb0ef41Sopenharmony_ciexport const makeRe = (pattern, options = {}) => new Minimatch(pattern, options).makeRe();
1661cb0ef41Sopenharmony_ciminimatch.makeRe = makeRe;
1671cb0ef41Sopenharmony_ciexport const match = (list, pattern, options = {}) => {
1681cb0ef41Sopenharmony_ci    const mm = new Minimatch(pattern, options);
1691cb0ef41Sopenharmony_ci    list = list.filter(f => mm.match(f));
1701cb0ef41Sopenharmony_ci    if (mm.options.nonull && !list.length) {
1711cb0ef41Sopenharmony_ci        list.push(pattern);
1721cb0ef41Sopenharmony_ci    }
1731cb0ef41Sopenharmony_ci    return list;
1741cb0ef41Sopenharmony_ci};
1751cb0ef41Sopenharmony_ciminimatch.match = match;
1761cb0ef41Sopenharmony_ci// replace stuff like \* with *
1771cb0ef41Sopenharmony_ciconst globMagic = /[?*]|[+@!]\(.*?\)|\[|\]/;
1781cb0ef41Sopenharmony_ciconst regExpEscape = (s) => s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
1791cb0ef41Sopenharmony_ciexport class Minimatch {
1801cb0ef41Sopenharmony_ci    options;
1811cb0ef41Sopenharmony_ci    set;
1821cb0ef41Sopenharmony_ci    pattern;
1831cb0ef41Sopenharmony_ci    windowsPathsNoEscape;
1841cb0ef41Sopenharmony_ci    nonegate;
1851cb0ef41Sopenharmony_ci    negate;
1861cb0ef41Sopenharmony_ci    comment;
1871cb0ef41Sopenharmony_ci    empty;
1881cb0ef41Sopenharmony_ci    preserveMultipleSlashes;
1891cb0ef41Sopenharmony_ci    partial;
1901cb0ef41Sopenharmony_ci    globSet;
1911cb0ef41Sopenharmony_ci    globParts;
1921cb0ef41Sopenharmony_ci    nocase;
1931cb0ef41Sopenharmony_ci    isWindows;
1941cb0ef41Sopenharmony_ci    platform;
1951cb0ef41Sopenharmony_ci    windowsNoMagicRoot;
1961cb0ef41Sopenharmony_ci    regexp;
1971cb0ef41Sopenharmony_ci    constructor(pattern, options = {}) {
1981cb0ef41Sopenharmony_ci        assertValidPattern(pattern);
1991cb0ef41Sopenharmony_ci        options = options || {};
2001cb0ef41Sopenharmony_ci        this.options = options;
2011cb0ef41Sopenharmony_ci        this.pattern = pattern;
2021cb0ef41Sopenharmony_ci        this.platform = options.platform || defaultPlatform;
2031cb0ef41Sopenharmony_ci        this.isWindows = this.platform === 'win32';
2041cb0ef41Sopenharmony_ci        this.windowsPathsNoEscape =
2051cb0ef41Sopenharmony_ci            !!options.windowsPathsNoEscape || options.allowWindowsEscape === false;
2061cb0ef41Sopenharmony_ci        if (this.windowsPathsNoEscape) {
2071cb0ef41Sopenharmony_ci            this.pattern = this.pattern.replace(/\\/g, '/');
2081cb0ef41Sopenharmony_ci        }
2091cb0ef41Sopenharmony_ci        this.preserveMultipleSlashes = !!options.preserveMultipleSlashes;
2101cb0ef41Sopenharmony_ci        this.regexp = null;
2111cb0ef41Sopenharmony_ci        this.negate = false;
2121cb0ef41Sopenharmony_ci        this.nonegate = !!options.nonegate;
2131cb0ef41Sopenharmony_ci        this.comment = false;
2141cb0ef41Sopenharmony_ci        this.empty = false;
2151cb0ef41Sopenharmony_ci        this.partial = !!options.partial;
2161cb0ef41Sopenharmony_ci        this.nocase = !!this.options.nocase;
2171cb0ef41Sopenharmony_ci        this.windowsNoMagicRoot =
2181cb0ef41Sopenharmony_ci            options.windowsNoMagicRoot !== undefined
2191cb0ef41Sopenharmony_ci                ? options.windowsNoMagicRoot
2201cb0ef41Sopenharmony_ci                : !!(this.isWindows && this.nocase);
2211cb0ef41Sopenharmony_ci        this.globSet = [];
2221cb0ef41Sopenharmony_ci        this.globParts = [];
2231cb0ef41Sopenharmony_ci        this.set = [];
2241cb0ef41Sopenharmony_ci        // make the set of regexps etc.
2251cb0ef41Sopenharmony_ci        this.make();
2261cb0ef41Sopenharmony_ci    }
2271cb0ef41Sopenharmony_ci    hasMagic() {
2281cb0ef41Sopenharmony_ci        if (this.options.magicalBraces && this.set.length > 1) {
2291cb0ef41Sopenharmony_ci            return true;
2301cb0ef41Sopenharmony_ci        }
2311cb0ef41Sopenharmony_ci        for (const pattern of this.set) {
2321cb0ef41Sopenharmony_ci            for (const part of pattern) {
2331cb0ef41Sopenharmony_ci                if (typeof part !== 'string')
2341cb0ef41Sopenharmony_ci                    return true;
2351cb0ef41Sopenharmony_ci            }
2361cb0ef41Sopenharmony_ci        }
2371cb0ef41Sopenharmony_ci        return false;
2381cb0ef41Sopenharmony_ci    }
2391cb0ef41Sopenharmony_ci    debug(..._) { }
2401cb0ef41Sopenharmony_ci    make() {
2411cb0ef41Sopenharmony_ci        const pattern = this.pattern;
2421cb0ef41Sopenharmony_ci        const options = this.options;
2431cb0ef41Sopenharmony_ci        // empty patterns and comments match nothing.
2441cb0ef41Sopenharmony_ci        if (!options.nocomment && pattern.charAt(0) === '#') {
2451cb0ef41Sopenharmony_ci            this.comment = true;
2461cb0ef41Sopenharmony_ci            return;
2471cb0ef41Sopenharmony_ci        }
2481cb0ef41Sopenharmony_ci        if (!pattern) {
2491cb0ef41Sopenharmony_ci            this.empty = true;
2501cb0ef41Sopenharmony_ci            return;
2511cb0ef41Sopenharmony_ci        }
2521cb0ef41Sopenharmony_ci        // step 1: figure out negation, etc.
2531cb0ef41Sopenharmony_ci        this.parseNegate();
2541cb0ef41Sopenharmony_ci        // step 2: expand braces
2551cb0ef41Sopenharmony_ci        this.globSet = [...new Set(this.braceExpand())];
2561cb0ef41Sopenharmony_ci        if (options.debug) {
2571cb0ef41Sopenharmony_ci            this.debug = (...args) => console.error(...args);
2581cb0ef41Sopenharmony_ci        }
2591cb0ef41Sopenharmony_ci        this.debug(this.pattern, this.globSet);
2601cb0ef41Sopenharmony_ci        // step 3: now we have a set, so turn each one into a series of
2611cb0ef41Sopenharmony_ci        // path-portion matching patterns.
2621cb0ef41Sopenharmony_ci        // These will be regexps, except in the case of "**", which is
2631cb0ef41Sopenharmony_ci        // set to the GLOBSTAR object for globstar behavior,
2641cb0ef41Sopenharmony_ci        // and will not contain any / characters
2651cb0ef41Sopenharmony_ci        //
2661cb0ef41Sopenharmony_ci        // First, we preprocess to make the glob pattern sets a bit simpler
2671cb0ef41Sopenharmony_ci        // and deduped.  There are some perf-killing patterns that can cause
2681cb0ef41Sopenharmony_ci        // problems with a glob walk, but we can simplify them down a bit.
2691cb0ef41Sopenharmony_ci        const rawGlobParts = this.globSet.map(s => this.slashSplit(s));
2701cb0ef41Sopenharmony_ci        this.globParts = this.preprocess(rawGlobParts);
2711cb0ef41Sopenharmony_ci        this.debug(this.pattern, this.globParts);
2721cb0ef41Sopenharmony_ci        // glob --> regexps
2731cb0ef41Sopenharmony_ci        let set = this.globParts.map((s, _, __) => {
2741cb0ef41Sopenharmony_ci            if (this.isWindows && this.windowsNoMagicRoot) {
2751cb0ef41Sopenharmony_ci                // check if it's a drive or unc path.
2761cb0ef41Sopenharmony_ci                const isUNC = s[0] === '' &&
2771cb0ef41Sopenharmony_ci                    s[1] === '' &&
2781cb0ef41Sopenharmony_ci                    (s[2] === '?' || !globMagic.test(s[2])) &&
2791cb0ef41Sopenharmony_ci                    !globMagic.test(s[3]);
2801cb0ef41Sopenharmony_ci                const isDrive = /^[a-z]:/i.test(s[0]);
2811cb0ef41Sopenharmony_ci                if (isUNC) {
2821cb0ef41Sopenharmony_ci                    return [...s.slice(0, 4), ...s.slice(4).map(ss => this.parse(ss))];
2831cb0ef41Sopenharmony_ci                }
2841cb0ef41Sopenharmony_ci                else if (isDrive) {
2851cb0ef41Sopenharmony_ci                    return [s[0], ...s.slice(1).map(ss => this.parse(ss))];
2861cb0ef41Sopenharmony_ci                }
2871cb0ef41Sopenharmony_ci            }
2881cb0ef41Sopenharmony_ci            return s.map(ss => this.parse(ss));
2891cb0ef41Sopenharmony_ci        });
2901cb0ef41Sopenharmony_ci        this.debug(this.pattern, set);
2911cb0ef41Sopenharmony_ci        // filter out everything that didn't compile properly.
2921cb0ef41Sopenharmony_ci        this.set = set.filter(s => s.indexOf(false) === -1);
2931cb0ef41Sopenharmony_ci        // do not treat the ? in UNC paths as magic
2941cb0ef41Sopenharmony_ci        if (this.isWindows) {
2951cb0ef41Sopenharmony_ci            for (let i = 0; i < this.set.length; i++) {
2961cb0ef41Sopenharmony_ci                const p = this.set[i];
2971cb0ef41Sopenharmony_ci                if (p[0] === '' &&
2981cb0ef41Sopenharmony_ci                    p[1] === '' &&
2991cb0ef41Sopenharmony_ci                    this.globParts[i][2] === '?' &&
3001cb0ef41Sopenharmony_ci                    typeof p[3] === 'string' &&
3011cb0ef41Sopenharmony_ci                    /^[a-z]:$/i.test(p[3])) {
3021cb0ef41Sopenharmony_ci                    p[2] = '?';
3031cb0ef41Sopenharmony_ci                }
3041cb0ef41Sopenharmony_ci            }
3051cb0ef41Sopenharmony_ci        }
3061cb0ef41Sopenharmony_ci        this.debug(this.pattern, this.set);
3071cb0ef41Sopenharmony_ci    }
3081cb0ef41Sopenharmony_ci    // various transforms to equivalent pattern sets that are
3091cb0ef41Sopenharmony_ci    // faster to process in a filesystem walk.  The goal is to
3101cb0ef41Sopenharmony_ci    // eliminate what we can, and push all ** patterns as far
3111cb0ef41Sopenharmony_ci    // to the right as possible, even if it increases the number
3121cb0ef41Sopenharmony_ci    // of patterns that we have to process.
3131cb0ef41Sopenharmony_ci    preprocess(globParts) {
3141cb0ef41Sopenharmony_ci        // if we're not in globstar mode, then turn all ** into *
3151cb0ef41Sopenharmony_ci        if (this.options.noglobstar) {
3161cb0ef41Sopenharmony_ci            for (let i = 0; i < globParts.length; i++) {
3171cb0ef41Sopenharmony_ci                for (let j = 0; j < globParts[i].length; j++) {
3181cb0ef41Sopenharmony_ci                    if (globParts[i][j] === '**') {
3191cb0ef41Sopenharmony_ci                        globParts[i][j] = '*';
3201cb0ef41Sopenharmony_ci                    }
3211cb0ef41Sopenharmony_ci                }
3221cb0ef41Sopenharmony_ci            }
3231cb0ef41Sopenharmony_ci        }
3241cb0ef41Sopenharmony_ci        const { optimizationLevel = 1 } = this.options;
3251cb0ef41Sopenharmony_ci        if (optimizationLevel >= 2) {
3261cb0ef41Sopenharmony_ci            // aggressive optimization for the purpose of fs walking
3271cb0ef41Sopenharmony_ci            globParts = this.firstPhasePreProcess(globParts);
3281cb0ef41Sopenharmony_ci            globParts = this.secondPhasePreProcess(globParts);
3291cb0ef41Sopenharmony_ci        }
3301cb0ef41Sopenharmony_ci        else if (optimizationLevel >= 1) {
3311cb0ef41Sopenharmony_ci            // just basic optimizations to remove some .. parts
3321cb0ef41Sopenharmony_ci            globParts = this.levelOneOptimize(globParts);
3331cb0ef41Sopenharmony_ci        }
3341cb0ef41Sopenharmony_ci        else {
3351cb0ef41Sopenharmony_ci            globParts = this.adjascentGlobstarOptimize(globParts);
3361cb0ef41Sopenharmony_ci        }
3371cb0ef41Sopenharmony_ci        return globParts;
3381cb0ef41Sopenharmony_ci    }
3391cb0ef41Sopenharmony_ci    // just get rid of adjascent ** portions
3401cb0ef41Sopenharmony_ci    adjascentGlobstarOptimize(globParts) {
3411cb0ef41Sopenharmony_ci        return globParts.map(parts => {
3421cb0ef41Sopenharmony_ci            let gs = -1;
3431cb0ef41Sopenharmony_ci            while (-1 !== (gs = parts.indexOf('**', gs + 1))) {
3441cb0ef41Sopenharmony_ci                let i = gs;
3451cb0ef41Sopenharmony_ci                while (parts[i + 1] === '**') {
3461cb0ef41Sopenharmony_ci                    i++;
3471cb0ef41Sopenharmony_ci                }
3481cb0ef41Sopenharmony_ci                if (i !== gs) {
3491cb0ef41Sopenharmony_ci                    parts.splice(gs, i - gs);
3501cb0ef41Sopenharmony_ci                }
3511cb0ef41Sopenharmony_ci            }
3521cb0ef41Sopenharmony_ci            return parts;
3531cb0ef41Sopenharmony_ci        });
3541cb0ef41Sopenharmony_ci    }
3551cb0ef41Sopenharmony_ci    // get rid of adjascent ** and resolve .. portions
3561cb0ef41Sopenharmony_ci    levelOneOptimize(globParts) {
3571cb0ef41Sopenharmony_ci        return globParts.map(parts => {
3581cb0ef41Sopenharmony_ci            parts = parts.reduce((set, part) => {
3591cb0ef41Sopenharmony_ci                const prev = set[set.length - 1];
3601cb0ef41Sopenharmony_ci                if (part === '**' && prev === '**') {
3611cb0ef41Sopenharmony_ci                    return set;
3621cb0ef41Sopenharmony_ci                }
3631cb0ef41Sopenharmony_ci                if (part === '..') {
3641cb0ef41Sopenharmony_ci                    if (prev && prev !== '..' && prev !== '.' && prev !== '**') {
3651cb0ef41Sopenharmony_ci                        set.pop();
3661cb0ef41Sopenharmony_ci                        return set;
3671cb0ef41Sopenharmony_ci                    }
3681cb0ef41Sopenharmony_ci                }
3691cb0ef41Sopenharmony_ci                set.push(part);
3701cb0ef41Sopenharmony_ci                return set;
3711cb0ef41Sopenharmony_ci            }, []);
3721cb0ef41Sopenharmony_ci            return parts.length === 0 ? [''] : parts;
3731cb0ef41Sopenharmony_ci        });
3741cb0ef41Sopenharmony_ci    }
3751cb0ef41Sopenharmony_ci    levelTwoFileOptimize(parts) {
3761cb0ef41Sopenharmony_ci        if (!Array.isArray(parts)) {
3771cb0ef41Sopenharmony_ci            parts = this.slashSplit(parts);
3781cb0ef41Sopenharmony_ci        }
3791cb0ef41Sopenharmony_ci        let didSomething = false;
3801cb0ef41Sopenharmony_ci        do {
3811cb0ef41Sopenharmony_ci            didSomething = false;
3821cb0ef41Sopenharmony_ci            // <pre>/<e>/<rest> -> <pre>/<rest>
3831cb0ef41Sopenharmony_ci            if (!this.preserveMultipleSlashes) {
3841cb0ef41Sopenharmony_ci                for (let i = 1; i < parts.length - 1; i++) {
3851cb0ef41Sopenharmony_ci                    const p = parts[i];
3861cb0ef41Sopenharmony_ci                    // don't squeeze out UNC patterns
3871cb0ef41Sopenharmony_ci                    if (i === 1 && p === '' && parts[0] === '')
3881cb0ef41Sopenharmony_ci                        continue;
3891cb0ef41Sopenharmony_ci                    if (p === '.' || p === '') {
3901cb0ef41Sopenharmony_ci                        didSomething = true;
3911cb0ef41Sopenharmony_ci                        parts.splice(i, 1);
3921cb0ef41Sopenharmony_ci                        i--;
3931cb0ef41Sopenharmony_ci                    }
3941cb0ef41Sopenharmony_ci                }
3951cb0ef41Sopenharmony_ci                if (parts[0] === '.' &&
3961cb0ef41Sopenharmony_ci                    parts.length === 2 &&
3971cb0ef41Sopenharmony_ci                    (parts[1] === '.' || parts[1] === '')) {
3981cb0ef41Sopenharmony_ci                    didSomething = true;
3991cb0ef41Sopenharmony_ci                    parts.pop();
4001cb0ef41Sopenharmony_ci                }
4011cb0ef41Sopenharmony_ci            }
4021cb0ef41Sopenharmony_ci            // <pre>/<p>/../<rest> -> <pre>/<rest>
4031cb0ef41Sopenharmony_ci            let dd = 0;
4041cb0ef41Sopenharmony_ci            while (-1 !== (dd = parts.indexOf('..', dd + 1))) {
4051cb0ef41Sopenharmony_ci                const p = parts[dd - 1];
4061cb0ef41Sopenharmony_ci                if (p && p !== '.' && p !== '..' && p !== '**') {
4071cb0ef41Sopenharmony_ci                    didSomething = true;
4081cb0ef41Sopenharmony_ci                    parts.splice(dd - 1, 2);
4091cb0ef41Sopenharmony_ci                    dd -= 2;
4101cb0ef41Sopenharmony_ci                }
4111cb0ef41Sopenharmony_ci            }
4121cb0ef41Sopenharmony_ci        } while (didSomething);
4131cb0ef41Sopenharmony_ci        return parts.length === 0 ? [''] : parts;
4141cb0ef41Sopenharmony_ci    }
4151cb0ef41Sopenharmony_ci    // First phase: single-pattern processing
4161cb0ef41Sopenharmony_ci    // <pre> is 1 or more portions
4171cb0ef41Sopenharmony_ci    // <rest> is 1 or more portions
4181cb0ef41Sopenharmony_ci    // <p> is any portion other than ., .., '', or **
4191cb0ef41Sopenharmony_ci    // <e> is . or ''
4201cb0ef41Sopenharmony_ci    //
4211cb0ef41Sopenharmony_ci    // **/.. is *brutal* for filesystem walking performance, because
4221cb0ef41Sopenharmony_ci    // it effectively resets the recursive walk each time it occurs,
4231cb0ef41Sopenharmony_ci    // and ** cannot be reduced out by a .. pattern part like a regexp
4241cb0ef41Sopenharmony_ci    // or most strings (other than .., ., and '') can be.
4251cb0ef41Sopenharmony_ci    //
4261cb0ef41Sopenharmony_ci    // <pre>/**/../<p>/<p>/<rest> -> {<pre>/../<p>/<p>/<rest>,<pre>/**/<p>/<p>/<rest>}
4271cb0ef41Sopenharmony_ci    // <pre>/<e>/<rest> -> <pre>/<rest>
4281cb0ef41Sopenharmony_ci    // <pre>/<p>/../<rest> -> <pre>/<rest>
4291cb0ef41Sopenharmony_ci    // **/**/<rest> -> **/<rest>
4301cb0ef41Sopenharmony_ci    //
4311cb0ef41Sopenharmony_ci    // **/*/<rest> -> */**/<rest> <== not valid because ** doesn't follow
4321cb0ef41Sopenharmony_ci    // this WOULD be allowed if ** did follow symlinks, or * didn't
4331cb0ef41Sopenharmony_ci    firstPhasePreProcess(globParts) {
4341cb0ef41Sopenharmony_ci        let didSomething = false;
4351cb0ef41Sopenharmony_ci        do {
4361cb0ef41Sopenharmony_ci            didSomething = false;
4371cb0ef41Sopenharmony_ci            // <pre>/**/../<p>/<p>/<rest> -> {<pre>/../<p>/<p>/<rest>,<pre>/**/<p>/<p>/<rest>}
4381cb0ef41Sopenharmony_ci            for (let parts of globParts) {
4391cb0ef41Sopenharmony_ci                let gs = -1;
4401cb0ef41Sopenharmony_ci                while (-1 !== (gs = parts.indexOf('**', gs + 1))) {
4411cb0ef41Sopenharmony_ci                    let gss = gs;
4421cb0ef41Sopenharmony_ci                    while (parts[gss + 1] === '**') {
4431cb0ef41Sopenharmony_ci                        // <pre>/**/**/<rest> -> <pre>/**/<rest>
4441cb0ef41Sopenharmony_ci                        gss++;
4451cb0ef41Sopenharmony_ci                    }
4461cb0ef41Sopenharmony_ci                    // eg, if gs is 2 and gss is 4, that means we have 3 **
4471cb0ef41Sopenharmony_ci                    // parts, and can remove 2 of them.
4481cb0ef41Sopenharmony_ci                    if (gss > gs) {
4491cb0ef41Sopenharmony_ci                        parts.splice(gs + 1, gss - gs);
4501cb0ef41Sopenharmony_ci                    }
4511cb0ef41Sopenharmony_ci                    let next = parts[gs + 1];
4521cb0ef41Sopenharmony_ci                    const p = parts[gs + 2];
4531cb0ef41Sopenharmony_ci                    const p2 = parts[gs + 3];
4541cb0ef41Sopenharmony_ci                    if (next !== '..')
4551cb0ef41Sopenharmony_ci                        continue;
4561cb0ef41Sopenharmony_ci                    if (!p ||
4571cb0ef41Sopenharmony_ci                        p === '.' ||
4581cb0ef41Sopenharmony_ci                        p === '..' ||
4591cb0ef41Sopenharmony_ci                        !p2 ||
4601cb0ef41Sopenharmony_ci                        p2 === '.' ||
4611cb0ef41Sopenharmony_ci                        p2 === '..') {
4621cb0ef41Sopenharmony_ci                        continue;
4631cb0ef41Sopenharmony_ci                    }
4641cb0ef41Sopenharmony_ci                    didSomething = true;
4651cb0ef41Sopenharmony_ci                    // edit parts in place, and push the new one
4661cb0ef41Sopenharmony_ci                    parts.splice(gs, 1);
4671cb0ef41Sopenharmony_ci                    const other = parts.slice(0);
4681cb0ef41Sopenharmony_ci                    other[gs] = '**';
4691cb0ef41Sopenharmony_ci                    globParts.push(other);
4701cb0ef41Sopenharmony_ci                    gs--;
4711cb0ef41Sopenharmony_ci                }
4721cb0ef41Sopenharmony_ci                // <pre>/<e>/<rest> -> <pre>/<rest>
4731cb0ef41Sopenharmony_ci                if (!this.preserveMultipleSlashes) {
4741cb0ef41Sopenharmony_ci                    for (let i = 1; i < parts.length - 1; i++) {
4751cb0ef41Sopenharmony_ci                        const p = parts[i];
4761cb0ef41Sopenharmony_ci                        // don't squeeze out UNC patterns
4771cb0ef41Sopenharmony_ci                        if (i === 1 && p === '' && parts[0] === '')
4781cb0ef41Sopenharmony_ci                            continue;
4791cb0ef41Sopenharmony_ci                        if (p === '.' || p === '') {
4801cb0ef41Sopenharmony_ci                            didSomething = true;
4811cb0ef41Sopenharmony_ci                            parts.splice(i, 1);
4821cb0ef41Sopenharmony_ci                            i--;
4831cb0ef41Sopenharmony_ci                        }
4841cb0ef41Sopenharmony_ci                    }
4851cb0ef41Sopenharmony_ci                    if (parts[0] === '.' &&
4861cb0ef41Sopenharmony_ci                        parts.length === 2 &&
4871cb0ef41Sopenharmony_ci                        (parts[1] === '.' || parts[1] === '')) {
4881cb0ef41Sopenharmony_ci                        didSomething = true;
4891cb0ef41Sopenharmony_ci                        parts.pop();
4901cb0ef41Sopenharmony_ci                    }
4911cb0ef41Sopenharmony_ci                }
4921cb0ef41Sopenharmony_ci                // <pre>/<p>/../<rest> -> <pre>/<rest>
4931cb0ef41Sopenharmony_ci                let dd = 0;
4941cb0ef41Sopenharmony_ci                while (-1 !== (dd = parts.indexOf('..', dd + 1))) {
4951cb0ef41Sopenharmony_ci                    const p = parts[dd - 1];
4961cb0ef41Sopenharmony_ci                    if (p && p !== '.' && p !== '..' && p !== '**') {
4971cb0ef41Sopenharmony_ci                        didSomething = true;
4981cb0ef41Sopenharmony_ci                        const needDot = dd === 1 && parts[dd + 1] === '**';
4991cb0ef41Sopenharmony_ci                        const splin = needDot ? ['.'] : [];
5001cb0ef41Sopenharmony_ci                        parts.splice(dd - 1, 2, ...splin);
5011cb0ef41Sopenharmony_ci                        if (parts.length === 0)
5021cb0ef41Sopenharmony_ci                            parts.push('');
5031cb0ef41Sopenharmony_ci                        dd -= 2;
5041cb0ef41Sopenharmony_ci                    }
5051cb0ef41Sopenharmony_ci                }
5061cb0ef41Sopenharmony_ci            }
5071cb0ef41Sopenharmony_ci        } while (didSomething);
5081cb0ef41Sopenharmony_ci        return globParts;
5091cb0ef41Sopenharmony_ci    }
5101cb0ef41Sopenharmony_ci    // second phase: multi-pattern dedupes
5111cb0ef41Sopenharmony_ci    // {<pre>/*/<rest>,<pre>/<p>/<rest>} -> <pre>/*/<rest>
5121cb0ef41Sopenharmony_ci    // {<pre>/<rest>,<pre>/<rest>} -> <pre>/<rest>
5131cb0ef41Sopenharmony_ci    // {<pre>/**/<rest>,<pre>/<rest>} -> <pre>/**/<rest>
5141cb0ef41Sopenharmony_ci    //
5151cb0ef41Sopenharmony_ci    // {<pre>/**/<rest>,<pre>/**/<p>/<rest>} -> <pre>/**/<rest>
5161cb0ef41Sopenharmony_ci    // ^-- not valid because ** doens't follow symlinks
5171cb0ef41Sopenharmony_ci    secondPhasePreProcess(globParts) {
5181cb0ef41Sopenharmony_ci        for (let i = 0; i < globParts.length - 1; i++) {
5191cb0ef41Sopenharmony_ci            for (let j = i + 1; j < globParts.length; j++) {
5201cb0ef41Sopenharmony_ci                const matched = this.partsMatch(globParts[i], globParts[j], !this.preserveMultipleSlashes);
5211cb0ef41Sopenharmony_ci                if (!matched)
5221cb0ef41Sopenharmony_ci                    continue;
5231cb0ef41Sopenharmony_ci                globParts[i] = matched;
5241cb0ef41Sopenharmony_ci                globParts[j] = [];
5251cb0ef41Sopenharmony_ci            }
5261cb0ef41Sopenharmony_ci        }
5271cb0ef41Sopenharmony_ci        return globParts.filter(gs => gs.length);
5281cb0ef41Sopenharmony_ci    }
5291cb0ef41Sopenharmony_ci    partsMatch(a, b, emptyGSMatch = false) {
5301cb0ef41Sopenharmony_ci        let ai = 0;
5311cb0ef41Sopenharmony_ci        let bi = 0;
5321cb0ef41Sopenharmony_ci        let result = [];
5331cb0ef41Sopenharmony_ci        let which = '';
5341cb0ef41Sopenharmony_ci        while (ai < a.length && bi < b.length) {
5351cb0ef41Sopenharmony_ci            if (a[ai] === b[bi]) {
5361cb0ef41Sopenharmony_ci                result.push(which === 'b' ? b[bi] : a[ai]);
5371cb0ef41Sopenharmony_ci                ai++;
5381cb0ef41Sopenharmony_ci                bi++;
5391cb0ef41Sopenharmony_ci            }
5401cb0ef41Sopenharmony_ci            else if (emptyGSMatch && a[ai] === '**' && b[bi] === a[ai + 1]) {
5411cb0ef41Sopenharmony_ci                result.push(a[ai]);
5421cb0ef41Sopenharmony_ci                ai++;
5431cb0ef41Sopenharmony_ci            }
5441cb0ef41Sopenharmony_ci            else if (emptyGSMatch && b[bi] === '**' && a[ai] === b[bi + 1]) {
5451cb0ef41Sopenharmony_ci                result.push(b[bi]);
5461cb0ef41Sopenharmony_ci                bi++;
5471cb0ef41Sopenharmony_ci            }
5481cb0ef41Sopenharmony_ci            else if (a[ai] === '*' &&
5491cb0ef41Sopenharmony_ci                b[bi] &&
5501cb0ef41Sopenharmony_ci                (this.options.dot || !b[bi].startsWith('.')) &&
5511cb0ef41Sopenharmony_ci                b[bi] !== '**') {
5521cb0ef41Sopenharmony_ci                if (which === 'b')
5531cb0ef41Sopenharmony_ci                    return false;
5541cb0ef41Sopenharmony_ci                which = 'a';
5551cb0ef41Sopenharmony_ci                result.push(a[ai]);
5561cb0ef41Sopenharmony_ci                ai++;
5571cb0ef41Sopenharmony_ci                bi++;
5581cb0ef41Sopenharmony_ci            }
5591cb0ef41Sopenharmony_ci            else if (b[bi] === '*' &&
5601cb0ef41Sopenharmony_ci                a[ai] &&
5611cb0ef41Sopenharmony_ci                (this.options.dot || !a[ai].startsWith('.')) &&
5621cb0ef41Sopenharmony_ci                a[ai] !== '**') {
5631cb0ef41Sopenharmony_ci                if (which === 'a')
5641cb0ef41Sopenharmony_ci                    return false;
5651cb0ef41Sopenharmony_ci                which = 'b';
5661cb0ef41Sopenharmony_ci                result.push(b[bi]);
5671cb0ef41Sopenharmony_ci                ai++;
5681cb0ef41Sopenharmony_ci                bi++;
5691cb0ef41Sopenharmony_ci            }
5701cb0ef41Sopenharmony_ci            else {
5711cb0ef41Sopenharmony_ci                return false;
5721cb0ef41Sopenharmony_ci            }
5731cb0ef41Sopenharmony_ci        }
5741cb0ef41Sopenharmony_ci        // if we fall out of the loop, it means they two are identical
5751cb0ef41Sopenharmony_ci        // as long as their lengths match
5761cb0ef41Sopenharmony_ci        return a.length === b.length && result;
5771cb0ef41Sopenharmony_ci    }
5781cb0ef41Sopenharmony_ci    parseNegate() {
5791cb0ef41Sopenharmony_ci        if (this.nonegate)
5801cb0ef41Sopenharmony_ci            return;
5811cb0ef41Sopenharmony_ci        const pattern = this.pattern;
5821cb0ef41Sopenharmony_ci        let negate = false;
5831cb0ef41Sopenharmony_ci        let negateOffset = 0;
5841cb0ef41Sopenharmony_ci        for (let i = 0; i < pattern.length && pattern.charAt(i) === '!'; i++) {
5851cb0ef41Sopenharmony_ci            negate = !negate;
5861cb0ef41Sopenharmony_ci            negateOffset++;
5871cb0ef41Sopenharmony_ci        }
5881cb0ef41Sopenharmony_ci        if (negateOffset)
5891cb0ef41Sopenharmony_ci            this.pattern = pattern.slice(negateOffset);
5901cb0ef41Sopenharmony_ci        this.negate = negate;
5911cb0ef41Sopenharmony_ci    }
5921cb0ef41Sopenharmony_ci    // set partial to true to test if, for example,
5931cb0ef41Sopenharmony_ci    // "/a/b" matches the start of "/*/b/*/d"
5941cb0ef41Sopenharmony_ci    // Partial means, if you run out of file before you run
5951cb0ef41Sopenharmony_ci    // out of pattern, then that's fine, as long as all
5961cb0ef41Sopenharmony_ci    // the parts match.
5971cb0ef41Sopenharmony_ci    matchOne(file, pattern, partial = false) {
5981cb0ef41Sopenharmony_ci        const options = this.options;
5991cb0ef41Sopenharmony_ci        // UNC paths like //?/X:/... can match X:/... and vice versa
6001cb0ef41Sopenharmony_ci        // Drive letters in absolute drive or unc paths are always compared
6011cb0ef41Sopenharmony_ci        // case-insensitively.
6021cb0ef41Sopenharmony_ci        if (this.isWindows) {
6031cb0ef41Sopenharmony_ci            const fileDrive = typeof file[0] === 'string' && /^[a-z]:$/i.test(file[0]);
6041cb0ef41Sopenharmony_ci            const fileUNC = !fileDrive &&
6051cb0ef41Sopenharmony_ci                file[0] === '' &&
6061cb0ef41Sopenharmony_ci                file[1] === '' &&
6071cb0ef41Sopenharmony_ci                file[2] === '?' &&
6081cb0ef41Sopenharmony_ci                /^[a-z]:$/i.test(file[3]);
6091cb0ef41Sopenharmony_ci            const patternDrive = typeof pattern[0] === 'string' && /^[a-z]:$/i.test(pattern[0]);
6101cb0ef41Sopenharmony_ci            const patternUNC = !patternDrive &&
6111cb0ef41Sopenharmony_ci                pattern[0] === '' &&
6121cb0ef41Sopenharmony_ci                pattern[1] === '' &&
6131cb0ef41Sopenharmony_ci                pattern[2] === '?' &&
6141cb0ef41Sopenharmony_ci                typeof pattern[3] === 'string' &&
6151cb0ef41Sopenharmony_ci                /^[a-z]:$/i.test(pattern[3]);
6161cb0ef41Sopenharmony_ci            const fdi = fileUNC ? 3 : fileDrive ? 0 : undefined;
6171cb0ef41Sopenharmony_ci            const pdi = patternUNC ? 3 : patternDrive ? 0 : undefined;
6181cb0ef41Sopenharmony_ci            if (typeof fdi === 'number' && typeof pdi === 'number') {
6191cb0ef41Sopenharmony_ci                const [fd, pd] = [file[fdi], pattern[pdi]];
6201cb0ef41Sopenharmony_ci                if (fd.toLowerCase() === pd.toLowerCase()) {
6211cb0ef41Sopenharmony_ci                    pattern[pdi] = fd;
6221cb0ef41Sopenharmony_ci                    if (pdi > fdi) {
6231cb0ef41Sopenharmony_ci                        pattern = pattern.slice(pdi);
6241cb0ef41Sopenharmony_ci                    }
6251cb0ef41Sopenharmony_ci                    else if (fdi > pdi) {
6261cb0ef41Sopenharmony_ci                        file = file.slice(fdi);
6271cb0ef41Sopenharmony_ci                    }
6281cb0ef41Sopenharmony_ci                }
6291cb0ef41Sopenharmony_ci            }
6301cb0ef41Sopenharmony_ci        }
6311cb0ef41Sopenharmony_ci        // resolve and reduce . and .. portions in the file as well.
6321cb0ef41Sopenharmony_ci        // dont' need to do the second phase, because it's only one string[]
6331cb0ef41Sopenharmony_ci        const { optimizationLevel = 1 } = this.options;
6341cb0ef41Sopenharmony_ci        if (optimizationLevel >= 2) {
6351cb0ef41Sopenharmony_ci            file = this.levelTwoFileOptimize(file);
6361cb0ef41Sopenharmony_ci        }
6371cb0ef41Sopenharmony_ci        this.debug('matchOne', this, { file, pattern });
6381cb0ef41Sopenharmony_ci        this.debug('matchOne', file.length, pattern.length);
6391cb0ef41Sopenharmony_ci        for (var fi = 0, pi = 0, fl = file.length, pl = pattern.length; fi < fl && pi < pl; fi++, pi++) {
6401cb0ef41Sopenharmony_ci            this.debug('matchOne loop');
6411cb0ef41Sopenharmony_ci            var p = pattern[pi];
6421cb0ef41Sopenharmony_ci            var f = file[fi];
6431cb0ef41Sopenharmony_ci            this.debug(pattern, p, f);
6441cb0ef41Sopenharmony_ci            // should be impossible.
6451cb0ef41Sopenharmony_ci            // some invalid regexp stuff in the set.
6461cb0ef41Sopenharmony_ci            /* c8 ignore start */
6471cb0ef41Sopenharmony_ci            if (p === false) {
6481cb0ef41Sopenharmony_ci                return false;
6491cb0ef41Sopenharmony_ci            }
6501cb0ef41Sopenharmony_ci            /* c8 ignore stop */
6511cb0ef41Sopenharmony_ci            if (p === GLOBSTAR) {
6521cb0ef41Sopenharmony_ci                this.debug('GLOBSTAR', [pattern, p, f]);
6531cb0ef41Sopenharmony_ci                // "**"
6541cb0ef41Sopenharmony_ci                // a/**/b/**/c would match the following:
6551cb0ef41Sopenharmony_ci                // a/b/x/y/z/c
6561cb0ef41Sopenharmony_ci                // a/x/y/z/b/c
6571cb0ef41Sopenharmony_ci                // a/b/x/b/x/c
6581cb0ef41Sopenharmony_ci                // a/b/c
6591cb0ef41Sopenharmony_ci                // To do this, take the rest of the pattern after
6601cb0ef41Sopenharmony_ci                // the **, and see if it would match the file remainder.
6611cb0ef41Sopenharmony_ci                // If so, return success.
6621cb0ef41Sopenharmony_ci                // If not, the ** "swallows" a segment, and try again.
6631cb0ef41Sopenharmony_ci                // This is recursively awful.
6641cb0ef41Sopenharmony_ci                //
6651cb0ef41Sopenharmony_ci                // a/**/b/**/c matching a/b/x/y/z/c
6661cb0ef41Sopenharmony_ci                // - a matches a
6671cb0ef41Sopenharmony_ci                // - doublestar
6681cb0ef41Sopenharmony_ci                //   - matchOne(b/x/y/z/c, b/**/c)
6691cb0ef41Sopenharmony_ci                //     - b matches b
6701cb0ef41Sopenharmony_ci                //     - doublestar
6711cb0ef41Sopenharmony_ci                //       - matchOne(x/y/z/c, c) -> no
6721cb0ef41Sopenharmony_ci                //       - matchOne(y/z/c, c) -> no
6731cb0ef41Sopenharmony_ci                //       - matchOne(z/c, c) -> no
6741cb0ef41Sopenharmony_ci                //       - matchOne(c, c) yes, hit
6751cb0ef41Sopenharmony_ci                var fr = fi;
6761cb0ef41Sopenharmony_ci                var pr = pi + 1;
6771cb0ef41Sopenharmony_ci                if (pr === pl) {
6781cb0ef41Sopenharmony_ci                    this.debug('** at the end');
6791cb0ef41Sopenharmony_ci                    // a ** at the end will just swallow the rest.
6801cb0ef41Sopenharmony_ci                    // We have found a match.
6811cb0ef41Sopenharmony_ci                    // however, it will not swallow /.x, unless
6821cb0ef41Sopenharmony_ci                    // options.dot is set.
6831cb0ef41Sopenharmony_ci                    // . and .. are *never* matched by **, for explosively
6841cb0ef41Sopenharmony_ci                    // exponential reasons.
6851cb0ef41Sopenharmony_ci                    for (; fi < fl; fi++) {
6861cb0ef41Sopenharmony_ci                        if (file[fi] === '.' ||
6871cb0ef41Sopenharmony_ci                            file[fi] === '..' ||
6881cb0ef41Sopenharmony_ci                            (!options.dot && file[fi].charAt(0) === '.'))
6891cb0ef41Sopenharmony_ci                            return false;
6901cb0ef41Sopenharmony_ci                    }
6911cb0ef41Sopenharmony_ci                    return true;
6921cb0ef41Sopenharmony_ci                }
6931cb0ef41Sopenharmony_ci                // ok, let's see if we can swallow whatever we can.
6941cb0ef41Sopenharmony_ci                while (fr < fl) {
6951cb0ef41Sopenharmony_ci                    var swallowee = file[fr];
6961cb0ef41Sopenharmony_ci                    this.debug('\nglobstar while', file, fr, pattern, pr, swallowee);
6971cb0ef41Sopenharmony_ci                    // XXX remove this slice.  Just pass the start index.
6981cb0ef41Sopenharmony_ci                    if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) {
6991cb0ef41Sopenharmony_ci                        this.debug('globstar found match!', fr, fl, swallowee);
7001cb0ef41Sopenharmony_ci                        // found a match.
7011cb0ef41Sopenharmony_ci                        return true;
7021cb0ef41Sopenharmony_ci                    }
7031cb0ef41Sopenharmony_ci                    else {
7041cb0ef41Sopenharmony_ci                        // can't swallow "." or ".." ever.
7051cb0ef41Sopenharmony_ci                        // can only swallow ".foo" when explicitly asked.
7061cb0ef41Sopenharmony_ci                        if (swallowee === '.' ||
7071cb0ef41Sopenharmony_ci                            swallowee === '..' ||
7081cb0ef41Sopenharmony_ci                            (!options.dot && swallowee.charAt(0) === '.')) {
7091cb0ef41Sopenharmony_ci                            this.debug('dot detected!', file, fr, pattern, pr);
7101cb0ef41Sopenharmony_ci                            break;
7111cb0ef41Sopenharmony_ci                        }
7121cb0ef41Sopenharmony_ci                        // ** swallows a segment, and continue.
7131cb0ef41Sopenharmony_ci                        this.debug('globstar swallow a segment, and continue');
7141cb0ef41Sopenharmony_ci                        fr++;
7151cb0ef41Sopenharmony_ci                    }
7161cb0ef41Sopenharmony_ci                }
7171cb0ef41Sopenharmony_ci                // no match was found.
7181cb0ef41Sopenharmony_ci                // However, in partial mode, we can't say this is necessarily over.
7191cb0ef41Sopenharmony_ci                /* c8 ignore start */
7201cb0ef41Sopenharmony_ci                if (partial) {
7211cb0ef41Sopenharmony_ci                    // ran out of file
7221cb0ef41Sopenharmony_ci                    this.debug('\n>>> no match, partial?', file, fr, pattern, pr);
7231cb0ef41Sopenharmony_ci                    if (fr === fl) {
7241cb0ef41Sopenharmony_ci                        return true;
7251cb0ef41Sopenharmony_ci                    }
7261cb0ef41Sopenharmony_ci                }
7271cb0ef41Sopenharmony_ci                /* c8 ignore stop */
7281cb0ef41Sopenharmony_ci                return false;
7291cb0ef41Sopenharmony_ci            }
7301cb0ef41Sopenharmony_ci            // something other than **
7311cb0ef41Sopenharmony_ci            // non-magic patterns just have to match exactly
7321cb0ef41Sopenharmony_ci            // patterns with magic have been turned into regexps.
7331cb0ef41Sopenharmony_ci            let hit;
7341cb0ef41Sopenharmony_ci            if (typeof p === 'string') {
7351cb0ef41Sopenharmony_ci                hit = f === p;
7361cb0ef41Sopenharmony_ci                this.debug('string match', p, f, hit);
7371cb0ef41Sopenharmony_ci            }
7381cb0ef41Sopenharmony_ci            else {
7391cb0ef41Sopenharmony_ci                hit = p.test(f);
7401cb0ef41Sopenharmony_ci                this.debug('pattern match', p, f, hit);
7411cb0ef41Sopenharmony_ci            }
7421cb0ef41Sopenharmony_ci            if (!hit)
7431cb0ef41Sopenharmony_ci                return false;
7441cb0ef41Sopenharmony_ci        }
7451cb0ef41Sopenharmony_ci        // Note: ending in / means that we'll get a final ""
7461cb0ef41Sopenharmony_ci        // at the end of the pattern.  This can only match a
7471cb0ef41Sopenharmony_ci        // corresponding "" at the end of the file.
7481cb0ef41Sopenharmony_ci        // If the file ends in /, then it can only match a
7491cb0ef41Sopenharmony_ci        // a pattern that ends in /, unless the pattern just
7501cb0ef41Sopenharmony_ci        // doesn't have any more for it. But, a/b/ should *not*
7511cb0ef41Sopenharmony_ci        // match "a/b/*", even though "" matches against the
7521cb0ef41Sopenharmony_ci        // [^/]*? pattern, except in partial mode, where it might
7531cb0ef41Sopenharmony_ci        // simply not be reached yet.
7541cb0ef41Sopenharmony_ci        // However, a/b/ should still satisfy a/*
7551cb0ef41Sopenharmony_ci        // now either we fell off the end of the pattern, or we're done.
7561cb0ef41Sopenharmony_ci        if (fi === fl && pi === pl) {
7571cb0ef41Sopenharmony_ci            // ran out of pattern and filename at the same time.
7581cb0ef41Sopenharmony_ci            // an exact hit!
7591cb0ef41Sopenharmony_ci            return true;
7601cb0ef41Sopenharmony_ci        }
7611cb0ef41Sopenharmony_ci        else if (fi === fl) {
7621cb0ef41Sopenharmony_ci            // ran out of file, but still had pattern left.
7631cb0ef41Sopenharmony_ci            // this is ok if we're doing the match as part of
7641cb0ef41Sopenharmony_ci            // a glob fs traversal.
7651cb0ef41Sopenharmony_ci            return partial;
7661cb0ef41Sopenharmony_ci        }
7671cb0ef41Sopenharmony_ci        else if (pi === pl) {
7681cb0ef41Sopenharmony_ci            // ran out of pattern, still have file left.
7691cb0ef41Sopenharmony_ci            // this is only acceptable if we're on the very last
7701cb0ef41Sopenharmony_ci            // empty segment of a file with a trailing slash.
7711cb0ef41Sopenharmony_ci            // a/* should match a/b/
7721cb0ef41Sopenharmony_ci            return fi === fl - 1 && file[fi] === '';
7731cb0ef41Sopenharmony_ci            /* c8 ignore start */
7741cb0ef41Sopenharmony_ci        }
7751cb0ef41Sopenharmony_ci        else {
7761cb0ef41Sopenharmony_ci            // should be unreachable.
7771cb0ef41Sopenharmony_ci            throw new Error('wtf?');
7781cb0ef41Sopenharmony_ci        }
7791cb0ef41Sopenharmony_ci        /* c8 ignore stop */
7801cb0ef41Sopenharmony_ci    }
7811cb0ef41Sopenharmony_ci    braceExpand() {
7821cb0ef41Sopenharmony_ci        return braceExpand(this.pattern, this.options);
7831cb0ef41Sopenharmony_ci    }
7841cb0ef41Sopenharmony_ci    parse(pattern) {
7851cb0ef41Sopenharmony_ci        assertValidPattern(pattern);
7861cb0ef41Sopenharmony_ci        const options = this.options;
7871cb0ef41Sopenharmony_ci        // shortcuts
7881cb0ef41Sopenharmony_ci        if (pattern === '**')
7891cb0ef41Sopenharmony_ci            return GLOBSTAR;
7901cb0ef41Sopenharmony_ci        if (pattern === '')
7911cb0ef41Sopenharmony_ci            return '';
7921cb0ef41Sopenharmony_ci        // far and away, the most common glob pattern parts are
7931cb0ef41Sopenharmony_ci        // *, *.*, and *.<ext>  Add a fast check method for those.
7941cb0ef41Sopenharmony_ci        let m;
7951cb0ef41Sopenharmony_ci        let fastTest = null;
7961cb0ef41Sopenharmony_ci        if ((m = pattern.match(starRE))) {
7971cb0ef41Sopenharmony_ci            fastTest = options.dot ? starTestDot : starTest;
7981cb0ef41Sopenharmony_ci        }
7991cb0ef41Sopenharmony_ci        else if ((m = pattern.match(starDotExtRE))) {
8001cb0ef41Sopenharmony_ci            fastTest = (options.nocase
8011cb0ef41Sopenharmony_ci                ? options.dot
8021cb0ef41Sopenharmony_ci                    ? starDotExtTestNocaseDot
8031cb0ef41Sopenharmony_ci                    : starDotExtTestNocase
8041cb0ef41Sopenharmony_ci                : options.dot
8051cb0ef41Sopenharmony_ci                    ? starDotExtTestDot
8061cb0ef41Sopenharmony_ci                    : starDotExtTest)(m[1]);
8071cb0ef41Sopenharmony_ci        }
8081cb0ef41Sopenharmony_ci        else if ((m = pattern.match(qmarksRE))) {
8091cb0ef41Sopenharmony_ci            fastTest = (options.nocase
8101cb0ef41Sopenharmony_ci                ? options.dot
8111cb0ef41Sopenharmony_ci                    ? qmarksTestNocaseDot
8121cb0ef41Sopenharmony_ci                    : qmarksTestNocase
8131cb0ef41Sopenharmony_ci                : options.dot
8141cb0ef41Sopenharmony_ci                    ? qmarksTestDot
8151cb0ef41Sopenharmony_ci                    : qmarksTest)(m);
8161cb0ef41Sopenharmony_ci        }
8171cb0ef41Sopenharmony_ci        else if ((m = pattern.match(starDotStarRE))) {
8181cb0ef41Sopenharmony_ci            fastTest = options.dot ? starDotStarTestDot : starDotStarTest;
8191cb0ef41Sopenharmony_ci        }
8201cb0ef41Sopenharmony_ci        else if ((m = pattern.match(dotStarRE))) {
8211cb0ef41Sopenharmony_ci            fastTest = dotStarTest;
8221cb0ef41Sopenharmony_ci        }
8231cb0ef41Sopenharmony_ci        const re = AST.fromGlob(pattern, this.options).toMMPattern();
8241cb0ef41Sopenharmony_ci        return fastTest ? Object.assign(re, { test: fastTest }) : re;
8251cb0ef41Sopenharmony_ci    }
8261cb0ef41Sopenharmony_ci    makeRe() {
8271cb0ef41Sopenharmony_ci        if (this.regexp || this.regexp === false)
8281cb0ef41Sopenharmony_ci            return this.regexp;
8291cb0ef41Sopenharmony_ci        // at this point, this.set is a 2d array of partial
8301cb0ef41Sopenharmony_ci        // pattern strings, or "**".
8311cb0ef41Sopenharmony_ci        //
8321cb0ef41Sopenharmony_ci        // It's better to use .match().  This function shouldn't
8331cb0ef41Sopenharmony_ci        // be used, really, but it's pretty convenient sometimes,
8341cb0ef41Sopenharmony_ci        // when you just want to work with a regex.
8351cb0ef41Sopenharmony_ci        const set = this.set;
8361cb0ef41Sopenharmony_ci        if (!set.length) {
8371cb0ef41Sopenharmony_ci            this.regexp = false;
8381cb0ef41Sopenharmony_ci            return this.regexp;
8391cb0ef41Sopenharmony_ci        }
8401cb0ef41Sopenharmony_ci        const options = this.options;
8411cb0ef41Sopenharmony_ci        const twoStar = options.noglobstar
8421cb0ef41Sopenharmony_ci            ? star
8431cb0ef41Sopenharmony_ci            : options.dot
8441cb0ef41Sopenharmony_ci                ? twoStarDot
8451cb0ef41Sopenharmony_ci                : twoStarNoDot;
8461cb0ef41Sopenharmony_ci        const flags = new Set(options.nocase ? ['i'] : []);
8471cb0ef41Sopenharmony_ci        // regexpify non-globstar patterns
8481cb0ef41Sopenharmony_ci        // if ** is only item, then we just do one twoStar
8491cb0ef41Sopenharmony_ci        // if ** is first, and there are more, prepend (\/|twoStar\/)? to next
8501cb0ef41Sopenharmony_ci        // if ** is last, append (\/twoStar|) to previous
8511cb0ef41Sopenharmony_ci        // if ** is in the middle, append (\/|\/twoStar\/) to previous
8521cb0ef41Sopenharmony_ci        // then filter out GLOBSTAR symbols
8531cb0ef41Sopenharmony_ci        let re = set
8541cb0ef41Sopenharmony_ci            .map(pattern => {
8551cb0ef41Sopenharmony_ci            const pp = pattern.map(p => {
8561cb0ef41Sopenharmony_ci                if (p instanceof RegExp) {
8571cb0ef41Sopenharmony_ci                    for (const f of p.flags.split(''))
8581cb0ef41Sopenharmony_ci                        flags.add(f);
8591cb0ef41Sopenharmony_ci                }
8601cb0ef41Sopenharmony_ci                return typeof p === 'string'
8611cb0ef41Sopenharmony_ci                    ? regExpEscape(p)
8621cb0ef41Sopenharmony_ci                    : p === GLOBSTAR
8631cb0ef41Sopenharmony_ci                        ? GLOBSTAR
8641cb0ef41Sopenharmony_ci                        : p._src;
8651cb0ef41Sopenharmony_ci            });
8661cb0ef41Sopenharmony_ci            pp.forEach((p, i) => {
8671cb0ef41Sopenharmony_ci                const next = pp[i + 1];
8681cb0ef41Sopenharmony_ci                const prev = pp[i - 1];
8691cb0ef41Sopenharmony_ci                if (p !== GLOBSTAR || prev === GLOBSTAR) {
8701cb0ef41Sopenharmony_ci                    return;
8711cb0ef41Sopenharmony_ci                }
8721cb0ef41Sopenharmony_ci                if (prev === undefined) {
8731cb0ef41Sopenharmony_ci                    if (next !== undefined && next !== GLOBSTAR) {
8741cb0ef41Sopenharmony_ci                        pp[i + 1] = '(?:\\/|' + twoStar + '\\/)?' + next;
8751cb0ef41Sopenharmony_ci                    }
8761cb0ef41Sopenharmony_ci                    else {
8771cb0ef41Sopenharmony_ci                        pp[i] = twoStar;
8781cb0ef41Sopenharmony_ci                    }
8791cb0ef41Sopenharmony_ci                }
8801cb0ef41Sopenharmony_ci                else if (next === undefined) {
8811cb0ef41Sopenharmony_ci                    pp[i - 1] = prev + '(?:\\/|' + twoStar + ')?';
8821cb0ef41Sopenharmony_ci                }
8831cb0ef41Sopenharmony_ci                else if (next !== GLOBSTAR) {
8841cb0ef41Sopenharmony_ci                    pp[i - 1] = prev + '(?:\\/|\\/' + twoStar + '\\/)' + next;
8851cb0ef41Sopenharmony_ci                    pp[i + 1] = GLOBSTAR;
8861cb0ef41Sopenharmony_ci                }
8871cb0ef41Sopenharmony_ci            });
8881cb0ef41Sopenharmony_ci            return pp.filter(p => p !== GLOBSTAR).join('/');
8891cb0ef41Sopenharmony_ci        })
8901cb0ef41Sopenharmony_ci            .join('|');
8911cb0ef41Sopenharmony_ci        // need to wrap in parens if we had more than one thing with |,
8921cb0ef41Sopenharmony_ci        // otherwise only the first will be anchored to ^ and the last to $
8931cb0ef41Sopenharmony_ci        const [open, close] = set.length > 1 ? ['(?:', ')'] : ['', ''];
8941cb0ef41Sopenharmony_ci        // must match entire pattern
8951cb0ef41Sopenharmony_ci        // ending in a * or ** will make it less strict.
8961cb0ef41Sopenharmony_ci        re = '^' + open + re + close + '$';
8971cb0ef41Sopenharmony_ci        // can match anything, as long as it's not this.
8981cb0ef41Sopenharmony_ci        if (this.negate)
8991cb0ef41Sopenharmony_ci            re = '^(?!' + re + ').+$';
9001cb0ef41Sopenharmony_ci        try {
9011cb0ef41Sopenharmony_ci            this.regexp = new RegExp(re, [...flags].join(''));
9021cb0ef41Sopenharmony_ci            /* c8 ignore start */
9031cb0ef41Sopenharmony_ci        }
9041cb0ef41Sopenharmony_ci        catch (ex) {
9051cb0ef41Sopenharmony_ci            // should be impossible
9061cb0ef41Sopenharmony_ci            this.regexp = false;
9071cb0ef41Sopenharmony_ci        }
9081cb0ef41Sopenharmony_ci        /* c8 ignore stop */
9091cb0ef41Sopenharmony_ci        return this.regexp;
9101cb0ef41Sopenharmony_ci    }
9111cb0ef41Sopenharmony_ci    slashSplit(p) {
9121cb0ef41Sopenharmony_ci        // if p starts with // on windows, we preserve that
9131cb0ef41Sopenharmony_ci        // so that UNC paths aren't broken.  Otherwise, any number of
9141cb0ef41Sopenharmony_ci        // / characters are coalesced into one, unless
9151cb0ef41Sopenharmony_ci        // preserveMultipleSlashes is set to true.
9161cb0ef41Sopenharmony_ci        if (this.preserveMultipleSlashes) {
9171cb0ef41Sopenharmony_ci            return p.split('/');
9181cb0ef41Sopenharmony_ci        }
9191cb0ef41Sopenharmony_ci        else if (this.isWindows && /^\/\/[^\/]+/.test(p)) {
9201cb0ef41Sopenharmony_ci            // add an extra '' for the one we lose
9211cb0ef41Sopenharmony_ci            return ['', ...p.split(/\/+/)];
9221cb0ef41Sopenharmony_ci        }
9231cb0ef41Sopenharmony_ci        else {
9241cb0ef41Sopenharmony_ci            return p.split(/\/+/);
9251cb0ef41Sopenharmony_ci        }
9261cb0ef41Sopenharmony_ci    }
9271cb0ef41Sopenharmony_ci    match(f, partial = this.partial) {
9281cb0ef41Sopenharmony_ci        this.debug('match', f, this.pattern);
9291cb0ef41Sopenharmony_ci        // short-circuit in the case of busted things.
9301cb0ef41Sopenharmony_ci        // comments, etc.
9311cb0ef41Sopenharmony_ci        if (this.comment) {
9321cb0ef41Sopenharmony_ci            return false;
9331cb0ef41Sopenharmony_ci        }
9341cb0ef41Sopenharmony_ci        if (this.empty) {
9351cb0ef41Sopenharmony_ci            return f === '';
9361cb0ef41Sopenharmony_ci        }
9371cb0ef41Sopenharmony_ci        if (f === '/' && partial) {
9381cb0ef41Sopenharmony_ci            return true;
9391cb0ef41Sopenharmony_ci        }
9401cb0ef41Sopenharmony_ci        const options = this.options;
9411cb0ef41Sopenharmony_ci        // windows: need to use /, not \
9421cb0ef41Sopenharmony_ci        if (this.isWindows) {
9431cb0ef41Sopenharmony_ci            f = f.split('\\').join('/');
9441cb0ef41Sopenharmony_ci        }
9451cb0ef41Sopenharmony_ci        // treat the test path as a set of pathparts.
9461cb0ef41Sopenharmony_ci        const ff = this.slashSplit(f);
9471cb0ef41Sopenharmony_ci        this.debug(this.pattern, 'split', ff);
9481cb0ef41Sopenharmony_ci        // just ONE of the pattern sets in this.set needs to match
9491cb0ef41Sopenharmony_ci        // in order for it to be valid.  If negating, then just one
9501cb0ef41Sopenharmony_ci        // match means that we have failed.
9511cb0ef41Sopenharmony_ci        // Either way, return on the first hit.
9521cb0ef41Sopenharmony_ci        const set = this.set;
9531cb0ef41Sopenharmony_ci        this.debug(this.pattern, 'set', set);
9541cb0ef41Sopenharmony_ci        // Find the basename of the path by looking for the last non-empty segment
9551cb0ef41Sopenharmony_ci        let filename = ff[ff.length - 1];
9561cb0ef41Sopenharmony_ci        if (!filename) {
9571cb0ef41Sopenharmony_ci            for (let i = ff.length - 2; !filename && i >= 0; i--) {
9581cb0ef41Sopenharmony_ci                filename = ff[i];
9591cb0ef41Sopenharmony_ci            }
9601cb0ef41Sopenharmony_ci        }
9611cb0ef41Sopenharmony_ci        for (let i = 0; i < set.length; i++) {
9621cb0ef41Sopenharmony_ci            const pattern = set[i];
9631cb0ef41Sopenharmony_ci            let file = ff;
9641cb0ef41Sopenharmony_ci            if (options.matchBase && pattern.length === 1) {
9651cb0ef41Sopenharmony_ci                file = [filename];
9661cb0ef41Sopenharmony_ci            }
9671cb0ef41Sopenharmony_ci            const hit = this.matchOne(file, pattern, partial);
9681cb0ef41Sopenharmony_ci            if (hit) {
9691cb0ef41Sopenharmony_ci                if (options.flipNegate) {
9701cb0ef41Sopenharmony_ci                    return true;
9711cb0ef41Sopenharmony_ci                }
9721cb0ef41Sopenharmony_ci                return !this.negate;
9731cb0ef41Sopenharmony_ci            }
9741cb0ef41Sopenharmony_ci        }
9751cb0ef41Sopenharmony_ci        // didn't get any hits.  this is success if it's a negative
9761cb0ef41Sopenharmony_ci        // pattern, failure otherwise.
9771cb0ef41Sopenharmony_ci        if (options.flipNegate) {
9781cb0ef41Sopenharmony_ci            return false;
9791cb0ef41Sopenharmony_ci        }
9801cb0ef41Sopenharmony_ci        return this.negate;
9811cb0ef41Sopenharmony_ci    }
9821cb0ef41Sopenharmony_ci    static defaults(def) {
9831cb0ef41Sopenharmony_ci        return minimatch.defaults(def).Minimatch;
9841cb0ef41Sopenharmony_ci    }
9851cb0ef41Sopenharmony_ci}
9861cb0ef41Sopenharmony_ci/* c8 ignore start */
9871cb0ef41Sopenharmony_ciexport { AST } from './ast.js';
9881cb0ef41Sopenharmony_ciexport { escape } from './escape.js';
9891cb0ef41Sopenharmony_ciexport { unescape } from './unescape.js';
9901cb0ef41Sopenharmony_ci/* c8 ignore stop */
9911cb0ef41Sopenharmony_ciminimatch.AST = AST;
9921cb0ef41Sopenharmony_ciminimatch.Minimatch = Minimatch;
9931cb0ef41Sopenharmony_ciminimatch.escape = escape;
9941cb0ef41Sopenharmony_ciminimatch.unescape = unescape;
9951cb0ef41Sopenharmony_ci//# sourceMappingURL=index.js.map