Index: node_modules/brace-expansion/README.md
===================================================================
--- node_modules/brace-expansion/README.md	(revision 81bc7da776d8cda42939ef4ab350c88d13b4941f)
+++ node_modules/brace-expansion/README.md	(revision 33517cc23b4f63a19074ebcdcf7ef56c65850f09)
@@ -46,5 +46,5 @@
 
 ```js
-import { expand } from '@isaacs/brace-expansion'
+import { expand } from 'brace-expansion'
 ```
 
@@ -63,4 +63,15 @@
 })
 // expansions.length will be 100, not 100^5
+```
+
+The `options` object can also provide a `maxLength` value to cap the
+total number of characters across all expansions. This is limited to
+`4_000_000` by default, to prevent memory exhaustion from inputs whose
+result count stays under `max` while each result grows very long.
+
+```js
+const expansions = expand('{a,b}'.repeat(1500), {
+  maxLength: 10_000,
+})
 ```
 
Index: node_modules/brace-expansion/dist/commonjs/index.d.ts
===================================================================
--- node_modules/brace-expansion/dist/commonjs/index.d.ts	(revision 81bc7da776d8cda42939ef4ab350c88d13b4941f)
+++ node_modules/brace-expansion/dist/commonjs/index.d.ts	(revision 33517cc23b4f63a19074ebcdcf7ef56c65850f09)
@@ -1,5 +1,11 @@
 export declare const EXPANSION_MAX = 100000;
+export declare const EXPANSION_MAX_LENGTH = 4000000;
+export declare const EXPANSION_MAX_DEPTH = 1000;
+export declare const EXPANSION_MAX_REWRITES = 1000;
 export type BraceExpansionOptions = {
     max?: number;
+    maxLength?: number;
+    maxDepth?: number;
+    maxRewrites?: number;
 };
 export declare function expand(str: string, options?: BraceExpansionOptions): string[];
Index: node_modules/brace-expansion/dist/commonjs/index.d.ts.map
===================================================================
--- node_modules/brace-expansion/dist/commonjs/index.d.ts.map	(revision 81bc7da776d8cda42939ef4ab350c88d13b4941f)
+++ node_modules/brace-expansion/dist/commonjs/index.d.ts.map	(revision 33517cc23b4f63a19074ebcdcf7ef56c65850f09)
@@ -1,1 +1,1 @@
-{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAkBA,eAAO,MAAM,aAAa,SAAU,CAAA;AAwDpC,MAAM,MAAM,qBAAqB,GAAG;IAClC,GAAG,CAAC,EAAE,MAAM,CAAA;CACb,CAAA;AAED,wBAAgB,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,qBAA0B,YAkBtE"}
+{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAkBA,eAAO,MAAM,aAAa,SAAU,CAAA;AAYpC,eAAO,MAAM,oBAAoB,UAAY,CAAA;AAU7C,eAAO,MAAM,mBAAmB,OAAQ,CAAA;AAUxC,eAAO,MAAM,sBAAsB,OAAQ,CAAA;AAyE3C,MAAM,MAAM,qBAAqB,GAAG;IAClC,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,CAAA;AAED,wBAAgB,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,qBAA0B,YA+BtE"}
Index: node_modules/brace-expansion/dist/commonjs/index.js
===================================================================
--- node_modules/brace-expansion/dist/commonjs/index.js	(revision 81bc7da776d8cda42939ef4ab350c88d13b4941f)
+++ node_modules/brace-expansion/dist/commonjs/index.js	(revision 33517cc23b4f63a19074ebcdcf7ef56c65850f09)
@@ -1,5 +1,5 @@
 "use strict";
 Object.defineProperty(exports, "__esModule", { value: true });
-exports.EXPANSION_MAX = void 0;
+exports.EXPANSION_MAX_REWRITES = exports.EXPANSION_MAX_DEPTH = exports.EXPANSION_MAX_LENGTH = exports.EXPANSION_MAX = void 0;
 exports.expand = expand;
 const balanced_match_1 = require("balanced-match");
@@ -18,6 +18,35 @@
 const closePattern = /\\}/g;
 const commaPattern = /\\,/g;
-const periodPattern = /\\./g;
+const periodPattern = /\\\./g;
 exports.EXPANSION_MAX = 100_000;
+// `EXPANSION_MAX` caps the *number* of expansions, but not their length. An
+// input like `'{a,b}'.repeat(1500)` stays under that count - its output is
+// truncated to 100k results - while making every result ~1500 characters
+// long. The result set, and the intermediate arrays built while combining
+// brace sets, then grow large enough to exhaust memory and crash the process
+// (CVE-2026-14257). `EXPANSION_MAX_LENGTH` bounds the total number of
+// characters the accumulator may hold at any point, so memory stays flat no
+// matter how many brace groups are chained. The limit sits well above any
+// realistic expansion (100k results hitting `EXPANSION_MAX` measure ~1M
+// characters) so legitimate input is unaffected.
+exports.EXPANSION_MAX_LENGTH = 4_000_000;
+// `expand_` recurses once per level of brace *nesting* - both when expanding a
+// set's comma members and when re-wrapping a set whose body is a single part.
+// The CVE-2026-14257 fix made the *tail* iterative (recursion on `m.post`, one
+// level per chained group), which left nesting depth unbounded: about 3,100
+// levels of `{{{...a,b...}}}` - only ~6KB of input - exhausted the native stack
+// and crashed the process. `EXPANSION_MAX_DEPTH` bounds how deep the parser
+// will follow nesting. It sits far above any realistic pattern and well below
+// the depth at which the stack runs out.
+exports.EXPANSION_MAX_DEPTH = 1_000;
+// Bash keeps a quirk where a brace group followed by a comma set still expands
+// (`{a},b}`). The parser implements it by rewriting the string and restarting
+// the scan, absorbing one `}` per pass. `n` trailing braces therefore cost `n`
+// full passes over a string that itself grows by one `escClose` sentinel each
+// time - quadratic in `n`, with a ~26x constant from the sentinel's length.
+// 128KB of `'{a}' + '}'.repeat(n) + ',z}'` blocked the event loop for 27
+// seconds to produce two results. `EXPANSION_MAX_REWRITES` bounds how many
+// times the scan may restart. Real `{a},b}` input needs a handful.
+exports.EXPANSION_MAX_REWRITES = 1_000;
 function numeric(str) {
     return !isNaN(str) ? parseInt(str, 10) : str.charCodeAt(0);
@@ -39,4 +68,10 @@
         .replace(escPeriodPattern, '.');
 }
+// Like `target.push(...items)` but doesn't overflow the stack
+function pushAll(target, items) {
+    for (let i = 0; i < items.length; i++) {
+        target.push(items[i]);
+    }
+}
 /**
  * Basically just str.split(","), but handling cases
@@ -45,23 +80,32 @@
  */
 function parseCommaParts(str) {
-    if (!str) {
-        return [''];
-    }
     const parts = [];
-    const m = (0, balanced_match_1.balanced)('{', '}', str);
-    if (!m) {
-        return str.split(',');
-    }
-    const { pre, body, post } = m;
-    const p = pre.split(',');
-    p[p.length - 1] += '{' + body + '}';
-    const postParts = parseCommaParts(post);
-    if (post.length) {
-        ;
-        p[p.length - 1] += postParts.shift();
-        p.push.apply(p, postParts);
-    }
-    parts.push.apply(parts, p);
-    return parts;
+    // Walk the brace groups iteratively. Recursing on `post` once per group let a
+    // chain of them exhaust the stack - the parsing-side counterpart to
+    // the `expand_` overflow fixed for CVE-2026-14257, and not something `max` or
+    // `maxLength` can bound, since it happens before expansion.
+    //
+    // The part the next chunk continues
+    let carry = '';
+    for (;;) {
+        const m = (0, balanced_match_1.balanced)('{', '}', str);
+        if (!m) {
+            const tail = str.split(',');
+            tail[0] = carry + tail[0];
+            pushAll(parts, tail);
+            return parts;
+        }
+        const { pre, body, post } = m;
+        const p = pre.split(',');
+        p[0] = carry + p[0];
+        p[p.length - 1] += '{' + body + '}';
+        if (!post.length) {
+            pushAll(parts, p);
+            return parts;
+        }
+        carry = p.pop();
+        pushAll(parts, p);
+        str = post;
+    }
 }
 function expand(str, options = {}) {
@@ -69,5 +113,5 @@
         return [];
     }
-    const { max = exports.EXPANSION_MAX } = options;
+    const { max = exports.EXPANSION_MAX, maxLength = exports.EXPANSION_MAX_LENGTH, maxDepth = exports.EXPANSION_MAX_DEPTH, maxRewrites = exports.EXPANSION_MAX_REWRITES, } = options;
     // I don't know why Bash 4.3 does this, but it does.
     // Anything starting with {} will have the first two bytes preserved
@@ -79,5 +123,5 @@
         str = '\\{\\}' + str.slice(2);
     }
-    return expand_(escapeBraces(str), max, true).map(unescapeBraces);
+    return expand_(escapeBraces(str), max, maxLength, maxDepth, 0, maxRewrites, true).map(unescapeBraces);
 }
 function embrace(str) {
@@ -93,20 +137,124 @@
     return i >= y;
 }
-function expand_(str, max, isTop) {
-    /** @type {string[]} */
-    const expansions = [];
-    const m = (0, balanced_match_1.balanced)('{', '}', str);
-    if (!m)
+// Build `{ acc[a] + pre + values[v] }` for every combination, capping the
+// number of results at `max` and the total number of characters at `maxLength`.
+// This is the one place output grows, so bounding it here keeps the single
+// accumulator - and therefore memory - flat regardless of how many brace groups
+// are combined (CVE-2026-14257).
+function combine(acc, pre, values, max, maxLength, dropEmpties) {
+    const out = [];
+    let length = 0;
+    for (let a = 0; a < acc.length; a++) {
+        for (let v = 0; v < values.length; v++) {
+            if (out.length >= max)
+                return out;
+            const expansion = acc[a] + pre + values[v];
+            // Bash drops empty results at the top level. Skip them before they count
+            // against `max`, so `max` bounds the number of *kept* results.
+            if (dropEmpties && !expansion)
+                continue;
+            if (length + expansion.length > maxLength)
+                return out;
+            out.push(expansion);
+            length += expansion.length;
+        }
+    }
+    return out;
+}
+// The expansion values of a single numeric (`1..5`) or alphabetic (`a..e..2`)
+// sequence body.
+function expandSequence(body, isAlphaSequence, max, maxLength) {
+    const n = body.split(/\.\./);
+    const N = [];
+    // A sequence body always splits into two or three parts, but the compiler
+    // can't know that.
+    /* c8 ignore start */
+    if (n[0] === undefined || n[1] === undefined) {
+        return N;
+    }
+    /* c8 ignore stop */
+    const x = numeric(n[0]);
+    const y = numeric(n[1]);
+    const width = Math.max(n[0].length, n[1].length);
+    let incr = n.length === 3 && n[2] !== undefined ?
+        Math.max(Math.abs(numeric(n[2])), 1)
+        : 1;
+    let test = lte;
+    const reverse = y < x;
+    if (reverse) {
+        incr *= -1;
+        test = gte;
+    }
+    const pad = n.some(isPadded);
+    let length = 0;
+    for (let i = x; test(i, y) && N.length < max; i += incr) {
+        let c;
+        if (isAlphaSequence) {
+            c = String.fromCharCode(i);
+            if (c === '\\') {
+                c = '';
+            }
+        }
+        else {
+            c = String(i);
+            if (pad) {
+                const need = width - c.length;
+                if (need > 0) {
+                    const z = new Array(need + 1).join('0');
+                    if (i < 0) {
+                        c = '-' + z + c.slice(1);
+                    }
+                    else {
+                        c = z + c;
+                    }
+                }
+            }
+        }
+        if (length + c.length > maxLength)
+            break;
+        N.push(c);
+        length += c.length;
+    }
+    return N;
+}
+function expand_(str, max, maxLength, maxDepth, depth, maxRewrites, isTop) {
+    // Too deeply nested to keep following: treat the rest as literal, the same
+    // way a group that cannot expand is already handled. Truncating rather than
+    // throwing keeps `expand` total, matching `max` and `maxLength`.
+    if (depth > maxDepth) {
         return [str];
-    // no need to expand pre, since it is guaranteed to be free of brace-sets
-    const pre = m.pre;
-    const post = m.post.length ? expand_(m.post, max, false) : [''];
-    if (/\$$/.test(m.pre)) {
-        for (let k = 0; k < post.length && k < max; k++) {
-            const expansion = pre + '{' + m.body + '}' + post[k];
-            expansions.push(expansion);
-        }
-    }
-    else {
+    }
+    // Consume the string's top-level brace groups left to right, threading a
+    // running set of combined prefixes (`acc`). Expanding the tail iteratively -
+    // rather than recursing on `m.post` once per group - keeps the native stack
+    // depth constant, so deeply chained input (`'{a,b}'.repeat(3000)`) can no
+    // longer overflow the stack, and leaves a single accumulator whose size
+    // `maxLength` bounds directly (CVE-2026-14257).
+    let acc = [''];
+    // Bash drops empty results, but only when the *first* top-level group is a
+    // comma set - a sequence like `{a..\}` may legitimately yield ''. The drop
+    // is on the final strings, so it is applied to whichever `combine` produces
+    // them (the one with no brace set left in the tail).
+    // How many times the `{a},b}` rewrite below has restarted the scan. Each pass
+    // re-reads the whole string, so leaving this unbounded is quadratic.
+    let rewrites = 0;
+    let dropEmpties = false;
+    let firstGroup = true;
+    for (;;) {
+        const m = (0, balanced_match_1.balanced)('{', '}', str);
+        // No brace set left: the rest of the string is literal.
+        if (!m) {
+            return combine(acc, str, [''], max, maxLength, dropEmpties);
+        }
+        // no need to expand pre, since it is guaranteed to be free of brace-sets
+        const pre = m.pre;
+        if (/\$$/.test(pre)) {
+            acc = combine(acc, pre + '{' + m.body + '}', [''], max, maxLength, dropEmpties && !m.post.length);
+            firstGroup = false;
+            if (!m.post.length)
+                break;
+            str = m.post;
+            continue;
+        }
         const isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body);
         const isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body);
@@ -115,85 +263,71 @@
         if (!isSequence && !isOptions) {
             // {a},b}
-            if (m.post.match(/,(?!,).*\}/)) {
+            if (rewrites < maxRewrites && m.post.match(/,(?!,).*\}/)) {
+                rewrites++;
                 str = m.pre + '{' + m.body + escClose + m.post;
-                return expand_(str, max, true);
-            }
-            return [str];
-        }
-        let n;
+                isTop = true;
+                continue;
+            }
+            // Nothing here expands, so the whole remaining string is literal.
+            return combine(acc, pre + '{' + m.body + '}' + m.post, [''], max, maxLength, dropEmpties);
+        }
+        if (firstGroup) {
+            dropEmpties = isTop && !isSequence;
+            firstGroup = false;
+        }
+        let values;
         if (isSequence) {
-            n = m.body.split(/\.\./);
+            values = expandSequence(m.body, isAlphaSequence, max, maxLength);
         }
         else {
-            n = parseCommaParts(m.body);
+            let n = parseCommaParts(m.body);
             if (n.length === 1 && n[0] !== undefined) {
                 // x{{a,b}}y ==> x{a}y x{b}y
-                n = expand_(n[0], max, false).map(embrace);
+                n = expand_(n[0], max, maxLength, maxDepth, depth + 1, maxRewrites, false).map(embrace);
                 //XXX is this necessary? Can't seem to hit it in tests.
                 /* c8 ignore start */
                 if (n.length === 1) {
-                    return post.map(p => m.pre + n[0] + p);
+                    acc = combine(acc, pre + n[0], [''], max, maxLength, dropEmpties && !m.post.length);
+                    if (!m.post.length)
+                        break;
+                    str = m.post;
+                    continue;
                 }
                 /* c8 ignore stop */
             }
-        }
-        // at this point, n is the parts, and we know it's not a comma set
-        // with a single entry.
-        let N;
-        if (isSequence && n[0] !== undefined && n[1] !== undefined) {
-            const x = numeric(n[0]);
-            const y = numeric(n[1]);
-            const width = Math.max(n[0].length, n[1].length);
-            let incr = n.length === 3 && n[2] !== undefined ? Math.abs(numeric(n[2])) : 1;
-            let test = lte;
-            const reverse = y < x;
-            if (reverse) {
-                incr *= -1;
-                test = gte;
-            }
-            const pad = n.some(isPadded);
-            N = [];
-            for (let i = x; test(i, y); i += incr) {
-                let c;
-                if (isAlphaSequence) {
-                    c = String.fromCharCode(i);
-                    if (c === '\\') {
-                        c = '';
+            // Values that `combine` is going to drop as empty produce no result, so
+            // they must not count against `max` - otherwise `{a,,b}` with `max: 2`
+            // would stop at `['a', '']` and yield one result instead of two. Skipping
+            // them outright keeps `values` bounded while leaving `max` a bound on
+            // *kept* results.
+            let dropsEmpties = dropEmpties && !m.post.length && !pre;
+            for (let d = 0; dropsEmpties && d < acc.length; d++) {
+                if (acc[d]) {
+                    dropsEmpties = false;
+                }
+            }
+            values = [];
+            let valuesLength = 0;
+            outer: for (let j = 0; j < n.length; j++) {
+                const expanded = expand_(n[j], max, maxLength, maxDepth, depth + 1, maxRewrites, false);
+                for (let k = 0; k < expanded.length; k++) {
+                    const v = expanded[k];
+                    if (dropsEmpties && !v)
+                        continue;
+                    if (values.length >= max ||
+                        valuesLength + v.length > maxLength) {
+                        break outer;
                     }
+                    values.push(v);
+                    valuesLength += v.length;
                 }
-                else {
-                    c = String(i);
-                    if (pad) {
-                        const need = width - c.length;
-                        if (need > 0) {
-                            const z = new Array(need + 1).join('0');
-                            if (i < 0) {
-                                c = '-' + z + c.slice(1);
-                            }
-                            else {
-                                c = z + c;
-                            }
-                        }
-                    }
-                }
-                N.push(c);
-            }
-        }
-        else {
-            N = [];
-            for (let j = 0; j < n.length; j++) {
-                N.push.apply(N, expand_(n[j], max, false));
-            }
-        }
-        for (let j = 0; j < N.length; j++) {
-            for (let k = 0; k < post.length && expansions.length < max; k++) {
-                const expansion = pre + N[j] + post[k];
-                if (!isTop || isSequence || expansion) {
-                    expansions.push(expansion);
-                }
-            }
-        }
-    }
-    return expansions;
+            }
+        }
+        acc = combine(acc, pre, values, max, maxLength, dropEmpties && !m.post.length);
+        if (!m.post.length)
+            break;
+        str = m.post;
+    }
+    return acc;
 }
 //# sourceMappingURL=index.js.map
Index: node_modules/brace-expansion/dist/commonjs/index.js.map
===================================================================
--- node_modules/brace-expansion/dist/commonjs/index.js.map	(revision 81bc7da776d8cda42939ef4ab350c88d13b4941f)
+++ node_modules/brace-expansion/dist/commonjs/index.js.map	(revision 33517cc23b4f63a19074ebcdcf7ef56c65850f09)
@@ -1,1 +1,1 @@
-{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { balanced } from 'balanced-match'\n\nconst escSlash = '\\0SLASH' + Math.random() + '\\0'\nconst escOpen = '\\0OPEN' + Math.random() + '\\0'\nconst escClose = '\\0CLOSE' + Math.random() + '\\0'\nconst escComma = '\\0COMMA' + Math.random() + '\\0'\nconst escPeriod = '\\0PERIOD' + Math.random() + '\\0'\nconst escSlashPattern = new RegExp(escSlash, 'g')\nconst escOpenPattern = new RegExp(escOpen, 'g')\nconst escClosePattern = new RegExp(escClose, 'g')\nconst escCommaPattern = new RegExp(escComma, 'g')\nconst escPeriodPattern = new RegExp(escPeriod, 'g')\nconst slashPattern = /\\\\\\\\/g\nconst openPattern = /\\\\{/g\nconst closePattern = /\\\\}/g\nconst commaPattern = /\\\\,/g\nconst periodPattern = /\\\\./g\n\nexport const EXPANSION_MAX = 100_000\n\nfunction numeric(str: string) {\n  return !isNaN(str as any) ? parseInt(str, 10) : str.charCodeAt(0)\n}\n\nfunction escapeBraces(str: string) {\n  return str\n    .replace(slashPattern, escSlash)\n    .replace(openPattern, escOpen)\n    .replace(closePattern, escClose)\n    .replace(commaPattern, escComma)\n    .replace(periodPattern, escPeriod)\n}\n\nfunction unescapeBraces(str: string) {\n  return str\n    .replace(escSlashPattern, '\\\\')\n    .replace(escOpenPattern, '{')\n    .replace(escClosePattern, '}')\n    .replace(escCommaPattern, ',')\n    .replace(escPeriodPattern, '.')\n}\n\n/**\n * Basically just str.split(\",\"), but handling cases\n * where we have nested braced sections, which should be\n * treated as individual members, like {a,{b,c},d}\n */\nfunction parseCommaParts(str: string) {\n  if (!str) {\n    return ['']\n  }\n\n  const parts: string[] = []\n  const m = balanced('{', '}', str)\n\n  if (!m) {\n    return str.split(',')\n  }\n\n  const { pre, body, post } = m\n  const p = pre.split(',')\n\n  p[p.length - 1] += '{' + body + '}'\n  const postParts = parseCommaParts(post)\n  if (post.length) {\n    ;(p[p.length - 1] as string) += postParts.shift()\n    p.push.apply(p, postParts)\n  }\n\n  parts.push.apply(parts, p)\n\n  return parts\n}\n\nexport type BraceExpansionOptions = {\n  max?: number\n}\n\nexport function expand(str: string, options: BraceExpansionOptions = {}) {\n  if (!str) {\n    return []\n  }\n\n  const { max = EXPANSION_MAX } = options\n\n  // I don't know why Bash 4.3 does this, but it does.\n  // Anything starting with {} will have the first two bytes preserved\n  // but *only* at the top level, so {},a}b will not expand to anything,\n  // but a{},b}c will be expanded to [a}c,abc].\n  // One could argue that this is a bug in Bash, but since the goal of\n  // this module is to match Bash's rules, we escape a leading {}\n  if (str.slice(0, 2) === '{}') {\n    str = '\\\\{\\\\}' + str.slice(2)\n  }\n\n  return expand_(escapeBraces(str), max, true).map(unescapeBraces)\n}\n\nfunction embrace(str: string) {\n  return '{' + str + '}'\n}\n\nfunction isPadded(el: string) {\n  return /^-?0\\d/.test(el)\n}\n\nfunction lte(i: number, y: number) {\n  return i <= y\n}\n\nfunction gte(i: number, y: number) {\n  return i >= y\n}\n\nfunction expand_(str: string, max: number, isTop: boolean): string[] {\n  /** @type {string[]} */\n  const expansions: string[] = []\n\n  const m = balanced('{', '}', str)\n  if (!m) return [str]\n\n  // no need to expand pre, since it is guaranteed to be free of brace-sets\n  const pre = m.pre\n  const post: string[] = m.post.length ? expand_(m.post, max, false) : ['']\n\n  if (/\\$$/.test(m.pre)) {\n    for (let k = 0; k < post.length && k < max; k++) {\n      const expansion = pre + '{' + m.body + '}' + post[k]\n      expansions.push(expansion)\n    }\n  } else {\n    const isNumericSequence = /^-?\\d+\\.\\.-?\\d+(?:\\.\\.-?\\d+)?$/.test(m.body)\n    const isAlphaSequence = /^[a-zA-Z]\\.\\.[a-zA-Z](?:\\.\\.-?\\d+)?$/.test(\n      m.body,\n    )\n    const isSequence = isNumericSequence || isAlphaSequence\n    const isOptions = m.body.indexOf(',') >= 0\n    if (!isSequence && !isOptions) {\n      // {a},b}\n      if (m.post.match(/,(?!,).*\\}/)) {\n        str = m.pre + '{' + m.body + escClose + m.post\n        return expand_(str, max, true)\n      }\n      return [str]\n    }\n\n    let n: string[]\n    if (isSequence) {\n      n = m.body.split(/\\.\\./)\n    } else {\n      n = parseCommaParts(m.body)\n      if (n.length === 1 && n[0] !== undefined) {\n        // x{{a,b}}y ==> x{a}y x{b}y\n        n = expand_(n[0], max, false).map(embrace)\n        //XXX is this necessary? Can't seem to hit it in tests.\n        /* c8 ignore start */\n        if (n.length === 1) {\n          return post.map(p => m.pre + n[0] + p)\n        }\n        /* c8 ignore stop */\n      }\n    }\n\n    // at this point, n is the parts, and we know it's not a comma set\n    // with a single entry.\n    let N: string[]\n\n    if (isSequence && n[0] !== undefined && n[1] !== undefined) {\n      const x = numeric(n[0])\n      const y = numeric(n[1])\n      const width = Math.max(n[0].length, n[1].length)\n      let incr =\n        n.length === 3 && n[2] !== undefined ? Math.abs(numeric(n[2])) : 1\n      let test = lte\n      const reverse = y < x\n      if (reverse) {\n        incr *= -1\n        test = gte\n      }\n      const pad = n.some(isPadded)\n\n      N = []\n\n      for (let i = x; test(i, y); i += incr) {\n        let c\n        if (isAlphaSequence) {\n          c = String.fromCharCode(i)\n          if (c === '\\\\') {\n            c = ''\n          }\n        } else {\n          c = String(i)\n          if (pad) {\n            const need = width - c.length\n            if (need > 0) {\n              const z = new Array(need + 1).join('0')\n              if (i < 0) {\n                c = '-' + z + c.slice(1)\n              } else {\n                c = z + c\n              }\n            }\n          }\n        }\n        N.push(c)\n      }\n    } else {\n      N = []\n\n      for (let j = 0; j < n.length; j++) {\n        N.push.apply(N, expand_(n[j] as string, max, false))\n      }\n    }\n\n    for (let j = 0; j < N.length; j++) {\n      for (let k = 0; k < post.length && expansions.length < max; k++) {\n        const expansion = pre + N[j] + post[k]\n        if (!isTop || isSequence || expansion) {\n          expansions.push(expansion)\n        }\n      }\n    }\n  }\n\n  return expansions\n}\n"]}
+{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { balanced } from 'balanced-match'\n\nconst escSlash = '\\0SLASH' + Math.random() + '\\0'\nconst escOpen = '\\0OPEN' + Math.random() + '\\0'\nconst escClose = '\\0CLOSE' + Math.random() + '\\0'\nconst escComma = '\\0COMMA' + Math.random() + '\\0'\nconst escPeriod = '\\0PERIOD' + Math.random() + '\\0'\nconst escSlashPattern = new RegExp(escSlash, 'g')\nconst escOpenPattern = new RegExp(escOpen, 'g')\nconst escClosePattern = new RegExp(escClose, 'g')\nconst escCommaPattern = new RegExp(escComma, 'g')\nconst escPeriodPattern = new RegExp(escPeriod, 'g')\nconst slashPattern = /\\\\\\\\/g\nconst openPattern = /\\\\{/g\nconst closePattern = /\\\\}/g\nconst commaPattern = /\\\\,/g\nconst periodPattern = /\\\\\\./g\n\nexport const EXPANSION_MAX = 100_000\n\n// `EXPANSION_MAX` caps the *number* of expansions, but not their length. An\n// input like `'{a,b}'.repeat(1500)` stays under that count - its output is\n// truncated to 100k results - while making every result ~1500 characters\n// long. The result set, and the intermediate arrays built while combining\n// brace sets, then grow large enough to exhaust memory and crash the process\n// (CVE-2026-14257). `EXPANSION_MAX_LENGTH` bounds the total number of\n// characters the accumulator may hold at any point, so memory stays flat no\n// matter how many brace groups are chained. The limit sits well above any\n// realistic expansion (100k results hitting `EXPANSION_MAX` measure ~1M\n// characters) so legitimate input is unaffected.\nexport const EXPANSION_MAX_LENGTH = 4_000_000\n\n// `expand_` recurses once per level of brace *nesting* - both when expanding a\n// set's comma members and when re-wrapping a set whose body is a single part.\n// The CVE-2026-14257 fix made the *tail* iterative (recursion on `m.post`, one\n// level per chained group), which left nesting depth unbounded: about 3,100\n// levels of `{{{...a,b...}}}` - only ~6KB of input - exhausted the native stack\n// and crashed the process. `EXPANSION_MAX_DEPTH` bounds how deep the parser\n// will follow nesting. It sits far above any realistic pattern and well below\n// the depth at which the stack runs out.\nexport const EXPANSION_MAX_DEPTH = 1_000\n\n// Bash keeps a quirk where a brace group followed by a comma set still expands\n// (`{a},b}`). The parser implements it by rewriting the string and restarting\n// the scan, absorbing one `}` per pass. `n` trailing braces therefore cost `n`\n// full passes over a string that itself grows by one `escClose` sentinel each\n// time - quadratic in `n`, with a ~26x constant from the sentinel's length.\n// 128KB of `'{a}' + '}'.repeat(n) + ',z}'` blocked the event loop for 27\n// seconds to produce two results. `EXPANSION_MAX_REWRITES` bounds how many\n// times the scan may restart. Real `{a},b}` input needs a handful.\nexport const EXPANSION_MAX_REWRITES = 1_000\n\nfunction numeric(str: string) {\n  return !isNaN(str as any) ? parseInt(str, 10) : str.charCodeAt(0)\n}\n\nfunction escapeBraces(str: string) {\n  return str\n    .replace(slashPattern, escSlash)\n    .replace(openPattern, escOpen)\n    .replace(closePattern, escClose)\n    .replace(commaPattern, escComma)\n    .replace(periodPattern, escPeriod)\n}\n\nfunction unescapeBraces(str: string) {\n  return str\n    .replace(escSlashPattern, '\\\\')\n    .replace(escOpenPattern, '{')\n    .replace(escClosePattern, '}')\n    .replace(escCommaPattern, ',')\n    .replace(escPeriodPattern, '.')\n}\n\n// Like `target.push(...items)` but doesn't overflow the stack\nfunction pushAll(target: string[], items: string[]) {\n  for (let i = 0; i < items.length; i++) {\n    target.push(items[i] as string)\n  }\n}\n\n/**\n * Basically just str.split(\",\"), but handling cases\n * where we have nested braced sections, which should be\n * treated as individual members, like {a,{b,c},d}\n */\nfunction parseCommaParts(str: string) {\n  const parts: string[] = []\n\n  // Walk the brace groups iteratively. Recursing on `post` once per group let a\n  // chain of them exhaust the stack - the parsing-side counterpart to\n  // the `expand_` overflow fixed for CVE-2026-14257, and not something `max` or\n  // `maxLength` can bound, since it happens before expansion.\n  //\n  // The part the next chunk continues\n  let carry = ''\n\n  for (;;) {\n    const m = balanced('{', '}', str)\n\n    if (!m) {\n      const tail = str.split(',')\n      tail[0] = carry + (tail[0] as string)\n      pushAll(parts, tail)\n      return parts\n    }\n\n    const { pre, body, post } = m\n    const p = pre.split(',')\n    p[0] = carry + (p[0] as string)\n    p[p.length - 1] += '{' + body + '}'\n\n    if (!post.length) {\n      pushAll(parts, p)\n      return parts\n    }\n\n    carry = p.pop() as string\n    pushAll(parts, p)\n    str = post\n  }\n}\n\nexport type BraceExpansionOptions = {\n  max?: number\n  maxLength?: number\n  maxDepth?: number\n  maxRewrites?: number\n}\n\nexport function expand(str: string, options: BraceExpansionOptions = {}) {\n  if (!str) {\n    return []\n  }\n\n  const {\n    max = EXPANSION_MAX,\n    maxLength = EXPANSION_MAX_LENGTH,\n    maxDepth = EXPANSION_MAX_DEPTH,\n    maxRewrites = EXPANSION_MAX_REWRITES,\n  } = options\n\n  // I don't know why Bash 4.3 does this, but it does.\n  // Anything starting with {} will have the first two bytes preserved\n  // but *only* at the top level, so {},a}b will not expand to anything,\n  // but a{},b}c will be expanded to [a}c,abc].\n  // One could argue that this is a bug in Bash, but since the goal of\n  // this module is to match Bash's rules, we escape a leading {}\n  if (str.slice(0, 2) === '{}') {\n    str = '\\\\{\\\\}' + str.slice(2)\n  }\n\n  return expand_(\n    escapeBraces(str),\n    max,\n    maxLength,\n    maxDepth,\n    0,\n    maxRewrites,\n    true,\n  ).map(unescapeBraces)\n}\n\nfunction embrace(str: string) {\n  return '{' + str + '}'\n}\n\nfunction isPadded(el: string) {\n  return /^-?0\\d/.test(el)\n}\n\nfunction lte(i: number, y: number) {\n  return i <= y\n}\n\nfunction gte(i: number, y: number) {\n  return i >= y\n}\n\n// Build `{ acc[a] + pre + values[v] }` for every combination, capping the\n// number of results at `max` and the total number of characters at `maxLength`.\n// This is the one place output grows, so bounding it here keeps the single\n// accumulator - and therefore memory - flat regardless of how many brace groups\n// are combined (CVE-2026-14257).\nfunction combine(\n  acc: string[],\n  pre: string,\n  values: string[],\n  max: number,\n  maxLength: number,\n  dropEmpties: boolean,\n): string[] {\n  const out: string[] = []\n  let length = 0\n  for (let a = 0; a < acc.length; a++) {\n    for (let v = 0; v < values.length; v++) {\n      if (out.length >= max) return out\n      const expansion = (acc[a] as string) + pre + values[v]\n      // Bash drops empty results at the top level. Skip them before they count\n      // against `max`, so `max` bounds the number of *kept* results.\n      if (dropEmpties && !expansion) continue\n      if (length + expansion.length > maxLength) return out\n      out.push(expansion)\n      length += expansion.length\n    }\n  }\n  return out\n}\n\n// The expansion values of a single numeric (`1..5`) or alphabetic (`a..e..2`)\n// sequence body.\nfunction expandSequence(\n  body: string,\n  isAlphaSequence: boolean,\n  max: number,\n  maxLength: number,\n): string[] {\n  const n = body.split(/\\.\\./)\n  const N: string[] = []\n  // A sequence body always splits into two or three parts, but the compiler\n  // can't know that.\n  /* c8 ignore start */\n  if (n[0] === undefined || n[1] === undefined) {\n    return N\n  }\n  /* c8 ignore stop */\n  const x = numeric(n[0])\n  const y = numeric(n[1])\n  const width = Math.max(n[0].length, n[1].length)\n  let incr =\n    n.length === 3 && n[2] !== undefined ?\n      Math.max(Math.abs(numeric(n[2])), 1)\n    : 1\n  let test = lte\n  const reverse = y < x\n  if (reverse) {\n    incr *= -1\n    test = gte\n  }\n  const pad = n.some(isPadded)\n\n  let length = 0\n  for (let i = x; test(i, y) && N.length < max; i += incr) {\n    let c\n    if (isAlphaSequence) {\n      c = String.fromCharCode(i)\n      if (c === '\\\\') {\n        c = ''\n      }\n    } else {\n      c = String(i)\n      if (pad) {\n        const need = width - c.length\n        if (need > 0) {\n          const z = new Array(need + 1).join('0')\n          if (i < 0) {\n            c = '-' + z + c.slice(1)\n          } else {\n            c = z + c\n          }\n        }\n      }\n    }\n    if (length + c.length > maxLength) break\n    N.push(c)\n    length += c.length\n  }\n  return N\n}\n\nfunction expand_(\n  str: string,\n  max: number,\n  maxLength: number,\n  maxDepth: number,\n  depth: number,\n  maxRewrites: number,\n  isTop: boolean,\n): string[] {\n  // Too deeply nested to keep following: treat the rest as literal, the same\n  // way a group that cannot expand is already handled. Truncating rather than\n  // throwing keeps `expand` total, matching `max` and `maxLength`.\n  if (depth > maxDepth) {\n    return [str]\n  }\n\n  // Consume the string's top-level brace groups left to right, threading a\n  // running set of combined prefixes (`acc`). Expanding the tail iteratively -\n  // rather than recursing on `m.post` once per group - keeps the native stack\n  // depth constant, so deeply chained input (`'{a,b}'.repeat(3000)`) can no\n  // longer overflow the stack, and leaves a single accumulator whose size\n  // `maxLength` bounds directly (CVE-2026-14257).\n  let acc: string[] = ['']\n\n  // Bash drops empty results, but only when the *first* top-level group is a\n  // comma set - a sequence like `{a..\\}` may legitimately yield ''. The drop\n  // is on the final strings, so it is applied to whichever `combine` produces\n  // them (the one with no brace set left in the tail).\n  // How many times the `{a},b}` rewrite below has restarted the scan. Each pass\n  // re-reads the whole string, so leaving this unbounded is quadratic.\n  let rewrites = 0\n  let dropEmpties = false\n  let firstGroup = true\n\n  for (;;) {\n    const m = balanced('{', '}', str)\n\n    // No brace set left: the rest of the string is literal.\n    if (!m) {\n      return combine(acc, str, [''], max, maxLength, dropEmpties)\n    }\n\n    // no need to expand pre, since it is guaranteed to be free of brace-sets\n    const pre = m.pre\n\n    if (/\\$$/.test(pre)) {\n      acc = combine(\n        acc,\n        pre + '{' + m.body + '}',\n        [''],\n        max,\n        maxLength,\n        dropEmpties && !m.post.length,\n      )\n      firstGroup = false\n      if (!m.post.length) break\n      str = m.post\n      continue\n    }\n\n    const isNumericSequence = /^-?\\d+\\.\\.-?\\d+(?:\\.\\.-?\\d+)?$/.test(m.body)\n    const isAlphaSequence = /^[a-zA-Z]\\.\\.[a-zA-Z](?:\\.\\.-?\\d+)?$/.test(\n      m.body,\n    )\n    const isSequence = isNumericSequence || isAlphaSequence\n    const isOptions = m.body.indexOf(',') >= 0\n    if (!isSequence && !isOptions) {\n      // {a},b}\n      if (rewrites < maxRewrites && m.post.match(/,(?!,).*\\}/)) {\n        rewrites++\n        str = m.pre + '{' + m.body + escClose + m.post\n        isTop = true\n        continue\n      }\n      // Nothing here expands, so the whole remaining string is literal.\n      return combine(\n        acc,\n        pre + '{' + m.body + '}' + m.post,\n        [''],\n        max,\n        maxLength,\n        dropEmpties,\n      )\n    }\n\n    if (firstGroup) {\n      dropEmpties = isTop && !isSequence\n      firstGroup = false\n    }\n\n    let values: string[]\n    if (isSequence) {\n      values = expandSequence(m.body, isAlphaSequence, max, maxLength)\n    } else {\n      let n = parseCommaParts(m.body)\n      if (n.length === 1 && n[0] !== undefined) {\n        // x{{a,b}}y ==> x{a}y x{b}y\n        n = expand_(\n          n[0],\n          max,\n          maxLength,\n          maxDepth,\n          depth + 1,\n          maxRewrites,\n          false,\n        ).map(embrace)\n        //XXX is this necessary? Can't seem to hit it in tests.\n        /* c8 ignore start */\n        if (n.length === 1) {\n          acc = combine(\n            acc,\n            pre + n[0],\n            [''],\n            max,\n            maxLength,\n            dropEmpties && !m.post.length,\n          )\n          if (!m.post.length) break\n          str = m.post\n          continue\n        }\n        /* c8 ignore stop */\n      }\n\n      // Values that `combine` is going to drop as empty produce no result, so\n      // they must not count against `max` - otherwise `{a,,b}` with `max: 2`\n      // would stop at `['a', '']` and yield one result instead of two. Skipping\n      // them outright keeps `values` bounded while leaving `max` a bound on\n      // *kept* results.\n      let dropsEmpties = dropEmpties && !m.post.length && !pre\n      for (let d = 0; dropsEmpties && d < acc.length; d++) {\n        if (acc[d]) {\n          dropsEmpties = false\n        }\n      }\n\n      values = []\n      let valuesLength = 0\n      outer: for (let j = 0; j < n.length; j++) {\n        const expanded = expand_(\n          n[j] as string,\n          max,\n          maxLength,\n          maxDepth,\n          depth + 1,\n          maxRewrites,\n          false,\n        )\n        for (let k = 0; k < expanded.length; k++) {\n          const v = expanded[k] as string\n          if (dropsEmpties && !v) continue\n          if (\n            values.length >= max ||\n            valuesLength + v.length > maxLength\n          ) {\n            break outer\n          }\n          values.push(v)\n          valuesLength += v.length\n        }\n      }\n    }\n\n    acc = combine(\n      acc,\n      pre,\n      values,\n      max,\n      maxLength,\n      dropEmpties && !m.post.length,\n    )\n    if (!m.post.length) break\n    str = m.post\n  }\n\n  return acc\n}\n"]}
Index: node_modules/brace-expansion/dist/esm/index.d.ts
===================================================================
--- node_modules/brace-expansion/dist/esm/index.d.ts	(revision 81bc7da776d8cda42939ef4ab350c88d13b4941f)
+++ node_modules/brace-expansion/dist/esm/index.d.ts	(revision 33517cc23b4f63a19074ebcdcf7ef56c65850f09)
@@ -1,5 +1,11 @@
 export declare const EXPANSION_MAX = 100000;
+export declare const EXPANSION_MAX_LENGTH = 4000000;
+export declare const EXPANSION_MAX_DEPTH = 1000;
+export declare const EXPANSION_MAX_REWRITES = 1000;
 export type BraceExpansionOptions = {
     max?: number;
+    maxLength?: number;
+    maxDepth?: number;
+    maxRewrites?: number;
 };
 export declare function expand(str: string, options?: BraceExpansionOptions): string[];
Index: node_modules/brace-expansion/dist/esm/index.d.ts.map
===================================================================
--- node_modules/brace-expansion/dist/esm/index.d.ts.map	(revision 81bc7da776d8cda42939ef4ab350c88d13b4941f)
+++ node_modules/brace-expansion/dist/esm/index.d.ts.map	(revision 33517cc23b4f63a19074ebcdcf7ef56c65850f09)
@@ -1,1 +1,1 @@
-{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAkBA,eAAO,MAAM,aAAa,SAAU,CAAA;AAwDpC,MAAM,MAAM,qBAAqB,GAAG;IAClC,GAAG,CAAC,EAAE,MAAM,CAAA;CACb,CAAA;AAED,wBAAgB,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,qBAA0B,YAkBtE"}
+{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAkBA,eAAO,MAAM,aAAa,SAAU,CAAA;AAYpC,eAAO,MAAM,oBAAoB,UAAY,CAAA;AAU7C,eAAO,MAAM,mBAAmB,OAAQ,CAAA;AAUxC,eAAO,MAAM,sBAAsB,OAAQ,CAAA;AAyE3C,MAAM,MAAM,qBAAqB,GAAG;IAClC,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,CAAA;AAED,wBAAgB,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,qBAA0B,YA+BtE"}
Index: node_modules/brace-expansion/dist/esm/index.js
===================================================================
--- node_modules/brace-expansion/dist/esm/index.js	(revision 81bc7da776d8cda42939ef4ab350c88d13b4941f)
+++ node_modules/brace-expansion/dist/esm/index.js	(revision 33517cc23b4f63a19074ebcdcf7ef56c65850f09)
@@ -14,6 +14,35 @@
 const closePattern = /\\}/g;
 const commaPattern = /\\,/g;
-const periodPattern = /\\./g;
+const periodPattern = /\\\./g;
 export const EXPANSION_MAX = 100_000;
+// `EXPANSION_MAX` caps the *number* of expansions, but not their length. An
+// input like `'{a,b}'.repeat(1500)` stays under that count - its output is
+// truncated to 100k results - while making every result ~1500 characters
+// long. The result set, and the intermediate arrays built while combining
+// brace sets, then grow large enough to exhaust memory and crash the process
+// (CVE-2026-14257). `EXPANSION_MAX_LENGTH` bounds the total number of
+// characters the accumulator may hold at any point, so memory stays flat no
+// matter how many brace groups are chained. The limit sits well above any
+// realistic expansion (100k results hitting `EXPANSION_MAX` measure ~1M
+// characters) so legitimate input is unaffected.
+export const EXPANSION_MAX_LENGTH = 4_000_000;
+// `expand_` recurses once per level of brace *nesting* - both when expanding a
+// set's comma members and when re-wrapping a set whose body is a single part.
+// The CVE-2026-14257 fix made the *tail* iterative (recursion on `m.post`, one
+// level per chained group), which left nesting depth unbounded: about 3,100
+// levels of `{{{...a,b...}}}` - only ~6KB of input - exhausted the native stack
+// and crashed the process. `EXPANSION_MAX_DEPTH` bounds how deep the parser
+// will follow nesting. It sits far above any realistic pattern and well below
+// the depth at which the stack runs out.
+export const EXPANSION_MAX_DEPTH = 1_000;
+// Bash keeps a quirk where a brace group followed by a comma set still expands
+// (`{a},b}`). The parser implements it by rewriting the string and restarting
+// the scan, absorbing one `}` per pass. `n` trailing braces therefore cost `n`
+// full passes over a string that itself grows by one `escClose` sentinel each
+// time - quadratic in `n`, with a ~26x constant from the sentinel's length.
+// 128KB of `'{a}' + '}'.repeat(n) + ',z}'` blocked the event loop for 27
+// seconds to produce two results. `EXPANSION_MAX_REWRITES` bounds how many
+// times the scan may restart. Real `{a},b}` input needs a handful.
+export const EXPANSION_MAX_REWRITES = 1_000;
 function numeric(str) {
     return !isNaN(str) ? parseInt(str, 10) : str.charCodeAt(0);
@@ -35,4 +64,10 @@
         .replace(escPeriodPattern, '.');
 }
+// Like `target.push(...items)` but doesn't overflow the stack
+function pushAll(target, items) {
+    for (let i = 0; i < items.length; i++) {
+        target.push(items[i]);
+    }
+}
 /**
  * Basically just str.split(","), but handling cases
@@ -41,23 +76,32 @@
  */
 function parseCommaParts(str) {
-    if (!str) {
-        return [''];
-    }
     const parts = [];
-    const m = balanced('{', '}', str);
-    if (!m) {
-        return str.split(',');
-    }
-    const { pre, body, post } = m;
-    const p = pre.split(',');
-    p[p.length - 1] += '{' + body + '}';
-    const postParts = parseCommaParts(post);
-    if (post.length) {
-        ;
-        p[p.length - 1] += postParts.shift();
-        p.push.apply(p, postParts);
-    }
-    parts.push.apply(parts, p);
-    return parts;
+    // Walk the brace groups iteratively. Recursing on `post` once per group let a
+    // chain of them exhaust the stack - the parsing-side counterpart to
+    // the `expand_` overflow fixed for CVE-2026-14257, and not something `max` or
+    // `maxLength` can bound, since it happens before expansion.
+    //
+    // The part the next chunk continues
+    let carry = '';
+    for (;;) {
+        const m = balanced('{', '}', str);
+        if (!m) {
+            const tail = str.split(',');
+            tail[0] = carry + tail[0];
+            pushAll(parts, tail);
+            return parts;
+        }
+        const { pre, body, post } = m;
+        const p = pre.split(',');
+        p[0] = carry + p[0];
+        p[p.length - 1] += '{' + body + '}';
+        if (!post.length) {
+            pushAll(parts, p);
+            return parts;
+        }
+        carry = p.pop();
+        pushAll(parts, p);
+        str = post;
+    }
 }
 export function expand(str, options = {}) {
@@ -65,5 +109,5 @@
         return [];
     }
-    const { max = EXPANSION_MAX } = options;
+    const { max = EXPANSION_MAX, maxLength = EXPANSION_MAX_LENGTH, maxDepth = EXPANSION_MAX_DEPTH, maxRewrites = EXPANSION_MAX_REWRITES, } = options;
     // I don't know why Bash 4.3 does this, but it does.
     // Anything starting with {} will have the first two bytes preserved
@@ -75,5 +119,5 @@
         str = '\\{\\}' + str.slice(2);
     }
-    return expand_(escapeBraces(str), max, true).map(unescapeBraces);
+    return expand_(escapeBraces(str), max, maxLength, maxDepth, 0, maxRewrites, true).map(unescapeBraces);
 }
 function embrace(str) {
@@ -89,20 +133,124 @@
     return i >= y;
 }
-function expand_(str, max, isTop) {
-    /** @type {string[]} */
-    const expansions = [];
-    const m = balanced('{', '}', str);
-    if (!m)
+// Build `{ acc[a] + pre + values[v] }` for every combination, capping the
+// number of results at `max` and the total number of characters at `maxLength`.
+// This is the one place output grows, so bounding it here keeps the single
+// accumulator - and therefore memory - flat regardless of how many brace groups
+// are combined (CVE-2026-14257).
+function combine(acc, pre, values, max, maxLength, dropEmpties) {
+    const out = [];
+    let length = 0;
+    for (let a = 0; a < acc.length; a++) {
+        for (let v = 0; v < values.length; v++) {
+            if (out.length >= max)
+                return out;
+            const expansion = acc[a] + pre + values[v];
+            // Bash drops empty results at the top level. Skip them before they count
+            // against `max`, so `max` bounds the number of *kept* results.
+            if (dropEmpties && !expansion)
+                continue;
+            if (length + expansion.length > maxLength)
+                return out;
+            out.push(expansion);
+            length += expansion.length;
+        }
+    }
+    return out;
+}
+// The expansion values of a single numeric (`1..5`) or alphabetic (`a..e..2`)
+// sequence body.
+function expandSequence(body, isAlphaSequence, max, maxLength) {
+    const n = body.split(/\.\./);
+    const N = [];
+    // A sequence body always splits into two or three parts, but the compiler
+    // can't know that.
+    /* c8 ignore start */
+    if (n[0] === undefined || n[1] === undefined) {
+        return N;
+    }
+    /* c8 ignore stop */
+    const x = numeric(n[0]);
+    const y = numeric(n[1]);
+    const width = Math.max(n[0].length, n[1].length);
+    let incr = n.length === 3 && n[2] !== undefined ?
+        Math.max(Math.abs(numeric(n[2])), 1)
+        : 1;
+    let test = lte;
+    const reverse = y < x;
+    if (reverse) {
+        incr *= -1;
+        test = gte;
+    }
+    const pad = n.some(isPadded);
+    let length = 0;
+    for (let i = x; test(i, y) && N.length < max; i += incr) {
+        let c;
+        if (isAlphaSequence) {
+            c = String.fromCharCode(i);
+            if (c === '\\') {
+                c = '';
+            }
+        }
+        else {
+            c = String(i);
+            if (pad) {
+                const need = width - c.length;
+                if (need > 0) {
+                    const z = new Array(need + 1).join('0');
+                    if (i < 0) {
+                        c = '-' + z + c.slice(1);
+                    }
+                    else {
+                        c = z + c;
+                    }
+                }
+            }
+        }
+        if (length + c.length > maxLength)
+            break;
+        N.push(c);
+        length += c.length;
+    }
+    return N;
+}
+function expand_(str, max, maxLength, maxDepth, depth, maxRewrites, isTop) {
+    // Too deeply nested to keep following: treat the rest as literal, the same
+    // way a group that cannot expand is already handled. Truncating rather than
+    // throwing keeps `expand` total, matching `max` and `maxLength`.
+    if (depth > maxDepth) {
         return [str];
-    // no need to expand pre, since it is guaranteed to be free of brace-sets
-    const pre = m.pre;
-    const post = m.post.length ? expand_(m.post, max, false) : [''];
-    if (/\$$/.test(m.pre)) {
-        for (let k = 0; k < post.length && k < max; k++) {
-            const expansion = pre + '{' + m.body + '}' + post[k];
-            expansions.push(expansion);
-        }
-    }
-    else {
+    }
+    // Consume the string's top-level brace groups left to right, threading a
+    // running set of combined prefixes (`acc`). Expanding the tail iteratively -
+    // rather than recursing on `m.post` once per group - keeps the native stack
+    // depth constant, so deeply chained input (`'{a,b}'.repeat(3000)`) can no
+    // longer overflow the stack, and leaves a single accumulator whose size
+    // `maxLength` bounds directly (CVE-2026-14257).
+    let acc = [''];
+    // Bash drops empty results, but only when the *first* top-level group is a
+    // comma set - a sequence like `{a..\}` may legitimately yield ''. The drop
+    // is on the final strings, so it is applied to whichever `combine` produces
+    // them (the one with no brace set left in the tail).
+    // How many times the `{a},b}` rewrite below has restarted the scan. Each pass
+    // re-reads the whole string, so leaving this unbounded is quadratic.
+    let rewrites = 0;
+    let dropEmpties = false;
+    let firstGroup = true;
+    for (;;) {
+        const m = balanced('{', '}', str);
+        // No brace set left: the rest of the string is literal.
+        if (!m) {
+            return combine(acc, str, [''], max, maxLength, dropEmpties);
+        }
+        // no need to expand pre, since it is guaranteed to be free of brace-sets
+        const pre = m.pre;
+        if (/\$$/.test(pre)) {
+            acc = combine(acc, pre + '{' + m.body + '}', [''], max, maxLength, dropEmpties && !m.post.length);
+            firstGroup = false;
+            if (!m.post.length)
+                break;
+            str = m.post;
+            continue;
+        }
         const isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body);
         const isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body);
@@ -111,85 +259,71 @@
         if (!isSequence && !isOptions) {
             // {a},b}
-            if (m.post.match(/,(?!,).*\}/)) {
+            if (rewrites < maxRewrites && m.post.match(/,(?!,).*\}/)) {
+                rewrites++;
                 str = m.pre + '{' + m.body + escClose + m.post;
-                return expand_(str, max, true);
-            }
-            return [str];
-        }
-        let n;
+                isTop = true;
+                continue;
+            }
+            // Nothing here expands, so the whole remaining string is literal.
+            return combine(acc, pre + '{' + m.body + '}' + m.post, [''], max, maxLength, dropEmpties);
+        }
+        if (firstGroup) {
+            dropEmpties = isTop && !isSequence;
+            firstGroup = false;
+        }
+        let values;
         if (isSequence) {
-            n = m.body.split(/\.\./);
+            values = expandSequence(m.body, isAlphaSequence, max, maxLength);
         }
         else {
-            n = parseCommaParts(m.body);
+            let n = parseCommaParts(m.body);
             if (n.length === 1 && n[0] !== undefined) {
                 // x{{a,b}}y ==> x{a}y x{b}y
-                n = expand_(n[0], max, false).map(embrace);
+                n = expand_(n[0], max, maxLength, maxDepth, depth + 1, maxRewrites, false).map(embrace);
                 //XXX is this necessary? Can't seem to hit it in tests.
                 /* c8 ignore start */
                 if (n.length === 1) {
-                    return post.map(p => m.pre + n[0] + p);
+                    acc = combine(acc, pre + n[0], [''], max, maxLength, dropEmpties && !m.post.length);
+                    if (!m.post.length)
+                        break;
+                    str = m.post;
+                    continue;
                 }
                 /* c8 ignore stop */
             }
-        }
-        // at this point, n is the parts, and we know it's not a comma set
-        // with a single entry.
-        let N;
-        if (isSequence && n[0] !== undefined && n[1] !== undefined) {
-            const x = numeric(n[0]);
-            const y = numeric(n[1]);
-            const width = Math.max(n[0].length, n[1].length);
-            let incr = n.length === 3 && n[2] !== undefined ? Math.abs(numeric(n[2])) : 1;
-            let test = lte;
-            const reverse = y < x;
-            if (reverse) {
-                incr *= -1;
-                test = gte;
-            }
-            const pad = n.some(isPadded);
-            N = [];
-            for (let i = x; test(i, y); i += incr) {
-                let c;
-                if (isAlphaSequence) {
-                    c = String.fromCharCode(i);
-                    if (c === '\\') {
-                        c = '';
+            // Values that `combine` is going to drop as empty produce no result, so
+            // they must not count against `max` - otherwise `{a,,b}` with `max: 2`
+            // would stop at `['a', '']` and yield one result instead of two. Skipping
+            // them outright keeps `values` bounded while leaving `max` a bound on
+            // *kept* results.
+            let dropsEmpties = dropEmpties && !m.post.length && !pre;
+            for (let d = 0; dropsEmpties && d < acc.length; d++) {
+                if (acc[d]) {
+                    dropsEmpties = false;
+                }
+            }
+            values = [];
+            let valuesLength = 0;
+            outer: for (let j = 0; j < n.length; j++) {
+                const expanded = expand_(n[j], max, maxLength, maxDepth, depth + 1, maxRewrites, false);
+                for (let k = 0; k < expanded.length; k++) {
+                    const v = expanded[k];
+                    if (dropsEmpties && !v)
+                        continue;
+                    if (values.length >= max ||
+                        valuesLength + v.length > maxLength) {
+                        break outer;
                     }
+                    values.push(v);
+                    valuesLength += v.length;
                 }
-                else {
-                    c = String(i);
-                    if (pad) {
-                        const need = width - c.length;
-                        if (need > 0) {
-                            const z = new Array(need + 1).join('0');
-                            if (i < 0) {
-                                c = '-' + z + c.slice(1);
-                            }
-                            else {
-                                c = z + c;
-                            }
-                        }
-                    }
-                }
-                N.push(c);
-            }
-        }
-        else {
-            N = [];
-            for (let j = 0; j < n.length; j++) {
-                N.push.apply(N, expand_(n[j], max, false));
-            }
-        }
-        for (let j = 0; j < N.length; j++) {
-            for (let k = 0; k < post.length && expansions.length < max; k++) {
-                const expansion = pre + N[j] + post[k];
-                if (!isTop || isSequence || expansion) {
-                    expansions.push(expansion);
-                }
-            }
-        }
-    }
-    return expansions;
+            }
+        }
+        acc = combine(acc, pre, values, max, maxLength, dropEmpties && !m.post.length);
+        if (!m.post.length)
+            break;
+        str = m.post;
+    }
+    return acc;
 }
 //# sourceMappingURL=index.js.map
Index: node_modules/brace-expansion/dist/esm/index.js.map
===================================================================
--- node_modules/brace-expansion/dist/esm/index.js.map	(revision 81bc7da776d8cda42939ef4ab350c88d13b4941f)
+++ node_modules/brace-expansion/dist/esm/index.js.map	(revision 33517cc23b4f63a19074ebcdcf7ef56c65850f09)
@@ -1,1 +1,1 @@
-{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { balanced } from 'balanced-match'\n\nconst escSlash = '\\0SLASH' + Math.random() + '\\0'\nconst escOpen = '\\0OPEN' + Math.random() + '\\0'\nconst escClose = '\\0CLOSE' + Math.random() + '\\0'\nconst escComma = '\\0COMMA' + Math.random() + '\\0'\nconst escPeriod = '\\0PERIOD' + Math.random() + '\\0'\nconst escSlashPattern = new RegExp(escSlash, 'g')\nconst escOpenPattern = new RegExp(escOpen, 'g')\nconst escClosePattern = new RegExp(escClose, 'g')\nconst escCommaPattern = new RegExp(escComma, 'g')\nconst escPeriodPattern = new RegExp(escPeriod, 'g')\nconst slashPattern = /\\\\\\\\/g\nconst openPattern = /\\\\{/g\nconst closePattern = /\\\\}/g\nconst commaPattern = /\\\\,/g\nconst periodPattern = /\\\\./g\n\nexport const EXPANSION_MAX = 100_000\n\nfunction numeric(str: string) {\n  return !isNaN(str as any) ? parseInt(str, 10) : str.charCodeAt(0)\n}\n\nfunction escapeBraces(str: string) {\n  return str\n    .replace(slashPattern, escSlash)\n    .replace(openPattern, escOpen)\n    .replace(closePattern, escClose)\n    .replace(commaPattern, escComma)\n    .replace(periodPattern, escPeriod)\n}\n\nfunction unescapeBraces(str: string) {\n  return str\n    .replace(escSlashPattern, '\\\\')\n    .replace(escOpenPattern, '{')\n    .replace(escClosePattern, '}')\n    .replace(escCommaPattern, ',')\n    .replace(escPeriodPattern, '.')\n}\n\n/**\n * Basically just str.split(\",\"), but handling cases\n * where we have nested braced sections, which should be\n * treated as individual members, like {a,{b,c},d}\n */\nfunction parseCommaParts(str: string) {\n  if (!str) {\n    return ['']\n  }\n\n  const parts: string[] = []\n  const m = balanced('{', '}', str)\n\n  if (!m) {\n    return str.split(',')\n  }\n\n  const { pre, body, post } = m\n  const p = pre.split(',')\n\n  p[p.length - 1] += '{' + body + '}'\n  const postParts = parseCommaParts(post)\n  if (post.length) {\n    ;(p[p.length - 1] as string) += postParts.shift()\n    p.push.apply(p, postParts)\n  }\n\n  parts.push.apply(parts, p)\n\n  return parts\n}\n\nexport type BraceExpansionOptions = {\n  max?: number\n}\n\nexport function expand(str: string, options: BraceExpansionOptions = {}) {\n  if (!str) {\n    return []\n  }\n\n  const { max = EXPANSION_MAX } = options\n\n  // I don't know why Bash 4.3 does this, but it does.\n  // Anything starting with {} will have the first two bytes preserved\n  // but *only* at the top level, so {},a}b will not expand to anything,\n  // but a{},b}c will be expanded to [a}c,abc].\n  // One could argue that this is a bug in Bash, but since the goal of\n  // this module is to match Bash's rules, we escape a leading {}\n  if (str.slice(0, 2) === '{}') {\n    str = '\\\\{\\\\}' + str.slice(2)\n  }\n\n  return expand_(escapeBraces(str), max, true).map(unescapeBraces)\n}\n\nfunction embrace(str: string) {\n  return '{' + str + '}'\n}\n\nfunction isPadded(el: string) {\n  return /^-?0\\d/.test(el)\n}\n\nfunction lte(i: number, y: number) {\n  return i <= y\n}\n\nfunction gte(i: number, y: number) {\n  return i >= y\n}\n\nfunction expand_(str: string, max: number, isTop: boolean): string[] {\n  /** @type {string[]} */\n  const expansions: string[] = []\n\n  const m = balanced('{', '}', str)\n  if (!m) return [str]\n\n  // no need to expand pre, since it is guaranteed to be free of brace-sets\n  const pre = m.pre\n  const post: string[] = m.post.length ? expand_(m.post, max, false) : ['']\n\n  if (/\\$$/.test(m.pre)) {\n    for (let k = 0; k < post.length && k < max; k++) {\n      const expansion = pre + '{' + m.body + '}' + post[k]\n      expansions.push(expansion)\n    }\n  } else {\n    const isNumericSequence = /^-?\\d+\\.\\.-?\\d+(?:\\.\\.-?\\d+)?$/.test(m.body)\n    const isAlphaSequence = /^[a-zA-Z]\\.\\.[a-zA-Z](?:\\.\\.-?\\d+)?$/.test(\n      m.body,\n    )\n    const isSequence = isNumericSequence || isAlphaSequence\n    const isOptions = m.body.indexOf(',') >= 0\n    if (!isSequence && !isOptions) {\n      // {a},b}\n      if (m.post.match(/,(?!,).*\\}/)) {\n        str = m.pre + '{' + m.body + escClose + m.post\n        return expand_(str, max, true)\n      }\n      return [str]\n    }\n\n    let n: string[]\n    if (isSequence) {\n      n = m.body.split(/\\.\\./)\n    } else {\n      n = parseCommaParts(m.body)\n      if (n.length === 1 && n[0] !== undefined) {\n        // x{{a,b}}y ==> x{a}y x{b}y\n        n = expand_(n[0], max, false).map(embrace)\n        //XXX is this necessary? Can't seem to hit it in tests.\n        /* c8 ignore start */\n        if (n.length === 1) {\n          return post.map(p => m.pre + n[0] + p)\n        }\n        /* c8 ignore stop */\n      }\n    }\n\n    // at this point, n is the parts, and we know it's not a comma set\n    // with a single entry.\n    let N: string[]\n\n    if (isSequence && n[0] !== undefined && n[1] !== undefined) {\n      const x = numeric(n[0])\n      const y = numeric(n[1])\n      const width = Math.max(n[0].length, n[1].length)\n      let incr =\n        n.length === 3 && n[2] !== undefined ? Math.abs(numeric(n[2])) : 1\n      let test = lte\n      const reverse = y < x\n      if (reverse) {\n        incr *= -1\n        test = gte\n      }\n      const pad = n.some(isPadded)\n\n      N = []\n\n      for (let i = x; test(i, y); i += incr) {\n        let c\n        if (isAlphaSequence) {\n          c = String.fromCharCode(i)\n          if (c === '\\\\') {\n            c = ''\n          }\n        } else {\n          c = String(i)\n          if (pad) {\n            const need = width - c.length\n            if (need > 0) {\n              const z = new Array(need + 1).join('0')\n              if (i < 0) {\n                c = '-' + z + c.slice(1)\n              } else {\n                c = z + c\n              }\n            }\n          }\n        }\n        N.push(c)\n      }\n    } else {\n      N = []\n\n      for (let j = 0; j < n.length; j++) {\n        N.push.apply(N, expand_(n[j] as string, max, false))\n      }\n    }\n\n    for (let j = 0; j < N.length; j++) {\n      for (let k = 0; k < post.length && expansions.length < max; k++) {\n        const expansion = pre + N[j] + post[k]\n        if (!isTop || isSequence || expansion) {\n          expansions.push(expansion)\n        }\n      }\n    }\n  }\n\n  return expansions\n}\n"]}
+{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { balanced } from 'balanced-match'\n\nconst escSlash = '\\0SLASH' + Math.random() + '\\0'\nconst escOpen = '\\0OPEN' + Math.random() + '\\0'\nconst escClose = '\\0CLOSE' + Math.random() + '\\0'\nconst escComma = '\\0COMMA' + Math.random() + '\\0'\nconst escPeriod = '\\0PERIOD' + Math.random() + '\\0'\nconst escSlashPattern = new RegExp(escSlash, 'g')\nconst escOpenPattern = new RegExp(escOpen, 'g')\nconst escClosePattern = new RegExp(escClose, 'g')\nconst escCommaPattern = new RegExp(escComma, 'g')\nconst escPeriodPattern = new RegExp(escPeriod, 'g')\nconst slashPattern = /\\\\\\\\/g\nconst openPattern = /\\\\{/g\nconst closePattern = /\\\\}/g\nconst commaPattern = /\\\\,/g\nconst periodPattern = /\\\\\\./g\n\nexport const EXPANSION_MAX = 100_000\n\n// `EXPANSION_MAX` caps the *number* of expansions, but not their length. An\n// input like `'{a,b}'.repeat(1500)` stays under that count - its output is\n// truncated to 100k results - while making every result ~1500 characters\n// long. The result set, and the intermediate arrays built while combining\n// brace sets, then grow large enough to exhaust memory and crash the process\n// (CVE-2026-14257). `EXPANSION_MAX_LENGTH` bounds the total number of\n// characters the accumulator may hold at any point, so memory stays flat no\n// matter how many brace groups are chained. The limit sits well above any\n// realistic expansion (100k results hitting `EXPANSION_MAX` measure ~1M\n// characters) so legitimate input is unaffected.\nexport const EXPANSION_MAX_LENGTH = 4_000_000\n\n// `expand_` recurses once per level of brace *nesting* - both when expanding a\n// set's comma members and when re-wrapping a set whose body is a single part.\n// The CVE-2026-14257 fix made the *tail* iterative (recursion on `m.post`, one\n// level per chained group), which left nesting depth unbounded: about 3,100\n// levels of `{{{...a,b...}}}` - only ~6KB of input - exhausted the native stack\n// and crashed the process. `EXPANSION_MAX_DEPTH` bounds how deep the parser\n// will follow nesting. It sits far above any realistic pattern and well below\n// the depth at which the stack runs out.\nexport const EXPANSION_MAX_DEPTH = 1_000\n\n// Bash keeps a quirk where a brace group followed by a comma set still expands\n// (`{a},b}`). The parser implements it by rewriting the string and restarting\n// the scan, absorbing one `}` per pass. `n` trailing braces therefore cost `n`\n// full passes over a string that itself grows by one `escClose` sentinel each\n// time - quadratic in `n`, with a ~26x constant from the sentinel's length.\n// 128KB of `'{a}' + '}'.repeat(n) + ',z}'` blocked the event loop for 27\n// seconds to produce two results. `EXPANSION_MAX_REWRITES` bounds how many\n// times the scan may restart. Real `{a},b}` input needs a handful.\nexport const EXPANSION_MAX_REWRITES = 1_000\n\nfunction numeric(str: string) {\n  return !isNaN(str as any) ? parseInt(str, 10) : str.charCodeAt(0)\n}\n\nfunction escapeBraces(str: string) {\n  return str\n    .replace(slashPattern, escSlash)\n    .replace(openPattern, escOpen)\n    .replace(closePattern, escClose)\n    .replace(commaPattern, escComma)\n    .replace(periodPattern, escPeriod)\n}\n\nfunction unescapeBraces(str: string) {\n  return str\n    .replace(escSlashPattern, '\\\\')\n    .replace(escOpenPattern, '{')\n    .replace(escClosePattern, '}')\n    .replace(escCommaPattern, ',')\n    .replace(escPeriodPattern, '.')\n}\n\n// Like `target.push(...items)` but doesn't overflow the stack\nfunction pushAll(target: string[], items: string[]) {\n  for (let i = 0; i < items.length; i++) {\n    target.push(items[i] as string)\n  }\n}\n\n/**\n * Basically just str.split(\",\"), but handling cases\n * where we have nested braced sections, which should be\n * treated as individual members, like {a,{b,c},d}\n */\nfunction parseCommaParts(str: string) {\n  const parts: string[] = []\n\n  // Walk the brace groups iteratively. Recursing on `post` once per group let a\n  // chain of them exhaust the stack - the parsing-side counterpart to\n  // the `expand_` overflow fixed for CVE-2026-14257, and not something `max` or\n  // `maxLength` can bound, since it happens before expansion.\n  //\n  // The part the next chunk continues\n  let carry = ''\n\n  for (;;) {\n    const m = balanced('{', '}', str)\n\n    if (!m) {\n      const tail = str.split(',')\n      tail[0] = carry + (tail[0] as string)\n      pushAll(parts, tail)\n      return parts\n    }\n\n    const { pre, body, post } = m\n    const p = pre.split(',')\n    p[0] = carry + (p[0] as string)\n    p[p.length - 1] += '{' + body + '}'\n\n    if (!post.length) {\n      pushAll(parts, p)\n      return parts\n    }\n\n    carry = p.pop() as string\n    pushAll(parts, p)\n    str = post\n  }\n}\n\nexport type BraceExpansionOptions = {\n  max?: number\n  maxLength?: number\n  maxDepth?: number\n  maxRewrites?: number\n}\n\nexport function expand(str: string, options: BraceExpansionOptions = {}) {\n  if (!str) {\n    return []\n  }\n\n  const {\n    max = EXPANSION_MAX,\n    maxLength = EXPANSION_MAX_LENGTH,\n    maxDepth = EXPANSION_MAX_DEPTH,\n    maxRewrites = EXPANSION_MAX_REWRITES,\n  } = options\n\n  // I don't know why Bash 4.3 does this, but it does.\n  // Anything starting with {} will have the first two bytes preserved\n  // but *only* at the top level, so {},a}b will not expand to anything,\n  // but a{},b}c will be expanded to [a}c,abc].\n  // One could argue that this is a bug in Bash, but since the goal of\n  // this module is to match Bash's rules, we escape a leading {}\n  if (str.slice(0, 2) === '{}') {\n    str = '\\\\{\\\\}' + str.slice(2)\n  }\n\n  return expand_(\n    escapeBraces(str),\n    max,\n    maxLength,\n    maxDepth,\n    0,\n    maxRewrites,\n    true,\n  ).map(unescapeBraces)\n}\n\nfunction embrace(str: string) {\n  return '{' + str + '}'\n}\n\nfunction isPadded(el: string) {\n  return /^-?0\\d/.test(el)\n}\n\nfunction lte(i: number, y: number) {\n  return i <= y\n}\n\nfunction gte(i: number, y: number) {\n  return i >= y\n}\n\n// Build `{ acc[a] + pre + values[v] }` for every combination, capping the\n// number of results at `max` and the total number of characters at `maxLength`.\n// This is the one place output grows, so bounding it here keeps the single\n// accumulator - and therefore memory - flat regardless of how many brace groups\n// are combined (CVE-2026-14257).\nfunction combine(\n  acc: string[],\n  pre: string,\n  values: string[],\n  max: number,\n  maxLength: number,\n  dropEmpties: boolean,\n): string[] {\n  const out: string[] = []\n  let length = 0\n  for (let a = 0; a < acc.length; a++) {\n    for (let v = 0; v < values.length; v++) {\n      if (out.length >= max) return out\n      const expansion = (acc[a] as string) + pre + values[v]\n      // Bash drops empty results at the top level. Skip them before they count\n      // against `max`, so `max` bounds the number of *kept* results.\n      if (dropEmpties && !expansion) continue\n      if (length + expansion.length > maxLength) return out\n      out.push(expansion)\n      length += expansion.length\n    }\n  }\n  return out\n}\n\n// The expansion values of a single numeric (`1..5`) or alphabetic (`a..e..2`)\n// sequence body.\nfunction expandSequence(\n  body: string,\n  isAlphaSequence: boolean,\n  max: number,\n  maxLength: number,\n): string[] {\n  const n = body.split(/\\.\\./)\n  const N: string[] = []\n  // A sequence body always splits into two or three parts, but the compiler\n  // can't know that.\n  /* c8 ignore start */\n  if (n[0] === undefined || n[1] === undefined) {\n    return N\n  }\n  /* c8 ignore stop */\n  const x = numeric(n[0])\n  const y = numeric(n[1])\n  const width = Math.max(n[0].length, n[1].length)\n  let incr =\n    n.length === 3 && n[2] !== undefined ?\n      Math.max(Math.abs(numeric(n[2])), 1)\n    : 1\n  let test = lte\n  const reverse = y < x\n  if (reverse) {\n    incr *= -1\n    test = gte\n  }\n  const pad = n.some(isPadded)\n\n  let length = 0\n  for (let i = x; test(i, y) && N.length < max; i += incr) {\n    let c\n    if (isAlphaSequence) {\n      c = String.fromCharCode(i)\n      if (c === '\\\\') {\n        c = ''\n      }\n    } else {\n      c = String(i)\n      if (pad) {\n        const need = width - c.length\n        if (need > 0) {\n          const z = new Array(need + 1).join('0')\n          if (i < 0) {\n            c = '-' + z + c.slice(1)\n          } else {\n            c = z + c\n          }\n        }\n      }\n    }\n    if (length + c.length > maxLength) break\n    N.push(c)\n    length += c.length\n  }\n  return N\n}\n\nfunction expand_(\n  str: string,\n  max: number,\n  maxLength: number,\n  maxDepth: number,\n  depth: number,\n  maxRewrites: number,\n  isTop: boolean,\n): string[] {\n  // Too deeply nested to keep following: treat the rest as literal, the same\n  // way a group that cannot expand is already handled. Truncating rather than\n  // throwing keeps `expand` total, matching `max` and `maxLength`.\n  if (depth > maxDepth) {\n    return [str]\n  }\n\n  // Consume the string's top-level brace groups left to right, threading a\n  // running set of combined prefixes (`acc`). Expanding the tail iteratively -\n  // rather than recursing on `m.post` once per group - keeps the native stack\n  // depth constant, so deeply chained input (`'{a,b}'.repeat(3000)`) can no\n  // longer overflow the stack, and leaves a single accumulator whose size\n  // `maxLength` bounds directly (CVE-2026-14257).\n  let acc: string[] = ['']\n\n  // Bash drops empty results, but only when the *first* top-level group is a\n  // comma set - a sequence like `{a..\\}` may legitimately yield ''. The drop\n  // is on the final strings, so it is applied to whichever `combine` produces\n  // them (the one with no brace set left in the tail).\n  // How many times the `{a},b}` rewrite below has restarted the scan. Each pass\n  // re-reads the whole string, so leaving this unbounded is quadratic.\n  let rewrites = 0\n  let dropEmpties = false\n  let firstGroup = true\n\n  for (;;) {\n    const m = balanced('{', '}', str)\n\n    // No brace set left: the rest of the string is literal.\n    if (!m) {\n      return combine(acc, str, [''], max, maxLength, dropEmpties)\n    }\n\n    // no need to expand pre, since it is guaranteed to be free of brace-sets\n    const pre = m.pre\n\n    if (/\\$$/.test(pre)) {\n      acc = combine(\n        acc,\n        pre + '{' + m.body + '}',\n        [''],\n        max,\n        maxLength,\n        dropEmpties && !m.post.length,\n      )\n      firstGroup = false\n      if (!m.post.length) break\n      str = m.post\n      continue\n    }\n\n    const isNumericSequence = /^-?\\d+\\.\\.-?\\d+(?:\\.\\.-?\\d+)?$/.test(m.body)\n    const isAlphaSequence = /^[a-zA-Z]\\.\\.[a-zA-Z](?:\\.\\.-?\\d+)?$/.test(\n      m.body,\n    )\n    const isSequence = isNumericSequence || isAlphaSequence\n    const isOptions = m.body.indexOf(',') >= 0\n    if (!isSequence && !isOptions) {\n      // {a},b}\n      if (rewrites < maxRewrites && m.post.match(/,(?!,).*\\}/)) {\n        rewrites++\n        str = m.pre + '{' + m.body + escClose + m.post\n        isTop = true\n        continue\n      }\n      // Nothing here expands, so the whole remaining string is literal.\n      return combine(\n        acc,\n        pre + '{' + m.body + '}' + m.post,\n        [''],\n        max,\n        maxLength,\n        dropEmpties,\n      )\n    }\n\n    if (firstGroup) {\n      dropEmpties = isTop && !isSequence\n      firstGroup = false\n    }\n\n    let values: string[]\n    if (isSequence) {\n      values = expandSequence(m.body, isAlphaSequence, max, maxLength)\n    } else {\n      let n = parseCommaParts(m.body)\n      if (n.length === 1 && n[0] !== undefined) {\n        // x{{a,b}}y ==> x{a}y x{b}y\n        n = expand_(\n          n[0],\n          max,\n          maxLength,\n          maxDepth,\n          depth + 1,\n          maxRewrites,\n          false,\n        ).map(embrace)\n        //XXX is this necessary? Can't seem to hit it in tests.\n        /* c8 ignore start */\n        if (n.length === 1) {\n          acc = combine(\n            acc,\n            pre + n[0],\n            [''],\n            max,\n            maxLength,\n            dropEmpties && !m.post.length,\n          )\n          if (!m.post.length) break\n          str = m.post\n          continue\n        }\n        /* c8 ignore stop */\n      }\n\n      // Values that `combine` is going to drop as empty produce no result, so\n      // they must not count against `max` - otherwise `{a,,b}` with `max: 2`\n      // would stop at `['a', '']` and yield one result instead of two. Skipping\n      // them outright keeps `values` bounded while leaving `max` a bound on\n      // *kept* results.\n      let dropsEmpties = dropEmpties && !m.post.length && !pre\n      for (let d = 0; dropsEmpties && d < acc.length; d++) {\n        if (acc[d]) {\n          dropsEmpties = false\n        }\n      }\n\n      values = []\n      let valuesLength = 0\n      outer: for (let j = 0; j < n.length; j++) {\n        const expanded = expand_(\n          n[j] as string,\n          max,\n          maxLength,\n          maxDepth,\n          depth + 1,\n          maxRewrites,\n          false,\n        )\n        for (let k = 0; k < expanded.length; k++) {\n          const v = expanded[k] as string\n          if (dropsEmpties && !v) continue\n          if (\n            values.length >= max ||\n            valuesLength + v.length > maxLength\n          ) {\n            break outer\n          }\n          values.push(v)\n          valuesLength += v.length\n        }\n      }\n    }\n\n    acc = combine(\n      acc,\n      pre,\n      values,\n      max,\n      maxLength,\n      dropEmpties && !m.post.length,\n    )\n    if (!m.post.length) break\n    str = m.post\n  }\n\n  return acc\n}\n"]}
Index: node_modules/brace-expansion/package.json
===================================================================
--- node_modules/brace-expansion/package.json	(revision 81bc7da776d8cda42939ef4ab350c88d13b4941f)
+++ node_modules/brace-expansion/package.json	(revision 33517cc23b4f63a19074ebcdcf7ef56c65850f09)
@@ -2,5 +2,5 @@
   "name": "brace-expansion",
   "description": "Brace expansion as known from sh/bash",
-  "version": "5.0.3",
+  "version": "5.0.12",
   "files": [
     "dist"
@@ -30,4 +30,5 @@
     "snap": "tap",
     "format": "prettier --write .",
+    "format:check": "prettier --check .",
     "benchmark": "node benchmark/index.js",
     "typedoc": "typedoc --tsconfig .tshy/esm.json ./src/*.ts"
@@ -47,5 +48,5 @@
   "license": "MIT",
   "engines": {
-    "node": "18 || 20 || >=22"
+    "node": "20 || >=22"
   },
   "tshy": {
@@ -60,5 +61,5 @@
   "repository": {
     "type": "git",
-    "url": "git+ssh://git@github.com/juliangruber/brace-expansion.git"
+    "url": "git+https://github.com/juliangruber/brace-expansion.git"
   }
 }
