diff --git a/README.md b/README.md
index 216b55b..8e28949 100644
--- a/README.md
+++ b/README.md
@@ -73,7 +73,7 @@ permissions:
| Name | Default | Description |
|---------------------------|---------------------------------------|------------------------------------------------------------------------------------------------------------------|
-| `metafiles` | - | A required comma-separated list of paths to [esbuild's meta file]([https://esbuild.github.io/api/#metafile]). |
+| `metafiles` | - | A required comma-separated list of paths to [esbuild's meta file]([https://esbuild.github.io/api/#metafile]). Glob (`dist/**/meta.json`) is supported. |
| `name` | ${{ github.event.
repository.name }} | The name of your project. This will be used in the comment header. |
| `analyze_directory` | `.analyzer` | A path to working directory where bundle analysis are stored. |
| `include_extensions` | `.js,.cjs,.mjs` | A comma-separated list of file extension to be included in the analysis table. |
diff --git a/__tests__/__fixtures__/examples/basic/esbuild.mjs b/__tests__/__fixtures__/examples/basic/esbuild.mjs
index cc48781..aa3cf70 100644
--- a/__tests__/__fixtures__/examples/basic/esbuild.mjs
+++ b/__tests__/__fixtures__/examples/basic/esbuild.mjs
@@ -1,4 +1,4 @@
-import { writeFileSync } from "node:fs";
+import {mkdirSync, writeFileSync} from "node:fs";
import { build } from "esbuild";
const result = await build({
@@ -17,4 +17,5 @@ const result = await build({
assetNames: "resources/[name]-[hash]",
});
-writeFileSync(`out/meta.json`, JSON.stringify(result.metafile, null, 2));
+mkdirSync(`out/foo`, { recursive: true });
+writeFileSync(`out/foo/meta.json`, JSON.stringify(result.metafile, null, 2));
diff --git a/__tests__/__fixtures__/examples/multi-outputs/esbuild.mjs b/__tests__/__fixtures__/examples/multi-outputs/esbuild.mjs
index 9433503..14c9fe8 100644
--- a/__tests__/__fixtures__/examples/multi-outputs/esbuild.mjs
+++ b/__tests__/__fixtures__/examples/multi-outputs/esbuild.mjs
@@ -1,4 +1,4 @@
-import { writeFileSync } from "node:fs";
+import { writeFileSync, mkdirSync } from "node:fs";
import { build } from "esbuild";
const result = await build({
@@ -17,4 +17,5 @@ const result = await build({
assetNames: "resources/[name]-[hash]",
});
-writeFileSync(`out/meta.json`, JSON.stringify(result.metafile, null, 2));
+mkdirSync(`out/bar`, { recursive: true });
+writeFileSync(`out/bar/meta.json`, JSON.stringify(result.metafile, null, 2));
diff --git a/__tests__/no-base.test.ts b/__tests__/no-base.test.ts
index a7d83df..9099a5f 100644
--- a/__tests__/no-base.test.ts
+++ b/__tests__/no-base.test.ts
@@ -18,7 +18,7 @@ describe("examples w/o base analysis", () => {
analyzerDirectory: ".analyzer",
percentExtraAttention: 20,
includeExtensions: [".js", ".mjs", ".cjs"],
- metafiles: ["out/meta.json"],
+ metafiles: ["out/**/meta.json"],
name: "test",
showDetails: false,
};
diff --git a/action.yaml b/action.yaml
index b49cee5..3408d79 100644
--- a/action.yaml
+++ b/action.yaml
@@ -9,7 +9,9 @@ inputs:
metafiles:
required: true
description: |
- A comma-separated list of paths to [esbuild's meta file]([https://esbuild.github.io/api/#metafile]). Must be non-empty.
+ A comma-separated list of paths to [esbuild's meta file]([https://esbuild.github.io/api/#metafile]).
+ Must be non-empty.
+ Glob (`dist/**/meta.json`) is supported.
As of esbuild v0.20.0, you need to write the meta file by yourself after build, something like this:
diff --git a/dist/index.mjs b/dist/index.mjs
index f20e162..7fe76b8 100644
--- a/dist/index.mjs
+++ b/dist/index.mjs
@@ -1,26 +1,6566 @@
+var __create = Object.create;
+var __defProp = Object.defineProperty;
+var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
+var __getOwnPropNames = Object.getOwnPropertyNames;
+var __getProtoOf = Object.getPrototypeOf;
+var __hasOwnProp = Object.prototype.hasOwnProperty;
+var __commonJS = (cb, mod) => function __require() {
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
+};
+var __copyProps = (to, from, except, desc) => {
+ if (from && typeof from === "object" || typeof from === "function") {
+ for (let key of __getOwnPropNames(from))
+ if (!__hasOwnProp.call(to, key) && key !== except)
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
+ }
+ return to;
+};
+var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
+ // If the importer is in node compatibility mode or this is not an ESM
+ // file that has been converted to a CommonJS file using a Babel-
+ // compatible transform (i.e. "__esModule" has not been set), then set
+ // "default" to the CommonJS "module.exports" for node compatibility.
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
+ mod
+));
+
+// node_modules/balanced-match/index.js
+var require_balanced_match = __commonJS({
+ "node_modules/balanced-match/index.js"(exports, module) {
+ "use strict";
+ module.exports = balanced;
+ function balanced(a, b, str) {
+ if (a instanceof RegExp)
+ a = maybeMatch(a, str);
+ if (b instanceof RegExp)
+ b = maybeMatch(b, str);
+ var r = range(a, b, str);
+ return r && {
+ start: r[0],
+ end: r[1],
+ pre: str.slice(0, r[0]),
+ body: str.slice(r[0] + a.length, r[1]),
+ post: str.slice(r[1] + b.length)
+ };
+ }
+ function maybeMatch(reg, str) {
+ var m = str.match(reg);
+ return m ? m[0] : null;
+ }
+ balanced.range = range;
+ function range(a, b, str) {
+ var begs, beg, left, right, result;
+ var ai = str.indexOf(a);
+ var bi = str.indexOf(b, ai + 1);
+ var i = ai;
+ if (ai >= 0 && bi > 0) {
+ if (a === b) {
+ return [ai, bi];
+ }
+ begs = [];
+ left = str.length;
+ while (i >= 0 && !result) {
+ if (i == ai) {
+ begs.push(i);
+ ai = str.indexOf(a, i + 1);
+ } else if (begs.length == 1) {
+ result = [begs.pop(), bi];
+ } else {
+ beg = begs.pop();
+ if (beg < left) {
+ left = beg;
+ right = bi;
+ }
+ bi = str.indexOf(b, i + 1);
+ }
+ i = ai < bi && ai >= 0 ? ai : bi;
+ }
+ if (begs.length) {
+ result = [left, right];
+ }
+ }
+ return result;
+ }
+ }
+});
+
+// node_modules/brace-expansion/index.js
+var require_brace_expansion = __commonJS({
+ "node_modules/brace-expansion/index.js"(exports, module) {
+ var balanced = require_balanced_match();
+ module.exports = expandTop;
+ var escSlash = "\0SLASH" + Math.random() + "\0";
+ var escOpen = "\0OPEN" + Math.random() + "\0";
+ var escClose = "\0CLOSE" + Math.random() + "\0";
+ var escComma = "\0COMMA" + Math.random() + "\0";
+ var escPeriod = "\0PERIOD" + Math.random() + "\0";
+ function numeric(str) {
+ return parseInt(str, 10) == str ? parseInt(str, 10) : str.charCodeAt(0);
+ }
+ function escapeBraces(str) {
+ return str.split("\\\\").join(escSlash).split("\\{").join(escOpen).split("\\}").join(escClose).split("\\,").join(escComma).split("\\.").join(escPeriod);
+ }
+ function unescapeBraces(str) {
+ return str.split(escSlash).join("\\").split(escOpen).join("{").split(escClose).join("}").split(escComma).join(",").split(escPeriod).join(".");
+ }
+ function parseCommaParts(str) {
+ if (!str)
+ return [""];
+ var parts = [];
+ var m = balanced("{", "}", str);
+ if (!m)
+ return str.split(",");
+ var pre = m.pre;
+ var body = m.body;
+ var post = m.post;
+ var p = pre.split(",");
+ p[p.length - 1] += "{" + body + "}";
+ var postParts = parseCommaParts(post);
+ if (post.length) {
+ p[p.length - 1] += postParts.shift();
+ p.push.apply(p, postParts);
+ }
+ parts.push.apply(parts, p);
+ return parts;
+ }
+ function expandTop(str) {
+ if (!str)
+ return [];
+ if (str.substr(0, 2) === "{}") {
+ str = "\\{\\}" + str.substr(2);
+ }
+ return expand2(escapeBraces(str), true).map(unescapeBraces);
+ }
+ function embrace(str) {
+ return "{" + str + "}";
+ }
+ function isPadded(el) {
+ return /^-?0\d/.test(el);
+ }
+ function lte(i, y) {
+ return i <= y;
+ }
+ function gte(i, y) {
+ return i >= y;
+ }
+ function expand2(str, isTop) {
+ var expansions = [];
+ var m = balanced("{", "}", str);
+ if (!m)
+ return [str];
+ var pre = m.pre;
+ var post = m.post.length ? expand2(m.post, false) : [""];
+ if (/\$$/.test(m.pre)) {
+ for (var k = 0; k < post.length; k++) {
+ var expansion = pre + "{" + m.body + "}" + post[k];
+ expansions.push(expansion);
+ }
+ } else {
+ var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body);
+ var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body);
+ var isSequence = isNumericSequence || isAlphaSequence;
+ var isOptions = m.body.indexOf(",") >= 0;
+ if (!isSequence && !isOptions) {
+ if (m.post.match(/,.*\}/)) {
+ str = m.pre + "{" + m.body + escClose + m.post;
+ return expand2(str);
+ }
+ return [str];
+ }
+ var n;
+ if (isSequence) {
+ n = m.body.split(/\.\./);
+ } else {
+ n = parseCommaParts(m.body);
+ if (n.length === 1) {
+ n = expand2(n[0], false).map(embrace);
+ if (n.length === 1) {
+ return post.map(function(p) {
+ return m.pre + n[0] + p;
+ });
+ }
+ }
+ }
+ var N;
+ if (isSequence) {
+ var x = numeric(n[0]);
+ var y = numeric(n[1]);
+ var width = Math.max(n[0].length, n[1].length);
+ var incr = n.length == 3 ? Math.abs(numeric(n[2])) : 1;
+ var test = lte;
+ var reverse = y < x;
+ if (reverse) {
+ incr *= -1;
+ test = gte;
+ }
+ var pad = n.some(isPadded);
+ N = [];
+ for (var i = x; test(i, y); i += incr) {
+ var c;
+ if (isAlphaSequence) {
+ c = String.fromCharCode(i);
+ if (c === "\\")
+ c = "";
+ } else {
+ c = String(i);
+ if (pad) {
+ var need = width - c.length;
+ if (need > 0) {
+ var 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 (var j = 0; j < n.length; j++) {
+ N.push.apply(N, expand2(n[j], false));
+ }
+ }
+ for (var j = 0; j < N.length; j++) {
+ for (var k = 0; k < post.length; k++) {
+ var expansion = pre + N[j] + post[k];
+ if (!isTop || isSequence || expansion)
+ expansions.push(expansion);
+ }
+ }
+ }
+ return expansions;
+ }
+ }
+});
+
// src/index.ts
import { pathToFileURL } from "node:url";
-// src/compare.ts
-import fs2 from "node:fs";
-import path from "node:path";
+// src/compare.ts
+import fs3 from "node:fs";
+import path3 from "node:path";
+
+// src/report.ts
+import fs2 from "node:fs";
+import path2 from "node:path";
+import process2 from "node:process";
+import * as console2 from "node:console";
+
+// node_modules/minimatch/dist/esm/index.js
+var import_brace_expansion = __toESM(require_brace_expansion(), 1);
+
+// node_modules/minimatch/dist/esm/assert-valid-pattern.js
+var MAX_PATTERN_LENGTH = 1024 * 64;
+var assertValidPattern = (pattern) => {
+ if (typeof pattern !== "string") {
+ throw new TypeError("invalid pattern");
+ }
+ if (pattern.length > MAX_PATTERN_LENGTH) {
+ throw new TypeError("pattern is too long");
+ }
+};
+
+// node_modules/minimatch/dist/esm/brace-expressions.js
+var posixClasses = {
+ "[:alnum:]": ["\\p{L}\\p{Nl}\\p{Nd}", true],
+ "[:alpha:]": ["\\p{L}\\p{Nl}", true],
+ "[:ascii:]": ["\\x00-\\x7f", false],
+ "[:blank:]": ["\\p{Zs}\\t", true],
+ "[:cntrl:]": ["\\p{Cc}", true],
+ "[:digit:]": ["\\p{Nd}", true],
+ "[:graph:]": ["\\p{Z}\\p{C}", true, true],
+ "[:lower:]": ["\\p{Ll}", true],
+ "[:print:]": ["\\p{C}", true],
+ "[:punct:]": ["\\p{P}", true],
+ "[:space:]": ["\\p{Z}\\t\\r\\n\\v\\f", true],
+ "[:upper:]": ["\\p{Lu}", true],
+ "[:word:]": ["\\p{L}\\p{Nl}\\p{Nd}\\p{Pc}", true],
+ "[:xdigit:]": ["A-Fa-f0-9", false]
+};
+var braceEscape = (s) => s.replace(/[[\]\\-]/g, "\\$&");
+var regexpEscape = (s) => s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
+var rangesToString = (ranges) => ranges.join("");
+var parseClass = (glob2, position) => {
+ const pos = position;
+ if (glob2.charAt(pos) !== "[") {
+ throw new Error("not in a brace expression");
+ }
+ const ranges = [];
+ const negs = [];
+ let i = pos + 1;
+ let sawStart = false;
+ let uflag = false;
+ let escaping = false;
+ let negate = false;
+ let endPos = pos;
+ let rangeStart = "";
+ WHILE:
+ while (i < glob2.length) {
+ const c = glob2.charAt(i);
+ if ((c === "!" || c === "^") && i === pos + 1) {
+ negate = true;
+ i++;
+ continue;
+ }
+ if (c === "]" && sawStart && !escaping) {
+ endPos = i + 1;
+ break;
+ }
+ sawStart = true;
+ if (c === "\\") {
+ if (!escaping) {
+ escaping = true;
+ i++;
+ continue;
+ }
+ }
+ if (c === "[" && !escaping) {
+ for (const [cls, [unip, u, neg]] of Object.entries(posixClasses)) {
+ if (glob2.startsWith(cls, i)) {
+ if (rangeStart) {
+ return ["$.", false, glob2.length - pos, true];
+ }
+ i += cls.length;
+ if (neg)
+ negs.push(unip);
+ else
+ ranges.push(unip);
+ uflag = uflag || u;
+ continue WHILE;
+ }
+ }
+ }
+ escaping = false;
+ if (rangeStart) {
+ if (c > rangeStart) {
+ ranges.push(braceEscape(rangeStart) + "-" + braceEscape(c));
+ } else if (c === rangeStart) {
+ ranges.push(braceEscape(c));
+ }
+ rangeStart = "";
+ i++;
+ continue;
+ }
+ if (glob2.startsWith("-]", i + 1)) {
+ ranges.push(braceEscape(c + "-"));
+ i += 2;
+ continue;
+ }
+ if (glob2.startsWith("-", i + 1)) {
+ rangeStart = c;
+ i += 2;
+ continue;
+ }
+ ranges.push(braceEscape(c));
+ i++;
+ }
+ if (endPos < i) {
+ return ["", false, 0, false];
+ }
+ if (!ranges.length && !negs.length) {
+ return ["$.", false, glob2.length - pos, true];
+ }
+ if (negs.length === 0 && ranges.length === 1 && /^\\?.$/.test(ranges[0]) && !negate) {
+ const r = ranges[0].length === 2 ? ranges[0].slice(-1) : ranges[0];
+ return [regexpEscape(r), false, endPos - pos, false];
+ }
+ const sranges = "[" + (negate ? "^" : "") + rangesToString(ranges) + "]";
+ const snegs = "[" + (negate ? "" : "^") + rangesToString(negs) + "]";
+ const comb = ranges.length && negs.length ? "(" + sranges + "|" + snegs + ")" : ranges.length ? sranges : snegs;
+ return [comb, uflag, endPos - pos, true];
+};
+
+// node_modules/minimatch/dist/esm/unescape.js
+var unescape = (s, { windowsPathsNoEscape = false } = {}) => {
+ return windowsPathsNoEscape ? s.replace(/\[([^\/\\])\]/g, "$1") : s.replace(/((?!\\).|^)\[([^\/\\])\]/g, "$1$2").replace(/\\([^\/])/g, "$1");
+};
+
+// node_modules/minimatch/dist/esm/ast.js
+var types = /* @__PURE__ */ new Set(["!", "?", "+", "*", "@"]);
+var isExtglobType = (c) => types.has(c);
+var startNoTraversal = "(?!(?:^|/)\\.\\.?(?:$|/))";
+var startNoDot = "(?!\\.)";
+var addPatternStart = /* @__PURE__ */ new Set(["[", "."]);
+var justDots = /* @__PURE__ */ new Set(["..", "."]);
+var reSpecials = new Set("().*{}+?[]^$\\!");
+var regExpEscape = (s) => s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
+var qmark = "[^/]";
+var star = qmark + "*?";
+var starNoEmpty = qmark + "+?";
+var AST = class _AST {
+ type;
+ #root;
+ #hasMagic;
+ #uflag = false;
+ #parts = [];
+ #parent;
+ #parentIndex;
+ #negs;
+ #filledNegs = false;
+ #options;
+ #toString;
+ // set to true if it's an extglob with no children
+ // (which really means one child of '')
+ #emptyExt = false;
+ constructor(type, parent, options = {}) {
+ this.type = type;
+ if (type)
+ this.#hasMagic = true;
+ this.#parent = parent;
+ this.#root = this.#parent ? this.#parent.#root : this;
+ this.#options = this.#root === this ? options : this.#root.#options;
+ this.#negs = this.#root === this ? [] : this.#root.#negs;
+ if (type === "!" && !this.#root.#filledNegs)
+ this.#negs.push(this);
+ this.#parentIndex = this.#parent ? this.#parent.#parts.length : 0;
+ }
+ get hasMagic() {
+ if (this.#hasMagic !== void 0)
+ return this.#hasMagic;
+ for (const p of this.#parts) {
+ if (typeof p === "string")
+ continue;
+ if (p.type || p.hasMagic)
+ return this.#hasMagic = true;
+ }
+ return this.#hasMagic;
+ }
+ // reconstructs the pattern
+ toString() {
+ if (this.#toString !== void 0)
+ return this.#toString;
+ if (!this.type) {
+ return this.#toString = this.#parts.map((p) => String(p)).join("");
+ } else {
+ return this.#toString = this.type + "(" + this.#parts.map((p) => String(p)).join("|") + ")";
+ }
+ }
+ #fillNegs() {
+ if (this !== this.#root)
+ throw new Error("should only call on root");
+ if (this.#filledNegs)
+ return this;
+ this.toString();
+ this.#filledNegs = true;
+ let n;
+ while (n = this.#negs.pop()) {
+ if (n.type !== "!")
+ continue;
+ let p = n;
+ let pp = p.#parent;
+ while (pp) {
+ for (let i = p.#parentIndex + 1; !pp.type && i < pp.#parts.length; i++) {
+ for (const part of n.#parts) {
+ if (typeof part === "string") {
+ throw new Error("string part in extglob AST??");
+ }
+ part.copyIn(pp.#parts[i]);
+ }
+ }
+ p = pp;
+ pp = p.#parent;
+ }
+ }
+ return this;
+ }
+ push(...parts) {
+ for (const p of parts) {
+ if (p === "")
+ continue;
+ if (typeof p !== "string" && !(p instanceof _AST && p.#parent === this)) {
+ throw new Error("invalid part: " + p);
+ }
+ this.#parts.push(p);
+ }
+ }
+ toJSON() {
+ const ret = this.type === null ? this.#parts.slice().map((p) => typeof p === "string" ? p : p.toJSON()) : [this.type, ...this.#parts.map((p) => p.toJSON())];
+ if (this.isStart() && !this.type)
+ ret.unshift([]);
+ if (this.isEnd() && (this === this.#root || this.#root.#filledNegs && this.#parent?.type === "!")) {
+ ret.push({});
+ }
+ return ret;
+ }
+ isStart() {
+ if (this.#root === this)
+ return true;
+ if (!this.#parent?.isStart())
+ return false;
+ if (this.#parentIndex === 0)
+ return true;
+ const p = this.#parent;
+ for (let i = 0; i < this.#parentIndex; i++) {
+ const pp = p.#parts[i];
+ if (!(pp instanceof _AST && pp.type === "!")) {
+ return false;
+ }
+ }
+ return true;
+ }
+ isEnd() {
+ if (this.#root === this)
+ return true;
+ if (this.#parent?.type === "!")
+ return true;
+ if (!this.#parent?.isEnd())
+ return false;
+ if (!this.type)
+ return this.#parent?.isEnd();
+ const pl = this.#parent ? this.#parent.#parts.length : 0;
+ return this.#parentIndex === pl - 1;
+ }
+ copyIn(part) {
+ if (typeof part === "string")
+ this.push(part);
+ else
+ this.push(part.clone(this));
+ }
+ clone(parent) {
+ const c = new _AST(this.type, parent);
+ for (const p of this.#parts) {
+ c.copyIn(p);
+ }
+ return c;
+ }
+ static #parseAST(str, ast, pos, opt) {
+ let escaping = false;
+ let inBrace = false;
+ let braceStart = -1;
+ let braceNeg = false;
+ if (ast.type === null) {
+ let i2 = pos;
+ let acc2 = "";
+ while (i2 < str.length) {
+ const c = str.charAt(i2++);
+ if (escaping || c === "\\") {
+ escaping = !escaping;
+ acc2 += c;
+ continue;
+ }
+ if (inBrace) {
+ if (i2 === braceStart + 1) {
+ if (c === "^" || c === "!") {
+ braceNeg = true;
+ }
+ } else if (c === "]" && !(i2 === braceStart + 2 && braceNeg)) {
+ inBrace = false;
+ }
+ acc2 += c;
+ continue;
+ } else if (c === "[") {
+ inBrace = true;
+ braceStart = i2;
+ braceNeg = false;
+ acc2 += c;
+ continue;
+ }
+ if (!opt.noext && isExtglobType(c) && str.charAt(i2) === "(") {
+ ast.push(acc2);
+ acc2 = "";
+ const ext2 = new _AST(c, ast);
+ i2 = _AST.#parseAST(str, ext2, i2, opt);
+ ast.push(ext2);
+ continue;
+ }
+ acc2 += c;
+ }
+ ast.push(acc2);
+ return i2;
+ }
+ let i = pos + 1;
+ let part = new _AST(null, ast);
+ const parts = [];
+ let acc = "";
+ while (i < str.length) {
+ const c = str.charAt(i++);
+ if (escaping || c === "\\") {
+ escaping = !escaping;
+ acc += c;
+ continue;
+ }
+ if (inBrace) {
+ if (i === braceStart + 1) {
+ if (c === "^" || c === "!") {
+ braceNeg = true;
+ }
+ } else if (c === "]" && !(i === braceStart + 2 && braceNeg)) {
+ inBrace = false;
+ }
+ acc += c;
+ continue;
+ } else if (c === "[") {
+ inBrace = true;
+ braceStart = i;
+ braceNeg = false;
+ acc += c;
+ continue;
+ }
+ if (isExtglobType(c) && str.charAt(i) === "(") {
+ part.push(acc);
+ acc = "";
+ const ext2 = new _AST(c, part);
+ part.push(ext2);
+ i = _AST.#parseAST(str, ext2, i, opt);
+ continue;
+ }
+ if (c === "|") {
+ part.push(acc);
+ acc = "";
+ parts.push(part);
+ part = new _AST(null, ast);
+ continue;
+ }
+ if (c === ")") {
+ if (acc === "" && ast.#parts.length === 0) {
+ ast.#emptyExt = true;
+ }
+ part.push(acc);
+ acc = "";
+ ast.push(...parts, part);
+ return i;
+ }
+ acc += c;
+ }
+ ast.type = null;
+ ast.#hasMagic = void 0;
+ ast.#parts = [str.substring(pos - 1)];
+ return i;
+ }
+ static fromGlob(pattern, options = {}) {
+ const ast = new _AST(null, void 0, options);
+ _AST.#parseAST(pattern, ast, 0, options);
+ return ast;
+ }
+ // returns the regular expression if there's magic, or the unescaped
+ // string if not.
+ toMMPattern() {
+ if (this !== this.#root)
+ return this.#root.toMMPattern();
+ const glob2 = this.toString();
+ const [re, body, hasMagic2, uflag] = this.toRegExpSource();
+ const anyMagic = hasMagic2 || this.#hasMagic || this.#options.nocase && !this.#options.nocaseMagicOnly && glob2.toUpperCase() !== glob2.toLowerCase();
+ if (!anyMagic) {
+ return body;
+ }
+ const flags = (this.#options.nocase ? "i" : "") + (uflag ? "u" : "");
+ return Object.assign(new RegExp(`^${re}$`, flags), {
+ _src: re,
+ _glob: glob2
+ });
+ }
+ get options() {
+ return this.#options;
+ }
+ // returns the string match, the regexp source, whether there's magic
+ // in the regexp (so a regular expression is required) and whether or
+ // not the uflag is needed for the regular expression (for posix classes)
+ // TODO: instead of injecting the start/end at this point, just return
+ // the BODY of the regexp, along with the start/end portions suitable
+ // for binding the start/end in either a joined full-path makeRe context
+ // (where we bind to (^|/), or a standalone matchPart context (where
+ // we bind to ^, and not /). Otherwise slashes get duped!
+ //
+ // In part-matching mode, the start is:
+ // - if not isStart: nothing
+ // - if traversal possible, but not allowed: ^(?!\.\.?$)
+ // - if dots allowed or not possible: ^
+ // - if dots possible and not allowed: ^(?!\.)
+ // end is:
+ // - if not isEnd(): nothing
+ // - else: $
+ //
+ // In full-path matching mode, we put the slash at the START of the
+ // pattern, so start is:
+ // - if first pattern: same as part-matching mode
+ // - if not isStart(): nothing
+ // - if traversal possible, but not allowed: /(?!\.\.?(?:$|/))
+ // - if dots allowed or not possible: /
+ // - if dots possible and not allowed: /(?!\.)
+ // end is:
+ // - if last pattern, same as part-matching mode
+ // - else nothing
+ //
+ // Always put the (?:$|/) on negated tails, though, because that has to be
+ // there to bind the end of the negated pattern portion, and it's easier to
+ // just stick it in now rather than try to inject it later in the middle of
+ // the pattern.
+ //
+ // We can just always return the same end, and leave it up to the caller
+ // to know whether it's going to be used joined or in parts.
+ // And, if the start is adjusted slightly, can do the same there:
+ // - if not isStart: nothing
+ // - if traversal possible, but not allowed: (?:/|^)(?!\.\.?$)
+ // - if dots allowed or not possible: (?:/|^)
+ // - if dots possible and not allowed: (?:/|^)(?!\.)
+ //
+ // But it's better to have a simpler binding without a conditional, for
+ // performance, so probably better to return both start options.
+ //
+ // Then the caller just ignores the end if it's not the first pattern,
+ // and the start always gets applied.
+ //
+ // But that's always going to be $ if it's the ending pattern, or nothing,
+ // so the caller can just attach $ at the end of the pattern when building.
+ //
+ // So the todo is:
+ // - better detect what kind of start is needed
+ // - return both flavors of starting pattern
+ // - attach $ at the end of the pattern when creating the actual RegExp
+ //
+ // Ah, but wait, no, that all only applies to the root when the first pattern
+ // is not an extglob. If the first pattern IS an extglob, then we need all
+ // that dot prevention biz to live in the extglob portions, because eg
+ // +(*|.x*) can match .xy but not .yx.
+ //
+ // So, return the two flavors if it's #root and the first child is not an
+ // AST, otherwise leave it to the child AST to handle it, and there,
+ // use the (?:^|/) style of start binding.
+ //
+ // Even simplified further:
+ // - Since the start for a join is eg /(?!\.) and the start for a part
+ // is ^(?!\.), we can just prepend (?!\.) to the pattern (either root
+ // or start or whatever) and prepend ^ or / at the Regexp construction.
+ toRegExpSource(allowDot) {
+ const dot = allowDot ?? !!this.#options.dot;
+ if (this.#root === this)
+ this.#fillNegs();
+ if (!this.type) {
+ const noEmpty = this.isStart() && this.isEnd();
+ const src = this.#parts.map((p) => {
+ const [re, _, hasMagic2, uflag] = typeof p === "string" ? _AST.#parseGlob(p, this.#hasMagic, noEmpty) : p.toRegExpSource(allowDot);
+ this.#hasMagic = this.#hasMagic || hasMagic2;
+ this.#uflag = this.#uflag || uflag;
+ return re;
+ }).join("");
+ let start2 = "";
+ if (this.isStart()) {
+ if (typeof this.#parts[0] === "string") {
+ const dotTravAllowed = this.#parts.length === 1 && justDots.has(this.#parts[0]);
+ if (!dotTravAllowed) {
+ const aps = addPatternStart;
+ const needNoTrav = (
+ // dots are allowed, and the pattern starts with [ or .
+ dot && aps.has(src.charAt(0)) || // the pattern starts with \., and then [ or .
+ src.startsWith("\\.") && aps.has(src.charAt(2)) || // the pattern starts with \.\., and then [ or .
+ src.startsWith("\\.\\.") && aps.has(src.charAt(4))
+ );
+ const needNoDot = !dot && !allowDot && aps.has(src.charAt(0));
+ start2 = needNoTrav ? startNoTraversal : needNoDot ? startNoDot : "";
+ }
+ }
+ }
+ let end = "";
+ if (this.isEnd() && this.#root.#filledNegs && this.#parent?.type === "!") {
+ end = "(?:$|\\/)";
+ }
+ const final2 = start2 + src + end;
+ return [
+ final2,
+ unescape(src),
+ this.#hasMagic = !!this.#hasMagic,
+ this.#uflag
+ ];
+ }
+ const repeated = this.type === "*" || this.type === "+";
+ const start = this.type === "!" ? "(?:(?!(?:" : "(?:";
+ let body = this.#partsToRegExp(dot);
+ if (this.isStart() && this.isEnd() && !body && this.type !== "!") {
+ const s = this.toString();
+ this.#parts = [s];
+ this.type = null;
+ this.#hasMagic = void 0;
+ return [s, unescape(this.toString()), false, false];
+ }
+ let bodyDotAllowed = !repeated || allowDot || dot || !startNoDot ? "" : this.#partsToRegExp(true);
+ if (bodyDotAllowed === body) {
+ bodyDotAllowed = "";
+ }
+ if (bodyDotAllowed) {
+ body = `(?:${body})(?:${bodyDotAllowed})*?`;
+ }
+ let final = "";
+ if (this.type === "!" && this.#emptyExt) {
+ final = (this.isStart() && !dot ? startNoDot : "") + starNoEmpty;
+ } else {
+ const close = this.type === "!" ? (
+ // !() must match something,but !(x) can match ''
+ "))" + (this.isStart() && !dot && !allowDot ? startNoDot : "") + star + ")"
+ ) : this.type === "@" ? ")" : this.type === "?" ? ")?" : this.type === "+" && bodyDotAllowed ? ")" : this.type === "*" && bodyDotAllowed ? `)?` : `)${this.type}`;
+ final = start + body + close;
+ }
+ return [
+ final,
+ unescape(body),
+ this.#hasMagic = !!this.#hasMagic,
+ this.#uflag
+ ];
+ }
+ #partsToRegExp(dot) {
+ return this.#parts.map((p) => {
+ if (typeof p === "string") {
+ throw new Error("string type in extglob ast??");
+ }
+ const [re, _, _hasMagic, uflag] = p.toRegExpSource(dot);
+ this.#uflag = this.#uflag || uflag;
+ return re;
+ }).filter((p) => !(this.isStart() && this.isEnd()) || !!p).join("|");
+ }
+ static #parseGlob(glob2, hasMagic2, noEmpty = false) {
+ let escaping = false;
+ let re = "";
+ let uflag = false;
+ for (let i = 0; i < glob2.length; i++) {
+ const c = glob2.charAt(i);
+ if (escaping) {
+ escaping = false;
+ re += (reSpecials.has(c) ? "\\" : "") + c;
+ continue;
+ }
+ if (c === "\\") {
+ if (i === glob2.length - 1) {
+ re += "\\\\";
+ } else {
+ escaping = true;
+ }
+ continue;
+ }
+ if (c === "[") {
+ const [src, needUflag, consumed, magic] = parseClass(glob2, i);
+ if (consumed) {
+ re += src;
+ uflag = uflag || needUflag;
+ i += consumed - 1;
+ hasMagic2 = hasMagic2 || magic;
+ continue;
+ }
+ }
+ if (c === "*") {
+ if (noEmpty && glob2 === "*")
+ re += starNoEmpty;
+ else
+ re += star;
+ hasMagic2 = true;
+ continue;
+ }
+ if (c === "?") {
+ re += qmark;
+ hasMagic2 = true;
+ continue;
+ }
+ re += regExpEscape(c);
+ }
+ return [re, unescape(glob2), !!hasMagic2, uflag];
+ }
+};
+
+// node_modules/minimatch/dist/esm/escape.js
+var escape = (s, { windowsPathsNoEscape = false } = {}) => {
+ return windowsPathsNoEscape ? s.replace(/[?*()[\]]/g, "[$&]") : s.replace(/[?*()[\]\\]/g, "\\$&");
+};
+
+// node_modules/minimatch/dist/esm/index.js
+var minimatch = (p, pattern, options = {}) => {
+ assertValidPattern(pattern);
+ if (!options.nocomment && pattern.charAt(0) === "#") {
+ return false;
+ }
+ return new Minimatch(pattern, options).match(p);
+};
+var starDotExtRE = /^\*+([^+@!?\*\[\(]*)$/;
+var starDotExtTest = (ext2) => (f) => !f.startsWith(".") && f.endsWith(ext2);
+var starDotExtTestDot = (ext2) => (f) => f.endsWith(ext2);
+var starDotExtTestNocase = (ext2) => {
+ ext2 = ext2.toLowerCase();
+ return (f) => !f.startsWith(".") && f.toLowerCase().endsWith(ext2);
+};
+var starDotExtTestNocaseDot = (ext2) => {
+ ext2 = ext2.toLowerCase();
+ return (f) => f.toLowerCase().endsWith(ext2);
+};
+var starDotStarRE = /^\*+\.\*+$/;
+var starDotStarTest = (f) => !f.startsWith(".") && f.includes(".");
+var starDotStarTestDot = (f) => f !== "." && f !== ".." && f.includes(".");
+var dotStarRE = /^\.\*+$/;
+var dotStarTest = (f) => f !== "." && f !== ".." && f.startsWith(".");
+var starRE = /^\*+$/;
+var starTest = (f) => f.length !== 0 && !f.startsWith(".");
+var starTestDot = (f) => f.length !== 0 && f !== "." && f !== "..";
+var qmarksRE = /^\?+([^+@!?\*\[\(]*)?$/;
+var qmarksTestNocase = ([$0, ext2 = ""]) => {
+ const noext = qmarksTestNoExt([$0]);
+ if (!ext2)
+ return noext;
+ ext2 = ext2.toLowerCase();
+ return (f) => noext(f) && f.toLowerCase().endsWith(ext2);
+};
+var qmarksTestNocaseDot = ([$0, ext2 = ""]) => {
+ const noext = qmarksTestNoExtDot([$0]);
+ if (!ext2)
+ return noext;
+ ext2 = ext2.toLowerCase();
+ return (f) => noext(f) && f.toLowerCase().endsWith(ext2);
+};
+var qmarksTestDot = ([$0, ext2 = ""]) => {
+ const noext = qmarksTestNoExtDot([$0]);
+ return !ext2 ? noext : (f) => noext(f) && f.endsWith(ext2);
+};
+var qmarksTest = ([$0, ext2 = ""]) => {
+ const noext = qmarksTestNoExt([$0]);
+ return !ext2 ? noext : (f) => noext(f) && f.endsWith(ext2);
+};
+var qmarksTestNoExt = ([$0]) => {
+ const len = $0.length;
+ return (f) => f.length === len && !f.startsWith(".");
+};
+var qmarksTestNoExtDot = ([$0]) => {
+ const len = $0.length;
+ return (f) => f.length === len && f !== "." && f !== "..";
+};
+var defaultPlatform = typeof process === "object" && process ? typeof process.env === "object" && process.env && process.env.__MINIMATCH_TESTING_PLATFORM__ || process.platform : "posix";
+var path = {
+ win32: { sep: "\\" },
+ posix: { sep: "/" }
+};
+var sep = defaultPlatform === "win32" ? path.win32.sep : path.posix.sep;
+minimatch.sep = sep;
+var GLOBSTAR = Symbol("globstar **");
+minimatch.GLOBSTAR = GLOBSTAR;
+var qmark2 = "[^/]";
+var star2 = qmark2 + "*?";
+var twoStarDot = "(?:(?!(?:\\/|^)(?:\\.{1,2})($|\\/)).)*?";
+var twoStarNoDot = "(?:(?!(?:\\/|^)\\.).)*?";
+var filter = (pattern, options = {}) => (p) => minimatch(p, pattern, options);
+minimatch.filter = filter;
+var ext = (a, b = {}) => Object.assign({}, a, b);
+var defaults = (def) => {
+ if (!def || typeof def !== "object" || !Object.keys(def).length) {
+ return minimatch;
+ }
+ const orig = minimatch;
+ const m = (p, pattern, options = {}) => orig(p, pattern, ext(def, options));
+ return Object.assign(m, {
+ Minimatch: class Minimatch extends orig.Minimatch {
+ constructor(pattern, options = {}) {
+ super(pattern, ext(def, options));
+ }
+ static defaults(options) {
+ return orig.defaults(ext(def, options)).Minimatch;
+ }
+ },
+ AST: class AST extends orig.AST {
+ /* c8 ignore start */
+ constructor(type, parent, options = {}) {
+ super(type, parent, ext(def, options));
+ }
+ /* c8 ignore stop */
+ static fromGlob(pattern, options = {}) {
+ return orig.AST.fromGlob(pattern, ext(def, options));
+ }
+ },
+ unescape: (s, options = {}) => orig.unescape(s, ext(def, options)),
+ escape: (s, options = {}) => orig.escape(s, ext(def, options)),
+ filter: (pattern, options = {}) => orig.filter(pattern, ext(def, options)),
+ defaults: (options) => orig.defaults(ext(def, options)),
+ makeRe: (pattern, options = {}) => orig.makeRe(pattern, ext(def, options)),
+ braceExpand: (pattern, options = {}) => orig.braceExpand(pattern, ext(def, options)),
+ match: (list, pattern, options = {}) => orig.match(list, pattern, ext(def, options)),
+ sep: orig.sep,
+ GLOBSTAR
+ });
+};
+minimatch.defaults = defaults;
+var braceExpand = (pattern, options = {}) => {
+ assertValidPattern(pattern);
+ if (options.nobrace || !/\{(?:(?!\{).)*\}/.test(pattern)) {
+ return [pattern];
+ }
+ return (0, import_brace_expansion.default)(pattern);
+};
+minimatch.braceExpand = braceExpand;
+var makeRe = (pattern, options = {}) => new Minimatch(pattern, options).makeRe();
+minimatch.makeRe = makeRe;
+var match = (list, pattern, options = {}) => {
+ const mm = new Minimatch(pattern, options);
+ list = list.filter((f) => mm.match(f));
+ if (mm.options.nonull && !list.length) {
+ list.push(pattern);
+ }
+ return list;
+};
+minimatch.match = match;
+var globMagic = /[?*]|[+@!]\(.*?\)|\[|\]/;
+var regExpEscape2 = (s) => s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
+var Minimatch = class {
+ options;
+ set;
+ pattern;
+ windowsPathsNoEscape;
+ nonegate;
+ negate;
+ comment;
+ empty;
+ preserveMultipleSlashes;
+ partial;
+ globSet;
+ globParts;
+ nocase;
+ isWindows;
+ platform;
+ windowsNoMagicRoot;
+ regexp;
+ constructor(pattern, options = {}) {
+ assertValidPattern(pattern);
+ options = options || {};
+ this.options = options;
+ this.pattern = pattern;
+ this.platform = options.platform || defaultPlatform;
+ this.isWindows = this.platform === "win32";
+ this.windowsPathsNoEscape = !!options.windowsPathsNoEscape || options.allowWindowsEscape === false;
+ if (this.windowsPathsNoEscape) {
+ this.pattern = this.pattern.replace(/\\/g, "/");
+ }
+ this.preserveMultipleSlashes = !!options.preserveMultipleSlashes;
+ this.regexp = null;
+ this.negate = false;
+ this.nonegate = !!options.nonegate;
+ this.comment = false;
+ this.empty = false;
+ this.partial = !!options.partial;
+ this.nocase = !!this.options.nocase;
+ this.windowsNoMagicRoot = options.windowsNoMagicRoot !== void 0 ? options.windowsNoMagicRoot : !!(this.isWindows && this.nocase);
+ this.globSet = [];
+ this.globParts = [];
+ this.set = [];
+ this.make();
+ }
+ hasMagic() {
+ if (this.options.magicalBraces && this.set.length > 1) {
+ return true;
+ }
+ for (const pattern of this.set) {
+ for (const part of pattern) {
+ if (typeof part !== "string")
+ return true;
+ }
+ }
+ return false;
+ }
+ debug(..._) {
+ }
+ make() {
+ const pattern = this.pattern;
+ const options = this.options;
+ if (!options.nocomment && pattern.charAt(0) === "#") {
+ this.comment = true;
+ return;
+ }
+ if (!pattern) {
+ this.empty = true;
+ return;
+ }
+ this.parseNegate();
+ this.globSet = [...new Set(this.braceExpand())];
+ if (options.debug) {
+ this.debug = (...args) => console.error(...args);
+ }
+ this.debug(this.pattern, this.globSet);
+ const rawGlobParts = this.globSet.map((s) => this.slashSplit(s));
+ this.globParts = this.preprocess(rawGlobParts);
+ this.debug(this.pattern, this.globParts);
+ let set = this.globParts.map((s, _, __) => {
+ if (this.isWindows && this.windowsNoMagicRoot) {
+ const isUNC = s[0] === "" && s[1] === "" && (s[2] === "?" || !globMagic.test(s[2])) && !globMagic.test(s[3]);
+ const isDrive = /^[a-z]:/i.test(s[0]);
+ if (isUNC) {
+ return [...s.slice(0, 4), ...s.slice(4).map((ss) => this.parse(ss))];
+ } else if (isDrive) {
+ return [s[0], ...s.slice(1).map((ss) => this.parse(ss))];
+ }
+ }
+ return s.map((ss) => this.parse(ss));
+ });
+ this.debug(this.pattern, set);
+ this.set = set.filter((s) => s.indexOf(false) === -1);
+ if (this.isWindows) {
+ for (let i = 0; i < this.set.length; i++) {
+ const p = this.set[i];
+ if (p[0] === "" && p[1] === "" && this.globParts[i][2] === "?" && typeof p[3] === "string" && /^[a-z]:$/i.test(p[3])) {
+ p[2] = "?";
+ }
+ }
+ }
+ this.debug(this.pattern, this.set);
+ }
+ // various transforms to equivalent pattern sets that are
+ // faster to process in a filesystem walk. The goal is to
+ // eliminate what we can, and push all ** patterns as far
+ // to the right as possible, even if it increases the number
+ // of patterns that we have to process.
+ preprocess(globParts) {
+ if (this.options.noglobstar) {
+ for (let i = 0; i < globParts.length; i++) {
+ for (let j = 0; j < globParts[i].length; j++) {
+ if (globParts[i][j] === "**") {
+ globParts[i][j] = "*";
+ }
+ }
+ }
+ }
+ const { optimizationLevel = 1 } = this.options;
+ if (optimizationLevel >= 2) {
+ globParts = this.firstPhasePreProcess(globParts);
+ globParts = this.secondPhasePreProcess(globParts);
+ } else if (optimizationLevel >= 1) {
+ globParts = this.levelOneOptimize(globParts);
+ } else {
+ globParts = this.adjascentGlobstarOptimize(globParts);
+ }
+ return globParts;
+ }
+ // just get rid of adjascent ** portions
+ adjascentGlobstarOptimize(globParts) {
+ return globParts.map((parts) => {
+ let gs = -1;
+ while (-1 !== (gs = parts.indexOf("**", gs + 1))) {
+ let i = gs;
+ while (parts[i + 1] === "**") {
+ i++;
+ }
+ if (i !== gs) {
+ parts.splice(gs, i - gs);
+ }
+ }
+ return parts;
+ });
+ }
+ // get rid of adjascent ** and resolve .. portions
+ levelOneOptimize(globParts) {
+ return globParts.map((parts) => {
+ parts = parts.reduce((set, part) => {
+ const prev = set[set.length - 1];
+ if (part === "**" && prev === "**") {
+ return set;
+ }
+ if (part === "..") {
+ if (prev && prev !== ".." && prev !== "." && prev !== "**") {
+ set.pop();
+ return set;
+ }
+ }
+ set.push(part);
+ return set;
+ }, []);
+ return parts.length === 0 ? [""] : parts;
+ });
+ }
+ levelTwoFileOptimize(parts) {
+ if (!Array.isArray(parts)) {
+ parts = this.slashSplit(parts);
+ }
+ let didSomething = false;
+ do {
+ didSomething = false;
+ if (!this.preserveMultipleSlashes) {
+ for (let i = 1; i < parts.length - 1; i++) {
+ const p = parts[i];
+ if (i === 1 && p === "" && parts[0] === "")
+ continue;
+ if (p === "." || p === "") {
+ didSomething = true;
+ parts.splice(i, 1);
+ i--;
+ }
+ }
+ if (parts[0] === "." && parts.length === 2 && (parts[1] === "." || parts[1] === "")) {
+ didSomething = true;
+ parts.pop();
+ }
+ }
+ let dd = 0;
+ while (-1 !== (dd = parts.indexOf("..", dd + 1))) {
+ const p = parts[dd - 1];
+ if (p && p !== "." && p !== ".." && p !== "**") {
+ didSomething = true;
+ parts.splice(dd - 1, 2);
+ dd -= 2;
+ }
+ }
+ } while (didSomething);
+ return parts.length === 0 ? [""] : parts;
+ }
+ // First phase: single-pattern processing
+ //
is 1 or more portions + //is 1 or more portions + // is any portion other than ., .., '', or ** + //
is . or '' + // + // **/.. is *brutal* for filesystem walking performance, because + // it effectively resets the recursive walk each time it occurs, + // and ** cannot be reduced out by a .. pattern part like a regexp + // or most strings (other than .., ., and '') can be. + // + // /**/..//
/
-> { /..//
/
, /**//
/
} + // // -> /+ // //../
-> /+ // **/**/ -> **/ + // + // **/*/ -> */**/ <== not valid because ** doesn't follow + // this WOULD be allowed if ** did follow symlinks, or * didn't + firstPhasePreProcess(globParts) { + let didSomething = false; + do { + didSomething = false; + for (let parts of globParts) { + let gs = -1; + while (-1 !== (gs = parts.indexOf("**", gs + 1))) { + let gss = gs; + while (parts[gss + 1] === "**") { + gss++; + } + if (gss > gs) { + parts.splice(gs + 1, gss - gs); + } + let next = parts[gs + 1]; + const p = parts[gs + 2]; + const p2 = parts[gs + 3]; + if (next !== "..") + continue; + if (!p || p === "." || p === ".." || !p2 || p2 === "." || p2 === "..") { + continue; + } + didSomething = true; + parts.splice(gs, 1); + const other = parts.slice(0); + other[gs] = "**"; + globParts.push(other); + gs--; + } + if (!this.preserveMultipleSlashes) { + for (let i = 1; i < parts.length - 1; i++) { + const p = parts[i]; + if (i === 1 && p === "" && parts[0] === "") + continue; + if (p === "." || p === "") { + didSomething = true; + parts.splice(i, 1); + i--; + } + } + if (parts[0] === "." && parts.length === 2 && (parts[1] === "." || parts[1] === "")) { + didSomething = true; + parts.pop(); + } + } + let dd = 0; + while (-1 !== (dd = parts.indexOf("..", dd + 1))) { + const p = parts[dd - 1]; + if (p && p !== "." && p !== ".." && p !== "**") { + didSomething = true; + const needDot = dd === 1 && parts[dd + 1] === "**"; + const splin = needDot ? ["."] : []; + parts.splice(dd - 1, 2, ...splin); + if (parts.length === 0) + parts.push(""); + dd -= 2; + } + } + } + } while (didSomething); + return globParts; + } + // second phase: multi-pattern dedupes + // { /*/, //
} -> /*/+ // { /, /} -> /+ // { /**/, /} -> /**/+ // + // { /**/, /**//
} -> /**/+ // ^-- not valid because ** doens't follow symlinks + secondPhasePreProcess(globParts) { + for (let i = 0; i < globParts.length - 1; i++) { + for (let j = i + 1; j < globParts.length; j++) { + const matched = this.partsMatch(globParts[i], globParts[j], !this.preserveMultipleSlashes); + if (!matched) + continue; + globParts[i] = matched; + globParts[j] = []; + } + } + return globParts.filter((gs) => gs.length); + } + partsMatch(a, b, emptyGSMatch = false) { + let ai = 0; + let bi = 0; + let result = []; + let which = ""; + while (ai < a.length && bi < b.length) { + if (a[ai] === b[bi]) { + result.push(which === "b" ? b[bi] : a[ai]); + ai++; + bi++; + } else if (emptyGSMatch && a[ai] === "**" && b[bi] === a[ai + 1]) { + result.push(a[ai]); + ai++; + } else if (emptyGSMatch && b[bi] === "**" && a[ai] === b[bi + 1]) { + result.push(b[bi]); + bi++; + } else if (a[ai] === "*" && b[bi] && (this.options.dot || !b[bi].startsWith(".")) && b[bi] !== "**") { + if (which === "b") + return false; + which = "a"; + result.push(a[ai]); + ai++; + bi++; + } else if (b[bi] === "*" && a[ai] && (this.options.dot || !a[ai].startsWith(".")) && a[ai] !== "**") { + if (which === "a") + return false; + which = "b"; + result.push(b[bi]); + ai++; + bi++; + } else { + return false; + } + } + return a.length === b.length && result; + } + parseNegate() { + if (this.nonegate) + return; + const pattern = this.pattern; + let negate = false; + let negateOffset = 0; + for (let i = 0; i < pattern.length && pattern.charAt(i) === "!"; i++) { + negate = !negate; + negateOffset++; + } + if (negateOffset) + this.pattern = pattern.slice(negateOffset); + this.negate = negate; + } + // set partial to true to test if, for example, + // "/a/b" matches the start of "/*/b/*/d" + // Partial means, if you run out of file before you run + // out of pattern, then that's fine, as long as all + // the parts match. + matchOne(file, pattern, partial = false) { + const options = this.options; + if (this.isWindows) { + const fileDrive = typeof file[0] === "string" && /^[a-z]:$/i.test(file[0]); + const fileUNC = !fileDrive && file[0] === "" && file[1] === "" && file[2] === "?" && /^[a-z]:$/i.test(file[3]); + const patternDrive = typeof pattern[0] === "string" && /^[a-z]:$/i.test(pattern[0]); + const patternUNC = !patternDrive && pattern[0] === "" && pattern[1] === "" && pattern[2] === "?" && typeof pattern[3] === "string" && /^[a-z]:$/i.test(pattern[3]); + const fdi = fileUNC ? 3 : fileDrive ? 0 : void 0; + const pdi = patternUNC ? 3 : patternDrive ? 0 : void 0; + if (typeof fdi === "number" && typeof pdi === "number") { + const [fd, pd] = [file[fdi], pattern[pdi]]; + if (fd.toLowerCase() === pd.toLowerCase()) { + pattern[pdi] = fd; + if (pdi > fdi) { + pattern = pattern.slice(pdi); + } else if (fdi > pdi) { + file = file.slice(fdi); + } + } + } + } + const { optimizationLevel = 1 } = this.options; + if (optimizationLevel >= 2) { + file = this.levelTwoFileOptimize(file); + } + this.debug("matchOne", this, { file, pattern }); + this.debug("matchOne", file.length, pattern.length); + for (var fi = 0, pi = 0, fl = file.length, pl = pattern.length; fi < fl && pi < pl; fi++, pi++) { + this.debug("matchOne loop"); + var p = pattern[pi]; + var f = file[fi]; + this.debug(pattern, p, f); + if (p === false) { + return false; + } + if (p === GLOBSTAR) { + this.debug("GLOBSTAR", [pattern, p, f]); + var fr = fi; + var pr = pi + 1; + if (pr === pl) { + this.debug("** at the end"); + for (; fi < fl; fi++) { + if (file[fi] === "." || file[fi] === ".." || !options.dot && file[fi].charAt(0) === ".") + return false; + } + return true; + } + while (fr < fl) { + var swallowee = file[fr]; + this.debug("\nglobstar while", file, fr, pattern, pr, swallowee); + if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) { + this.debug("globstar found match!", fr, fl, swallowee); + return true; + } else { + if (swallowee === "." || swallowee === ".." || !options.dot && swallowee.charAt(0) === ".") { + this.debug("dot detected!", file, fr, pattern, pr); + break; + } + this.debug("globstar swallow a segment, and continue"); + fr++; + } + } + if (partial) { + this.debug("\n>>> no match, partial?", file, fr, pattern, pr); + if (fr === fl) { + return true; + } + } + return false; + } + let hit; + if (typeof p === "string") { + hit = f === p; + this.debug("string match", p, f, hit); + } else { + hit = p.test(f); + this.debug("pattern match", p, f, hit); + } + if (!hit) + return false; + } + if (fi === fl && pi === pl) { + return true; + } else if (fi === fl) { + return partial; + } else if (pi === pl) { + return fi === fl - 1 && file[fi] === ""; + } else { + throw new Error("wtf?"); + } + } + braceExpand() { + return braceExpand(this.pattern, this.options); + } + parse(pattern) { + assertValidPattern(pattern); + const options = this.options; + if (pattern === "**") + return GLOBSTAR; + if (pattern === "") + return ""; + let m; + let fastTest = null; + if (m = pattern.match(starRE)) { + fastTest = options.dot ? starTestDot : starTest; + } else if (m = pattern.match(starDotExtRE)) { + fastTest = (options.nocase ? options.dot ? starDotExtTestNocaseDot : starDotExtTestNocase : options.dot ? starDotExtTestDot : starDotExtTest)(m[1]); + } else if (m = pattern.match(qmarksRE)) { + fastTest = (options.nocase ? options.dot ? qmarksTestNocaseDot : qmarksTestNocase : options.dot ? qmarksTestDot : qmarksTest)(m); + } else if (m = pattern.match(starDotStarRE)) { + fastTest = options.dot ? starDotStarTestDot : starDotStarTest; + } else if (m = pattern.match(dotStarRE)) { + fastTest = dotStarTest; + } + const re = AST.fromGlob(pattern, this.options).toMMPattern(); + if (fastTest && typeof re === "object") { + Reflect.defineProperty(re, "test", { value: fastTest }); + } + return re; + } + makeRe() { + if (this.regexp || this.regexp === false) + return this.regexp; + const set = this.set; + if (!set.length) { + this.regexp = false; + return this.regexp; + } + const options = this.options; + const twoStar = options.noglobstar ? star2 : options.dot ? twoStarDot : twoStarNoDot; + const flags = new Set(options.nocase ? ["i"] : []); + let re = set.map((pattern) => { + const pp = pattern.map((p) => { + if (p instanceof RegExp) { + for (const f of p.flags.split("")) + flags.add(f); + } + return typeof p === "string" ? regExpEscape2(p) : p === GLOBSTAR ? GLOBSTAR : p._src; + }); + pp.forEach((p, i) => { + const next = pp[i + 1]; + const prev = pp[i - 1]; + if (p !== GLOBSTAR || prev === GLOBSTAR) { + return; + } + if (prev === void 0) { + if (next !== void 0 && next !== GLOBSTAR) { + pp[i + 1] = "(?:\\/|" + twoStar + "\\/)?" + next; + } else { + pp[i] = twoStar; + } + } else if (next === void 0) { + pp[i - 1] = prev + "(?:\\/|" + twoStar + ")?"; + } else if (next !== GLOBSTAR) { + pp[i - 1] = prev + "(?:\\/|\\/" + twoStar + "\\/)" + next; + pp[i + 1] = GLOBSTAR; + } + }); + return pp.filter((p) => p !== GLOBSTAR).join("/"); + }).join("|"); + const [open, close] = set.length > 1 ? ["(?:", ")"] : ["", ""]; + re = "^" + open + re + close + "$"; + if (this.negate) + re = "^(?!" + re + ").+$"; + try { + this.regexp = new RegExp(re, [...flags].join("")); + } catch (ex) { + this.regexp = false; + } + return this.regexp; + } + slashSplit(p) { + if (this.preserveMultipleSlashes) { + return p.split("/"); + } else if (this.isWindows && /^\/\/[^\/]+/.test(p)) { + return ["", ...p.split(/\/+/)]; + } else { + return p.split(/\/+/); + } + } + match(f, partial = this.partial) { + this.debug("match", f, this.pattern); + if (this.comment) { + return false; + } + if (this.empty) { + return f === ""; + } + if (f === "/" && partial) { + return true; + } + const options = this.options; + if (this.isWindows) { + f = f.split("\\").join("/"); + } + const ff = this.slashSplit(f); + this.debug(this.pattern, "split", ff); + const set = this.set; + this.debug(this.pattern, "set", set); + let filename = ff[ff.length - 1]; + if (!filename) { + for (let i = ff.length - 2; !filename && i >= 0; i--) { + filename = ff[i]; + } + } + for (let i = 0; i < set.length; i++) { + const pattern = set[i]; + let file = ff; + if (options.matchBase && pattern.length === 1) { + file = [filename]; + } + const hit = this.matchOne(file, pattern, partial); + if (hit) { + if (options.flipNegate) { + return true; + } + return !this.negate; + } + } + if (options.flipNegate) { + return false; + } + return this.negate; + } + static defaults(def) { + return minimatch.defaults(def).Minimatch; + } +}; +minimatch.AST = AST; +minimatch.Minimatch = Minimatch; +minimatch.escape = escape; +minimatch.unescape = unescape; + +// node_modules/lru-cache/dist/esm/index.js +var perf = typeof performance === "object" && performance && typeof performance.now === "function" ? performance : Date; +var warned = /* @__PURE__ */ new Set(); +var PROCESS = typeof process === "object" && !!process ? process : {}; +var emitWarning = (msg, type, code, fn) => { + typeof PROCESS.emitWarning === "function" ? PROCESS.emitWarning(msg, type, code, fn) : console.error(`[${code}] ${type}: ${msg}`); +}; +var AC = globalThis.AbortController; +var AS = globalThis.AbortSignal; +if (typeof AC === "undefined") { + AS = class AbortSignal { + onabort; + _onabort = []; + reason; + aborted = false; + addEventListener(_, fn) { + this._onabort.push(fn); + } + }; + AC = class AbortController { + constructor() { + warnACPolyfill(); + } + signal = new AS(); + abort(reason) { + if (this.signal.aborted) + return; + this.signal.reason = reason; + this.signal.aborted = true; + for (const fn of this.signal._onabort) { + fn(reason); + } + this.signal.onabort?.(reason); + } + }; + let printACPolyfillWarning = PROCESS.env?.LRU_CACHE_IGNORE_AC_WARNING !== "1"; + const warnACPolyfill = () => { + if (!printACPolyfillWarning) + return; + printACPolyfillWarning = false; + emitWarning("AbortController is not defined. If using lru-cache in node 14, load an AbortController polyfill from the `node-abort-controller` package. A minimal polyfill is provided for use by LRUCache.fetch(), but it should not be relied upon in other contexts (eg, passing it to other APIs that use AbortController/AbortSignal might have undesirable effects). You may disable this with LRU_CACHE_IGNORE_AC_WARNING=1 in the env.", "NO_ABORT_CONTROLLER", "ENOTSUP", warnACPolyfill); + }; +} +var shouldWarn = (code) => !warned.has(code); +var TYPE = Symbol("type"); +var isPosInt = (n) => n && n === Math.floor(n) && n > 0 && isFinite(n); +var getUintArray = (max) => !isPosInt(max) ? null : max <= Math.pow(2, 8) ? Uint8Array : max <= Math.pow(2, 16) ? Uint16Array : max <= Math.pow(2, 32) ? Uint32Array : max <= Number.MAX_SAFE_INTEGER ? ZeroArray : null; +var ZeroArray = class extends Array { + constructor(size) { + super(size); + this.fill(0); + } +}; +var Stack = class _Stack { + heap; + length; + // private constructor + static #constructing = false; + static create(max) { + const HeapCls = getUintArray(max); + if (!HeapCls) + return []; + _Stack.#constructing = true; + const s = new _Stack(max, HeapCls); + _Stack.#constructing = false; + return s; + } + constructor(max, HeapCls) { + if (!_Stack.#constructing) { + throw new TypeError("instantiate Stack using Stack.create(n)"); + } + this.heap = new HeapCls(max); + this.length = 0; + } + push(n) { + this.heap[this.length++] = n; + } + pop() { + return this.heap[--this.length]; + } +}; +var LRUCache = class _LRUCache { + // properties coming in from the options of these, only max and maxSize + // really *need* to be protected. The rest can be modified, as they just + // set defaults for various methods. + #max; + #maxSize; + #dispose; + #disposeAfter; + #fetchMethod; + /** + * {@link LRUCache.OptionsBase.ttl} + */ + ttl; + /** + * {@link LRUCache.OptionsBase.ttlResolution} + */ + ttlResolution; + /** + * {@link LRUCache.OptionsBase.ttlAutopurge} + */ + ttlAutopurge; + /** + * {@link LRUCache.OptionsBase.updateAgeOnGet} + */ + updateAgeOnGet; + /** + * {@link LRUCache.OptionsBase.updateAgeOnHas} + */ + updateAgeOnHas; + /** + * {@link LRUCache.OptionsBase.allowStale} + */ + allowStale; + /** + * {@link LRUCache.OptionsBase.noDisposeOnSet} + */ + noDisposeOnSet; + /** + * {@link LRUCache.OptionsBase.noUpdateTTL} + */ + noUpdateTTL; + /** + * {@link LRUCache.OptionsBase.maxEntrySize} + */ + maxEntrySize; + /** + * {@link LRUCache.OptionsBase.sizeCalculation} + */ + sizeCalculation; + /** + * {@link LRUCache.OptionsBase.noDeleteOnFetchRejection} + */ + noDeleteOnFetchRejection; + /** + * {@link LRUCache.OptionsBase.noDeleteOnStaleGet} + */ + noDeleteOnStaleGet; + /** + * {@link LRUCache.OptionsBase.allowStaleOnFetchAbort} + */ + allowStaleOnFetchAbort; + /** + * {@link LRUCache.OptionsBase.allowStaleOnFetchRejection} + */ + allowStaleOnFetchRejection; + /** + * {@link LRUCache.OptionsBase.ignoreFetchAbort} + */ + ignoreFetchAbort; + // computed properties + #size; + #calculatedSize; + #keyMap; + #keyList; + #valList; + #next; + #prev; + #head; + #tail; + #free; + #disposed; + #sizes; + #starts; + #ttls; + #hasDispose; + #hasFetchMethod; + #hasDisposeAfter; + /** + * Do not call this method unless you need to inspect the + * inner workings of the cache. If anything returned by this + * object is modified in any way, strange breakage may occur. + * + * These fields are private for a reason! + * + * @internal + */ + static unsafeExposeInternals(c) { + return { + // properties + starts: c.#starts, + ttls: c.#ttls, + sizes: c.#sizes, + keyMap: c.#keyMap, + keyList: c.#keyList, + valList: c.#valList, + next: c.#next, + prev: c.#prev, + get head() { + return c.#head; + }, + get tail() { + return c.#tail; + }, + free: c.#free, + // methods + isBackgroundFetch: (p) => c.#isBackgroundFetch(p), + backgroundFetch: (k, index, options, context) => c.#backgroundFetch(k, index, options, context), + moveToTail: (index) => c.#moveToTail(index), + indexes: (options) => c.#indexes(options), + rindexes: (options) => c.#rindexes(options), + isStale: (index) => c.#isStale(index) + }; + } + // Protected read-only members + /** + * {@link LRUCache.OptionsBase.max} (read-only) + */ + get max() { + return this.#max; + } + /** + * {@link LRUCache.OptionsBase.maxSize} (read-only) + */ + get maxSize() { + return this.#maxSize; + } + /** + * The total computed size of items in the cache (read-only) + */ + get calculatedSize() { + return this.#calculatedSize; + } + /** + * The number of items stored in the cache (read-only) + */ + get size() { + return this.#size; + } + /** + * {@link LRUCache.OptionsBase.fetchMethod} (read-only) + */ + get fetchMethod() { + return this.#fetchMethod; + } + /** + * {@link LRUCache.OptionsBase.dispose} (read-only) + */ + get dispose() { + return this.#dispose; + } + /** + * {@link LRUCache.OptionsBase.disposeAfter} (read-only) + */ + get disposeAfter() { + return this.#disposeAfter; + } + constructor(options) { + const { max = 0, ttl, ttlResolution = 1, ttlAutopurge, updateAgeOnGet, updateAgeOnHas, allowStale, dispose, disposeAfter, noDisposeOnSet, noUpdateTTL, maxSize = 0, maxEntrySize = 0, sizeCalculation, fetchMethod, noDeleteOnFetchRejection, noDeleteOnStaleGet, allowStaleOnFetchRejection, allowStaleOnFetchAbort, ignoreFetchAbort } = options; + if (max !== 0 && !isPosInt(max)) { + throw new TypeError("max option must be a nonnegative integer"); + } + const UintArray = max ? getUintArray(max) : Array; + if (!UintArray) { + throw new Error("invalid max value: " + max); + } + this.#max = max; + this.#maxSize = maxSize; + this.maxEntrySize = maxEntrySize || this.#maxSize; + this.sizeCalculation = sizeCalculation; + if (this.sizeCalculation) { + if (!this.#maxSize && !this.maxEntrySize) { + throw new TypeError("cannot set sizeCalculation without setting maxSize or maxEntrySize"); + } + if (typeof this.sizeCalculation !== "function") { + throw new TypeError("sizeCalculation set to non-function"); + } + } + if (fetchMethod !== void 0 && typeof fetchMethod !== "function") { + throw new TypeError("fetchMethod must be a function if specified"); + } + this.#fetchMethod = fetchMethod; + this.#hasFetchMethod = !!fetchMethod; + this.#keyMap = /* @__PURE__ */ new Map(); + this.#keyList = new Array(max).fill(void 0); + this.#valList = new Array(max).fill(void 0); + this.#next = new UintArray(max); + this.#prev = new UintArray(max); + this.#head = 0; + this.#tail = 0; + this.#free = Stack.create(max); + this.#size = 0; + this.#calculatedSize = 0; + if (typeof dispose === "function") { + this.#dispose = dispose; + } + if (typeof disposeAfter === "function") { + this.#disposeAfter = disposeAfter; + this.#disposed = []; + } else { + this.#disposeAfter = void 0; + this.#disposed = void 0; + } + this.#hasDispose = !!this.#dispose; + this.#hasDisposeAfter = !!this.#disposeAfter; + this.noDisposeOnSet = !!noDisposeOnSet; + this.noUpdateTTL = !!noUpdateTTL; + this.noDeleteOnFetchRejection = !!noDeleteOnFetchRejection; + this.allowStaleOnFetchRejection = !!allowStaleOnFetchRejection; + this.allowStaleOnFetchAbort = !!allowStaleOnFetchAbort; + this.ignoreFetchAbort = !!ignoreFetchAbort; + if (this.maxEntrySize !== 0) { + if (this.#maxSize !== 0) { + if (!isPosInt(this.#maxSize)) { + throw new TypeError("maxSize must be a positive integer if specified"); + } + } + if (!isPosInt(this.maxEntrySize)) { + throw new TypeError("maxEntrySize must be a positive integer if specified"); + } + this.#initializeSizeTracking(); + } + this.allowStale = !!allowStale; + this.noDeleteOnStaleGet = !!noDeleteOnStaleGet; + this.updateAgeOnGet = !!updateAgeOnGet; + this.updateAgeOnHas = !!updateAgeOnHas; + this.ttlResolution = isPosInt(ttlResolution) || ttlResolution === 0 ? ttlResolution : 1; + this.ttlAutopurge = !!ttlAutopurge; + this.ttl = ttl || 0; + if (this.ttl) { + if (!isPosInt(this.ttl)) { + throw new TypeError("ttl must be a positive integer if specified"); + } + this.#initializeTTLTracking(); + } + if (this.#max === 0 && this.ttl === 0 && this.#maxSize === 0) { + throw new TypeError("At least one of max, maxSize, or ttl is required"); + } + if (!this.ttlAutopurge && !this.#max && !this.#maxSize) { + const code = "LRU_CACHE_UNBOUNDED"; + if (shouldWarn(code)) { + warned.add(code); + const msg = "TTL caching without ttlAutopurge, max, or maxSize can result in unbounded memory consumption."; + emitWarning(msg, "UnboundedCacheWarning", code, _LRUCache); + } + } + } + /** + * Return the remaining TTL time for a given entry key + */ + getRemainingTTL(key) { + return this.#keyMap.has(key) ? Infinity : 0; + } + #initializeTTLTracking() { + const ttls = new ZeroArray(this.#max); + const starts = new ZeroArray(this.#max); + this.#ttls = ttls; + this.#starts = starts; + this.#setItemTTL = (index, ttl, start = perf.now()) => { + starts[index] = ttl !== 0 ? start : 0; + ttls[index] = ttl; + if (ttl !== 0 && this.ttlAutopurge) { + const t = setTimeout(() => { + if (this.#isStale(index)) { + this.delete(this.#keyList[index]); + } + }, ttl + 1); + if (t.unref) { + t.unref(); + } + } + }; + this.#updateItemAge = (index) => { + starts[index] = ttls[index] !== 0 ? perf.now() : 0; + }; + this.#statusTTL = (status, index) => { + if (ttls[index]) { + const ttl = ttls[index]; + const start = starts[index]; + if (!ttl || !start) + return; + status.ttl = ttl; + status.start = start; + status.now = cachedNow || getNow(); + const age = status.now - start; + status.remainingTTL = ttl - age; + } + }; + let cachedNow = 0; + const getNow = () => { + const n = perf.now(); + if (this.ttlResolution > 0) { + cachedNow = n; + const t = setTimeout(() => cachedNow = 0, this.ttlResolution); + if (t.unref) { + t.unref(); + } + } + return n; + }; + this.getRemainingTTL = (key) => { + const index = this.#keyMap.get(key); + if (index === void 0) { + return 0; + } + const ttl = ttls[index]; + const start = starts[index]; + if (!ttl || !start) { + return Infinity; + } + const age = (cachedNow || getNow()) - start; + return ttl - age; + }; + this.#isStale = (index) => { + const s = starts[index]; + const t = ttls[index]; + return !!t && !!s && (cachedNow || getNow()) - s > t; + }; + } + // conditionally set private methods related to TTL + #updateItemAge = () => { + }; + #statusTTL = () => { + }; + #setItemTTL = () => { + }; + /* c8 ignore stop */ + #isStale = () => false; + #initializeSizeTracking() { + const sizes = new ZeroArray(this.#max); + this.#calculatedSize = 0; + this.#sizes = sizes; + this.#removeItemSize = (index) => { + this.#calculatedSize -= sizes[index]; + sizes[index] = 0; + }; + this.#requireSize = (k, v, size, sizeCalculation) => { + if (this.#isBackgroundFetch(v)) { + return 0; + } + if (!isPosInt(size)) { + if (sizeCalculation) { + if (typeof sizeCalculation !== "function") { + throw new TypeError("sizeCalculation must be a function"); + } + size = sizeCalculation(v, k); + if (!isPosInt(size)) { + throw new TypeError("sizeCalculation return invalid (expect positive integer)"); + } + } else { + throw new TypeError("invalid size value (must be positive integer). When maxSize or maxEntrySize is used, sizeCalculation or size must be set."); + } + } + return size; + }; + this.#addItemSize = (index, size, status) => { + sizes[index] = size; + if (this.#maxSize) { + const maxSize = this.#maxSize - sizes[index]; + while (this.#calculatedSize > maxSize) { + this.#evict(true); + } + } + this.#calculatedSize += sizes[index]; + if (status) { + status.entrySize = size; + status.totalCalculatedSize = this.#calculatedSize; + } + }; + } + #removeItemSize = (_i) => { + }; + #addItemSize = (_i, _s, _st) => { + }; + #requireSize = (_k, _v, size, sizeCalculation) => { + if (size || sizeCalculation) { + throw new TypeError("cannot set size without setting maxSize or maxEntrySize on cache"); + } + return 0; + }; + *#indexes({ allowStale = this.allowStale } = {}) { + if (this.#size) { + for (let i = this.#tail; true; ) { + if (!this.#isValidIndex(i)) { + break; + } + if (allowStale || !this.#isStale(i)) { + yield i; + } + if (i === this.#head) { + break; + } else { + i = this.#prev[i]; + } + } + } + } + *#rindexes({ allowStale = this.allowStale } = {}) { + if (this.#size) { + for (let i = this.#head; true; ) { + if (!this.#isValidIndex(i)) { + break; + } + if (allowStale || !this.#isStale(i)) { + yield i; + } + if (i === this.#tail) { + break; + } else { + i = this.#next[i]; + } + } + } + } + #isValidIndex(index) { + return index !== void 0 && this.#keyMap.get(this.#keyList[index]) === index; + } + /** + * Return a generator yielding `[key, value]` pairs, + * in order from most recently used to least recently used. + */ + *entries() { + for (const i of this.#indexes()) { + if (this.#valList[i] !== void 0 && this.#keyList[i] !== void 0 && !this.#isBackgroundFetch(this.#valList[i])) { + yield [this.#keyList[i], this.#valList[i]]; + } + } + } + /** + * Inverse order version of {@link LRUCache.entries} + * + * Return a generator yielding `[key, value]` pairs, + * in order from least recently used to most recently used. + */ + *rentries() { + for (const i of this.#rindexes()) { + if (this.#valList[i] !== void 0 && this.#keyList[i] !== void 0 && !this.#isBackgroundFetch(this.#valList[i])) { + yield [this.#keyList[i], this.#valList[i]]; + } + } + } + /** + * Return a generator yielding the keys in the cache, + * in order from most recently used to least recently used. + */ + *keys() { + for (const i of this.#indexes()) { + const k = this.#keyList[i]; + if (k !== void 0 && !this.#isBackgroundFetch(this.#valList[i])) { + yield k; + } + } + } + /** + * Inverse order version of {@link LRUCache.keys} + * + * Return a generator yielding the keys in the cache, + * in order from least recently used to most recently used. + */ + *rkeys() { + for (const i of this.#rindexes()) { + const k = this.#keyList[i]; + if (k !== void 0 && !this.#isBackgroundFetch(this.#valList[i])) { + yield k; + } + } + } + /** + * Return a generator yielding the values in the cache, + * in order from most recently used to least recently used. + */ + *values() { + for (const i of this.#indexes()) { + const v = this.#valList[i]; + if (v !== void 0 && !this.#isBackgroundFetch(this.#valList[i])) { + yield this.#valList[i]; + } + } + } + /** + * Inverse order version of {@link LRUCache.values} + * + * Return a generator yielding the values in the cache, + * in order from least recently used to most recently used. + */ + *rvalues() { + for (const i of this.#rindexes()) { + const v = this.#valList[i]; + if (v !== void 0 && !this.#isBackgroundFetch(this.#valList[i])) { + yield this.#valList[i]; + } + } + } + /** + * Iterating over the cache itself yields the same results as + * {@link LRUCache.entries} + */ + [Symbol.iterator]() { + return this.entries(); + } + /** + * A String value that is used in the creation of the default string description of an object. + * Called by the built-in method Object.prototype.toString. + */ + [Symbol.toStringTag] = "LRUCache"; + /** + * Find a value for which the supplied fn method returns a truthy value, + * similar to Array.find(). fn is called as fn(value, key, cache). + */ + find(fn, getOptions = {}) { + for (const i of this.#indexes()) { + const v = this.#valList[i]; + const value = this.#isBackgroundFetch(v) ? v.__staleWhileFetching : v; + if (value === void 0) + continue; + if (fn(value, this.#keyList[i], this)) { + return this.get(this.#keyList[i], getOptions); + } + } + } + /** + * Call the supplied function on each item in the cache, in order from + * most recently used to least recently used. fn is called as + * fn(value, key, cache). Does not update age or recenty of use. + * Does not iterate over stale values. + */ + forEach(fn, thisp = this) { + for (const i of this.#indexes()) { + const v = this.#valList[i]; + const value = this.#isBackgroundFetch(v) ? v.__staleWhileFetching : v; + if (value === void 0) + continue; + fn.call(thisp, value, this.#keyList[i], this); + } + } + /** + * The same as {@link LRUCache.forEach} but items are iterated over in + * reverse order. (ie, less recently used items are iterated over first.) + */ + rforEach(fn, thisp = this) { + for (const i of this.#rindexes()) { + const v = this.#valList[i]; + const value = this.#isBackgroundFetch(v) ? v.__staleWhileFetching : v; + if (value === void 0) + continue; + fn.call(thisp, value, this.#keyList[i], this); + } + } + /** + * Delete any stale entries. Returns true if anything was removed, + * false otherwise. + */ + purgeStale() { + let deleted = false; + for (const i of this.#rindexes({ allowStale: true })) { + if (this.#isStale(i)) { + this.delete(this.#keyList[i]); + deleted = true; + } + } + return deleted; + } + /** + * Get the extended info about a given entry, to get its value, size, and + * TTL info simultaneously. Like {@link LRUCache#dump}, but just for a + * single key. Always returns stale values, if their info is found in the + * cache, so be sure to check for expired TTLs if relevant. + */ + info(key) { + const i = this.#keyMap.get(key); + if (i === void 0) + return void 0; + const v = this.#valList[i]; + const value = this.#isBackgroundFetch(v) ? v.__staleWhileFetching : v; + if (value === void 0) + return void 0; + const entry = { value }; + if (this.#ttls && this.#starts) { + const ttl = this.#ttls[i]; + const start = this.#starts[i]; + if (ttl && start) { + const remain = ttl - (perf.now() - start); + entry.ttl = remain; + entry.start = Date.now(); + } + } + if (this.#sizes) { + entry.size = this.#sizes[i]; + } + return entry; + } + /** + * Return an array of [key, {@link LRUCache.Entry}] tuples which can be + * passed to cache.load() + */ + dump() { + const arr = []; + for (const i of this.#indexes({ allowStale: true })) { + const key = this.#keyList[i]; + const v = this.#valList[i]; + const value = this.#isBackgroundFetch(v) ? v.__staleWhileFetching : v; + if (value === void 0 || key === void 0) + continue; + const entry = { value }; + if (this.#ttls && this.#starts) { + entry.ttl = this.#ttls[i]; + const age = perf.now() - this.#starts[i]; + entry.start = Math.floor(Date.now() - age); + } + if (this.#sizes) { + entry.size = this.#sizes[i]; + } + arr.unshift([key, entry]); + } + return arr; + } + /** + * Reset the cache and load in the items in entries in the order listed. + * Note that the shape of the resulting cache may be different if the + * same options are not used in both caches. + */ + load(arr) { + this.clear(); + for (const [key, entry] of arr) { + if (entry.start) { + const age = Date.now() - entry.start; + entry.start = perf.now() - age; + } + this.set(key, entry.value, entry); + } + } + /** + * Add a value to the cache. + * + * Note: if `undefined` is specified as a value, this is an alias for + * {@link LRUCache#delete} + */ + set(k, v, setOptions = {}) { + if (v === void 0) { + this.delete(k); + return this; + } + const { ttl = this.ttl, start, noDisposeOnSet = this.noDisposeOnSet, sizeCalculation = this.sizeCalculation, status } = setOptions; + let { noUpdateTTL = this.noUpdateTTL } = setOptions; + const size = this.#requireSize(k, v, setOptions.size || 0, sizeCalculation); + if (this.maxEntrySize && size > this.maxEntrySize) { + if (status) { + status.set = "miss"; + status.maxEntrySizeExceeded = true; + } + this.delete(k); + return this; + } + let index = this.#size === 0 ? void 0 : this.#keyMap.get(k); + if (index === void 0) { + index = this.#size === 0 ? this.#tail : this.#free.length !== 0 ? this.#free.pop() : this.#size === this.#max ? this.#evict(false) : this.#size; + this.#keyList[index] = k; + this.#valList[index] = v; + this.#keyMap.set(k, index); + this.#next[this.#tail] = index; + this.#prev[index] = this.#tail; + this.#tail = index; + this.#size++; + this.#addItemSize(index, size, status); + if (status) + status.set = "add"; + noUpdateTTL = false; + } else { + this.#moveToTail(index); + const oldVal = this.#valList[index]; + if (v !== oldVal) { + if (this.#hasFetchMethod && this.#isBackgroundFetch(oldVal)) { + oldVal.__abortController.abort(new Error("replaced")); + const { __staleWhileFetching: s } = oldVal; + if (s !== void 0 && !noDisposeOnSet) { + if (this.#hasDispose) { + this.#dispose?.(s, k, "set"); + } + if (this.#hasDisposeAfter) { + this.#disposed?.push([s, k, "set"]); + } + } + } else if (!noDisposeOnSet) { + if (this.#hasDispose) { + this.#dispose?.(oldVal, k, "set"); + } + if (this.#hasDisposeAfter) { + this.#disposed?.push([oldVal, k, "set"]); + } + } + this.#removeItemSize(index); + this.#addItemSize(index, size, status); + this.#valList[index] = v; + if (status) { + status.set = "replace"; + const oldValue = oldVal && this.#isBackgroundFetch(oldVal) ? oldVal.__staleWhileFetching : oldVal; + if (oldValue !== void 0) + status.oldValue = oldValue; + } + } else if (status) { + status.set = "update"; + } + } + if (ttl !== 0 && !this.#ttls) { + this.#initializeTTLTracking(); + } + if (this.#ttls) { + if (!noUpdateTTL) { + this.#setItemTTL(index, ttl, start); + } + if (status) + this.#statusTTL(status, index); + } + if (!noDisposeOnSet && this.#hasDisposeAfter && this.#disposed) { + const dt = this.#disposed; + let task; + while (task = dt?.shift()) { + this.#disposeAfter?.(...task); + } + } + return this; + } + /** + * Evict the least recently used item, returning its value or + * `undefined` if cache is empty. + */ + pop() { + try { + while (this.#size) { + const val = this.#valList[this.#head]; + this.#evict(true); + if (this.#isBackgroundFetch(val)) { + if (val.__staleWhileFetching) { + return val.__staleWhileFetching; + } + } else if (val !== void 0) { + return val; + } + } + } finally { + if (this.#hasDisposeAfter && this.#disposed) { + const dt = this.#disposed; + let task; + while (task = dt?.shift()) { + this.#disposeAfter?.(...task); + } + } + } + } + #evict(free) { + const head = this.#head; + const k = this.#keyList[head]; + const v = this.#valList[head]; + if (this.#hasFetchMethod && this.#isBackgroundFetch(v)) { + v.__abortController.abort(new Error("evicted")); + } else if (this.#hasDispose || this.#hasDisposeAfter) { + if (this.#hasDispose) { + this.#dispose?.(v, k, "evict"); + } + if (this.#hasDisposeAfter) { + this.#disposed?.push([v, k, "evict"]); + } + } + this.#removeItemSize(head); + if (free) { + this.#keyList[head] = void 0; + this.#valList[head] = void 0; + this.#free.push(head); + } + if (this.#size === 1) { + this.#head = this.#tail = 0; + this.#free.length = 0; + } else { + this.#head = this.#next[head]; + } + this.#keyMap.delete(k); + this.#size--; + return head; + } + /** + * Check if a key is in the cache, without updating the recency of use. + * Will return false if the item is stale, even though it is technically + * in the cache. + * + * Will not update item age unless + * {@link LRUCache.OptionsBase.updateAgeOnHas} is set. + */ + has(k, hasOptions = {}) { + const { updateAgeOnHas = this.updateAgeOnHas, status } = hasOptions; + const index = this.#keyMap.get(k); + if (index !== void 0) { + const v = this.#valList[index]; + if (this.#isBackgroundFetch(v) && v.__staleWhileFetching === void 0) { + return false; + } + if (!this.#isStale(index)) { + if (updateAgeOnHas) { + this.#updateItemAge(index); + } + if (status) { + status.has = "hit"; + this.#statusTTL(status, index); + } + return true; + } else if (status) { + status.has = "stale"; + this.#statusTTL(status, index); + } + } else if (status) { + status.has = "miss"; + } + return false; + } + /** + * Like {@link LRUCache#get} but doesn't update recency or delete stale + * items. + * + * Returns `undefined` if the item is stale, unless + * {@link LRUCache.OptionsBase.allowStale} is set. + */ + peek(k, peekOptions = {}) { + const { allowStale = this.allowStale } = peekOptions; + const index = this.#keyMap.get(k); + if (index === void 0 || !allowStale && this.#isStale(index)) { + return; + } + const v = this.#valList[index]; + return this.#isBackgroundFetch(v) ? v.__staleWhileFetching : v; + } + #backgroundFetch(k, index, options, context) { + const v = index === void 0 ? void 0 : this.#valList[index]; + if (this.#isBackgroundFetch(v)) { + return v; + } + const ac = new AC(); + const { signal } = options; + signal?.addEventListener("abort", () => ac.abort(signal.reason), { + signal: ac.signal + }); + const fetchOpts = { + signal: ac.signal, + options, + context + }; + const cb = (v2, updateCache = false) => { + const { aborted } = ac.signal; + const ignoreAbort = options.ignoreFetchAbort && v2 !== void 0; + if (options.status) { + if (aborted && !updateCache) { + options.status.fetchAborted = true; + options.status.fetchError = ac.signal.reason; + if (ignoreAbort) + options.status.fetchAbortIgnored = true; + } else { + options.status.fetchResolved = true; + } + } + if (aborted && !ignoreAbort && !updateCache) { + return fetchFail(ac.signal.reason); + } + const bf2 = p; + if (this.#valList[index] === p) { + if (v2 === void 0) { + if (bf2.__staleWhileFetching) { + this.#valList[index] = bf2.__staleWhileFetching; + } else { + this.delete(k); + } + } else { + if (options.status) + options.status.fetchUpdated = true; + this.set(k, v2, fetchOpts.options); + } + } + return v2; + }; + const eb = (er) => { + if (options.status) { + options.status.fetchRejected = true; + options.status.fetchError = er; + } + return fetchFail(er); + }; + const fetchFail = (er) => { + const { aborted } = ac.signal; + const allowStaleAborted = aborted && options.allowStaleOnFetchAbort; + const allowStale = allowStaleAborted || options.allowStaleOnFetchRejection; + const noDelete = allowStale || options.noDeleteOnFetchRejection; + const bf2 = p; + if (this.#valList[index] === p) { + const del = !noDelete || bf2.__staleWhileFetching === void 0; + if (del) { + this.delete(k); + } else if (!allowStaleAborted) { + this.#valList[index] = bf2.__staleWhileFetching; + } + } + if (allowStale) { + if (options.status && bf2.__staleWhileFetching !== void 0) { + options.status.returnedStale = true; + } + return bf2.__staleWhileFetching; + } else if (bf2.__returned === bf2) { + throw er; + } + }; + const pcall = (res, rej) => { + const fmp = this.#fetchMethod?.(k, v, fetchOpts); + if (fmp && fmp instanceof Promise) { + fmp.then((v2) => res(v2 === void 0 ? void 0 : v2), rej); + } + ac.signal.addEventListener("abort", () => { + if (!options.ignoreFetchAbort || options.allowStaleOnFetchAbort) { + res(void 0); + if (options.allowStaleOnFetchAbort) { + res = (v2) => cb(v2, true); + } + } + }); + }; + if (options.status) + options.status.fetchDispatched = true; + const p = new Promise(pcall).then(cb, eb); + const bf = Object.assign(p, { + __abortController: ac, + __staleWhileFetching: v, + __returned: void 0 + }); + if (index === void 0) { + this.set(k, bf, { ...fetchOpts.options, status: void 0 }); + index = this.#keyMap.get(k); + } else { + this.#valList[index] = bf; + } + return bf; + } + #isBackgroundFetch(p) { + if (!this.#hasFetchMethod) + return false; + const b = p; + return !!b && b instanceof Promise && b.hasOwnProperty("__staleWhileFetching") && b.__abortController instanceof AC; + } + async fetch(k, fetchOptions = {}) { + const { + // get options + allowStale = this.allowStale, + updateAgeOnGet = this.updateAgeOnGet, + noDeleteOnStaleGet = this.noDeleteOnStaleGet, + // set options + ttl = this.ttl, + noDisposeOnSet = this.noDisposeOnSet, + size = 0, + sizeCalculation = this.sizeCalculation, + noUpdateTTL = this.noUpdateTTL, + // fetch exclusive options + noDeleteOnFetchRejection = this.noDeleteOnFetchRejection, + allowStaleOnFetchRejection = this.allowStaleOnFetchRejection, + ignoreFetchAbort = this.ignoreFetchAbort, + allowStaleOnFetchAbort = this.allowStaleOnFetchAbort, + context, + forceRefresh = false, + status, + signal + } = fetchOptions; + if (!this.#hasFetchMethod) { + if (status) + status.fetch = "get"; + return this.get(k, { + allowStale, + updateAgeOnGet, + noDeleteOnStaleGet, + status + }); + } + const options = { + allowStale, + updateAgeOnGet, + noDeleteOnStaleGet, + ttl, + noDisposeOnSet, + size, + sizeCalculation, + noUpdateTTL, + noDeleteOnFetchRejection, + allowStaleOnFetchRejection, + allowStaleOnFetchAbort, + ignoreFetchAbort, + status, + signal + }; + let index = this.#keyMap.get(k); + if (index === void 0) { + if (status) + status.fetch = "miss"; + const p = this.#backgroundFetch(k, index, options, context); + return p.__returned = p; + } else { + const v = this.#valList[index]; + if (this.#isBackgroundFetch(v)) { + const stale = allowStale && v.__staleWhileFetching !== void 0; + if (status) { + status.fetch = "inflight"; + if (stale) + status.returnedStale = true; + } + return stale ? v.__staleWhileFetching : v.__returned = v; + } + const isStale = this.#isStale(index); + if (!forceRefresh && !isStale) { + if (status) + status.fetch = "hit"; + this.#moveToTail(index); + if (updateAgeOnGet) { + this.#updateItemAge(index); + } + if (status) + this.#statusTTL(status, index); + return v; + } + const p = this.#backgroundFetch(k, index, options, context); + const hasStale = p.__staleWhileFetching !== void 0; + const staleVal = hasStale && allowStale; + if (status) { + status.fetch = isStale ? "stale" : "refresh"; + if (staleVal && isStale) + status.returnedStale = true; + } + return staleVal ? p.__staleWhileFetching : p.__returned = p; + } + } + /** + * Return a value from the cache. Will update the recency of the cache + * entry found. + * + * If the key is not found, get() will return `undefined`. + */ + get(k, getOptions = {}) { + const { allowStale = this.allowStale, updateAgeOnGet = this.updateAgeOnGet, noDeleteOnStaleGet = this.noDeleteOnStaleGet, status } = getOptions; + const index = this.#keyMap.get(k); + if (index !== void 0) { + const value = this.#valList[index]; + const fetching = this.#isBackgroundFetch(value); + if (status) + this.#statusTTL(status, index); + if (this.#isStale(index)) { + if (status) + status.get = "stale"; + if (!fetching) { + if (!noDeleteOnStaleGet) { + this.delete(k); + } + if (status && allowStale) + status.returnedStale = true; + return allowStale ? value : void 0; + } else { + if (status && allowStale && value.__staleWhileFetching !== void 0) { + status.returnedStale = true; + } + return allowStale ? value.__staleWhileFetching : void 0; + } + } else { + if (status) + status.get = "hit"; + if (fetching) { + return value.__staleWhileFetching; + } + this.#moveToTail(index); + if (updateAgeOnGet) { + this.#updateItemAge(index); + } + return value; + } + } else if (status) { + status.get = "miss"; + } + } + #connect(p, n) { + this.#prev[n] = p; + this.#next[p] = n; + } + #moveToTail(index) { + if (index !== this.#tail) { + if (index === this.#head) { + this.#head = this.#next[index]; + } else { + this.#connect(this.#prev[index], this.#next[index]); + } + this.#connect(this.#tail, index); + this.#tail = index; + } + } + /** + * Deletes a key out of the cache. + * Returns true if the key was deleted, false otherwise. + */ + delete(k) { + let deleted = false; + if (this.#size !== 0) { + const index = this.#keyMap.get(k); + if (index !== void 0) { + deleted = true; + if (this.#size === 1) { + this.clear(); + } else { + this.#removeItemSize(index); + const v = this.#valList[index]; + if (this.#isBackgroundFetch(v)) { + v.__abortController.abort(new Error("deleted")); + } else if (this.#hasDispose || this.#hasDisposeAfter) { + if (this.#hasDispose) { + this.#dispose?.(v, k, "delete"); + } + if (this.#hasDisposeAfter) { + this.#disposed?.push([v, k, "delete"]); + } + } + this.#keyMap.delete(k); + this.#keyList[index] = void 0; + this.#valList[index] = void 0; + if (index === this.#tail) { + this.#tail = this.#prev[index]; + } else if (index === this.#head) { + this.#head = this.#next[index]; + } else { + const pi = this.#prev[index]; + this.#next[pi] = this.#next[index]; + const ni = this.#next[index]; + this.#prev[ni] = this.#prev[index]; + } + this.#size--; + this.#free.push(index); + } + } + } + if (this.#hasDisposeAfter && this.#disposed?.length) { + const dt = this.#disposed; + let task; + while (task = dt?.shift()) { + this.#disposeAfter?.(...task); + } + } + return deleted; + } + /** + * Clear the cache entirely, throwing away all values. + */ + clear() { + for (const index of this.#rindexes({ allowStale: true })) { + const v = this.#valList[index]; + if (this.#isBackgroundFetch(v)) { + v.__abortController.abort(new Error("deleted")); + } else { + const k = this.#keyList[index]; + if (this.#hasDispose) { + this.#dispose?.(v, k, "delete"); + } + if (this.#hasDisposeAfter) { + this.#disposed?.push([v, k, "delete"]); + } + } + } + this.#keyMap.clear(); + this.#valList.fill(void 0); + this.#keyList.fill(void 0); + if (this.#ttls && this.#starts) { + this.#ttls.fill(0); + this.#starts.fill(0); + } + if (this.#sizes) { + this.#sizes.fill(0); + } + this.#head = 0; + this.#tail = 0; + this.#free.length = 0; + this.#calculatedSize = 0; + this.#size = 0; + if (this.#hasDisposeAfter && this.#disposed) { + const dt = this.#disposed; + let task; + while (task = dt?.shift()) { + this.#disposeAfter?.(...task); + } + } + } +}; + +// node_modules/path-scurry/dist/esm/index.js +import { posix, win32 } from "path"; +import { fileURLToPath } from "url"; +import * as actualFS from "fs"; +import { lstatSync, readdir as readdirCB, readdirSync, readlinkSync, realpathSync as rps } from "fs"; +import { lstat, readdir, readlink, realpath } from "fs/promises"; + +// node_modules/minipass/dist/esm/index.js +import { EventEmitter } from "events"; +import Stream from "stream"; +import { StringDecoder } from "string_decoder"; +var proc = typeof process === "object" && process ? process : { + stdout: null, + stderr: null +}; +var isStream = (s) => !!s && typeof s === "object" && (s instanceof Minipass || s instanceof Stream || isReadable(s) || isWritable(s)); +var isReadable = (s) => !!s && typeof s === "object" && s instanceof EventEmitter && typeof s.pipe === "function" && // node core Writable streams have a pipe() method, but it throws +s.pipe !== Stream.Writable.prototype.pipe; +var isWritable = (s) => !!s && typeof s === "object" && s instanceof EventEmitter && typeof s.write === "function" && typeof s.end === "function"; +var EOF = Symbol("EOF"); +var MAYBE_EMIT_END = Symbol("maybeEmitEnd"); +var EMITTED_END = Symbol("emittedEnd"); +var EMITTING_END = Symbol("emittingEnd"); +var EMITTED_ERROR = Symbol("emittedError"); +var CLOSED = Symbol("closed"); +var READ = Symbol("read"); +var FLUSH = Symbol("flush"); +var FLUSHCHUNK = Symbol("flushChunk"); +var ENCODING = Symbol("encoding"); +var DECODER = Symbol("decoder"); +var FLOWING = Symbol("flowing"); +var PAUSED = Symbol("paused"); +var RESUME = Symbol("resume"); +var BUFFER = Symbol("buffer"); +var PIPES = Symbol("pipes"); +var BUFFERLENGTH = Symbol("bufferLength"); +var BUFFERPUSH = Symbol("bufferPush"); +var BUFFERSHIFT = Symbol("bufferShift"); +var OBJECTMODE = Symbol("objectMode"); +var DESTROYED = Symbol("destroyed"); +var ERROR = Symbol("error"); +var EMITDATA = Symbol("emitData"); +var EMITEND = Symbol("emitEnd"); +var EMITEND2 = Symbol("emitEnd2"); +var ASYNC = Symbol("async"); +var ABORT = Symbol("abort"); +var ABORTED = Symbol("aborted"); +var SIGNAL = Symbol("signal"); +var DATALISTENERS = Symbol("dataListeners"); +var DISCARDED = Symbol("discarded"); +var defer = (fn) => Promise.resolve().then(fn); +var nodefer = (fn) => fn(); +var isEndish = (ev) => ev === "end" || ev === "finish" || ev === "prefinish"; +var isArrayBufferLike = (b) => b instanceof ArrayBuffer || !!b && typeof b === "object" && b.constructor && b.constructor.name === "ArrayBuffer" && b.byteLength >= 0; +var isArrayBufferView = (b) => !Buffer.isBuffer(b) && ArrayBuffer.isView(b); +var Pipe = class { + src; + dest; + opts; + ondrain; + constructor(src, dest, opts) { + this.src = src; + this.dest = dest; + this.opts = opts; + this.ondrain = () => src[RESUME](); + this.dest.on("drain", this.ondrain); + } + unpipe() { + this.dest.removeListener("drain", this.ondrain); + } + // only here for the prototype + /* c8 ignore start */ + proxyErrors(_er) { + } + /* c8 ignore stop */ + end() { + this.unpipe(); + if (this.opts.end) + this.dest.end(); + } +}; +var PipeProxyErrors = class extends Pipe { + unpipe() { + this.src.removeListener("error", this.proxyErrors); + super.unpipe(); + } + constructor(src, dest, opts) { + super(src, dest, opts); + this.proxyErrors = (er) => dest.emit("error", er); + src.on("error", this.proxyErrors); + } +}; +var isObjectModeOptions = (o) => !!o.objectMode; +var isEncodingOptions = (o) => !o.objectMode && !!o.encoding && o.encoding !== "buffer"; +var Minipass = class extends EventEmitter { + [FLOWING] = false; + [PAUSED] = false; + [PIPES] = []; + [BUFFER] = []; + [OBJECTMODE]; + [ENCODING]; + [ASYNC]; + [DECODER]; + [EOF] = false; + [EMITTED_END] = false; + [EMITTING_END] = false; + [CLOSED] = false; + [EMITTED_ERROR] = null; + [BUFFERLENGTH] = 0; + [DESTROYED] = false; + [SIGNAL]; + [ABORTED] = false; + [DATALISTENERS] = 0; + [DISCARDED] = false; + /** + * true if the stream can be written + */ + writable = true; + /** + * true if the stream can be read + */ + readable = true; + /** + * If `RType` is Buffer, then options do not need to be provided. + * Otherwise, an options object must be provided to specify either + * {@link Minipass.SharedOptions.objectMode} or + * {@link Minipass.SharedOptions.encoding}, as appropriate. + */ + constructor(...args) { + const options = args[0] || {}; + super(); + if (options.objectMode && typeof options.encoding === "string") { + throw new TypeError("Encoding and objectMode may not be used together"); + } + if (isObjectModeOptions(options)) { + this[OBJECTMODE] = true; + this[ENCODING] = null; + } else if (isEncodingOptions(options)) { + this[ENCODING] = options.encoding; + this[OBJECTMODE] = false; + } else { + this[OBJECTMODE] = false; + this[ENCODING] = null; + } + this[ASYNC] = !!options.async; + this[DECODER] = this[ENCODING] ? new StringDecoder(this[ENCODING]) : null; + if (options && options.debugExposeBuffer === true) { + Object.defineProperty(this, "buffer", { get: () => this[BUFFER] }); + } + if (options && options.debugExposePipes === true) { + Object.defineProperty(this, "pipes", { get: () => this[PIPES] }); + } + const { signal } = options; + if (signal) { + this[SIGNAL] = signal; + if (signal.aborted) { + this[ABORT](); + } else { + signal.addEventListener("abort", () => this[ABORT]()); + } + } + } + /** + * The amount of data stored in the buffer waiting to be read. + * + * For Buffer strings, this will be the total byte length. + * For string encoding streams, this will be the string character length, + * according to JavaScript's `string.length` logic. + * For objectMode streams, this is a count of the items waiting to be + * emitted. + */ + get bufferLength() { + return this[BUFFERLENGTH]; + } + /** + * The `BufferEncoding` currently in use, or `null` + */ + get encoding() { + return this[ENCODING]; + } + /** + * @deprecated - This is a read only property + */ + set encoding(_enc) { + throw new Error("Encoding must be set at instantiation time"); + } + /** + * @deprecated - Encoding may only be set at instantiation time + */ + setEncoding(_enc) { + throw new Error("Encoding must be set at instantiation time"); + } + /** + * True if this is an objectMode stream + */ + get objectMode() { + return this[OBJECTMODE]; + } + /** + * @deprecated - This is a read-only property + */ + set objectMode(_om) { + throw new Error("objectMode must be set at instantiation time"); + } + /** + * true if this is an async stream + */ + get ["async"]() { + return this[ASYNC]; + } + /** + * Set to true to make this stream async. + * + * Once set, it cannot be unset, as this would potentially cause incorrect + * behavior. Ie, a sync stream can be made async, but an async stream + * cannot be safely made sync. + */ + set ["async"](a) { + this[ASYNC] = this[ASYNC] || !!a; + } + // drop everything and get out of the flow completely + [ABORT]() { + this[ABORTED] = true; + this.emit("abort", this[SIGNAL]?.reason); + this.destroy(this[SIGNAL]?.reason); + } + /** + * True if the stream has been aborted. + */ + get aborted() { + return this[ABORTED]; + } + /** + * No-op setter. Stream aborted status is set via the AbortSignal provided + * in the constructor options. + */ + set aborted(_) { + } + write(chunk, encoding, cb) { + if (this[ABORTED]) + return false; + if (this[EOF]) + throw new Error("write after end"); + if (this[DESTROYED]) { + this.emit("error", Object.assign(new Error("Cannot call write after a stream was destroyed"), { code: "ERR_STREAM_DESTROYED" })); + return true; + } + if (typeof encoding === "function") { + cb = encoding; + encoding = "utf8"; + } + if (!encoding) + encoding = "utf8"; + const fn = this[ASYNC] ? defer : nodefer; + if (!this[OBJECTMODE] && !Buffer.isBuffer(chunk)) { + if (isArrayBufferView(chunk)) { + chunk = Buffer.from(chunk.buffer, chunk.byteOffset, chunk.byteLength); + } else if (isArrayBufferLike(chunk)) { + chunk = Buffer.from(chunk); + } else if (typeof chunk !== "string") { + throw new Error("Non-contiguous data written to non-objectMode stream"); + } + } + if (this[OBJECTMODE]) { + if (this[FLOWING] && this[BUFFERLENGTH] !== 0) + this[FLUSH](true); + if (this[FLOWING]) + this.emit("data", chunk); + else + this[BUFFERPUSH](chunk); + if (this[BUFFERLENGTH] !== 0) + this.emit("readable"); + if (cb) + fn(cb); + return this[FLOWING]; + } + if (!chunk.length) { + if (this[BUFFERLENGTH] !== 0) + this.emit("readable"); + if (cb) + fn(cb); + return this[FLOWING]; + } + if (typeof chunk === "string" && // unless it is a string already ready for us to use + !(encoding === this[ENCODING] && !this[DECODER]?.lastNeed)) { + chunk = Buffer.from(chunk, encoding); + } + if (Buffer.isBuffer(chunk) && this[ENCODING]) { + chunk = this[DECODER].write(chunk); + } + if (this[FLOWING] && this[BUFFERLENGTH] !== 0) + this[FLUSH](true); + if (this[FLOWING]) + this.emit("data", chunk); + else + this[BUFFERPUSH](chunk); + if (this[BUFFERLENGTH] !== 0) + this.emit("readable"); + if (cb) + fn(cb); + return this[FLOWING]; + } + /** + * Low-level explicit read method. + * + * In objectMode, the argument is ignored, and one item is returned if + * available. + * + * `n` is the number of bytes (or in the case of encoding streams, + * characters) to consume. If `n` is not provided, then the entire buffer + * is returned, or `null` is returned if no data is available. + * + * If `n` is greater that the amount of data in the internal buffer, + * then `null` is returned. + */ + read(n) { + if (this[DESTROYED]) + return null; + this[DISCARDED] = false; + if (this[BUFFERLENGTH] === 0 || n === 0 || n && n > this[BUFFERLENGTH]) { + this[MAYBE_EMIT_END](); + return null; + } + if (this[OBJECTMODE]) + n = null; + if (this[BUFFER].length > 1 && !this[OBJECTMODE]) { + this[BUFFER] = [ + this[ENCODING] ? this[BUFFER].join("") : Buffer.concat(this[BUFFER], this[BUFFERLENGTH]) + ]; + } + const ret = this[READ](n || null, this[BUFFER][0]); + this[MAYBE_EMIT_END](); + return ret; + } + [READ](n, chunk) { + if (this[OBJECTMODE]) + this[BUFFERSHIFT](); + else { + const c = chunk; + if (n === c.length || n === null) + this[BUFFERSHIFT](); + else if (typeof c === "string") { + this[BUFFER][0] = c.slice(n); + chunk = c.slice(0, n); + this[BUFFERLENGTH] -= n; + } else { + this[BUFFER][0] = c.subarray(n); + chunk = c.subarray(0, n); + this[BUFFERLENGTH] -= n; + } + } + this.emit("data", chunk); + if (!this[BUFFER].length && !this[EOF]) + this.emit("drain"); + return chunk; + } + end(chunk, encoding, cb) { + if (typeof chunk === "function") { + cb = chunk; + chunk = void 0; + } + if (typeof encoding === "function") { + cb = encoding; + encoding = "utf8"; + } + if (chunk !== void 0) + this.write(chunk, encoding); + if (cb) + this.once("end", cb); + this[EOF] = true; + this.writable = false; + if (this[FLOWING] || !this[PAUSED]) + this[MAYBE_EMIT_END](); + return this; + } + // don't let the internal resume be overwritten + [RESUME]() { + if (this[DESTROYED]) + return; + if (!this[DATALISTENERS] && !this[PIPES].length) { + this[DISCARDED] = true; + } + this[PAUSED] = false; + this[FLOWING] = true; + this.emit("resume"); + if (this[BUFFER].length) + this[FLUSH](); + else if (this[EOF]) + this[MAYBE_EMIT_END](); + else + this.emit("drain"); + } + /** + * Resume the stream if it is currently in a paused state + * + * If called when there are no pipe destinations or `data` event listeners, + * this will place the stream in a "discarded" state, where all data will + * be thrown away. The discarded state is removed if a pipe destination or + * data handler is added, if pause() is called, or if any synchronous or + * asynchronous iteration is started. + */ + resume() { + return this[RESUME](); + } + /** + * Pause the stream + */ + pause() { + this[FLOWING] = false; + this[PAUSED] = true; + this[DISCARDED] = false; + } + /** + * true if the stream has been forcibly destroyed + */ + get destroyed() { + return this[DESTROYED]; + } + /** + * true if the stream is currently in a flowing state, meaning that + * any writes will be immediately emitted. + */ + get flowing() { + return this[FLOWING]; + } + /** + * true if the stream is currently in a paused state + */ + get paused() { + return this[PAUSED]; + } + [BUFFERPUSH](chunk) { + if (this[OBJECTMODE]) + this[BUFFERLENGTH] += 1; + else + this[BUFFERLENGTH] += chunk.length; + this[BUFFER].push(chunk); + } + [BUFFERSHIFT]() { + if (this[OBJECTMODE]) + this[BUFFERLENGTH] -= 1; + else + this[BUFFERLENGTH] -= this[BUFFER][0].length; + return this[BUFFER].shift(); + } + [FLUSH](noDrain = false) { + do { + } while (this[FLUSHCHUNK](this[BUFFERSHIFT]()) && this[BUFFER].length); + if (!noDrain && !this[BUFFER].length && !this[EOF]) + this.emit("drain"); + } + [FLUSHCHUNK](chunk) { + this.emit("data", chunk); + return this[FLOWING]; + } + /** + * Pipe all data emitted by this stream into the destination provided. + * + * Triggers the flow of data. + */ + pipe(dest, opts) { + if (this[DESTROYED]) + return dest; + this[DISCARDED] = false; + const ended = this[EMITTED_END]; + opts = opts || {}; + if (dest === proc.stdout || dest === proc.stderr) + opts.end = false; + else + opts.end = opts.end !== false; + opts.proxyErrors = !!opts.proxyErrors; + if (ended) { + if (opts.end) + dest.end(); + } else { + this[PIPES].push(!opts.proxyErrors ? new Pipe(this, dest, opts) : new PipeProxyErrors(this, dest, opts)); + if (this[ASYNC]) + defer(() => this[RESUME]()); + else + this[RESUME](); + } + return dest; + } + /** + * Fully unhook a piped destination stream. + * + * If the destination stream was the only consumer of this stream (ie, + * there are no other piped destinations or `'data'` event listeners) + * then the flow of data will stop until there is another consumer or + * {@link Minipass#resume} is explicitly called. + */ + unpipe(dest) { + const p = this[PIPES].find((p2) => p2.dest === dest); + if (p) { + if (this[PIPES].length === 1) { + if (this[FLOWING] && this[DATALISTENERS] === 0) { + this[FLOWING] = false; + } + this[PIPES] = []; + } else + this[PIPES].splice(this[PIPES].indexOf(p), 1); + p.unpipe(); + } + } + /** + * Alias for {@link Minipass#on} + */ + addListener(ev, handler) { + return this.on(ev, handler); + } + /** + * Mostly identical to `EventEmitter.on`, with the following + * behavior differences to prevent data loss and unnecessary hangs: + * + * - Adding a 'data' event handler will trigger the flow of data + * + * - Adding a 'readable' event handler when there is data waiting to be read + * will cause 'readable' to be emitted immediately. + * + * - Adding an 'endish' event handler ('end', 'finish', etc.) which has + * already passed will cause the event to be emitted immediately and all + * handlers removed. + * + * - Adding an 'error' event handler after an error has been emitted will + * cause the event to be re-emitted immediately with the error previously + * raised. + */ + on(ev, handler) { + const ret = super.on(ev, handler); + if (ev === "data") { + this[DISCARDED] = false; + this[DATALISTENERS]++; + if (!this[PIPES].length && !this[FLOWING]) { + this[RESUME](); + } + } else if (ev === "readable" && this[BUFFERLENGTH] !== 0) { + super.emit("readable"); + } else if (isEndish(ev) && this[EMITTED_END]) { + super.emit(ev); + this.removeAllListeners(ev); + } else if (ev === "error" && this[EMITTED_ERROR]) { + const h = handler; + if (this[ASYNC]) + defer(() => h.call(this, this[EMITTED_ERROR])); + else + h.call(this, this[EMITTED_ERROR]); + } + return ret; + } + /** + * Alias for {@link Minipass#off} + */ + removeListener(ev, handler) { + return this.off(ev, handler); + } + /** + * Mostly identical to `EventEmitter.off` + * + * If a 'data' event handler is removed, and it was the last consumer + * (ie, there are no pipe destinations or other 'data' event listeners), + * then the flow of data will stop until there is another consumer or + * {@link Minipass#resume} is explicitly called. + */ + off(ev, handler) { + const ret = super.off(ev, handler); + if (ev === "data") { + this[DATALISTENERS] = this.listeners("data").length; + if (this[DATALISTENERS] === 0 && !this[DISCARDED] && !this[PIPES].length) { + this[FLOWING] = false; + } + } + return ret; + } + /** + * Mostly identical to `EventEmitter.removeAllListeners` + * + * If all 'data' event handlers are removed, and they were the last consumer + * (ie, there are no pipe destinations), then the flow of data will stop + * until there is another consumer or {@link Minipass#resume} is explicitly + * called. + */ + removeAllListeners(ev) { + const ret = super.removeAllListeners(ev); + if (ev === "data" || ev === void 0) { + this[DATALISTENERS] = 0; + if (!this[DISCARDED] && !this[PIPES].length) { + this[FLOWING] = false; + } + } + return ret; + } + /** + * true if the 'end' event has been emitted + */ + get emittedEnd() { + return this[EMITTED_END]; + } + [MAYBE_EMIT_END]() { + if (!this[EMITTING_END] && !this[EMITTED_END] && !this[DESTROYED] && this[BUFFER].length === 0 && this[EOF]) { + this[EMITTING_END] = true; + this.emit("end"); + this.emit("prefinish"); + this.emit("finish"); + if (this[CLOSED]) + this.emit("close"); + this[EMITTING_END] = false; + } + } + /** + * Mostly identical to `EventEmitter.emit`, with the following + * behavior differences to prevent data loss and unnecessary hangs: + * + * If the stream has been destroyed, and the event is something other + * than 'close' or 'error', then `false` is returned and no handlers + * are called. + * + * If the event is 'end', and has already been emitted, then the event + * is ignored. If the stream is in a paused or non-flowing state, then + * the event will be deferred until data flow resumes. If the stream is + * async, then handlers will be called on the next tick rather than + * immediately. + * + * If the event is 'close', and 'end' has not yet been emitted, then + * the event will be deferred until after 'end' is emitted. + * + * If the event is 'error', and an AbortSignal was provided for the stream, + * and there are no listeners, then the event is ignored, matching the + * behavior of node core streams in the presense of an AbortSignal. + * + * If the event is 'finish' or 'prefinish', then all listeners will be + * removed after emitting the event, to prevent double-firing. + */ + emit(ev, ...args) { + const data = args[0]; + if (ev !== "error" && ev !== "close" && ev !== DESTROYED && this[DESTROYED]) { + return false; + } else if (ev === "data") { + return !this[OBJECTMODE] && !data ? false : this[ASYNC] ? (defer(() => this[EMITDATA](data)), true) : this[EMITDATA](data); + } else if (ev === "end") { + return this[EMITEND](); + } else if (ev === "close") { + this[CLOSED] = true; + if (!this[EMITTED_END] && !this[DESTROYED]) + return false; + const ret2 = super.emit("close"); + this.removeAllListeners("close"); + return ret2; + } else if (ev === "error") { + this[EMITTED_ERROR] = data; + super.emit(ERROR, data); + const ret2 = !this[SIGNAL] || this.listeners("error").length ? super.emit("error", data) : false; + this[MAYBE_EMIT_END](); + return ret2; + } else if (ev === "resume") { + const ret2 = super.emit("resume"); + this[MAYBE_EMIT_END](); + return ret2; + } else if (ev === "finish" || ev === "prefinish") { + const ret2 = super.emit(ev); + this.removeAllListeners(ev); + return ret2; + } + const ret = super.emit(ev, ...args); + this[MAYBE_EMIT_END](); + return ret; + } + [EMITDATA](data) { + for (const p of this[PIPES]) { + if (p.dest.write(data) === false) + this.pause(); + } + const ret = this[DISCARDED] ? false : super.emit("data", data); + this[MAYBE_EMIT_END](); + return ret; + } + [EMITEND]() { + if (this[EMITTED_END]) + return false; + this[EMITTED_END] = true; + this.readable = false; + return this[ASYNC] ? (defer(() => this[EMITEND2]()), true) : this[EMITEND2](); + } + [EMITEND2]() { + if (this[DECODER]) { + const data = this[DECODER].end(); + if (data) { + for (const p of this[PIPES]) { + p.dest.write(data); + } + if (!this[DISCARDED]) + super.emit("data", data); + } + } + for (const p of this[PIPES]) { + p.end(); + } + const ret = super.emit("end"); + this.removeAllListeners("end"); + return ret; + } + /** + * Return a Promise that resolves to an array of all emitted data once + * the stream ends. + */ + async collect() { + const buf = Object.assign([], { + dataLength: 0 + }); + if (!this[OBJECTMODE]) + buf.dataLength = 0; + const p = this.promise(); + this.on("data", (c) => { + buf.push(c); + if (!this[OBJECTMODE]) + buf.dataLength += c.length; + }); + await p; + return buf; + } + /** + * Return a Promise that resolves to the concatenation of all emitted data + * once the stream ends. + * + * Not allowed on objectMode streams. + */ + async concat() { + if (this[OBJECTMODE]) { + throw new Error("cannot concat in objectMode"); + } + const buf = await this.collect(); + return this[ENCODING] ? buf.join("") : Buffer.concat(buf, buf.dataLength); + } + /** + * Return a void Promise that resolves once the stream ends. + */ + async promise() { + return new Promise((resolve, reject) => { + this.on(DESTROYED, () => reject(new Error("stream destroyed"))); + this.on("error", (er) => reject(er)); + this.on("end", () => resolve()); + }); + } + /** + * Asynchronous `for await of` iteration. + * + * This will continue emitting all chunks until the stream terminates. + */ + [Symbol.asyncIterator]() { + this[DISCARDED] = false; + let stopped = false; + const stop = async () => { + this.pause(); + stopped = true; + return { value: void 0, done: true }; + }; + const next = () => { + if (stopped) + return stop(); + const res = this.read(); + if (res !== null) + return Promise.resolve({ done: false, value: res }); + if (this[EOF]) + return stop(); + let resolve; + let reject; + const onerr = (er) => { + this.off("data", ondata); + this.off("end", onend); + this.off(DESTROYED, ondestroy); + stop(); + reject(er); + }; + const ondata = (value) => { + this.off("error", onerr); + this.off("end", onend); + this.off(DESTROYED, ondestroy); + this.pause(); + resolve({ value, done: !!this[EOF] }); + }; + const onend = () => { + this.off("error", onerr); + this.off("data", ondata); + this.off(DESTROYED, ondestroy); + stop(); + resolve({ done: true, value: void 0 }); + }; + const ondestroy = () => onerr(new Error("stream destroyed")); + return new Promise((res2, rej) => { + reject = rej; + resolve = res2; + this.once(DESTROYED, ondestroy); + this.once("error", onerr); + this.once("end", onend); + this.once("data", ondata); + }); + }; + return { + next, + throw: stop, + return: stop, + [Symbol.asyncIterator]() { + return this; + } + }; + } + /** + * Synchronous `for of` iteration. + * + * The iteration will terminate when the internal buffer runs out, even + * if the stream has not yet terminated. + */ + [Symbol.iterator]() { + this[DISCARDED] = false; + let stopped = false; + const stop = () => { + this.pause(); + this.off(ERROR, stop); + this.off(DESTROYED, stop); + this.off("end", stop); + stopped = true; + return { done: true, value: void 0 }; + }; + const next = () => { + if (stopped) + return stop(); + const value = this.read(); + return value === null ? stop() : { done: false, value }; + }; + this.once("end", stop); + this.once(ERROR, stop); + this.once(DESTROYED, stop); + return { + next, + throw: stop, + return: stop, + [Symbol.iterator]() { + return this; + } + }; + } + /** + * Destroy a stream, preventing it from being used for any further purpose. + * + * If the stream has a `close()` method, then it will be called on + * destruction. + * + * After destruction, any attempt to write data, read data, or emit most + * events will be ignored. + * + * If an error argument is provided, then it will be emitted in an + * 'error' event. + */ + destroy(er) { + if (this[DESTROYED]) { + if (er) + this.emit("error", er); + else + this.emit(DESTROYED); + return this; + } + this[DESTROYED] = true; + this[DISCARDED] = true; + this[BUFFER].length = 0; + this[BUFFERLENGTH] = 0; + const wc = this; + if (typeof wc.close === "function" && !this[CLOSED]) + wc.close(); + if (er) + this.emit("error", er); + else + this.emit(DESTROYED); + return this; + } + /** + * Alias for {@link isStream} + * + * Former export location, maintained for backwards compatibility. + * + * @deprecated + */ + static get isStream() { + return isStream; + } +}; + +// node_modules/path-scurry/dist/esm/index.js +var realpathSync = rps.native; +var defaultFS = { + lstatSync, + readdir: readdirCB, + readdirSync, + readlinkSync, + realpathSync, + promises: { + lstat, + readdir, + readlink, + realpath + } +}; +var fsFromOption = (fsOption) => !fsOption || fsOption === defaultFS || fsOption === actualFS ? defaultFS : { + ...defaultFS, + ...fsOption, + promises: { + ...defaultFS.promises, + ...fsOption.promises || {} + } +}; +var uncDriveRegexp = /^\\\\\?\\([a-z]:)\\?$/i; +var uncToDrive = (rootPath) => rootPath.replace(/\//g, "\\").replace(uncDriveRegexp, "$1\\"); +var eitherSep = /[\\\/]/; +var UNKNOWN = 0; +var IFIFO = 1; +var IFCHR = 2; +var IFDIR = 4; +var IFBLK = 6; +var IFREG = 8; +var IFLNK = 10; +var IFSOCK = 12; +var IFMT = 15; +var IFMT_UNKNOWN = ~IFMT; +var READDIR_CALLED = 16; +var LSTAT_CALLED = 32; +var ENOTDIR = 64; +var ENOENT = 128; +var ENOREADLINK = 256; +var ENOREALPATH = 512; +var ENOCHILD = ENOTDIR | ENOENT | ENOREALPATH; +var TYPEMASK = 1023; +var entToType = (s) => s.isFile() ? IFREG : s.isDirectory() ? IFDIR : s.isSymbolicLink() ? IFLNK : s.isCharacterDevice() ? IFCHR : s.isBlockDevice() ? IFBLK : s.isSocket() ? IFSOCK : s.isFIFO() ? IFIFO : UNKNOWN; +var normalizeCache = /* @__PURE__ */ new Map(); +var normalize = (s) => { + const c = normalizeCache.get(s); + if (c) + return c; + const n = s.normalize("NFKD"); + normalizeCache.set(s, n); + return n; +}; +var normalizeNocaseCache = /* @__PURE__ */ new Map(); +var normalizeNocase = (s) => { + const c = normalizeNocaseCache.get(s); + if (c) + return c; + const n = normalize(s.toLowerCase()); + normalizeNocaseCache.set(s, n); + return n; +}; +var ResolveCache = class extends LRUCache { + constructor() { + super({ max: 256 }); + } +}; +var ChildrenCache = class extends LRUCache { + constructor(maxSize = 16 * 1024) { + super({ + maxSize, + // parent + children + sizeCalculation: (a) => a.length + 1 + }); + } +}; +var setAsCwd = Symbol("PathScurry setAsCwd"); +var PathBase = class { + /** + * the basename of this path + * + * **Important**: *always* test the path name against any test string + * usingthe {@link isNamed} method, and not by directly comparing this + * string. Otherwise, unicode path strings that the system sees as identical + * will not be properly treated as the same path, leading to incorrect + * behavior and possible security issues. + */ + name; + /** + * the Path entry corresponding to the path root. + * + * @internal + */ + root; + /** + * All roots found within the current PathScurry family + * + * @internal + */ + roots; + /** + * a reference to the parent path, or undefined in the case of root entries + * + * @internal + */ + parent; + /** + * boolean indicating whether paths are compared case-insensitively + * @internal + */ + nocase; + // potential default fs override + #fs; + // Stats fields + #dev; + get dev() { + return this.#dev; + } + #mode; + get mode() { + return this.#mode; + } + #nlink; + get nlink() { + return this.#nlink; + } + #uid; + get uid() { + return this.#uid; + } + #gid; + get gid() { + return this.#gid; + } + #rdev; + get rdev() { + return this.#rdev; + } + #blksize; + get blksize() { + return this.#blksize; + } + #ino; + get ino() { + return this.#ino; + } + #size; + get size() { + return this.#size; + } + #blocks; + get blocks() { + return this.#blocks; + } + #atimeMs; + get atimeMs() { + return this.#atimeMs; + } + #mtimeMs; + get mtimeMs() { + return this.#mtimeMs; + } + #ctimeMs; + get ctimeMs() { + return this.#ctimeMs; + } + #birthtimeMs; + get birthtimeMs() { + return this.#birthtimeMs; + } + #atime; + get atime() { + return this.#atime; + } + #mtime; + get mtime() { + return this.#mtime; + } + #ctime; + get ctime() { + return this.#ctime; + } + #birthtime; + get birthtime() { + return this.#birthtime; + } + #matchName; + #depth; + #fullpath; + #fullpathPosix; + #relative; + #relativePosix; + #type; + #children; + #linkTarget; + #realpath; + /** + * This property is for compatibility with the Dirent class as of + * Node v20, where Dirent['path'] refers to the path of the directory + * that was passed to readdir. So, somewhat counterintuitively, this + * property refers to the *parent* path, not the path object itself. + * For root entries, it's the path to the entry itself. + */ + get path() { + return (this.parent || this).fullpath(); + } + /** + * Do not create new Path objects directly. They should always be accessed + * via the PathScurry class or other methods on the Path class. + * + * @internal + */ + constructor(name, type = UNKNOWN, root, roots, nocase, children, opts) { + this.name = name; + this.#matchName = nocase ? normalizeNocase(name) : normalize(name); + this.#type = type & TYPEMASK; + this.nocase = nocase; + this.roots = roots; + this.root = root || this; + this.#children = children; + this.#fullpath = opts.fullpath; + this.#relative = opts.relative; + this.#relativePosix = opts.relativePosix; + this.parent = opts.parent; + if (this.parent) { + this.#fs = this.parent.#fs; + } else { + this.#fs = fsFromOption(opts.fs); + } + } + /** + * Returns the depth of the Path object from its root. + * + * For example, a path at `/foo/bar` would have a depth of 2. + */ + depth() { + if (this.#depth !== void 0) + return this.#depth; + if (!this.parent) + return this.#depth = 0; + return this.#depth = this.parent.depth() + 1; + } + /** + * @internal + */ + childrenCache() { + return this.#children; + } + /** + * Get the Path object referenced by the string path, resolved from this Path + */ + resolve(path4) { + if (!path4) { + return this; + } + const rootPath = this.getRootString(path4); + const dir = path4.substring(rootPath.length); + const dirParts = dir.split(this.splitSep); + const result = rootPath ? this.getRoot(rootPath).#resolveParts(dirParts) : this.#resolveParts(dirParts); + return result; + } + #resolveParts(dirParts) { + let p = this; + for (const part of dirParts) { + p = p.child(part); + } + return p; + } + /** + * Returns the cached children Path objects, if still available. If they + * have fallen out of the cache, then returns an empty array, and resets the + * READDIR_CALLED bit, so that future calls to readdir() will require an fs + * lookup. + * + * @internal + */ + children() { + const cached = this.#children.get(this); + if (cached) { + return cached; + } + const children = Object.assign([], { provisional: 0 }); + this.#children.set(this, children); + this.#type &= ~READDIR_CALLED; + return children; + } + /** + * Resolves a path portion and returns or creates the child Path. + * + * Returns `this` if pathPart is `''` or `'.'`, or `parent` if pathPart is + * `'..'`. + * + * This should not be called directly. If `pathPart` contains any path + * separators, it will lead to unsafe undefined behavior. + * + * Use `Path.resolve()` instead. + * + * @internal + */ + child(pathPart, opts) { + if (pathPart === "" || pathPart === ".") { + return this; + } + if (pathPart === "..") { + return this.parent || this; + } + const children = this.children(); + const name = this.nocase ? normalizeNocase(pathPart) : normalize(pathPart); + for (const p of children) { + if (p.#matchName === name) { + return p; + } + } + const s = this.parent ? this.sep : ""; + const fullpath = this.#fullpath ? this.#fullpath + s + pathPart : void 0; + const pchild = this.newChild(pathPart, UNKNOWN, { + ...opts, + parent: this, + fullpath + }); + if (!this.canReaddir()) { + pchild.#type |= ENOENT; + } + children.push(pchild); + return pchild; + } + /** + * The relative path from the cwd. If it does not share an ancestor with + * the cwd, then this ends up being equivalent to the fullpath() + */ + relative() { + if (this.#relative !== void 0) { + return this.#relative; + } + const name = this.name; + const p = this.parent; + if (!p) { + return this.#relative = this.name; + } + const pv = p.relative(); + return pv + (!pv || !p.parent ? "" : this.sep) + name; + } + /** + * The relative path from the cwd, using / as the path separator. + * If it does not share an ancestor with + * the cwd, then this ends up being equivalent to the fullpathPosix() + * On posix systems, this is identical to relative(). + */ + relativePosix() { + if (this.sep === "/") + return this.relative(); + if (this.#relativePosix !== void 0) + return this.#relativePosix; + const name = this.name; + const p = this.parent; + if (!p) { + return this.#relativePosix = this.fullpathPosix(); + } + const pv = p.relativePosix(); + return pv + (!pv || !p.parent ? "" : "/") + name; + } + /** + * The fully resolved path string for this Path entry + */ + fullpath() { + if (this.#fullpath !== void 0) { + return this.#fullpath; + } + const name = this.name; + const p = this.parent; + if (!p) { + return this.#fullpath = this.name; + } + const pv = p.fullpath(); + const fp = pv + (!p.parent ? "" : this.sep) + name; + return this.#fullpath = fp; + } + /** + * On platforms other than windows, this is identical to fullpath. + * + * On windows, this is overridden to return the forward-slash form of the + * full UNC path. + */ + fullpathPosix() { + if (this.#fullpathPosix !== void 0) + return this.#fullpathPosix; + if (this.sep === "/") + return this.#fullpathPosix = this.fullpath(); + if (!this.parent) { + const p2 = this.fullpath().replace(/\\/g, "/"); + if (/^[a-z]:\//i.test(p2)) { + return this.#fullpathPosix = `//?/${p2}`; + } else { + return this.#fullpathPosix = p2; + } + } + const p = this.parent; + const pfpp = p.fullpathPosix(); + const fpp = pfpp + (!pfpp || !p.parent ? "" : "/") + this.name; + return this.#fullpathPosix = fpp; + } + /** + * Is the Path of an unknown type? + * + * Note that we might know *something* about it if there has been a previous + * filesystem operation, for example that it does not exist, or is not a + * link, or whether it has child entries. + */ + isUnknown() { + return (this.#type & IFMT) === UNKNOWN; + } + isType(type) { + return this[`is${type}`](); + } + getType() { + return this.isUnknown() ? "Unknown" : this.isDirectory() ? "Directory" : this.isFile() ? "File" : this.isSymbolicLink() ? "SymbolicLink" : this.isFIFO() ? "FIFO" : this.isCharacterDevice() ? "CharacterDevice" : this.isBlockDevice() ? "BlockDevice" : ( + /* c8 ignore start */ + this.isSocket() ? "Socket" : "Unknown" + ); + } + /** + * Is the Path a regular file? + */ + isFile() { + return (this.#type & IFMT) === IFREG; + } + /** + * Is the Path a directory? + */ + isDirectory() { + return (this.#type & IFMT) === IFDIR; + } + /** + * Is the path a character device? + */ + isCharacterDevice() { + return (this.#type & IFMT) === IFCHR; + } + /** + * Is the path a block device? + */ + isBlockDevice() { + return (this.#type & IFMT) === IFBLK; + } + /** + * Is the path a FIFO pipe? + */ + isFIFO() { + return (this.#type & IFMT) === IFIFO; + } + /** + * Is the path a socket? + */ + isSocket() { + return (this.#type & IFMT) === IFSOCK; + } + /** + * Is the path a symbolic link? + */ + isSymbolicLink() { + return (this.#type & IFLNK) === IFLNK; + } + /** + * Return the entry if it has been subject of a successful lstat, or + * undefined otherwise. + * + * Does not read the filesystem, so an undefined result *could* simply + * mean that we haven't called lstat on it. + */ + lstatCached() { + return this.#type & LSTAT_CALLED ? this : void 0; + } + /** + * Return the cached link target if the entry has been the subject of a + * successful readlink, or undefined otherwise. + * + * Does not read the filesystem, so an undefined result *could* just mean we + * don't have any cached data. Only use it if you are very sure that a + * readlink() has been called at some point. + */ + readlinkCached() { + return this.#linkTarget; + } + /** + * Returns the cached realpath target if the entry has been the subject + * of a successful realpath, or undefined otherwise. + * + * Does not read the filesystem, so an undefined result *could* just mean we + * don't have any cached data. Only use it if you are very sure that a + * realpath() has been called at some point. + */ + realpathCached() { + return this.#realpath; + } + /** + * Returns the cached child Path entries array if the entry has been the + * subject of a successful readdir(), or [] otherwise. + * + * Does not read the filesystem, so an empty array *could* just mean we + * don't have any cached data. Only use it if you are very sure that a + * readdir() has been called recently enough to still be valid. + */ + readdirCached() { + const children = this.children(); + return children.slice(0, children.provisional); + } + /** + * Return true if it's worth trying to readlink. Ie, we don't (yet) have + * any indication that readlink will definitely fail. + * + * Returns false if the path is known to not be a symlink, if a previous + * readlink failed, or if the entry does not exist. + */ + canReadlink() { + if (this.#linkTarget) + return true; + if (!this.parent) + return false; + const ifmt = this.#type & IFMT; + return !(ifmt !== UNKNOWN && ifmt !== IFLNK || this.#type & ENOREADLINK || this.#type & ENOENT); + } + /** + * Return true if readdir has previously been successfully called on this + * path, indicating that cachedReaddir() is likely valid. + */ + calledReaddir() { + return !!(this.#type & READDIR_CALLED); + } + /** + * Returns true if the path is known to not exist. That is, a previous lstat + * or readdir failed to verify its existence when that would have been + * expected, or a parent entry was marked either enoent or enotdir. + */ + isENOENT() { + return !!(this.#type & ENOENT); + } + /** + * Return true if the path is a match for the given path name. This handles + * case sensitivity and unicode normalization. + * + * Note: even on case-sensitive systems, it is **not** safe to test the + * equality of the `.name` property to determine whether a given pathname + * matches, due to unicode normalization mismatches. + * + * Always use this method instead of testing the `path.name` property + * directly. + */ + isNamed(n) { + return !this.nocase ? this.#matchName === normalize(n) : this.#matchName === normalizeNocase(n); + } + /** + * Return the Path object corresponding to the target of a symbolic link. + * + * If the Path is not a symbolic link, or if the readlink call fails for any + * reason, `undefined` is returned. + * + * Result is cached, and thus may be outdated if the filesystem is mutated. + */ + async readlink() { + const target = this.#linkTarget; + if (target) { + return target; + } + if (!this.canReadlink()) { + return void 0; + } + if (!this.parent) { + return void 0; + } + try { + const read = await this.#fs.promises.readlink(this.fullpath()); + const linkTarget = (await this.parent.realpath())?.resolve(read); + if (linkTarget) { + return this.#linkTarget = linkTarget; + } + } catch (er) { + this.#readlinkFail(er.code); + return void 0; + } + } + /** + * Synchronous {@link PathBase.readlink} + */ + readlinkSync() { + const target = this.#linkTarget; + if (target) { + return target; + } + if (!this.canReadlink()) { + return void 0; + } + if (!this.parent) { + return void 0; + } + try { + const read = this.#fs.readlinkSync(this.fullpath()); + const linkTarget = this.parent.realpathSync()?.resolve(read); + if (linkTarget) { + return this.#linkTarget = linkTarget; + } + } catch (er) { + this.#readlinkFail(er.code); + return void 0; + } + } + #readdirSuccess(children) { + this.#type |= READDIR_CALLED; + for (let p = children.provisional; p < children.length; p++) { + const c = children[p]; + if (c) + c.#markENOENT(); + } + } + #markENOENT() { + if (this.#type & ENOENT) + return; + this.#type = (this.#type | ENOENT) & IFMT_UNKNOWN; + this.#markChildrenENOENT(); + } + #markChildrenENOENT() { + const children = this.children(); + children.provisional = 0; + for (const p of children) { + p.#markENOENT(); + } + } + #markENOREALPATH() { + this.#type |= ENOREALPATH; + this.#markENOTDIR(); + } + // save the information when we know the entry is not a dir + #markENOTDIR() { + if (this.#type & ENOTDIR) + return; + let t = this.#type; + if ((t & IFMT) === IFDIR) + t &= IFMT_UNKNOWN; + this.#type = t | ENOTDIR; + this.#markChildrenENOENT(); + } + #readdirFail(code = "") { + if (code === "ENOTDIR" || code === "EPERM") { + this.#markENOTDIR(); + } else if (code === "ENOENT") { + this.#markENOENT(); + } else { + this.children().provisional = 0; + } + } + #lstatFail(code = "") { + if (code === "ENOTDIR") { + const p = this.parent; + p.#markENOTDIR(); + } else if (code === "ENOENT") { + this.#markENOENT(); + } + } + #readlinkFail(code = "") { + let ter = this.#type; + ter |= ENOREADLINK; + if (code === "ENOENT") + ter |= ENOENT; + if (code === "EINVAL" || code === "UNKNOWN") { + ter &= IFMT_UNKNOWN; + } + this.#type = ter; + if (code === "ENOTDIR" && this.parent) { + this.parent.#markENOTDIR(); + } + } + #readdirAddChild(e, c) { + return this.#readdirMaybePromoteChild(e, c) || this.#readdirAddNewChild(e, c); + } + #readdirAddNewChild(e, c) { + const type = entToType(e); + const child = this.newChild(e.name, type, { parent: this }); + const ifmt = child.#type & IFMT; + if (ifmt !== IFDIR && ifmt !== IFLNK && ifmt !== UNKNOWN) { + child.#type |= ENOTDIR; + } + c.unshift(child); + c.provisional++; + return child; + } + #readdirMaybePromoteChild(e, c) { + for (let p = c.provisional; p < c.length; p++) { + const pchild = c[p]; + const name = this.nocase ? normalizeNocase(e.name) : normalize(e.name); + if (name !== pchild.#matchName) { + continue; + } + return this.#readdirPromoteChild(e, pchild, p, c); + } + } + #readdirPromoteChild(e, p, index, c) { + const v = p.name; + p.#type = p.#type & IFMT_UNKNOWN | entToType(e); + if (v !== e.name) + p.name = e.name; + if (index !== c.provisional) { + if (index === c.length - 1) + c.pop(); + else + c.splice(index, 1); + c.unshift(p); + } + c.provisional++; + return p; + } + /** + * Call lstat() on this Path, and update all known information that can be + * determined. + * + * Note that unlike `fs.lstat()`, the returned value does not contain some + * information, such as `mode`, `dev`, `nlink`, and `ino`. If that + * information is required, you will need to call `fs.lstat` yourself. + * + * If the Path refers to a nonexistent file, or if the lstat call fails for + * any reason, `undefined` is returned. Otherwise the updated Path object is + * returned. + * + * Results are cached, and thus may be out of date if the filesystem is + * mutated. + */ + async lstat() { + if ((this.#type & ENOENT) === 0) { + try { + this.#applyStat(await this.#fs.promises.lstat(this.fullpath())); + return this; + } catch (er) { + this.#lstatFail(er.code); + } + } + } + /** + * synchronous {@link PathBase.lstat} + */ + lstatSync() { + if ((this.#type & ENOENT) === 0) { + try { + this.#applyStat(this.#fs.lstatSync(this.fullpath())); + return this; + } catch (er) { + this.#lstatFail(er.code); + } + } + } + #applyStat(st) { + const { atime, atimeMs, birthtime, birthtimeMs, blksize, blocks: blocks2, ctime, ctimeMs, dev, gid, ino, mode, mtime, mtimeMs, nlink, rdev, size, uid } = st; + this.#atime = atime; + this.#atimeMs = atimeMs; + this.#birthtime = birthtime; + this.#birthtimeMs = birthtimeMs; + this.#blksize = blksize; + this.#blocks = blocks2; + this.#ctime = ctime; + this.#ctimeMs = ctimeMs; + this.#dev = dev; + this.#gid = gid; + this.#ino = ino; + this.#mode = mode; + this.#mtime = mtime; + this.#mtimeMs = mtimeMs; + this.#nlink = nlink; + this.#rdev = rdev; + this.#size = size; + this.#uid = uid; + const ifmt = entToType(st); + this.#type = this.#type & IFMT_UNKNOWN | ifmt | LSTAT_CALLED; + if (ifmt !== UNKNOWN && ifmt !== IFDIR && ifmt !== IFLNK) { + this.#type |= ENOTDIR; + } + } + #onReaddirCB = []; + #readdirCBInFlight = false; + #callOnReaddirCB(children) { + this.#readdirCBInFlight = false; + const cbs = this.#onReaddirCB.slice(); + this.#onReaddirCB.length = 0; + cbs.forEach((cb) => cb(null, children)); + } + /** + * Standard node-style callback interface to get list of directory entries. + * + * If the Path cannot or does not contain any children, then an empty array + * is returned. + * + * Results are cached, and thus may be out of date if the filesystem is + * mutated. + * + * @param cb The callback called with (er, entries). Note that the `er` + * param is somewhat extraneous, as all readdir() errors are handled and + * simply result in an empty set of entries being returned. + * @param allowZalgo Boolean indicating that immediately known results should + * *not* be deferred with `queueMicrotask`. Defaults to `false`. Release + * zalgo at your peril, the dark pony lord is devious and unforgiving. + */ + readdirCB(cb, allowZalgo = false) { + if (!this.canReaddir()) { + if (allowZalgo) + cb(null, []); + else + queueMicrotask(() => cb(null, [])); + return; + } + const children = this.children(); + if (this.calledReaddir()) { + const c = children.slice(0, children.provisional); + if (allowZalgo) + cb(null, c); + else + queueMicrotask(() => cb(null, c)); + return; + } + this.#onReaddirCB.push(cb); + if (this.#readdirCBInFlight) { + return; + } + this.#readdirCBInFlight = true; + const fullpath = this.fullpath(); + this.#fs.readdir(fullpath, { withFileTypes: true }, (er, entries) => { + if (er) { + this.#readdirFail(er.code); + children.provisional = 0; + } else { + for (const e of entries) { + this.#readdirAddChild(e, children); + } + this.#readdirSuccess(children); + } + this.#callOnReaddirCB(children.slice(0, children.provisional)); + return; + }); + } + #asyncReaddirInFlight; + /** + * Return an array of known child entries. + * + * If the Path cannot or does not contain any children, then an empty array + * is returned. + * + * Results are cached, and thus may be out of date if the filesystem is + * mutated. + */ + async readdir() { + if (!this.canReaddir()) { + return []; + } + const children = this.children(); + if (this.calledReaddir()) { + return children.slice(0, children.provisional); + } + const fullpath = this.fullpath(); + if (this.#asyncReaddirInFlight) { + await this.#asyncReaddirInFlight; + } else { + let resolve = () => { + }; + this.#asyncReaddirInFlight = new Promise((res) => resolve = res); + try { + for (const e of await this.#fs.promises.readdir(fullpath, { + withFileTypes: true + })) { + this.#readdirAddChild(e, children); + } + this.#readdirSuccess(children); + } catch (er) { + this.#readdirFail(er.code); + children.provisional = 0; + } + this.#asyncReaddirInFlight = void 0; + resolve(); + } + return children.slice(0, children.provisional); + } + /** + * synchronous {@link PathBase.readdir} + */ + readdirSync() { + if (!this.canReaddir()) { + return []; + } + const children = this.children(); + if (this.calledReaddir()) { + return children.slice(0, children.provisional); + } + const fullpath = this.fullpath(); + try { + for (const e of this.#fs.readdirSync(fullpath, { + withFileTypes: true + })) { + this.#readdirAddChild(e, children); + } + this.#readdirSuccess(children); + } catch (er) { + this.#readdirFail(er.code); + children.provisional = 0; + } + return children.slice(0, children.provisional); + } + canReaddir() { + if (this.#type & ENOCHILD) + return false; + const ifmt = IFMT & this.#type; + if (!(ifmt === UNKNOWN || ifmt === IFDIR || ifmt === IFLNK)) { + return false; + } + return true; + } + shouldWalk(dirs, walkFilter) { + return (this.#type & IFDIR) === IFDIR && !(this.#type & ENOCHILD) && !dirs.has(this) && (!walkFilter || walkFilter(this)); + } + /** + * Return the Path object corresponding to path as resolved + * by realpath(3). + * + * If the realpath call fails for any reason, `undefined` is returned. + * + * Result is cached, and thus may be outdated if the filesystem is mutated. + * On success, returns a Path object. + */ + async realpath() { + if (this.#realpath) + return this.#realpath; + if ((ENOREALPATH | ENOREADLINK | ENOENT) & this.#type) + return void 0; + try { + const rp = await this.#fs.promises.realpath(this.fullpath()); + return this.#realpath = this.resolve(rp); + } catch (_) { + this.#markENOREALPATH(); + } + } + /** + * Synchronous {@link realpath} + */ + realpathSync() { + if (this.#realpath) + return this.#realpath; + if ((ENOREALPATH | ENOREADLINK | ENOENT) & this.#type) + return void 0; + try { + const rp = this.#fs.realpathSync(this.fullpath()); + return this.#realpath = this.resolve(rp); + } catch (_) { + this.#markENOREALPATH(); + } + } + /** + * Internal method to mark this Path object as the scurry cwd, + * called by {@link PathScurry#chdir} + * + * @internal + */ + [setAsCwd](oldCwd) { + if (oldCwd === this) + return; + const changed = /* @__PURE__ */ new Set([]); + let rp = []; + let p = this; + while (p && p.parent) { + changed.add(p); + p.#relative = rp.join(this.sep); + p.#relativePosix = rp.join("/"); + p = p.parent; + rp.push(".."); + } + p = oldCwd; + while (p && p.parent && !changed.has(p)) { + p.#relative = void 0; + p.#relativePosix = void 0; + p = p.parent; + } + } +}; +var PathWin32 = class _PathWin32 extends PathBase { + /** + * Separator for generating path strings. + */ + sep = "\\"; + /** + * Separator for parsing path strings. + */ + splitSep = eitherSep; + /** + * Do not create new Path objects directly. They should always be accessed + * via the PathScurry class or other methods on the Path class. + * + * @internal + */ + constructor(name, type = UNKNOWN, root, roots, nocase, children, opts) { + super(name, type, root, roots, nocase, children, opts); + } + /** + * @internal + */ + newChild(name, type = UNKNOWN, opts = {}) { + return new _PathWin32(name, type, this.root, this.roots, this.nocase, this.childrenCache(), opts); + } + /** + * @internal + */ + getRootString(path4) { + return win32.parse(path4).root; + } + /** + * @internal + */ + getRoot(rootPath) { + rootPath = uncToDrive(rootPath.toUpperCase()); + if (rootPath === this.root.name) { + return this.root; + } + for (const [compare2, root] of Object.entries(this.roots)) { + if (this.sameRoot(rootPath, compare2)) { + return this.roots[rootPath] = root; + } + } + return this.roots[rootPath] = new PathScurryWin32(rootPath, this).root; + } + /** + * @internal + */ + sameRoot(rootPath, compare2 = this.root.name) { + rootPath = rootPath.toUpperCase().replace(/\//g, "\\").replace(uncDriveRegexp, "$1\\"); + return rootPath === compare2; + } +}; +var PathPosix = class _PathPosix extends PathBase { + /** + * separator for parsing path strings + */ + splitSep = "/"; + /** + * separator for generating path strings + */ + sep = "/"; + /** + * Do not create new Path objects directly. They should always be accessed + * via the PathScurry class or other methods on the Path class. + * + * @internal + */ + constructor(name, type = UNKNOWN, root, roots, nocase, children, opts) { + super(name, type, root, roots, nocase, children, opts); + } + /** + * @internal + */ + getRootString(path4) { + return path4.startsWith("/") ? "/" : ""; + } + /** + * @internal + */ + getRoot(_rootPath) { + return this.root; + } + /** + * @internal + */ + newChild(name, type = UNKNOWN, opts = {}) { + return new _PathPosix(name, type, this.root, this.roots, this.nocase, this.childrenCache(), opts); + } +}; +var PathScurryBase = class { + /** + * The root Path entry for the current working directory of this Scurry + */ + root; + /** + * The string path for the root of this Scurry's current working directory + */ + rootPath; + /** + * A collection of all roots encountered, referenced by rootPath + */ + roots; + /** + * The Path entry corresponding to this PathScurry's current working directory. + */ + cwd; + #resolveCache; + #resolvePosixCache; + #children; + /** + * Perform path comparisons case-insensitively. + * + * Defaults true on Darwin and Windows systems, false elsewhere. + */ + nocase; + #fs; + /** + * This class should not be instantiated directly. + * + * Use PathScurryWin32, PathScurryDarwin, PathScurryPosix, or PathScurry + * + * @internal + */ + constructor(cwd = process.cwd(), pathImpl, sep2, { nocase, childrenCacheSize = 16 * 1024, fs: fs4 = defaultFS } = {}) { + this.#fs = fsFromOption(fs4); + if (cwd instanceof URL || cwd.startsWith("file://")) { + cwd = fileURLToPath(cwd); + } + const cwdPath = pathImpl.resolve(cwd); + this.roots = /* @__PURE__ */ Object.create(null); + this.rootPath = this.parseRootPath(cwdPath); + this.#resolveCache = new ResolveCache(); + this.#resolvePosixCache = new ResolveCache(); + this.#children = new ChildrenCache(childrenCacheSize); + const split = cwdPath.substring(this.rootPath.length).split(sep2); + if (split.length === 1 && !split[0]) { + split.pop(); + } + if (nocase === void 0) { + throw new TypeError("must provide nocase setting to PathScurryBase ctor"); + } + this.nocase = nocase; + this.root = this.newRoot(this.#fs); + this.roots[this.rootPath] = this.root; + let prev = this.root; + let len = split.length - 1; + const joinSep = pathImpl.sep; + let abs = this.rootPath; + let sawFirst = false; + for (const part of split) { + const l = len--; + prev = prev.child(part, { + relative: new Array(l).fill("..").join(joinSep), + relativePosix: new Array(l).fill("..").join("/"), + fullpath: abs += (sawFirst ? "" : joinSep) + part + }); + sawFirst = true; + } + this.cwd = prev; + } + /** + * Get the depth of a provided path, string, or the cwd + */ + depth(path4 = this.cwd) { + if (typeof path4 === "string") { + path4 = this.cwd.resolve(path4); + } + return path4.depth(); + } + /** + * Return the cache of child entries. Exposed so subclasses can create + * child Path objects in a platform-specific way. + * + * @internal + */ + childrenCache() { + return this.#children; + } + /** + * Resolve one or more path strings to a resolved string + * + * Same interface as require('path').resolve. + * + * Much faster than path.resolve() when called multiple times for the same + * path, because the resolved Path objects are cached. Much slower + * otherwise. + */ + resolve(...paths) { + let r = ""; + for (let i = paths.length - 1; i >= 0; i--) { + const p = paths[i]; + if (!p || p === ".") + continue; + r = r ? `${p}/${r}` : p; + if (this.isAbsolute(p)) { + break; + } + } + const cached = this.#resolveCache.get(r); + if (cached !== void 0) { + return cached; + } + const result = this.cwd.resolve(r).fullpath(); + this.#resolveCache.set(r, result); + return result; + } + /** + * Resolve one or more path strings to a resolved string, returning + * the posix path. Identical to .resolve() on posix systems, but on + * windows will return a forward-slash separated UNC path. + * + * Same interface as require('path').resolve. + * + * Much faster than path.resolve() when called multiple times for the same + * path, because the resolved Path objects are cached. Much slower + * otherwise. + */ + resolvePosix(...paths) { + let r = ""; + for (let i = paths.length - 1; i >= 0; i--) { + const p = paths[i]; + if (!p || p === ".") + continue; + r = r ? `${p}/${r}` : p; + if (this.isAbsolute(p)) { + break; + } + } + const cached = this.#resolvePosixCache.get(r); + if (cached !== void 0) { + return cached; + } + const result = this.cwd.resolve(r).fullpathPosix(); + this.#resolvePosixCache.set(r, result); + return result; + } + /** + * find the relative path from the cwd to the supplied path string or entry + */ + relative(entry = this.cwd) { + if (typeof entry === "string") { + entry = this.cwd.resolve(entry); + } + return entry.relative(); + } + /** + * find the relative path from the cwd to the supplied path string or + * entry, using / as the path delimiter, even on Windows. + */ + relativePosix(entry = this.cwd) { + if (typeof entry === "string") { + entry = this.cwd.resolve(entry); + } + return entry.relativePosix(); + } + /** + * Return the basename for the provided string or Path object + */ + basename(entry = this.cwd) { + if (typeof entry === "string") { + entry = this.cwd.resolve(entry); + } + return entry.name; + } + /** + * Return the dirname for the provided string or Path object + */ + dirname(entry = this.cwd) { + if (typeof entry === "string") { + entry = this.cwd.resolve(entry); + } + return (entry.parent || entry).fullpath(); + } + async readdir(entry = this.cwd, opts = { + withFileTypes: true + }) { + if (typeof entry === "string") { + entry = this.cwd.resolve(entry); + } else if (!(entry instanceof PathBase)) { + opts = entry; + entry = this.cwd; + } + const { withFileTypes } = opts; + if (!entry.canReaddir()) { + return []; + } else { + const p = await entry.readdir(); + return withFileTypes ? p : p.map((e) => e.name); + } + } + readdirSync(entry = this.cwd, opts = { + withFileTypes: true + }) { + if (typeof entry === "string") { + entry = this.cwd.resolve(entry); + } else if (!(entry instanceof PathBase)) { + opts = entry; + entry = this.cwd; + } + const { withFileTypes = true } = opts; + if (!entry.canReaddir()) { + return []; + } else if (withFileTypes) { + return entry.readdirSync(); + } else { + return entry.readdirSync().map((e) => e.name); + } + } + /** + * Call lstat() on the string or Path object, and update all known + * information that can be determined. + * + * Note that unlike `fs.lstat()`, the returned value does not contain some + * information, such as `mode`, `dev`, `nlink`, and `ino`. If that + * information is required, you will need to call `fs.lstat` yourself. + * + * If the Path refers to a nonexistent file, or if the lstat call fails for + * any reason, `undefined` is returned. Otherwise the updated Path object is + * returned. + * + * Results are cached, and thus may be out of date if the filesystem is + * mutated. + */ + async lstat(entry = this.cwd) { + if (typeof entry === "string") { + entry = this.cwd.resolve(entry); + } + return entry.lstat(); + } + /** + * synchronous {@link PathScurryBase.lstat} + */ + lstatSync(entry = this.cwd) { + if (typeof entry === "string") { + entry = this.cwd.resolve(entry); + } + return entry.lstatSync(); + } + async readlink(entry = this.cwd, { withFileTypes } = { + withFileTypes: false + }) { + if (typeof entry === "string") { + entry = this.cwd.resolve(entry); + } else if (!(entry instanceof PathBase)) { + withFileTypes = entry.withFileTypes; + entry = this.cwd; + } + const e = await entry.readlink(); + return withFileTypes ? e : e?.fullpath(); + } + readlinkSync(entry = this.cwd, { withFileTypes } = { + withFileTypes: false + }) { + if (typeof entry === "string") { + entry = this.cwd.resolve(entry); + } else if (!(entry instanceof PathBase)) { + withFileTypes = entry.withFileTypes; + entry = this.cwd; + } + const e = entry.readlinkSync(); + return withFileTypes ? e : e?.fullpath(); + } + async realpath(entry = this.cwd, { withFileTypes } = { + withFileTypes: false + }) { + if (typeof entry === "string") { + entry = this.cwd.resolve(entry); + } else if (!(entry instanceof PathBase)) { + withFileTypes = entry.withFileTypes; + entry = this.cwd; + } + const e = await entry.realpath(); + return withFileTypes ? e : e?.fullpath(); + } + realpathSync(entry = this.cwd, { withFileTypes } = { + withFileTypes: false + }) { + if (typeof entry === "string") { + entry = this.cwd.resolve(entry); + } else if (!(entry instanceof PathBase)) { + withFileTypes = entry.withFileTypes; + entry = this.cwd; + } + const e = entry.realpathSync(); + return withFileTypes ? e : e?.fullpath(); + } + async walk(entry = this.cwd, opts = {}) { + if (typeof entry === "string") { + entry = this.cwd.resolve(entry); + } else if (!(entry instanceof PathBase)) { + opts = entry; + entry = this.cwd; + } + const { withFileTypes = true, follow = false, filter: filter2, walkFilter } = opts; + const results = []; + if (!filter2 || filter2(entry)) { + results.push(withFileTypes ? entry : entry.fullpath()); + } + const dirs = /* @__PURE__ */ new Set(); + const walk = (dir, cb) => { + dirs.add(dir); + dir.readdirCB((er, entries) => { + if (er) { + return cb(er); + } + let len = entries.length; + if (!len) + return cb(); + const next = () => { + if (--len === 0) { + cb(); + } + }; + for (const e of entries) { + if (!filter2 || filter2(e)) { + results.push(withFileTypes ? e : e.fullpath()); + } + if (follow && e.isSymbolicLink()) { + e.realpath().then((r) => r?.isUnknown() ? r.lstat() : r).then((r) => r?.shouldWalk(dirs, walkFilter) ? walk(r, next) : next()); + } else { + if (e.shouldWalk(dirs, walkFilter)) { + walk(e, next); + } else { + next(); + } + } + } + }, true); + }; + const start = entry; + return new Promise((res, rej) => { + walk(start, (er) => { + if (er) + return rej(er); + res(results); + }); + }); + } + walkSync(entry = this.cwd, opts = {}) { + if (typeof entry === "string") { + entry = this.cwd.resolve(entry); + } else if (!(entry instanceof PathBase)) { + opts = entry; + entry = this.cwd; + } + const { withFileTypes = true, follow = false, filter: filter2, walkFilter } = opts; + const results = []; + if (!filter2 || filter2(entry)) { + results.push(withFileTypes ? entry : entry.fullpath()); + } + const dirs = /* @__PURE__ */ new Set([entry]); + for (const dir of dirs) { + const entries = dir.readdirSync(); + for (const e of entries) { + if (!filter2 || filter2(e)) { + results.push(withFileTypes ? e : e.fullpath()); + } + let r = e; + if (e.isSymbolicLink()) { + if (!(follow && (r = e.realpathSync()))) + continue; + if (r.isUnknown()) + r.lstatSync(); + } + if (r.shouldWalk(dirs, walkFilter)) { + dirs.add(r); + } + } + } + return results; + } + /** + * Support for `for await` + * + * Alias for {@link PathScurryBase.iterate} + * + * Note: As of Node 19, this is very slow, compared to other methods of + * walking. Consider using {@link PathScurryBase.stream} if memory overhead + * and backpressure are concerns, or {@link PathScurryBase.walk} if not. + */ + [Symbol.asyncIterator]() { + return this.iterate(); + } + iterate(entry = this.cwd, options = {}) { + if (typeof entry === "string") { + entry = this.cwd.resolve(entry); + } else if (!(entry instanceof PathBase)) { + options = entry; + entry = this.cwd; + } + return this.stream(entry, options)[Symbol.asyncIterator](); + } + /** + * Iterating over a PathScurry performs a synchronous walk. + * + * Alias for {@link PathScurryBase.iterateSync} + */ + [Symbol.iterator]() { + return this.iterateSync(); + } + *iterateSync(entry = this.cwd, opts = {}) { + if (typeof entry === "string") { + entry = this.cwd.resolve(entry); + } else if (!(entry instanceof PathBase)) { + opts = entry; + entry = this.cwd; + } + const { withFileTypes = true, follow = false, filter: filter2, walkFilter } = opts; + if (!filter2 || filter2(entry)) { + yield withFileTypes ? entry : entry.fullpath(); + } + const dirs = /* @__PURE__ */ new Set([entry]); + for (const dir of dirs) { + const entries = dir.readdirSync(); + for (const e of entries) { + if (!filter2 || filter2(e)) { + yield withFileTypes ? e : e.fullpath(); + } + let r = e; + if (e.isSymbolicLink()) { + if (!(follow && (r = e.realpathSync()))) + continue; + if (r.isUnknown()) + r.lstatSync(); + } + if (r.shouldWalk(dirs, walkFilter)) { + dirs.add(r); + } + } + } + } + stream(entry = this.cwd, opts = {}) { + if (typeof entry === "string") { + entry = this.cwd.resolve(entry); + } else if (!(entry instanceof PathBase)) { + opts = entry; + entry = this.cwd; + } + const { withFileTypes = true, follow = false, filter: filter2, walkFilter } = opts; + const results = new Minipass({ objectMode: true }); + if (!filter2 || filter2(entry)) { + results.write(withFileTypes ? entry : entry.fullpath()); + } + const dirs = /* @__PURE__ */ new Set(); + const queue = [entry]; + let processing = 0; + const process3 = () => { + let paused = false; + while (!paused) { + const dir = queue.shift(); + if (!dir) { + if (processing === 0) + results.end(); + return; + } + processing++; + dirs.add(dir); + const onReaddir = (er, entries, didRealpaths = false) => { + if (er) + return results.emit("error", er); + if (follow && !didRealpaths) { + const promises = []; + for (const e of entries) { + if (e.isSymbolicLink()) { + promises.push(e.realpath().then((r) => r?.isUnknown() ? r.lstat() : r)); + } + } + if (promises.length) { + Promise.all(promises).then(() => onReaddir(null, entries, true)); + return; + } + } + for (const e of entries) { + if (e && (!filter2 || filter2(e))) { + if (!results.write(withFileTypes ? e : e.fullpath())) { + paused = true; + } + } + } + processing--; + for (const e of entries) { + const r = e.realpathCached() || e; + if (r.shouldWalk(dirs, walkFilter)) { + queue.push(r); + } + } + if (paused && !results.flowing) { + results.once("drain", process3); + } else if (!sync2) { + process3(); + } + }; + let sync2 = true; + dir.readdirCB(onReaddir, true); + sync2 = false; + } + }; + process3(); + return results; + } + streamSync(entry = this.cwd, opts = {}) { + if (typeof entry === "string") { + entry = this.cwd.resolve(entry); + } else if (!(entry instanceof PathBase)) { + opts = entry; + entry = this.cwd; + } + const { withFileTypes = true, follow = false, filter: filter2, walkFilter } = opts; + const results = new Minipass({ objectMode: true }); + const dirs = /* @__PURE__ */ new Set(); + if (!filter2 || filter2(entry)) { + results.write(withFileTypes ? entry : entry.fullpath()); + } + const queue = [entry]; + let processing = 0; + const process3 = () => { + let paused = false; + while (!paused) { + const dir = queue.shift(); + if (!dir) { + if (processing === 0) + results.end(); + return; + } + processing++; + dirs.add(dir); + const entries = dir.readdirSync(); + for (const e of entries) { + if (!filter2 || filter2(e)) { + if (!results.write(withFileTypes ? e : e.fullpath())) { + paused = true; + } + } + } + processing--; + for (const e of entries) { + let r = e; + if (e.isSymbolicLink()) { + if (!(follow && (r = e.realpathSync()))) + continue; + if (r.isUnknown()) + r.lstatSync(); + } + if (r.shouldWalk(dirs, walkFilter)) { + queue.push(r); + } + } + } + if (paused && !results.flowing) + results.once("drain", process3); + }; + process3(); + return results; + } + chdir(path4 = this.cwd) { + const oldCwd = this.cwd; + this.cwd = typeof path4 === "string" ? this.cwd.resolve(path4) : path4; + this.cwd[setAsCwd](oldCwd); + } +}; +var PathScurryWin32 = class extends PathScurryBase { + /** + * separator for generating path strings + */ + sep = "\\"; + constructor(cwd = process.cwd(), opts = {}) { + const { nocase = true } = opts; + super(cwd, win32, "\\", { ...opts, nocase }); + this.nocase = nocase; + for (let p = this.cwd; p; p = p.parent) { + p.nocase = this.nocase; + } + } + /** + * @internal + */ + parseRootPath(dir) { + return win32.parse(dir).root.toUpperCase(); + } + /** + * @internal + */ + newRoot(fs4) { + return new PathWin32(this.rootPath, IFDIR, void 0, this.roots, this.nocase, this.childrenCache(), { fs: fs4 }); + } + /** + * Return true if the provided path string is an absolute path + */ + isAbsolute(p) { + return p.startsWith("/") || p.startsWith("\\") || /^[a-z]:(\/|\\)/i.test(p); + } +}; +var PathScurryPosix = class extends PathScurryBase { + /** + * separator for generating path strings + */ + sep = "/"; + constructor(cwd = process.cwd(), opts = {}) { + const { nocase = false } = opts; + super(cwd, posix, "/", { ...opts, nocase }); + this.nocase = nocase; + } + /** + * @internal + */ + parseRootPath(_dir) { + return "/"; + } + /** + * @internal + */ + newRoot(fs4) { + return new PathPosix(this.rootPath, IFDIR, void 0, this.roots, this.nocase, this.childrenCache(), { fs: fs4 }); + } + /** + * Return true if the provided path string is an absolute path + */ + isAbsolute(p) { + return p.startsWith("/"); + } +}; +var PathScurryDarwin = class extends PathScurryPosix { + constructor(cwd = process.cwd(), opts = {}) { + const { nocase = true } = opts; + super(cwd, { ...opts, nocase }); + } +}; +var Path = process.platform === "win32" ? PathWin32 : PathPosix; +var PathScurry = process.platform === "win32" ? PathScurryWin32 : process.platform === "darwin" ? PathScurryDarwin : PathScurryPosix; + +// node_modules/glob/dist/esm/glob.js +import { fileURLToPath as fileURLToPath2 } from "url"; + +// node_modules/glob/dist/esm/pattern.js +var isPatternList = (pl) => pl.length >= 1; +var isGlobList = (gl) => gl.length >= 1; +var Pattern = class _Pattern { + #patternList; + #globList; + #index; + length; + #platform; + #rest; + #globString; + #isDrive; + #isUNC; + #isAbsolute; + #followGlobstar = true; + constructor(patternList, globList, index, platform) { + if (!isPatternList(patternList)) { + throw new TypeError("empty pattern list"); + } + if (!isGlobList(globList)) { + throw new TypeError("empty glob list"); + } + if (globList.length !== patternList.length) { + throw new TypeError("mismatched pattern list and glob list lengths"); + } + this.length = patternList.length; + if (index < 0 || index >= this.length) { + throw new TypeError("index out of range"); + } + this.#patternList = patternList; + this.#globList = globList; + this.#index = index; + this.#platform = platform; + if (this.#index === 0) { + if (this.isUNC()) { + const [p0, p1, p2, p3, ...prest] = this.#patternList; + const [g0, g1, g2, g3, ...grest] = this.#globList; + if (prest[0] === "") { + prest.shift(); + grest.shift(); + } + const p = [p0, p1, p2, p3, ""].join("/"); + const g = [g0, g1, g2, g3, ""].join("/"); + this.#patternList = [p, ...prest]; + this.#globList = [g, ...grest]; + this.length = this.#patternList.length; + } else if (this.isDrive() || this.isAbsolute()) { + const [p1, ...prest] = this.#patternList; + const [g1, ...grest] = this.#globList; + if (prest[0] === "") { + prest.shift(); + grest.shift(); + } + const p = p1 + "/"; + const g = g1 + "/"; + this.#patternList = [p, ...prest]; + this.#globList = [g, ...grest]; + this.length = this.#patternList.length; + } + } + } + /** + * The first entry in the parsed list of patterns + */ + pattern() { + return this.#patternList[this.#index]; + } + /** + * true of if pattern() returns a string + */ + isString() { + return typeof this.#patternList[this.#index] === "string"; + } + /** + * true of if pattern() returns GLOBSTAR + */ + isGlobstar() { + return this.#patternList[this.#index] === GLOBSTAR; + } + /** + * true if pattern() returns a regexp + */ + isRegExp() { + return this.#patternList[this.#index] instanceof RegExp; + } + /** + * The /-joined set of glob parts that make up this pattern + */ + globString() { + return this.#globString = this.#globString || (this.#index === 0 ? this.isAbsolute() ? this.#globList[0] + this.#globList.slice(1).join("/") : this.#globList.join("/") : this.#globList.slice(this.#index).join("/")); + } + /** + * true if there are more pattern parts after this one + */ + hasMore() { + return this.length > this.#index + 1; + } + /** + * The rest of the pattern after this part, or null if this is the end + */ + rest() { + if (this.#rest !== void 0) + return this.#rest; + if (!this.hasMore()) + return this.#rest = null; + this.#rest = new _Pattern(this.#patternList, this.#globList, this.#index + 1, this.#platform); + this.#rest.#isAbsolute = this.#isAbsolute; + this.#rest.#isUNC = this.#isUNC; + this.#rest.#isDrive = this.#isDrive; + return this.#rest; + } + /** + * true if the pattern represents a //unc/path/ on windows + */ + isUNC() { + const pl = this.#patternList; + return this.#isUNC !== void 0 ? this.#isUNC : this.#isUNC = this.#platform === "win32" && this.#index === 0 && pl[0] === "" && pl[1] === "" && typeof pl[2] === "string" && !!pl[2] && typeof pl[3] === "string" && !!pl[3]; + } + // pattern like C:/... + // split = ['C:', ...] + // XXX: would be nice to handle patterns like `c:*` to test the cwd + // in c: for *, but I don't know of a way to even figure out what that + // cwd is without actually chdir'ing into it? + /** + * True if the pattern starts with a drive letter on Windows + */ + isDrive() { + const pl = this.#patternList; + return this.#isDrive !== void 0 ? this.#isDrive : this.#isDrive = this.#platform === "win32" && this.#index === 0 && this.length > 1 && typeof pl[0] === "string" && /^[a-z]:$/i.test(pl[0]); + } + // pattern = '/' or '/...' or '/x/...' + // split = ['', ''] or ['', ...] or ['', 'x', ...] + // Drive and UNC both considered absolute on windows + /** + * True if the pattern is rooted on an absolute path + */ + isAbsolute() { + const pl = this.#patternList; + return this.#isAbsolute !== void 0 ? this.#isAbsolute : this.#isAbsolute = pl[0] === "" && pl.length > 1 || this.isDrive() || this.isUNC(); + } + /** + * consume the root of the pattern, and return it + */ + root() { + const p = this.#patternList[0]; + return typeof p === "string" && this.isAbsolute() && this.#index === 0 ? p : ""; + } + /** + * Check to see if the current globstar pattern is allowed to follow + * a symbolic link. + */ + checkFollowGlobstar() { + return !(this.#index === 0 || !this.isGlobstar() || !this.#followGlobstar); + } + /** + * Mark that the current globstar pattern is following a symbolic link + */ + markFollowGlobstar() { + if (this.#index === 0 || !this.isGlobstar() || !this.#followGlobstar) + return false; + this.#followGlobstar = false; + return true; + } +}; + +// node_modules/glob/dist/esm/ignore.js +var defaultPlatform2 = typeof process === "object" && process && typeof process.platform === "string" ? process.platform : "linux"; +var Ignore = class { + relative; + relativeChildren; + absolute; + absoluteChildren; + constructor(ignored, { nobrace, nocase, noext, noglobstar, platform = defaultPlatform2 }) { + this.relative = []; + this.absolute = []; + this.relativeChildren = []; + this.absoluteChildren = []; + const mmopts = { + dot: true, + nobrace, + nocase, + noext, + noglobstar, + optimizationLevel: 2, + platform, + nocomment: true, + nonegate: true + }; + for (const ign of ignored) { + const mm = new Minimatch(ign, mmopts); + for (let i = 0; i < mm.set.length; i++) { + const parsed = mm.set[i]; + const globParts = mm.globParts[i]; + if (!parsed || !globParts) { + throw new Error("invalid pattern object"); + } + while (parsed[0] === "." && globParts[0] === ".") { + parsed.shift(); + globParts.shift(); + } + const p = new Pattern(parsed, globParts, 0, platform); + const m = new Minimatch(p.globString(), mmopts); + const children = globParts[globParts.length - 1] === "**"; + const absolute = p.isAbsolute(); + if (absolute) + this.absolute.push(m); + else + this.relative.push(m); + if (children) { + if (absolute) + this.absoluteChildren.push(m); + else + this.relativeChildren.push(m); + } + } + } + } + ignored(p) { + const fullpath = p.fullpath(); + const fullpaths = `${fullpath}/`; + const relative = p.relative() || "."; + const relatives = `${relative}/`; + for (const m of this.relative) { + if (m.match(relative) || m.match(relatives)) + return true; + } + for (const m of this.absolute) { + if (m.match(fullpath) || m.match(fullpaths)) + return true; + } + return false; + } + childrenIgnored(p) { + const fullpath = p.fullpath() + "/"; + const relative = (p.relative() || ".") + "/"; + for (const m of this.relativeChildren) { + if (m.match(relative)) + return true; + } + for (const m of this.absoluteChildren) { + if (m.match(fullpath)) + return true; + } + return false; + } +}; + +// node_modules/glob/dist/esm/processor.js +var HasWalkedCache = class _HasWalkedCache { + store; + constructor(store = /* @__PURE__ */ new Map()) { + this.store = store; + } + copy() { + return new _HasWalkedCache(new Map(this.store)); + } + hasWalked(target, pattern) { + return this.store.get(target.fullpath())?.has(pattern.globString()); + } + storeWalked(target, pattern) { + const fullpath = target.fullpath(); + const cached = this.store.get(fullpath); + if (cached) + cached.add(pattern.globString()); + else + this.store.set(fullpath, /* @__PURE__ */ new Set([pattern.globString()])); + } +}; +var MatchRecord = class { + store = /* @__PURE__ */ new Map(); + add(target, absolute, ifDir) { + const n = (absolute ? 2 : 0) | (ifDir ? 1 : 0); + const current = this.store.get(target); + this.store.set(target, current === void 0 ? n : n & current); + } + // match, absolute, ifdir + entries() { + return [...this.store.entries()].map(([path4, n]) => [ + path4, + !!(n & 2), + !!(n & 1) + ]); + } +}; +var SubWalks = class { + store = /* @__PURE__ */ new Map(); + add(target, pattern) { + if (!target.canReaddir()) { + return; + } + const subs = this.store.get(target); + if (subs) { + if (!subs.find((p) => p.globString() === pattern.globString())) { + subs.push(pattern); + } + } else + this.store.set(target, [pattern]); + } + get(target) { + const subs = this.store.get(target); + if (!subs) { + throw new Error("attempting to walk unknown path"); + } + return subs; + } + entries() { + return this.keys().map((k) => [k, this.store.get(k)]); + } + keys() { + return [...this.store.keys()].filter((t) => t.canReaddir()); + } +}; +var Processor = class _Processor { + hasWalkedCache; + matches = new MatchRecord(); + subwalks = new SubWalks(); + patterns; + follow; + dot; + opts; + constructor(opts, hasWalkedCache) { + this.opts = opts; + this.follow = !!opts.follow; + this.dot = !!opts.dot; + this.hasWalkedCache = hasWalkedCache ? hasWalkedCache.copy() : new HasWalkedCache(); + } + processPatterns(target, patterns) { + this.patterns = patterns; + const processingSet = patterns.map((p) => [target, p]); + for (let [t, pattern] of processingSet) { + this.hasWalkedCache.storeWalked(t, pattern); + const root = pattern.root(); + const absolute = pattern.isAbsolute() && this.opts.absolute !== false; + if (root) { + t = t.resolve(root === "/" && this.opts.root !== void 0 ? this.opts.root : root); + const rest2 = pattern.rest(); + if (!rest2) { + this.matches.add(t, true, false); + continue; + } else { + pattern = rest2; + } + } + if (t.isENOENT()) + continue; + let p; + let rest; + let changed = false; + while (typeof (p = pattern.pattern()) === "string" && (rest = pattern.rest())) { + const c = t.resolve(p); + t = c; + pattern = rest; + changed = true; + } + p = pattern.pattern(); + rest = pattern.rest(); + if (changed) { + if (this.hasWalkedCache.hasWalked(t, pattern)) + continue; + this.hasWalkedCache.storeWalked(t, pattern); + } + if (typeof p === "string") { + const ifDir = p === ".." || p === "" || p === "."; + this.matches.add(t.resolve(p), absolute, ifDir); + continue; + } else if (p === GLOBSTAR) { + if (!t.isSymbolicLink() || this.follow || pattern.checkFollowGlobstar()) { + this.subwalks.add(t, pattern); + } + const rp = rest?.pattern(); + const rrest = rest?.rest(); + if (!rest || (rp === "" || rp === ".") && !rrest) { + this.matches.add(t, absolute, rp === "" || rp === "."); + } else { + if (rp === "..") { + const tp = t.parent || t; + if (!rrest) + this.matches.add(tp, absolute, true); + else if (!this.hasWalkedCache.hasWalked(tp, rrest)) { + this.subwalks.add(tp, rrest); + } + } + } + } else if (p instanceof RegExp) { + this.subwalks.add(t, pattern); + } + } + return this; + } + subwalkTargets() { + return this.subwalks.keys(); + } + child() { + return new _Processor(this.opts, this.hasWalkedCache); + } + // return a new Processor containing the subwalks for each + // child entry, and a set of matches, and + // a hasWalkedCache that's a copy of this one + // then we're going to call + filterEntries(parent, entries) { + const patterns = this.subwalks.get(parent); + const results = this.child(); + for (const e of entries) { + for (const pattern of patterns) { + const absolute = pattern.isAbsolute(); + const p = pattern.pattern(); + const rest = pattern.rest(); + if (p === GLOBSTAR) { + results.testGlobstar(e, pattern, rest, absolute); + } else if (p instanceof RegExp) { + results.testRegExp(e, p, rest, absolute); + } else { + results.testString(e, p, rest, absolute); + } + } + } + return results; + } + testGlobstar(e, pattern, rest, absolute) { + if (this.dot || !e.name.startsWith(".")) { + if (!pattern.hasMore()) { + this.matches.add(e, absolute, false); + } + if (e.canReaddir()) { + if (this.follow || !e.isSymbolicLink()) { + this.subwalks.add(e, pattern); + } else if (e.isSymbolicLink()) { + if (rest && pattern.checkFollowGlobstar()) { + this.subwalks.add(e, rest); + } else if (pattern.markFollowGlobstar()) { + this.subwalks.add(e, pattern); + } + } + } + } + if (rest) { + const rp = rest.pattern(); + if (typeof rp === "string" && // dots and empty were handled already + rp !== ".." && rp !== "" && rp !== ".") { + this.testString(e, rp, rest.rest(), absolute); + } else if (rp === "..") { + const ep = e.parent || e; + this.subwalks.add(ep, rest); + } else if (rp instanceof RegExp) { + this.testRegExp(e, rp, rest.rest(), absolute); + } + } + } + testRegExp(e, p, rest, absolute) { + if (!p.test(e.name)) + return; + if (!rest) { + this.matches.add(e, absolute, false); + } else { + this.subwalks.add(e, rest); + } + } + testString(e, p, rest, absolute) { + if (!e.isNamed(p)) + return; + if (!rest) { + this.matches.add(e, absolute, false); + } else { + this.subwalks.add(e, rest); + } + } +}; + +// node_modules/glob/dist/esm/walker.js +var makeIgnore = (ignore, opts) => typeof ignore === "string" ? new Ignore([ignore], opts) : Array.isArray(ignore) ? new Ignore(ignore, opts) : ignore; +var GlobUtil = class { + path; + patterns; + opts; + seen = /* @__PURE__ */ new Set(); + paused = false; + aborted = false; + #onResume = []; + #ignore; + #sep; + signal; + maxDepth; + constructor(patterns, path4, opts) { + this.patterns = patterns; + this.path = path4; + this.opts = opts; + this.#sep = !opts.posix && opts.platform === "win32" ? "\\" : "/"; + if (opts.ignore) { + this.#ignore = makeIgnore(opts.ignore, opts); + } + this.maxDepth = opts.maxDepth || Infinity; + if (opts.signal) { + this.signal = opts.signal; + this.signal.addEventListener("abort", () => { + this.#onResume.length = 0; + }); + } + } + #ignored(path4) { + return this.seen.has(path4) || !!this.#ignore?.ignored?.(path4); + } + #childrenIgnored(path4) { + return !!this.#ignore?.childrenIgnored?.(path4); + } + // backpressure mechanism + pause() { + this.paused = true; + } + resume() { + if (this.signal?.aborted) + return; + this.paused = false; + let fn = void 0; + while (!this.paused && (fn = this.#onResume.shift())) { + fn(); + } + } + onResume(fn) { + if (this.signal?.aborted) + return; + if (!this.paused) { + fn(); + } else { + this.#onResume.push(fn); + } + } + // do the requisite realpath/stat checking, and return the path + // to add or undefined to filter it out. + async matchCheck(e, ifDir) { + if (ifDir && this.opts.nodir) + return void 0; + let rpc; + if (this.opts.realpath) { + rpc = e.realpathCached() || await e.realpath(); + if (!rpc) + return void 0; + e = rpc; + } + const needStat = e.isUnknown() || this.opts.stat; + const s = needStat ? await e.lstat() : e; + if (this.opts.follow && this.opts.nodir && s?.isSymbolicLink()) { + const target = await s.realpath(); + if (target && (target.isUnknown() || this.opts.stat)) { + await target.lstat(); + } + } + return this.matchCheckTest(s, ifDir); + } + matchCheckTest(e, ifDir) { + return e && (this.maxDepth === Infinity || e.depth() <= this.maxDepth) && (!ifDir || e.canReaddir()) && (!this.opts.nodir || !e.isDirectory()) && (!this.opts.nodir || !this.opts.follow || !e.isSymbolicLink() || !e.realpathCached()?.isDirectory()) && !this.#ignored(e) ? e : void 0; + } + matchCheckSync(e, ifDir) { + if (ifDir && this.opts.nodir) + return void 0; + let rpc; + if (this.opts.realpath) { + rpc = e.realpathCached() || e.realpathSync(); + if (!rpc) + return void 0; + e = rpc; + } + const needStat = e.isUnknown() || this.opts.stat; + const s = needStat ? e.lstatSync() : e; + if (this.opts.follow && this.opts.nodir && s?.isSymbolicLink()) { + const target = s.realpathSync(); + if (target && (target?.isUnknown() || this.opts.stat)) { + target.lstatSync(); + } + } + return this.matchCheckTest(s, ifDir); + } + matchFinish(e, absolute) { + if (this.#ignored(e)) + return; + const abs = this.opts.absolute === void 0 ? absolute : this.opts.absolute; + this.seen.add(e); + const mark = this.opts.mark && e.isDirectory() ? this.#sep : ""; + if (this.opts.withFileTypes) { + this.matchEmit(e); + } else if (abs) { + const abs2 = this.opts.posix ? e.fullpathPosix() : e.fullpath(); + this.matchEmit(abs2 + mark); + } else { + const rel = this.opts.posix ? e.relativePosix() : e.relative(); + const pre = this.opts.dotRelative && !rel.startsWith(".." + this.#sep) ? "." + this.#sep : ""; + this.matchEmit(!rel ? "." + mark : pre + rel + mark); + } + } + async match(e, absolute, ifDir) { + const p = await this.matchCheck(e, ifDir); + if (p) + this.matchFinish(p, absolute); + } + matchSync(e, absolute, ifDir) { + const p = this.matchCheckSync(e, ifDir); + if (p) + this.matchFinish(p, absolute); + } + walkCB(target, patterns, cb) { + if (this.signal?.aborted) + cb(); + this.walkCB2(target, patterns, new Processor(this.opts), cb); + } + walkCB2(target, patterns, processor, cb) { + if (this.#childrenIgnored(target)) + return cb(); + if (this.signal?.aborted) + cb(); + if (this.paused) { + this.onResume(() => this.walkCB2(target, patterns, processor, cb)); + return; + } + processor.processPatterns(target, patterns); + let tasks = 1; + const next = () => { + if (--tasks === 0) + cb(); + }; + for (const [m, absolute, ifDir] of processor.matches.entries()) { + if (this.#ignored(m)) + continue; + tasks++; + this.match(m, absolute, ifDir).then(() => next()); + } + for (const t of processor.subwalkTargets()) { + if (this.maxDepth !== Infinity && t.depth() >= this.maxDepth) { + continue; + } + tasks++; + const childrenCached = t.readdirCached(); + if (t.calledReaddir()) + this.walkCB3(t, childrenCached, processor, next); + else { + t.readdirCB((_, entries) => this.walkCB3(t, entries, processor, next), true); + } + } + next(); + } + walkCB3(target, entries, processor, cb) { + processor = processor.filterEntries(target, entries); + let tasks = 1; + const next = () => { + if (--tasks === 0) + cb(); + }; + for (const [m, absolute, ifDir] of processor.matches.entries()) { + if (this.#ignored(m)) + continue; + tasks++; + this.match(m, absolute, ifDir).then(() => next()); + } + for (const [target2, patterns] of processor.subwalks.entries()) { + tasks++; + this.walkCB2(target2, patterns, processor.child(), next); + } + next(); + } + walkCBSync(target, patterns, cb) { + if (this.signal?.aborted) + cb(); + this.walkCB2Sync(target, patterns, new Processor(this.opts), cb); + } + walkCB2Sync(target, patterns, processor, cb) { + if (this.#childrenIgnored(target)) + return cb(); + if (this.signal?.aborted) + cb(); + if (this.paused) { + this.onResume(() => this.walkCB2Sync(target, patterns, processor, cb)); + return; + } + processor.processPatterns(target, patterns); + let tasks = 1; + const next = () => { + if (--tasks === 0) + cb(); + }; + for (const [m, absolute, ifDir] of processor.matches.entries()) { + if (this.#ignored(m)) + continue; + this.matchSync(m, absolute, ifDir); + } + for (const t of processor.subwalkTargets()) { + if (this.maxDepth !== Infinity && t.depth() >= this.maxDepth) { + continue; + } + tasks++; + const children = t.readdirSync(); + this.walkCB3Sync(t, children, processor, next); + } + next(); + } + walkCB3Sync(target, entries, processor, cb) { + processor = processor.filterEntries(target, entries); + let tasks = 1; + const next = () => { + if (--tasks === 0) + cb(); + }; + for (const [m, absolute, ifDir] of processor.matches.entries()) { + if (this.#ignored(m)) + continue; + this.matchSync(m, absolute, ifDir); + } + for (const [target2, patterns] of processor.subwalks.entries()) { + tasks++; + this.walkCB2Sync(target2, patterns, processor.child(), next); + } + next(); + } +}; +var GlobWalker = class extends GlobUtil { + matches; + constructor(patterns, path4, opts) { + super(patterns, path4, opts); + this.matches = /* @__PURE__ */ new Set(); + } + matchEmit(e) { + this.matches.add(e); + } + async walk() { + if (this.signal?.aborted) + throw this.signal.reason; + if (this.path.isUnknown()) { + await this.path.lstat(); + } + await new Promise((res, rej) => { + this.walkCB(this.path, this.patterns, () => { + if (this.signal?.aborted) { + rej(this.signal.reason); + } else { + res(this.matches); + } + }); + }); + return this.matches; + } + walkSync() { + if (this.signal?.aborted) + throw this.signal.reason; + if (this.path.isUnknown()) { + this.path.lstatSync(); + } + this.walkCBSync(this.path, this.patterns, () => { + if (this.signal?.aborted) + throw this.signal.reason; + }); + return this.matches; + } +}; +var GlobStream = class extends GlobUtil { + results; + constructor(patterns, path4, opts) { + super(patterns, path4, opts); + this.results = new Minipass({ + signal: this.signal, + objectMode: true + }); + this.results.on("drain", () => this.resume()); + this.results.on("resume", () => this.resume()); + } + matchEmit(e) { + this.results.write(e); + if (!this.results.flowing) + this.pause(); + } + stream() { + const target = this.path; + if (target.isUnknown()) { + target.lstat().then(() => { + this.walkCB(target, this.patterns, () => this.results.end()); + }); + } else { + this.walkCB(target, this.patterns, () => this.results.end()); + } + return this.results; + } + streamSync() { + if (this.path.isUnknown()) { + this.path.lstatSync(); + } + this.walkCBSync(this.path, this.patterns, () => this.results.end()); + return this.results; + } +}; + +// node_modules/glob/dist/esm/glob.js +var defaultPlatform3 = typeof process === "object" && process && typeof process.platform === "string" ? process.platform : "linux"; +var Glob = class { + absolute; + cwd; + root; + dot; + dotRelative; + follow; + ignore; + magicalBraces; + mark; + matchBase; + maxDepth; + nobrace; + nocase; + nodir; + noext; + noglobstar; + pattern; + platform; + realpath; + scurry; + stat; + signal; + windowsPathsNoEscape; + withFileTypes; + /** + * The options provided to the constructor. + */ + opts; + /** + * An array of parsed immutable {@link Pattern} objects. + */ + patterns; + /** + * All options are stored as properties on the `Glob` object. + * + * See {@link GlobOptions} for full options descriptions. + * + * Note that a previous `Glob` object can be passed as the + * `GlobOptions` to another `Glob` instantiation to re-use settings + * and caches with a new pattern. + * + * Traversal functions can be called multiple times to run the walk + * again. + */ + constructor(pattern, opts) { + if (!opts) + throw new TypeError("glob options required"); + this.withFileTypes = !!opts.withFileTypes; + this.signal = opts.signal; + this.follow = !!opts.follow; + this.dot = !!opts.dot; + this.dotRelative = !!opts.dotRelative; + this.nodir = !!opts.nodir; + this.mark = !!opts.mark; + if (!opts.cwd) { + this.cwd = ""; + } else if (opts.cwd instanceof URL || opts.cwd.startsWith("file://")) { + opts.cwd = fileURLToPath2(opts.cwd); + } + this.cwd = opts.cwd || ""; + this.root = opts.root; + this.magicalBraces = !!opts.magicalBraces; + this.nobrace = !!opts.nobrace; + this.noext = !!opts.noext; + this.realpath = !!opts.realpath; + this.absolute = opts.absolute; + this.noglobstar = !!opts.noglobstar; + this.matchBase = !!opts.matchBase; + this.maxDepth = typeof opts.maxDepth === "number" ? opts.maxDepth : Infinity; + this.stat = !!opts.stat; + this.ignore = opts.ignore; + if (this.withFileTypes && this.absolute !== void 0) { + throw new Error("cannot set absolute and withFileTypes:true"); + } + if (typeof pattern === "string") { + pattern = [pattern]; + } + this.windowsPathsNoEscape = !!opts.windowsPathsNoEscape || opts.allowWindowsEscape === false; + if (this.windowsPathsNoEscape) { + pattern = pattern.map((p) => p.replace(/\\/g, "/")); + } + if (this.matchBase) { + if (opts.noglobstar) { + throw new TypeError("base matching requires globstar"); + } + pattern = pattern.map((p) => p.includes("/") ? p : `./**/${p}`); + } + this.pattern = pattern; + this.platform = opts.platform || defaultPlatform3; + this.opts = { ...opts, platform: this.platform }; + if (opts.scurry) { + this.scurry = opts.scurry; + if (opts.nocase !== void 0 && opts.nocase !== opts.scurry.nocase) { + throw new Error("nocase option contradicts provided scurry option"); + } + } else { + const Scurry = opts.platform === "win32" ? PathScurryWin32 : opts.platform === "darwin" ? PathScurryDarwin : opts.platform ? PathScurryPosix : PathScurry; + this.scurry = new Scurry(this.cwd, { + nocase: opts.nocase, + fs: opts.fs + }); + } + this.nocase = this.scurry.nocase; + const nocaseMagicOnly = this.platform === "darwin" || this.platform === "win32"; + const mmo = { + // default nocase based on platform + ...opts, + dot: this.dot, + matchBase: this.matchBase, + nobrace: this.nobrace, + nocase: this.nocase, + nocaseMagicOnly, + nocomment: true, + noext: this.noext, + nonegate: true, + optimizationLevel: 2, + platform: this.platform, + windowsPathsNoEscape: this.windowsPathsNoEscape, + debug: !!this.opts.debug + }; + const mms = this.pattern.map((p) => new Minimatch(p, mmo)); + const [matchSet, globParts] = mms.reduce((set, m) => { + set[0].push(...m.set); + set[1].push(...m.globParts); + return set; + }, [[], []]); + this.patterns = matchSet.map((set, i) => { + const g = globParts[i]; + if (!g) + throw new Error("invalid pattern object"); + return new Pattern(set, g, 0, this.platform); + }); + } + async walk() { + return [ + ...await new GlobWalker(this.patterns, this.scurry.cwd, { + ...this.opts, + maxDepth: this.maxDepth !== Infinity ? this.maxDepth + this.scurry.cwd.depth() : Infinity, + platform: this.platform, + nocase: this.nocase + }).walk() + ]; + } + walkSync() { + return [ + ...new GlobWalker(this.patterns, this.scurry.cwd, { + ...this.opts, + maxDepth: this.maxDepth !== Infinity ? this.maxDepth + this.scurry.cwd.depth() : Infinity, + platform: this.platform, + nocase: this.nocase + }).walkSync() + ]; + } + stream() { + return new GlobStream(this.patterns, this.scurry.cwd, { + ...this.opts, + maxDepth: this.maxDepth !== Infinity ? this.maxDepth + this.scurry.cwd.depth() : Infinity, + platform: this.platform, + nocase: this.nocase + }).stream(); + } + streamSync() { + return new GlobStream(this.patterns, this.scurry.cwd, { + ...this.opts, + maxDepth: this.maxDepth !== Infinity ? this.maxDepth + this.scurry.cwd.depth() : Infinity, + platform: this.platform, + nocase: this.nocase + }).streamSync(); + } + /** + * Default sync iteration function. Returns a Generator that + * iterates over the results. + */ + iterateSync() { + return this.streamSync()[Symbol.iterator](); + } + [Symbol.iterator]() { + return this.iterateSync(); + } + /** + * Default async iteration function. Returns an AsyncGenerator that + * iterates over the results. + */ + iterate() { + return this.stream()[Symbol.asyncIterator](); + } + [Symbol.asyncIterator]() { + return this.iterate(); + } +}; + +// node_modules/glob/dist/esm/has-magic.js +var hasMagic = (pattern, options = {}) => { + if (!Array.isArray(pattern)) { + pattern = [pattern]; + } + for (const p of pattern) { + if (new Minimatch(p, options).hasMagic()) + return true; + } + return false; +}; + +// node_modules/glob/dist/esm/index.js +function globStreamSync(pattern, options = {}) { + return new Glob(pattern, options).streamSync(); +} +function globStream(pattern, options = {}) { + return new Glob(pattern, options).stream(); +} +function globSync(pattern, options = {}) { + return new Glob(pattern, options).walkSync(); +} +async function glob_(pattern, options = {}) { + return new Glob(pattern, options).walk(); +} +function globIterateSync(pattern, options = {}) { + return new Glob(pattern, options).iterateSync(); +} +function globIterate(pattern, options = {}) { + return new Glob(pattern, options).iterate(); +} +var streamSync = globStreamSync; +var stream = Object.assign(globStream, { sync: globStreamSync }); +var iterateSync = globIterateSync; +var iterate = Object.assign(globIterate, { + sync: globIterateSync +}); +var sync = Object.assign(globSync, { + stream: globStreamSync, + iterate: globIterateSync +}); +var glob = Object.assign(glob_, { + glob: glob_, + globSync, + sync, + globStream, + stream, + globStreamSync, + streamSync, + globIterate, + iterate, + globIterateSync, + iterateSync, + Glob, + hasMagic, + escape, + unescape +}); +glob.glob = glob; // src/utils.ts import fs from "node:fs"; -function loadJsonFile(path3) { - return JSON.parse(fs.readFileSync(path3).toString("utf-8")); +function loadJsonFile(path4) { + return JSON.parse(fs.readFileSync(path4).toString("utf-8")); } -function loadMetaFile(path3) { - return loadJsonFile(path3); +function loadMetaFile(path4) { + return loadJsonFile(path4); } -function loadAnalysisJson(path3) { - return loadJsonFile(path3); +function loadAnalysisJson(path4) { + return loadJsonFile(path4); } function getSingleInput(name) { const val = process.env[`INPUT_${name.toUpperCase()}`] || ""; return val.trim(); } +// src/report.ts +function report(input) { + const allPageSizes = getAllPageSizes(input); + fs2.mkdirSync(path2.join(process2.cwd(), input.analyzerDirectory), { + recursive: true + }); + const resultJsonPath = path2.join( + process2.cwd(), + input.analyzerDirectory, + "bundle_analysis.json" + ); + fs2.writeFileSync(resultJsonPath, JSON.stringify(allPageSizes, null, 2)); + console2.log(`Wrote ${resultJsonPath}`); +} +function findMetafiles(input) { + return input.metafiles.flatMap((metafile) => { + return globSync(path2.join(process2.cwd(), metafile), { + nodir: true + }).map((metaFilePath) => { + return { + relativePath: path2.relative(process2.cwd(), metaFilePath), + absolutePath: metaFilePath + }; + }); + }); +} +function getAllPageSizes(input) { + const acc = {}; + return findMetafiles(input).reduce((acc2, { relativePath, absolutePath }) => { + try { + fs2.accessSync(absolutePath, fs2.constants.R_OK); + } catch (err) { + console2.error( + `No meta file found at "${absolutePath}" - a path to meta file may be wrong, or esbuild is not executed.` + ); + process2.exit(1); + } + const metaFileJson = loadMetaFile(absolutePath); + Object.entries(metaFileJson.outputs).reduce((acc3, output) => { + const [outfile, buildMeta] = output; + if (!input.includeExtensions.some( + (ext2) => outfile.toLowerCase().endsWith(ext2) + )) { + return acc3; + } + acc3[`${relativePath} -> ${outfile}`] = { + bytes: buildMeta.bytes, + metafile: relativePath, + outfile + }; + return acc3; + }, acc2); + return acc2; + }, acc); +} + // src/compare.ts function compare(input) { let hasAnyChange = false; @@ -29,7 +6569,7 @@ function compare(input) { This analysis was generated by [esbuild-bundle-analyzer](https://github.com/exoego/esbuild-bundle-analyzer). \u{1F916} `; const current = loadAnalysisJson( - path.join(process.cwd(), input.analyzerDirectory, "bundle_analysis.json") + path3.join(process.cwd(), input.analyzerDirectory, "bundle_analysis.json") ); const base = loadBaseAnalysisJson(input); const fileTree = buildFileTree(input); @@ -75,11 +6615,11 @@ function treeKey(metafile, outfile) { return `${metafile} -> ${outfile}`; } function writeComment(input, output) { - fs2.mkdirSync(path.join(process.cwd(), input.analyzerDirectory), { + fs3.mkdirSync(path3.join(process.cwd(), input.analyzerDirectory), { recursive: true }); - fs2.writeFileSync( - path.join( + fs3.writeFileSync( + path3.join( process.cwd(), input.analyzerDirectory, "bundle_analysis_comment.txt" @@ -108,7 +6648,7 @@ function detail(input) { function loadBaseAnalysisJson(input) { try { return loadAnalysisJson( - path.join( + path3.join( process.cwd(), input.analyzerDirectory, "base/bundle/bundle_analysis.json" @@ -150,13 +6690,13 @@ function buildFileTree(input) { if (input.topNLargestPaths <= 0) { return trees; } - for (const metafile of input.metafiles) { - const metafileJson = loadMetaFile(path.join(process.cwd(), metafile)); + for (const { relativePath, absolutePath } of findMetafiles(input)) { + const metafileJson = loadMetaFile(absolutePath); for (const [outfile, buildMeta] of Object.entries(metafileJson.outputs)) { const tree = buildRoot(buildMeta.inputs); - trees.set(treeKey(metafile, outfile), tree); - fs2.writeFileSync( - path.join(process.cwd(), input.analyzerDirectory, "tree.json"), + trees.set(treeKey(relativePath, outfile), tree); + fs3.writeFileSync( + path3.join(process.cwd(), input.analyzerDirectory, "tree.json"), JSON.stringify(tree, null, 2) ); } @@ -250,9 +6790,9 @@ function fileSizeTable(data, topNLargestPaths) { d.tree, topNLargestPaths ); - for (const { path: path3, value } of largeNodes) { + for (const { path: path4, value } of largeNodes) { const percent = fixedPercent(value, totalSize); - output += `| ${path3} | ${renderBar(percent, value)} | + output += `| ${path4} | ${renderBar(percent, value)} | `; } if (hasOther) { @@ -315,54 +6855,6 @@ function renderStatusIndicator(percentChange, redThreshold) { return `${res} ${sign(percentChange)}`; } -// src/report.ts -import fs3 from "node:fs"; -import path2 from "node:path"; -import process2 from "node:process"; -function report(input) { - const allPageSizes = getAllPageSizes(input); - fs3.mkdirSync(path2.join(process2.cwd(), input.analyzerDirectory), { - recursive: true - }); - const resultJsonPath = path2.join( - process2.cwd(), - input.analyzerDirectory, - "bundle_analysis.json" - ); - fs3.writeFileSync(resultJsonPath, JSON.stringify(allPageSizes, null, 2)); - console.log(`Wrote ${resultJsonPath}`); -} -function getAllPageSizes(input) { - const acc = {}; - return input.metafiles.reduce((acc2, metafile) => { - const metaFilePath = path2.join(process2.cwd(), metafile); - try { - fs3.accessSync(metaFilePath, fs3.constants.R_OK); - } catch (err) { - console.error( - `No meta file found at "${metaFilePath}" - a path to meta file may be wrong, or esbuild is not executed.` - ); - process2.exit(1); - } - const metaFileJson = loadMetaFile(metaFilePath); - Object.entries(metaFileJson.outputs).reduce((acc3, output) => { - const [outfile, buildMeta] = output; - if (!input.includeExtensions.some( - (ext) => outfile.toLowerCase().endsWith(ext) - )) { - return acc3; - } - acc3[`${metafile} -> ${outfile}`] = { - bytes: buildMeta.bytes, - metafile, - outfile - }; - return acc3; - }, acc2); - return acc2; - }, acc); -} - // src/index.ts function getInput() { const rawMetafiles = getSingleInput("metafiles"); @@ -401,4 +6893,4 @@ if (import.meta.url === pathToFileURL(process.argv[1]).href) { export { run }; -//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL2luZGV4LnRzIiwgIi4uL3NyYy9jb21wYXJlLnRzIiwgIi4uL3NyYy91dGlscy50cyIsICIuLi9zcmMvcmVwb3J0LnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyJpbXBvcnQgeyBwYXRoVG9GaWxlVVJMIH0gZnJvbSBcIm5vZGU6dXJsXCI7XG5pbXBvcnQgeyBjb21wYXJlIH0gZnJvbSBcIi4vY29tcGFyZVwiO1xuaW1wb3J0IHsgcmVwb3J0IH0gZnJvbSBcIi4vcmVwb3J0XCI7XG5pbXBvcnQgdHlwZSB7IElucHV0IH0gZnJvbSBcIi4vdHlwZXNcIjtcbmltcG9ydCB7IGdldFNpbmdsZUlucHV0IH0gZnJvbSBcIi4vdXRpbHNcIjtcblxuZnVuY3Rpb24gZ2V0SW5wdXQoKTogSW5wdXQge1xuXHRjb25zdCByYXdNZXRhZmlsZXMgPSBnZXRTaW5nbGVJbnB1dChcIm1ldGFmaWxlc1wiKTtcblx0aWYgKCFyYXdNZXRhZmlsZXMpIHtcblx0XHR0aHJvdyBuZXcgRXJyb3IoXCJtZXRhZmlsZXMgaXMgbm90IHNwZWNpZmllZFwiKTtcblx0fVxuXHRjb25zdCBuYW1lID0gZ2V0U2luZ2xlSW5wdXQoXCJuYW1lXCIpO1xuXHRpZiAoIW5hbWUpIHtcblx0XHR0aHJvdyBuZXcgRXJyb3IoXCJuYW1lIGlzIG5vdCBzcGVjaWZpZWRcIik7XG5cdH1cblx0cmV0dXJuIHtcblx0XHRwZXJjZW50RXh0cmFBdHRlbnRpb246IE51bWJlci5wYXJzZUludChcblx0XHRcdGdldFNpbmdsZUlucHV0KFwicGVyY2VudF9leHRyYV9hdHRlbnRpb25cIikgfHwgXCIyMFwiLFxuXHRcdFx0MTAsXG5cdFx0KSxcblx0XHRzaG93RGV0YWlsczogW1widHJ1ZVwiLCBcIlRydWVcIiwgXCJUUlVFXCJdLmluY2x1ZGVzKFxuXHRcdFx0Z2V0U2luZ2xlSW5wdXQoXCJzaG93X2RldGFpbHNcIikgfHwgXCJ0cnVlXCIsXG5cdFx0KSxcblx0XHR0b3BOTGFyZ2VzdFBhdGhzOiBOdW1iZXIucGFyc2VJbnQoXG5cdFx0XHRnZXRTaW5nbGVJbnB1dChcInRvcF9uX2xhcmdlc3RfcGF0aHNcIikgfHwgXCIyMFwiLFxuXHRcdFx0MTAsXG5cdFx0KSxcblx0XHRpbmNsdWRlRXh0ZW5zaW9uczogKFxuXHRcdFx0Z2V0U2luZ2xlSW5wdXQoXCJpbmNsdWRlX2V4dGVuc2lvbnNcIikgfHwgXCIuanMsLm1qcywuY2pzXCJcblx0XHQpLnNwbGl0KFwiLFwiKSxcblx0XHRuYW1lLFxuXHRcdGFuYWx5emVyRGlyZWN0b3J5OiBnZXRTaW5nbGVJbnB1dChcImFuYWx5emVfZGlyZWN0b3J5XCIpIHx8IFwiLmFuYWx5emVyXCIsXG5cdFx0bWV0YWZpbGVzOiByYXdNZXRhZmlsZXMuc3BsaXQoXCIsXCIpLFxuXHR9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcnVuKGlucHV0OiBJbnB1dCA9IGdldElucHV0KCkpOiB2b2lkIHtcblx0cmVwb3J0KGlucHV0KTtcblx0Y29tcGFyZShpbnB1dCk7XG59XG5cbmlmIChpbXBvcnQubWV0YS51cmwgPT09IHBhdGhUb0ZpbGVVUkwocHJvY2Vzcy5hcmd2WzFdKS5ocmVmKSB7XG5cdHJ1bigpO1xufVxuIiwgImltcG9ydCBmcyBmcm9tIFwibm9kZTpmc1wiO1xuaW1wb3J0IHBhdGggZnJvbSBcIm5vZGU6cGF0aFwiO1xuaW1wb3J0IHR5cGUgeyBDb21wYXJlUmVzdWx0LCBJbnB1dCwgUmVwb3J0LCBUcmVlTWFwTm9kZSB9IGZyb20gXCIuL3R5cGVzXCI7XG5pbXBvcnQgeyBsb2FkQW5hbHlzaXNKc29uLCBsb2FkTWV0YUZpbGUgfSBmcm9tIFwiLi91dGlsc1wiO1xuXG5leHBvcnQgZnVuY3Rpb24gY29tcGFyZShpbnB1dDogSW5wdXQpOiB2b2lkIHtcblx0bGV0IGhhc0FueUNoYW5nZSA9IGZhbHNlO1xuXHRsZXQgb3V0cHV0ID0gYCMjIFx1RDgzRFx1RENFNiBlc2J1aWxkIEJ1bmRsZSBBbmFseXNpcyBmb3IgJHtpbnB1dC5uYW1lfVxuXG5UaGlzIGFuYWx5c2lzIHdhcyBnZW5lcmF0ZWQgYnkgW2VzYnVpbGQtYnVuZGxlLWFuYWx5emVyXShodHRwczovL2dpdGh1Yi5jb20vZXhvZWdvL2VzYnVpbGQtYnVuZGxlLWFuYWx5emVyKS4gXHVEODNFXHVERDE2XG5gO1xuXG5cdGNvbnN0IGN1cnJlbnQgPSBsb2FkQW5hbHlzaXNKc29uKFxuXHRcdHBhdGguam9pbihwcm9jZXNzLmN3ZCgpLCBpbnB1dC5hbmFseXplckRpcmVjdG9yeSwgXCJidW5kbGVfYW5hbHlzaXMuanNvblwiKSxcblx0KTtcblx0Y29uc3QgYmFzZSA9IGxvYWRCYXNlQW5hbHlzaXNKc29uKGlucHV0KTtcblxuXHRjb25zdCBmaWxlVHJlZSA9IGJ1aWxkRmlsZVRyZWUoaW5wdXQpO1xuXG5cdGNvbnN0IGFsbE91dEZpbGVzOiBzdHJpbmdbXSA9IFtcblx0XHQuLi5uZXcgU2V0KFsuLi5PYmplY3Qua2V5cyhjdXJyZW50KSwgLi4uT2JqZWN0LmtleXMoYmFzZSldKSxcblx0XS5zb3J0KCk7XG5cblx0Y29uc3QgY29tcGFyaXNvbjogQXJyYXk8Q29tcGFyZVJlc3VsdD4gPSBhbGxPdXRGaWxlcy5tYXAoKG91dGZpbGUpID0+IHtcblx0XHRjb25zdCBjdXJyZW50U3RhdHMgPSBjdXJyZW50W291dGZpbGVdO1xuXHRcdGNvbnN0IGJhc2VTdGF0cyA9IGJhc2Vbb3V0ZmlsZV07XG5cblx0XHRpZiAoIWN1cnJlbnRTdGF0cykge1xuXHRcdFx0aGFzQW55Q2hhbmdlID0gdHJ1ZTtcblx0XHRcdHJldHVybiB7IC4uLmJhc2VTdGF0cywgZGlmZjogLTEsIHJlbWFyazogXCJkZWxldGVkXCIsIHRyZWU6IHVuZGVmaW5lZCB9O1xuXHRcdH1cblxuXHRcdGNvbnN0IHRyZWUgPSBmaWxlVHJlZS5nZXQoXG5cdFx0XHR0cmVlS2V5KGN1cnJlbnRTdGF0cy5tZXRhZmlsZSwgY3VycmVudFN0YXRzLm91dGZpbGUpLFxuXHRcdCk7XG5cdFx0aWYgKCFiYXNlU3RhdHMpIHtcblx0XHRcdGhhc0FueUNoYW5nZSA9IHRydWU7XG5cdFx0XHRyZXR1cm4geyAuLi5jdXJyZW50U3RhdHMsIGRpZmY6IC0xLCByZW1hcms6IFwiYWRkZWRcIiwgdHJlZSB9O1xuXHRcdH1cblxuXHRcdGNvbnN0IGRpZmYgPSBjdXJyZW50U3RhdHMuYnl0ZXMgLSBiYXNlU3RhdHMuYnl0ZXM7XG5cdFx0aWYgKGRpZmYgIT09IDApIHtcblx0XHRcdGhhc0FueUNoYW5nZSA9IHRydWU7XG5cdFx0fVxuXHRcdHJldHVybiB7XG5cdFx0XHQuLi5jdXJyZW50U3RhdHMsXG5cdFx0XHRkaWZmLFxuXHRcdFx0dHJlZSxcblx0XHRcdHJlbWFyazogTWF0aC5zaWduKGRpZmYpID8gXCJpbmNyZWFzZWRcIiA6IFwiZGVjcmVhc2VkXCIsXG5cdFx0fTtcblx0fSk7XG5cblx0aWYgKGhhc0FueUNoYW5nZSkge1xuXHRcdG91dHB1dCArPSBtYXJrZG93blRhYmxlKGNvbXBhcmlzb24sIGlucHV0LnBlcmNlbnRFeHRyYUF0dGVudGlvbik7XG5cdFx0b3V0cHV0ICs9IGZpbGVTaXplVGFibGUoY29tcGFyaXNvbiwgaW5wdXQudG9wTkxhcmdlc3RQYXRocyk7XG5cdFx0b3V0cHV0ICs9IGRldGFpbChpbnB1dCk7XG5cdH0gZWxzZSB7XG5cdFx0b3V0cHV0ICs9IFwiVGhpcyBQUiBpbnRyb2R1Y2VkIG5vIGNoYW5nZXMgdG8gdGhlIGVzYnVpbGQgYnVuZGxlISBcdUQ4M0RcdURFNENcIjtcblx0fVxuXG5cdC8vIHdlIGFkZCB0aGlzIHRhZyBzbyB0aGF0IG91ciBhY3Rpb24gY2FuIGJlIGFibGUgdG8gZWFzaWx5IGFuZFxuXHQvLyBjb25zaXN0ZW50bHkgZmluZCB0aGUgcmlnaHQgY29tbWVudCB0byBlZGl0IGFzIG1vcmUgY29tbWl0cyBhcmUgcHVzaGVkLlxuXHRvdXRwdXQgKz0gYDwhLS0gX19FU0JVSUxEX0JVTkRMRV8ke2lucHV0Lm5hbWV9IC0tPmA7XG5cblx0d3JpdGVDb21tZW50KGlucHV0LCBvdXRwdXQpO1xufVxuXG5mdW5jdGlvbiB0cmVlS2V5KG1ldGFmaWxlOiBzdHJpbmcsIG91dGZpbGU6IHN0cmluZyk6IHN0cmluZyB7XG5cdHJldHVybiBgJHttZXRhZmlsZX0gLT4gJHtvdXRmaWxlfWA7XG59XG5cbi8vIFdyaXRlIHRoZSBvdXRwdXQgdG8gYSBmaWxlIHdoaWNoIGlzIGxhdGVyIHJlYWQgaW5cbi8vIGFzIGNvbW1lbnQgY29udGVudHMgYnkgdGhlIGFjdGlvbnMgd29ya2Zsb3cuXG5mdW5jdGlvbiB3cml0ZUNvbW1lbnQoaW5wdXQ6IElucHV0LCBvdXRwdXQ6IHN0cmluZyk6IHZvaWQge1xuXHRmcy5ta2RpclN5bmMocGF0aC5qb2luKHByb2Nlc3MuY3dkKCksIGlucHV0LmFuYWx5emVyRGlyZWN0b3J5KSwge1xuXHRcdHJlY3Vyc2l2ZTogdHJ1ZSxcblx0fSk7XG5cdGZzLndyaXRlRmlsZVN5bmMoXG5cdFx0cGF0aC5qb2luKFxuXHRcdFx0cHJvY2Vzcy5jd2QoKSxcblx0XHRcdGlucHV0LmFuYWx5emVyRGlyZWN0b3J5LFxuXHRcdFx0XCJidW5kbGVfYW5hbHlzaXNfY29tbWVudC50eHRcIixcblx0XHQpLFxuXHRcdG91dHB1dC50cmltKCksXG5cdCk7XG59XG5cbmZ1bmN0aW9uIGRldGFpbChpbnB1dDogSW5wdXQpOiBzdHJpbmcge1xuXHRpZiAoIWlucHV0LnNob3dEZXRhaWxzKSB7XG5cdFx0cmV0dXJuIFwiXCI7XG5cdH1cblx0cmV0dXJuIGBcXG48ZGV0YWlscz5cbjxzdW1tYXJ5PkRldGFpbHM8L3N1bW1hcnk+XG48cD5OZXh0IHRvIHRoZSBzaXplIGlzIGhvdyBtdWNoIHRoZSBzaXplIGhhcyBpbmNyZWFzZWQgb3IgZGVjcmVhc2VkIGNvbXBhcmVkIHdpdGggdGhlIGJhc2UgYnJhbmNoIG9mIHRoaXMgUFIuPC9wPlxuPHVsPlxuPGxpPlx1MjAzQ1x1RkUwRjogU2l6ZSBpbmNyZWFzZWQgYnkgJHtpbnB1dC5wZXJjZW50RXh0cmFBdHRlbnRpb259JSBvciBtb3JlLiBTcGVjaWFsIGF0dGVudGlvbiBzaG91bGQgYmUgZ2l2ZW4gdG8gdGhpcy48L2xpPlxuPGxpPlx1MjZBMFx1RkUwRjogU2l6ZSBpbmNyZWFzZWQgaW4gYWNjZXB0YWJsZSByYW5nZSAobG93ZXIgdGhhbiAke2lucHV0LnBlcmNlbnRFeHRyYUF0dGVudGlvbn0lKS48L2xpPlxuPGxpPlx1MjcwNTogTm8gY2hhbmdlIG9yIGV2ZW4gZG93bnNpemVkLjwvbGk+XG48bGk+XHVEODNEXHVEREQxXHVGRTBGOiBUaGUgb3V0IGZpbGUgaXMgZGVsZXRlZDogbm90IGZvdW5kIGluIGJhc2UgYnJhbmNoLjwvbGk+XG48bGk+XHVEODNDXHVERDk1OiBUaGUgb3V0IGZpbGUgaXMgbmV3bHkgZm91bmQ6IHdpbGwgYmUgYWRkZWQgdG8gYmFzZSBicmFuY2guPC9saT5cbjwvdWw+XG48L2RldGFpbHM+XFxuYDtcbn1cblxuZnVuY3Rpb24gbG9hZEJhc2VBbmFseXNpc0pzb24oaW5wdXQ6IElucHV0KTogUmVwb3J0IHtcblx0dHJ5IHtcblx0XHRyZXR1cm4gbG9hZEFuYWx5c2lzSnNvbihcblx0XHRcdHBhdGguam9pbihcblx0XHRcdFx0cHJvY2Vzcy5jd2QoKSxcblx0XHRcdFx0aW5wdXQuYW5hbHl6ZXJEaXJlY3RvcnksXG5cdFx0XHRcdFwiYmFzZS9idW5kbGUvYnVuZGxlX2FuYWx5c2lzLmpzb25cIixcblx0XHRcdCksXG5cdFx0KTtcblx0fSBjYXRjaCAoZSkge1xuXHRcdC8vIEVtcHR5IGlmIG5vIGJhc2UgYW5hbHlzaXMgZm91bmQuXG5cdFx0Ly8gVGhpcyBpcyBhIGNhc2Ugd2hlbiBhbmFseXplciBpcyBmaXJzdCBzZXQgdXAgb3IgYWxsIGFydGlmYWN0cyBhcmUgZXhwaXJlZC5cblx0XHRyZXR1cm4ge307XG5cdH1cbn1cblxuZnVuY3Rpb24gYnVpbGRGaWxlVHJlZShpbnB1dDogSW5wdXQpIHtcblx0ZnVuY3Rpb24gYnVpbGRSb290KFxuXHRcdGlucHV0OiBSZWNvcmQ8c3RyaW5nLCB7IGJ5dGVzSW5PdXRwdXQ6IG51bWJlciB9Pixcblx0KTogVHJlZU1hcE5vZGUge1xuXHRcdGNvbnN0IHJvb3Q6IFRyZWVNYXBOb2RlID0geyBuYW1lOiBcIlwiLCBwYXRoOiBcIlwiLCB2YWx1ZTogMCwgY2hpbGRyZW46IFtdIH07XG5cdFx0Zm9yIChjb25zdCBbZmlsZVBhdGgsIHsgYnl0ZXNJbk91dHB1dCB9XSBvZiBPYmplY3QuZW50cmllcyhpbnB1dCkpIHtcblx0XHRcdGNvbnN0IGRpcmVjdG9yaWVzID0gZmlsZVBhdGguc3BsaXQoXCIvXCIpO1xuXHRcdFx0YnVpbGROb2RlKHJvb3QsIGRpcmVjdG9yaWVzLCBieXRlc0luT3V0cHV0KTtcblx0XHR9XG5cdFx0cmV0dXJuIHJvb3Q7XG5cdH1cblxuXHRmdW5jdGlvbiBidWlsZE5vZGUoXG5cdFx0bm9kZTogVHJlZU1hcE5vZGUsXG5cdFx0cGF0aHM6IEFycmF5PHN0cmluZz4sXG5cdFx0dmFsdWU6IG51bWJlcixcblx0KTogdm9pZCB7XG5cdFx0Y29uc3QgZmlyc3QgPSBwYXRocy5zaGlmdCgpO1xuXHRcdGlmIChmaXJzdCA9PT0gdW5kZWZpbmVkKSB7XG5cdFx0XHQvLyBsZWFmIG5vZGUgKGZpbGUpXG5cdFx0XHRub2RlLnZhbHVlICs9IHZhbHVlO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblx0XHRsZXQgY2hpbGQgPSBub2RlLmNoaWxkcmVuLmZpbmQoKGNoaWxkKSA9PiBjaGlsZC5uYW1lID09PSBmaXJzdCk7XG5cdFx0aWYgKCFjaGlsZCkge1xuXHRcdFx0Y2hpbGQgPSB7XG5cdFx0XHRcdG5hbWU6IGZpcnN0LFxuXHRcdFx0XHRwYXRoOiBgJHtub2RlLnBhdGh9LyR7Zmlyc3R9YC5yZXBsYWNlKC9eXFwvLywgXCJcIiksXG5cdFx0XHRcdHZhbHVlOiAwLFxuXHRcdFx0XHRjaGlsZHJlbjogW10sXG5cdFx0XHR9O1xuXHRcdFx0bm9kZS5jaGlsZHJlbi5wdXNoKGNoaWxkKTtcblx0XHR9XG5cdFx0bm9kZS52YWx1ZSArPSB2YWx1ZTtcblx0XHRidWlsZE5vZGUoY2hpbGQsIHBhdGhzLCB2YWx1ZSk7XG5cdH1cblxuXHRjb25zdCB0cmVlcyA9IG5ldyBNYXA8c3RyaW5nLCBUcmVlTWFwTm9kZT4oKTtcblx0aWYgKGlucHV0LnRvcE5MYXJnZXN0UGF0aHMgPD0gMCkge1xuXHRcdC8vIFNraXAgYnVpbGRpbmcgdHJlZSBpZiB3ZSBkb24ndCBuZWVkIGl0LlxuXHRcdHJldHVybiB0cmVlcztcblx0fVxuXHRmb3IgKGNvbnN0IG1ldGFmaWxlIG9mIGlucHV0Lm1ldGFmaWxlcykge1xuXHRcdGNvbnN0IG1ldGFmaWxlSnNvbiA9IGxvYWRNZXRhRmlsZShwYXRoLmpvaW4ocHJvY2Vzcy5jd2QoKSwgbWV0YWZpbGUpKTtcblx0XHRmb3IgKGNvbnN0IFtvdXRmaWxlLCBidWlsZE1ldGFdIG9mIE9iamVjdC5lbnRyaWVzKG1ldGFmaWxlSnNvbi5vdXRwdXRzKSkge1xuXHRcdFx0Y29uc3QgdHJlZSA9IGJ1aWxkUm9vdChidWlsZE1ldGEuaW5wdXRzKTtcblx0XHRcdHRyZWVzLnNldCh0cmVlS2V5KG1ldGFmaWxlLCBvdXRmaWxlKSwgdHJlZSk7XG5cblx0XHRcdGZzLndyaXRlRmlsZVN5bmMoXG5cdFx0XHRcdHBhdGguam9pbihwcm9jZXNzLmN3ZCgpLCBpbnB1dC5hbmFseXplckRpcmVjdG9yeSwgXCJ0cmVlLmpzb25cIiksXG5cdFx0XHRcdEpTT04uc3RyaW5naWZ5KHRyZWUsIG51bGwsIDIpLFxuXHRcdFx0KTtcblx0XHR9XG5cdH1cblx0cmV0dXJuIHRyZWVzO1xufVxuXG5jb25zdCBzcGFjZXIgPSBcIlx1MDBBMFwiO1xuZnVuY3Rpb24gZmlsZXNpemUoYnl0ZXM6IG51bWJlcik6IHN0cmluZyB7XG5cdGNvbnN0IHNpZ24gPSBieXRlcyA8IDAgPyBcIi1cIiA6IFwiXCI7XG5cdGNvbnN0IG4gPSBNYXRoLmFicyhieXRlcyk7XG5cdGlmIChuIDwgMTAwMCkge1xuXHRcdHJldHVybiBgJHtzaWdufSR7bn0ke3NwYWNlcn1CYDtcblx0fVxuXHRpZiAobiA8IDEwMDAgKiAxMDAwKSB7XG5cdFx0cmV0dXJuIGAke3NpZ259JHsobiAvIDEwMDApLnRvRml4ZWQoMil9JHtzcGFjZXJ9S0JgO1xuXHR9XG5cdGlmIChuIDwgMTAwMCAqIDEwMDAgKiAxMDAwKSB7XG5cdFx0cmV0dXJuIGAke3NpZ259JHsobiAvIDEwMDAgLyAxMDAwKS50b0ZpeGVkKDIpfSR7c3BhY2VyfU1CYDtcblx0fVxuXHRpZiAobiA8IDEwMDAgKiAxMDAwICogMTAwMCAqIDEwMDApIHtcblx0XHRyZXR1cm4gYCR7c2lnbn0keyhuIC8gMTAwMCAvIDEwMDAgLyAxMDAwKS50b0ZpeGVkKDIpfSR7c3BhY2VyfUdCYDtcblx0fVxuXHR0aHJvdyBuZXcgRXJyb3IoXCJUb28gbGFyZ2UgZmlsZSBzaXplISEgQXJlIHlvdSBzdXJlP1wiKTtcbn1cblxuZnVuY3Rpb24gbWFya2Rvd25UYWJsZShcblx0ZGF0YTogQXJyYXk8Q29tcGFyZVJlc3VsdD4sXG5cdHJlZFRocmVzaG9sZDogbnVtYmVyLFxuKTogc3RyaW5nIHtcblx0Y29uc3Qgcm93cyA9IGRhdGFcblx0XHQubWFwKChkKSA9PiB7XG5cdFx0XHRyZXR1cm4gYCR7ZC5tZXRhZmlsZX0gfCAke2Qub3V0ZmlsZX0gfCAke3JlbmRlclNpemUoZCl9IHwgJHtyZW5kZXJOb3RlKFxuXHRcdFx0XHRkLFxuXHRcdFx0XHRyZWRUaHJlc2hvbGQsXG5cdFx0XHQpfVxcbmA7XG5cdFx0fSlcblx0XHQuam9pbihcIlwiKTtcblxuXHRyZXR1cm4gYFxuTWV0YSBGaWxlIHwgT3V0IEZpbGUgIHwgU2l6ZSAocmF3KSB8IE5vdGUgXG4tLS0tLS0tLS0tfC0tLS0tLS0tLS18LS0tLS0tLS0tLS06fC0tLS0tLVxuJHtyb3dzfWA7XG59XG5cbi8qKlxuICogRmluZCB0aGUgdG9wIE4gbGFyZ2VzdCBub2RlcyBpbiByb290IHRyZWUuXG4gKiBEaWcgbm9kZXMgdW50aWwgdGhlIGRlcHRoIG9mIDMuXG4gKi9cbmZ1bmN0aW9uIGZpbmRMYXJnZURpcmVjdG9yaWVzKHJvb3Q6IFRyZWVNYXBOb2RlLCBOOiBudW1iZXIpIHtcblx0Y29uc3Qgbm9kZXM6IFRyZWVNYXBOb2RlW10gPSBbXTtcblx0Y29uc3QgcXVldWU6IEFycmF5PHsgbm9kZTogVHJlZU1hcE5vZGU7IGRlcHRoOiBudW1iZXIgfT4gPSBbXG5cdFx0eyBub2RlOiByb290LCBkZXB0aDogMCB9LFxuXHRdO1xuXHR3aGlsZSAocXVldWUubGVuZ3RoID4gMCkge1xuXHRcdGNvbnN0IHNoaWZ0ID0gcXVldWUuc2hpZnQoKTtcblx0XHRpZiAoIXNoaWZ0KSB7XG5cdFx0XHRicmVhaztcblx0XHR9XG5cdFx0Y29uc3QgeyBub2RlLCBkZXB0aCB9ID0gc2hpZnQ7XG5cdFx0aWYgKGRlcHRoID09PSAzKSB7XG5cdFx0XHRub2Rlcy5wdXNoKG5vZGUpO1xuXHRcdFx0Y29udGludWU7XG5cdFx0fVxuXHRcdGlmIChub2RlLmNoaWxkcmVuLmxlbmd0aCA9PT0gMCkge1xuXHRcdFx0bm9kZXMucHVzaChub2RlKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0Zm9yIChjb25zdCBpdGVtIG9mIG5vZGUuY2hpbGRyZW4pIHtcblx0XHRcdFx0cXVldWUucHVzaCh7IG5vZGU6IGl0ZW0sIGRlcHRoOiBkZXB0aCArIDEgfSk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cdGNvbnN0IGxhcmdlTm9kZXMgPSBub2Rlcy5zb3J0KChhLCBiKSA9PiBiLnZhbHVlIC0gYS52YWx1ZSkuc2xpY2UoMCwgTik7XG5cdHJldHVybiB7XG5cdFx0bGFyZ2VOb2Rlcyxcblx0XHRoYXNPdGhlcjogbm9kZXMubGVuZ3RoID4gTixcblx0fTtcbn1cblxuZnVuY3Rpb24gZml4ZWRQZXJjZW50KG46IG51bWJlciwgZDogbnVtYmVyKTogbnVtYmVyIHtcblx0cmV0dXJuIE51bWJlci5wYXJzZUZsb2F0KCgobiAvIGQpICogMTAwKS50b0ZpeGVkKDEpKTtcbn1cblxuZnVuY3Rpb24gZmlsZVNpemVUYWJsZShcblx0ZGF0YTogQXJyYXk8Q29tcGFyZVJlc3VsdD4sXG5cdHRvcE5MYXJnZXN0UGF0aHM6IG51bWJlcixcbik6IHN0cmluZyB7XG5cdGlmIChkYXRhLmxlbmd0aCA9PT0gMCB8fCB0b3BOTGFyZ2VzdFBhdGhzIDw9IDApIHtcblx0XHRyZXR1cm4gXCJcIjtcblx0fVxuXHRsZXQgb3V0cHV0ID0gXCJcIjtcblx0b3V0cHV0ICs9IFwiPGRldGFpbHM+XFxuXCI7XG5cdG91dHB1dCArPSBcIjxzdW1tYXJ5Pkxhcmdlc3QgcGF0aHM8L3N1bW1hcnk+XFxuXCI7XG5cdG91dHB1dCArPSBgVGhlc2UgdmlzdWFsaXphdGlvbiBzaG93cyB0b3AgJHt0b3BOTGFyZ2VzdFBhdGhzfSBsYXJnZXN0IHBhdGhzIGluIHRoZSBidW5kbGUuXFxuYDtcblx0Zm9yIChjb25zdCBkIG9mIGRhdGEpIHtcblx0XHRvdXRwdXQgKz0gXCJcXG5cIjtcblx0XHRvdXRwdXQgKz0gYCMjIE1ldGEgZmlsZTogJHtkLm1ldGFmaWxlfSwgT3V0IGZpbGU6ICR7ZC5vdXRmaWxlfVxcbmA7XG5cdFx0aWYgKCFkLnRyZWUpIHtcblx0XHRcdG91dHB1dCArPSBcIlx1RkUwRlx1RkUwRlx1RDgzRFx1REREMVx1RkUwRkRlbGV0ZWRcXG5cIjtcblx0XHRcdGNvbnRpbnVlO1xuXHRcdH1cblx0XHRvdXRwdXQgKz0gXCJ8IFBhdGggfCBTaXplIHxcXG5cIjtcblx0XHRvdXRwdXQgKz0gXCJ8LS0tLS0tfC0tLS0tLS18XFxuXCI7XG5cdFx0Y29uc3QgdG90YWxTaXplID0gZC50cmVlLnZhbHVlO1xuXHRcdGNvbnN0IHsgbGFyZ2VOb2RlcywgaGFzT3RoZXIgfSA9IGZpbmRMYXJnZURpcmVjdG9yaWVzKFxuXHRcdFx0ZC50cmVlLFxuXHRcdFx0dG9wTkxhcmdlc3RQYXRocyxcblx0XHQpO1xuXHRcdGZvciAoY29uc3QgeyBwYXRoLCB2YWx1ZSB9IG9mIGxhcmdlTm9kZXMpIHtcblx0XHRcdGNvbnN0IHBlcmNlbnQgPSBmaXhlZFBlcmNlbnQodmFsdWUsIHRvdGFsU2l6ZSk7XG5cdFx0XHRvdXRwdXQgKz0gYHwgJHtwYXRofSB8ICR7cmVuZGVyQmFyKHBlcmNlbnQsIHZhbHVlKX0gfFxcbmA7XG5cdFx0fVxuXHRcdGlmIChoYXNPdGhlcikge1xuXHRcdFx0Y29uc3Qgb3RoZXJTaXplID0gdG90YWxTaXplIC0gbGFyZ2VOb2Rlc1swXS52YWx1ZTtcblx0XHRcdGNvbnN0IG90aGVyUGVyY2VudCA9IGZpeGVkUGVyY2VudChvdGhlclNpemUsIHRvdGFsU2l6ZSk7XG5cdFx0XHRvdXRwdXQgKz0gYHwgKG90aGVyKSB8ICR7cmVuZGVyQmFyKG90aGVyUGVyY2VudCwgb3RoZXJTaXplKX0gfFxcbmA7XG5cdFx0fVxuXHR9XG5cdG91dHB1dCArPSBcIjwvZGV0YWlscz5cXG5cIjtcblx0cmV0dXJuIG91dHB1dDtcbn1cblxuZnVuY3Rpb24gcmVuZGVyQmFyKHBlcmNlbnQ6IG51bWJlciwgYnl0ZXM6IG51bWJlcik6IHN0cmluZyB7XG5cdGNvbnN0IGJhciA9IHByb2dyZXNzKHBlcmNlbnQgLyAxMDApO1xuXHRyZXR1cm4gYFxcJHt7XFxcXGNvbG9ye0dvbGRlbnJvZH17ICR7YmFyfSB9fX1cXCQgJHtwZXJjZW50LnRvRml4ZWQoXG5cdFx0MSxcblx0KX0lLCAke2ZpbGVzaXplKGJ5dGVzKX1gO1xufVxuXG4vLyBCbG9jayBwcm9ncmVzc2lvbiBpcyAxLzggPSAwLjEyNVxuY29uc3QgYmxvY2tzID0gW1wiXCIsIFwiXHUyNThGXCIsIFwiXHUyNThFXCIsIFwiXHUyNThEXCIsIFwiXHUyNThDXCIsIFwiXHUyNThCXCIsIFwiXHUyNThBXCIsIFwiXHUyNTg5XCIsIFwiXHUyNTg4XCJdO1xuY29uc3QgcHJvZ3Jlc3Npb24gPSAxIC8gKGJsb2Nrcy5sZW5ndGggLSAxKTtcbmZ1bmN0aW9uIHByb2dyZXNzKHZhbHVlOiBudW1iZXIsIGxlbmd0aCA9IDI1LCB2bWluID0gMC4wLCB2bWF4ID0gMS4wKSB7XG5cdGNvbnN0IHYgPSB2YWx1ZSAqIGxlbmd0aDtcblx0Y29uc3QgaW50ZWdlclBhcnQgPSBNYXRoLmZsb29yKHYpO1xuXHRjb25zdCBmcmFjdGlvbmFsUGFydCA9IHYgLSBpbnRlZ2VyUGFydDtcblx0Y29uc3QgaSA9IE1hdGgucm91bmQoXG5cdFx0KHByb2dyZXNzaW9uICogTWF0aC5mbG9vcihmcmFjdGlvbmFsUGFydCAvIHByb2dyZXNzaW9uKSkgLyBwcm9ncmVzc2lvbixcblx0KTtcblx0cmV0dXJuIFwiXHUyNTg4XCIucmVwZWF0KGludGVnZXJQYXJ0KSArIGJsb2Nrc1tpXTtcbn1cblxuZnVuY3Rpb24gcmVuZGVyU2l6ZShkOiBDb21wYXJlUmVzdWx0KTogc3RyaW5nIHtcblx0cmV0dXJuIGZpbGVzaXplKGQuYnl0ZXMpO1xufVxuXG5mdW5jdGlvbiByZW5kZXJOb3RlKGQ6IENvbXBhcmVSZXN1bHQsIHJlZFRocmVzaG9sZDogbnVtYmVyKTogc3RyaW5nIHtcblx0aWYgKGQucmVtYXJrID09PSBcImRlbGV0ZWRcIikge1xuXHRcdHJldHVybiBcIlx1RDgzRFx1REREMVx1RkUwRiBEZWxldGVkXCI7XG5cdH1cblx0aWYgKGQucmVtYXJrID09PSBcImFkZGVkXCIpIHtcblx0XHRyZXR1cm4gXCJcdUQ4M0NcdUREOTUgQWRkZWRcIjtcblx0fVxuXHRpZiAoZC5kaWZmKSB7XG5cdFx0Y29uc3QgcGVyY2VudENoYW5nZSA9IChkLmRpZmYgLyBkLmJ5dGVzKSAqIDEwMDtcblx0XHRyZXR1cm4gYCR7cmVuZGVyU3RhdHVzSW5kaWNhdG9yKHBlcmNlbnRDaGFuZ2UsIHJlZFRocmVzaG9sZCl9JHtmaWxlc2l6ZShcblx0XHRcdGQuZGlmZixcblx0XHQpfSAoJHtzaWduKHBlcmNlbnRDaGFuZ2UpfSR7cGVyY2VudENoYW5nZS50b0ZpeGVkKDEpfSUpYDtcblx0fVxuXHRyZXR1cm4gXCJcdTI3MDUgIE5vIGNoYW5nZVwiO1xufVxuXG5mdW5jdGlvbiBzaWduKG51bTogbnVtYmVyKTogc3RyaW5nIHtcblx0cmV0dXJuIG51bSA8IDAgPyBcIlwiIDogXCIrXCI7XG59XG5cbmZ1bmN0aW9uIHJlbmRlclN0YXR1c0luZGljYXRvcihcblx0cGVyY2VudENoYW5nZTogbnVtYmVyLFxuXHRyZWRUaHJlc2hvbGQ6IG51bWJlcixcbik6IHN0cmluZyB7XG5cdGxldCByZXM6IHN0cmluZztcblx0aWYgKHBlcmNlbnRDaGFuZ2UgPiAwICYmIHBlcmNlbnRDaGFuZ2UgPCByZWRUaHJlc2hvbGQpIHtcblx0XHRyZXMgPSBcIlx1MjZBMFx1RkUwRlwiO1xuXHR9IGVsc2UgaWYgKHBlcmNlbnRDaGFuZ2UgPj0gcmVkVGhyZXNob2xkKSB7XG5cdFx0cmVzID0gXCJcdTIwM0NcdUZFMEZcIjtcblx0fSBlbHNlIHtcblx0XHRyZXMgPSBcIlx1MjcwNSBcIjtcblx0fVxuXHRyZXR1cm4gYCR7cmVzfSAke3NpZ24ocGVyY2VudENoYW5nZSl9YDtcbn1cbiIsICJpbXBvcnQgZnMgZnJvbSBcIm5vZGU6ZnNcIjtcblxuaW1wb3J0IHR5cGUgeyBNZXRhZmlsZSB9IGZyb20gXCJlc2J1aWxkXCI7XG5pbXBvcnQgdHlwZSB7IFJlcG9ydCB9IGZyb20gXCIuL3R5cGVzXCI7XG5cbmZ1bmN0aW9uIGxvYWRKc29uRmlsZShwYXRoOiBzdHJpbmcpIHtcblx0cmV0dXJuIEpTT04ucGFyc2UoZnMucmVhZEZpbGVTeW5jKHBhdGgpLnRvU3RyaW5nKFwidXRmLThcIikpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbG9hZE1ldGFGaWxlKHBhdGg6IHN0cmluZyk6IE1ldGFmaWxlIHtcblx0cmV0dXJuIGxvYWRKc29uRmlsZShwYXRoKSBhcyBNZXRhZmlsZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGxvYWRBbmFseXNpc0pzb24ocGF0aDogc3RyaW5nKTogUmVwb3J0IHtcblx0cmV0dXJuIGxvYWRKc29uRmlsZShwYXRoKSBhcyBSZXBvcnQ7XG59XG5cbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS9hY3Rpb25zL3Rvb2xraXQvYmxvYi84MWE3M2FiYThiZWRkNTMyZjZlZGRjYzQxZWQzYTBmYWQ4YjFjZmViL3BhY2thZ2VzL2NvcmUvc3JjL2NvcmUudHMjTDEyNlxuZXhwb3J0IGZ1bmN0aW9uIGdldFNpbmdsZUlucHV0KG5hbWU6IHN0cmluZyk6IHN0cmluZyB7XG5cdGNvbnN0IHZhbCA9IHByb2Nlc3MuZW52W2BJTlBVVF8ke25hbWUudG9VcHBlckNhc2UoKX1gXSB8fCBcIlwiO1xuXHRyZXR1cm4gdmFsLnRyaW0oKTtcbn1cbiIsICJpbXBvcnQgZnMgZnJvbSBcIm5vZGU6ZnNcIjtcbmltcG9ydCBwYXRoIGZyb20gXCJub2RlOnBhdGhcIjtcbmltcG9ydCBwcm9jZXNzIGZyb20gXCJub2RlOnByb2Nlc3NcIjtcblxuaW1wb3J0IHR5cGUgeyBJbnB1dCwgUmVwb3J0IH0gZnJvbSBcIi4vdHlwZXNcIjtcbmltcG9ydCB7IGxvYWRNZXRhRmlsZSB9IGZyb20gXCIuL3V0aWxzXCI7XG5cbmV4cG9ydCBmdW5jdGlvbiByZXBvcnQoaW5wdXQ6IElucHV0KTogdm9pZCB7XG5cdGNvbnN0IGFsbFBhZ2VTaXplcyA9IGdldEFsbFBhZ2VTaXplcyhpbnB1dCk7XG5cdGZzLm1rZGlyU3luYyhwYXRoLmpvaW4ocHJvY2Vzcy5jd2QoKSwgaW5wdXQuYW5hbHl6ZXJEaXJlY3RvcnkpLCB7XG5cdFx0cmVjdXJzaXZlOiB0cnVlLFxuXHR9KTtcblx0Y29uc3QgcmVzdWx0SnNvblBhdGggPSBwYXRoLmpvaW4oXG5cdFx0cHJvY2Vzcy5jd2QoKSxcblx0XHRpbnB1dC5hbmFseXplckRpcmVjdG9yeSxcblx0XHRcImJ1bmRsZV9hbmFseXNpcy5qc29uXCIsXG5cdCk7XG5cdGZzLndyaXRlRmlsZVN5bmMocmVzdWx0SnNvblBhdGgsIEpTT04uc3RyaW5naWZ5KGFsbFBhZ2VTaXplcywgbnVsbCwgMikpO1xuXHRjb25zb2xlLmxvZyhgV3JvdGUgJHtyZXN1bHRKc29uUGF0aH1gKTtcbn1cblxuZnVuY3Rpb24gZ2V0QWxsUGFnZVNpemVzKGlucHV0OiBJbnB1dCk6IFJlcG9ydCB7XG5cdGNvbnN0IGFjYzogUmVwb3J0ID0ge307XG5cdHJldHVybiBpbnB1dC5tZXRhZmlsZXMucmVkdWNlKChhY2MsIG1ldGFmaWxlKSA9PiB7XG5cdFx0Y29uc3QgbWV0YUZpbGVQYXRoID0gcGF0aC5qb2luKHByb2Nlc3MuY3dkKCksIG1ldGFmaWxlKTtcblx0XHR0cnkge1xuXHRcdFx0ZnMuYWNjZXNzU3luYyhtZXRhRmlsZVBhdGgsIGZzLmNvbnN0YW50cy5SX09LKTtcblx0XHR9IGNhdGNoIChlcnIpIHtcblx0XHRcdGNvbnNvbGUuZXJyb3IoXG5cdFx0XHRcdGBObyBtZXRhIGZpbGUgZm91bmQgYXQgXCIke21ldGFGaWxlUGF0aH1cIiAtIGEgcGF0aCB0byBtZXRhIGZpbGUgbWF5IGJlIHdyb25nLCBvciBlc2J1aWxkIGlzIG5vdCBleGVjdXRlZC5gLFxuXHRcdFx0KTtcblx0XHRcdHByb2Nlc3MuZXhpdCgxKTtcblx0XHR9XG5cblx0XHRjb25zdCBtZXRhRmlsZUpzb24gPSBsb2FkTWV0YUZpbGUobWV0YUZpbGVQYXRoKTtcblx0XHRPYmplY3QuZW50cmllcyhtZXRhRmlsZUpzb24ub3V0cHV0cykucmVkdWNlKChhY2MsIG91dHB1dCkgPT4ge1xuXHRcdFx0Y29uc3QgW291dGZpbGUsIGJ1aWxkTWV0YV0gPSBvdXRwdXQ7XG5cdFx0XHRpZiAoXG5cdFx0XHRcdCFpbnB1dC5pbmNsdWRlRXh0ZW5zaW9ucy5zb21lKChleHQpID0+XG5cdFx0XHRcdFx0b3V0ZmlsZS50b0xvd2VyQ2FzZSgpLmVuZHNXaXRoKGV4dCksXG5cdFx0XHRcdClcblx0XHRcdCkge1xuXHRcdFx0XHRyZXR1cm4gYWNjO1xuXHRcdFx0fVxuXHRcdFx0YWNjW2Ake21ldGFmaWxlfSAtPiAke291dGZpbGV9YF0gPSB7XG5cdFx0XHRcdGJ5dGVzOiBidWlsZE1ldGEuYnl0ZXMsXG5cdFx0XHRcdG1ldGFmaWxlLFxuXHRcdFx0XHRvdXRmaWxlLFxuXHRcdFx0fTtcblx0XHRcdHJldHVybiBhY2M7XG5cdFx0fSwgYWNjKTtcblx0XHRyZXR1cm4gYWNjO1xuXHR9LCBhY2MpO1xufVxuIl0sCiAgIm1hcHBpbmdzIjogIjtBQUFBLFNBQVMscUJBQXFCOzs7QUNBOUIsT0FBT0EsU0FBUTtBQUNmLE9BQU8sVUFBVTs7O0FDRGpCLE9BQU8sUUFBUTtBQUtmLFNB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 +//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL2luZGV4LnRzIiwgIi4uL3NyYy9jb21wYXJlLnRzIiwgIi4uL3NyYy9yZXBvcnQudHMiLCAiLi4vc3JjL3V0aWxzLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyJpbXBvcnQgeyBwYXRoVG9GaWxlVVJMIH0gZnJvbSBcIm5vZGU6dXJsXCI7XG5pbXBvcnQgeyBjb21wYXJlIH0gZnJvbSBcIi4vY29tcGFyZVwiO1xuaW1wb3J0IHsgcmVwb3J0IH0gZnJvbSBcIi4vcmVwb3J0XCI7XG5pbXBvcnQgdHlwZSB7IElucHV0IH0gZnJvbSBcIi4vdHlwZXNcIjtcbmltcG9ydCB7IGdldFNpbmdsZUlucHV0IH0gZnJvbSBcIi4vdXRpbHNcIjtcblxuZnVuY3Rpb24gZ2V0SW5wdXQoKTogSW5wdXQge1xuXHRjb25zdCByYXdNZXRhZmlsZXMgPSBnZXRTaW5nbGVJbnB1dChcIm1ldGFmaWxlc1wiKTtcblx0aWYgKCFyYXdNZXRhZmlsZXMpIHtcblx0XHR0aHJvdyBuZXcgRXJyb3IoXCJtZXRhZmlsZXMgaXMgbm90IHNwZWNpZmllZFwiKTtcblx0fVxuXHRjb25zdCBuYW1lID0gZ2V0U2luZ2xlSW5wdXQoXCJuYW1lXCIpO1xuXHRpZiAoIW5hbWUpIHtcblx0XHR0aHJvdyBuZXcgRXJyb3IoXCJuYW1lIGlzIG5vdCBzcGVjaWZpZWRcIik7XG5cdH1cblx0cmV0dXJuIHtcblx0XHRwZXJjZW50RXh0cmFBdHRlbnRpb246IE51bWJlci5wYXJzZUludChcblx0XHRcdGdldFNpbmdsZUlucHV0KFwicGVyY2VudF9leHRyYV9hdHRlbnRpb25cIikgfHwgXCIyMFwiLFxuXHRcdFx0MTAsXG5cdFx0KSxcblx0XHRzaG93RGV0YWlsczogW1widHJ1ZVwiLCBcIlRydWVcIiwgXCJUUlVFXCJdLmluY2x1ZGVzKFxuXHRcdFx0Z2V0U2luZ2xlSW5wdXQoXCJzaG93X2RldGFpbHNcIikgfHwgXCJ0cnVlXCIsXG5cdFx0KSxcblx0XHR0b3BOTGFyZ2VzdFBhdGhzOiBOdW1iZXIucGFyc2VJbnQoXG5cdFx0XHRnZXRTaW5nbGVJbnB1dChcInRvcF9uX2xhcmdlc3RfcGF0aHNcIikgfHwgXCIyMFwiLFxuXHRcdFx0MTAsXG5cdFx0KSxcblx0XHRpbmNsdWRlRXh0ZW5zaW9uczogKFxuXHRcdFx0Z2V0U2luZ2xlSW5wdXQoXCJpbmNsdWRlX2V4dGVuc2lvbnNcIikgfHwgXCIuanMsLm1qcywuY2pzXCJcblx0XHQpLnNwbGl0KFwiLFwiKSxcblx0XHRuYW1lLFxuXHRcdGFuYWx5emVyRGlyZWN0b3J5OiBnZXRTaW5nbGVJbnB1dChcImFuYWx5emVfZGlyZWN0b3J5XCIpIHx8IFwiLmFuYWx5emVyXCIsXG5cdFx0bWV0YWZpbGVzOiByYXdNZXRhZmlsZXMuc3BsaXQoXCIsXCIpLFxuXHR9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcnVuKGlucHV0OiBJbnB1dCA9IGdldElucHV0KCkpOiB2b2lkIHtcblx0cmVwb3J0KGlucHV0KTtcblx0Y29tcGFyZShpbnB1dCk7XG59XG5cbmlmIChpbXBvcnQubWV0YS51cmwgPT09IHBhdGhUb0ZpbGVVUkwocHJvY2Vzcy5hcmd2WzFdKS5ocmVmKSB7XG5cdHJ1bigpO1xufVxuIiwgImltcG9ydCBmcyBmcm9tIFwibm9kZTpmc1wiO1xuaW1wb3J0IHBhdGggZnJvbSBcIm5vZGU6cGF0aFwiO1xuaW1wb3J0IHsgZmluZE1ldGFmaWxlcyB9IGZyb20gXCIuL3JlcG9ydFwiO1xuaW1wb3J0IHR5cGUgeyBDb21wYXJlUmVzdWx0LCBJbnB1dCwgUmVwb3J0LCBUcmVlTWFwTm9kZSB9IGZyb20gXCIuL3R5cGVzXCI7XG5pbXBvcnQgeyBsb2FkQW5hbHlzaXNKc29uLCBsb2FkTWV0YUZpbGUgfSBmcm9tIFwiLi91dGlsc1wiO1xuXG5leHBvcnQgZnVuY3Rpb24gY29tcGFyZShpbnB1dDogSW5wdXQpOiB2b2lkIHtcblx0bGV0IGhhc0FueUNoYW5nZSA9IGZhbHNlO1xuXHRsZXQgb3V0cHV0ID0gYCMjIFx1RDgzRFx1RENFNiBlc2J1aWxkIEJ1bmRsZSBBbmFseXNpcyBmb3IgJHtpbnB1dC5uYW1lfVxuXG5UaGlzIGFuYWx5c2lzIHdhcyBnZW5lcmF0ZWQgYnkgW2VzYnVpbGQtYnVuZGxlLWFuYWx5emVyXShodHRwczovL2dpdGh1Yi5jb20vZXhvZWdvL2VzYnVpbGQtYnVuZGxlLWFuYWx5emVyKS4gXHVEODNFXHVERDE2XG5gO1xuXG5cdGNvbnN0IGN1cnJlbnQgPSBsb2FkQW5hbHlzaXNKc29uKFxuXHRcdHBhdGguam9pbihwcm9jZXNzLmN3ZCgpLCBpbnB1dC5hbmFseXplckRpcmVjdG9yeSwgXCJidW5kbGVfYW5hbHlzaXMuanNvblwiKSxcblx0KTtcblx0Y29uc3QgYmFzZSA9IGxvYWRCYXNlQW5hbHlzaXNKc29uKGlucHV0KTtcblxuXHRjb25zdCBmaWxlVHJlZSA9IGJ1aWxkRmlsZVRyZWUoaW5wdXQpO1xuXG5cdGNvbnN0IGFsbE91dEZpbGVzOiBzdHJpbmdbXSA9IFtcblx0XHQuLi5uZXcgU2V0KFsuLi5PYmplY3Qua2V5cyhjdXJyZW50KSwgLi4uT2JqZWN0LmtleXMoYmFzZSldKSxcblx0XS5zb3J0KCk7XG5cblx0Y29uc3QgY29tcGFyaXNvbjogQXJyYXk8Q29tcGFyZVJlc3VsdD4gPSBhbGxPdXRGaWxlcy5tYXAoKG91dGZpbGUpID0+IHtcblx0XHRjb25zdCBjdXJyZW50U3RhdHMgPSBjdXJyZW50W291dGZpbGVdO1xuXHRcdGNvbnN0IGJhc2VTdGF0cyA9IGJhc2Vbb3V0ZmlsZV07XG5cblx0XHRpZiAoIWN1cnJlbnRTdGF0cykge1xuXHRcdFx0aGFzQW55Q2hhbmdlID0gdHJ1ZTtcblx0XHRcdHJldHVybiB7IC4uLmJhc2VTdGF0cywgZGlmZjogLTEsIHJlbWFyazogXCJkZWxldGVkXCIsIHRyZWU6IHVuZGVmaW5lZCB9O1xuXHRcdH1cblxuXHRcdGNvbnN0IHRyZWUgPSBmaWxlVHJlZS5nZXQoXG5cdFx0XHR0cmVlS2V5KGN1cnJlbnRTdGF0cy5tZXRhZmlsZSwgY3VycmVudFN0YXRzLm91dGZpbGUpLFxuXHRcdCk7XG5cdFx0aWYgKCFiYXNlU3RhdHMpIHtcblx0XHRcdGhhc0FueUNoYW5nZSA9IHRydWU7XG5cdFx0XHRyZXR1cm4geyAuLi5jdXJyZW50U3RhdHMsIGRpZmY6IC0xLCByZW1hcms6IFwiYWRkZWRcIiwgdHJlZSB9O1xuXHRcdH1cblxuXHRcdGNvbnN0IGRpZmYgPSBjdXJyZW50U3RhdHMuYnl0ZXMgLSBiYXNlU3RhdHMuYnl0ZXM7XG5cdFx0aWYgKGRpZmYgIT09IDApIHtcblx0XHRcdGhhc0FueUNoYW5nZSA9IHRydWU7XG5cdFx0fVxuXHRcdHJldHVybiB7XG5cdFx0XHQuLi5jdXJyZW50U3RhdHMsXG5cdFx0XHRkaWZmLFxuXHRcdFx0dHJlZSxcblx0XHRcdHJlbWFyazogTWF0aC5zaWduKGRpZmYpID8gXCJpbmNyZWFzZWRcIiA6IFwiZGVjcmVhc2VkXCIsXG5cdFx0fTtcblx0fSk7XG5cblx0aWYgKGhhc0FueUNoYW5nZSkge1xuXHRcdG91dHB1dCArPSBtYXJrZG93blRhYmxlKGNvbXBhcmlzb24sIGlucHV0LnBlcmNlbnRFeHRyYUF0dGVudGlvbik7XG5cdFx0b3V0cHV0ICs9IGZpbGVTaXplVGFibGUoY29tcGFyaXNvbiwgaW5wdXQudG9wTkxhcmdlc3RQYXRocyk7XG5cdFx0b3V0cHV0ICs9IGRldGFpbChpbnB1dCk7XG5cdH0gZWxzZSB7XG5cdFx0b3V0cHV0ICs9IFwiVGhpcyBQUiBpbnRyb2R1Y2VkIG5vIGNoYW5nZXMgdG8gdGhlIGVzYnVpbGQgYnVuZGxlISBcdUQ4M0RcdURFNENcIjtcblx0fVxuXG5cdC8vIHdlIGFkZCB0aGlzIHRhZyBzbyB0aGF0IG91ciBhY3Rpb24gY2FuIGJlIGFibGUgdG8gZWFzaWx5IGFuZFxuXHQvLyBjb25zaXN0ZW50bHkgZmluZCB0aGUgcmlnaHQgY29tbWVudCB0byBlZGl0IGFzIG1vcmUgY29tbWl0cyBhcmUgcHVzaGVkLlxuXHRvdXRwdXQgKz0gYDwhLS0gX19FU0JVSUxEX0JVTkRMRV8ke2lucHV0Lm5hbWV9IC0tPmA7XG5cblx0d3JpdGVDb21tZW50KGlucHV0LCBvdXRwdXQpO1xufVxuXG5mdW5jdGlvbiB0cmVlS2V5KG1ldGFmaWxlOiBzdHJpbmcsIG91dGZpbGU6IHN0cmluZyk6IHN0cmluZyB7XG5cdHJldHVybiBgJHttZXRhZmlsZX0gLT4gJHtvdXRmaWxlfWA7XG59XG5cbi8vIFdyaXRlIHRoZSBvdXRwdXQgdG8gYSBmaWxlIHdoaWNoIGlzIGxhdGVyIHJlYWQgaW5cbi8vIGFzIGNvbW1lbnQgY29udGVudHMgYnkgdGhlIGFjdGlvbnMgd29ya2Zsb3cuXG5mdW5jdGlvbiB3cml0ZUNvbW1lbnQoaW5wdXQ6IElucHV0LCBvdXRwdXQ6IHN0cmluZyk6IHZvaWQge1xuXHRmcy5ta2RpclN5bmMocGF0aC5qb2luKHByb2Nlc3MuY3dkKCksIGlucHV0LmFuYWx5emVyRGlyZWN0b3J5KSwge1xuXHRcdHJlY3Vyc2l2ZTogdHJ1ZSxcblx0fSk7XG5cdGZzLndyaXRlRmlsZVN5bmMoXG5cdFx0cGF0aC5qb2luKFxuXHRcdFx0cHJvY2Vzcy5jd2QoKSxcblx0XHRcdGlucHV0LmFuYWx5emVyRGlyZWN0b3J5LFxuXHRcdFx0XCJidW5kbGVfYW5hbHlzaXNfY29tbWVudC50eHRcIixcblx0XHQpLFxuXHRcdG91dHB1dC50cmltKCksXG5cdCk7XG59XG5cbmZ1bmN0aW9uIGRldGFpbChpbnB1dDogSW5wdXQpOiBzdHJpbmcge1xuXHRpZiAoIWlucHV0LnNob3dEZXRhaWxzKSB7XG5cdFx0cmV0dXJuIFwiXCI7XG5cdH1cblx0cmV0dXJuIGBcXG48ZGV0YWlscz5cbjxzdW1tYXJ5PkRldGFpbHM8L3N1bW1hcnk+XG48cD5OZXh0IHRvIHRoZSBzaXplIGlzIGhvdyBtdWNoIHRoZSBzaXplIGhhcyBpbmNyZWFzZWQgb3IgZGVjcmVhc2VkIGNvbXBhcmVkIHdpdGggdGhlIGJhc2UgYnJhbmNoIG9mIHRoaXMgUFIuPC9wPlxuPHVsPlxuPGxpPlx1MjAzQ1x1RkUwRjogU2l6ZSBpbmNyZWFzZWQgYnkgJHtpbnB1dC5wZXJjZW50RXh0cmFBdHRlbnRpb259JSBvciBtb3JlLiBTcGVjaWFsIGF0dGVudGlvbiBzaG91bGQgYmUgZ2l2ZW4gdG8gdGhpcy48L2xpPlxuPGxpPlx1MjZBMFx1RkUwRjogU2l6ZSBpbmNyZWFzZWQgaW4gYWNjZXB0YWJsZSByYW5nZSAobG93ZXIgdGhhbiAke2lucHV0LnBlcmNlbnRFeHRyYUF0dGVudGlvbn0lKS48L2xpPlxuPGxpPlx1MjcwNTogTm8gY2hhbmdlIG9yIGV2ZW4gZG93bnNpemVkLjwvbGk+XG48bGk+XHVEODNEXHVEREQxXHVGRTBGOiBUaGUgb3V0IGZpbGUgaXMgZGVsZXRlZDogbm90IGZvdW5kIGluIGJhc2UgYnJhbmNoLjwvbGk+XG48bGk+XHVEODNDXHVERDk1OiBUaGUgb3V0IGZpbGUgaXMgbmV3bHkgZm91bmQ6IHdpbGwgYmUgYWRkZWQgdG8gYmFzZSBicmFuY2guPC9saT5cbjwvdWw+XG48L2RldGFpbHM+XFxuYDtcbn1cblxuZnVuY3Rpb24gbG9hZEJhc2VBbmFseXNpc0pzb24oaW5wdXQ6IElucHV0KTogUmVwb3J0IHtcblx0dHJ5IHtcblx0XHRyZXR1cm4gbG9hZEFuYWx5c2lzSnNvbihcblx0XHRcdHBhdGguam9pbihcblx0XHRcdFx0cHJvY2Vzcy5jd2QoKSxcblx0XHRcdFx0aW5wdXQuYW5hbHl6ZXJEaXJlY3RvcnksXG5cdFx0XHRcdFwiYmFzZS9idW5kbGUvYnVuZGxlX2FuYWx5c2lzLmpzb25cIixcblx0XHRcdCksXG5cdFx0KTtcblx0fSBjYXRjaCAoZSkge1xuXHRcdC8vIEVtcHR5IGlmIG5vIGJhc2UgYW5hbHlzaXMgZm91bmQuXG5cdFx0Ly8gVGhpcyBpcyBhIGNhc2Ugd2hlbiBhbmFseXplciBpcyBmaXJzdCBzZXQgdXAgb3IgYWxsIGFydGlmYWN0cyBhcmUgZXhwaXJlZC5cblx0XHRyZXR1cm4ge307XG5cdH1cbn1cblxuZnVuY3Rpb24gYnVpbGRGaWxlVHJlZShpbnB1dDogSW5wdXQpIHtcblx0ZnVuY3Rpb24gYnVpbGRSb290KFxuXHRcdGlucHV0OiBSZWNvcmQ8c3RyaW5nLCB7IGJ5dGVzSW5PdXRwdXQ6IG51bWJlciB9Pixcblx0KTogVHJlZU1hcE5vZGUge1xuXHRcdGNvbnN0IHJvb3Q6IFRyZWVNYXBOb2RlID0geyBuYW1lOiBcIlwiLCBwYXRoOiBcIlwiLCB2YWx1ZTogMCwgY2hpbGRyZW46IFtdIH07XG5cdFx0Zm9yIChjb25zdCBbZmlsZVBhdGgsIHsgYnl0ZXNJbk91dHB1dCB9XSBvZiBPYmplY3QuZW50cmllcyhpbnB1dCkpIHtcblx0XHRcdGNvbnN0IGRpcmVjdG9yaWVzID0gZmlsZVBhdGguc3BsaXQoXCIvXCIpO1xuXHRcdFx0YnVpbGROb2RlKHJvb3QsIGRpcmVjdG9yaWVzLCBieXRlc0luT3V0cHV0KTtcblx0XHR9XG5cdFx0cmV0dXJuIHJvb3Q7XG5cdH1cblxuXHRmdW5jdGlvbiBidWlsZE5vZGUoXG5cdFx0bm9kZTogVHJlZU1hcE5vZGUsXG5cdFx0cGF0aHM6IEFycmF5PHN0cmluZz4sXG5cdFx0dmFsdWU6IG51bWJlcixcblx0KTogdm9pZCB7XG5cdFx0Y29uc3QgZmlyc3QgPSBwYXRocy5zaGlmdCgpO1xuXHRcdGlmIChmaXJzdCA9PT0gdW5kZWZpbmVkKSB7XG5cdFx0XHQvLyBsZWFmIG5vZGUgKGZpbGUpXG5cdFx0XHRub2RlLnZhbHVlICs9IHZhbHVlO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblx0XHRsZXQgY2hpbGQgPSBub2RlLmNoaWxkcmVuLmZpbmQoKGNoaWxkKSA9PiBjaGlsZC5uYW1lID09PSBmaXJzdCk7XG5cdFx0aWYgKCFjaGlsZCkge1xuXHRcdFx0Y2hpbGQgPSB7XG5cdFx0XHRcdG5hbWU6IGZpcnN0LFxuXHRcdFx0XHRwYXRoOiBgJHtub2RlLnBhdGh9LyR7Zmlyc3R9YC5yZXBsYWNlKC9eXFwvLywgXCJcIiksXG5cdFx0XHRcdHZhbHVlOiAwLFxuXHRcdFx0XHRjaGlsZHJlbjogW10sXG5cdFx0XHR9O1xuXHRcdFx0bm9kZS5jaGlsZHJlbi5wdXNoKGNoaWxkKTtcblx0XHR9XG5cdFx0bm9kZS52YWx1ZSArPSB2YWx1ZTtcblx0XHRidWlsZE5vZGUoY2hpbGQsIHBhdGhzLCB2YWx1ZSk7XG5cdH1cblxuXHRjb25zdCB0cmVlcyA9IG5ldyBNYXA8c3RyaW5nLCBUcmVlTWFwTm9kZT4oKTtcblx0aWYgKGlucHV0LnRvcE5MYXJnZXN0UGF0aHMgPD0gMCkge1xuXHRcdC8vIFNraXAgYnVpbGRpbmcgdHJlZSBpZiB3ZSBkb24ndCBuZWVkIGl0LlxuXHRcdHJldHVybiB0cmVlcztcblx0fVxuXHRmb3IgKGNvbnN0IHsgcmVsYXRpdmVQYXRoLCBhYnNvbHV0ZVBhdGggfSBvZiBmaW5kTWV0YWZpbGVzKGlucHV0KSkge1xuXHRcdGNvbnN0IG1ldGFmaWxlSnNvbiA9IGxvYWRNZXRhRmlsZShhYnNvbHV0ZVBhdGgpO1xuXHRcdGZvciAoY29uc3QgW291dGZpbGUsIGJ1aWxkTWV0YV0gb2YgT2JqZWN0LmVudHJpZXMobWV0YWZpbGVKc29uLm91dHB1dHMpKSB7XG5cdFx0XHRjb25zdCB0cmVlID0gYnVpbGRSb290KGJ1aWxkTWV0YS5pbnB1dHMpO1xuXHRcdFx0dHJlZXMuc2V0KHRyZWVLZXkocmVsYXRpdmVQYXRoLCBvdXRmaWxlKSwgdHJlZSk7XG5cblx0XHRcdGZzLndyaXRlRmlsZVN5bmMoXG5cdFx0XHRcdHBhdGguam9pbihwcm9jZXNzLmN3ZCgpLCBpbnB1dC5hbmFseXplckRpcmVjdG9yeSwgXCJ0cmVlLmpzb25cIiksXG5cdFx0XHRcdEpTT04uc3RyaW5naWZ5KHRyZWUsIG51bGwsIDIpLFxuXHRcdFx0KTtcblx0XHR9XG5cdH1cblx0cmV0dXJuIHRyZWVzO1xufVxuXG5jb25zdCBzcGFjZXIgPSBcIlx1MDBBMFwiO1xuZnVuY3Rpb24gZmlsZXNpemUoYnl0ZXM6IG51bWJlcik6IHN0cmluZyB7XG5cdGNvbnN0IHNpZ24gPSBieXRlcyA8IDAgPyBcIi1cIiA6IFwiXCI7XG5cdGNvbnN0IG4gPSBNYXRoLmFicyhieXRlcyk7XG5cdGlmIChuIDwgMTAwMCkge1xuXHRcdHJldHVybiBgJHtzaWdufSR7bn0ke3NwYWNlcn1CYDtcblx0fVxuXHRpZiAobiA8IDEwMDAgKiAxMDAwKSB7XG5cdFx0cmV0dXJuIGAke3NpZ259JHsobiAvIDEwMDApLnRvRml4ZWQoMil9JHtzcGFjZXJ9S0JgO1xuXHR9XG5cdGlmIChuIDwgMTAwMCAqIDEwMDAgKiAxMDAwKSB7XG5cdFx0cmV0dXJuIGAke3NpZ259JHsobiAvIDEwMDAgLyAxMDAwKS50b0ZpeGVkKDIpfSR7c3BhY2VyfU1CYDtcblx0fVxuXHRpZiAobiA8IDEwMDAgKiAxMDAwICogMTAwMCAqIDEwMDApIHtcblx0XHRyZXR1cm4gYCR7c2lnbn0keyhuIC8gMTAwMCAvIDEwMDAgLyAxMDAwKS50b0ZpeGVkKDIpfSR7c3BhY2VyfUdCYDtcblx0fVxuXHR0aHJvdyBuZXcgRXJyb3IoXCJUb28gbGFyZ2UgZmlsZSBzaXplISEgQXJlIHlvdSBzdXJlP1wiKTtcbn1cblxuZnVuY3Rpb24gbWFya2Rvd25UYWJsZShcblx0ZGF0YTogQXJyYXk8Q29tcGFyZVJlc3VsdD4sXG5cdHJlZFRocmVzaG9sZDogbnVtYmVyLFxuKTogc3RyaW5nIHtcblx0Y29uc3Qgcm93cyA9IGRhdGFcblx0XHQubWFwKChkKSA9PiB7XG5cdFx0XHRyZXR1cm4gYCR7ZC5tZXRhZmlsZX0gfCAke2Qub3V0ZmlsZX0gfCAke3JlbmRlclNpemUoZCl9IHwgJHtyZW5kZXJOb3RlKFxuXHRcdFx0XHRkLFxuXHRcdFx0XHRyZWRUaHJlc2hvbGQsXG5cdFx0XHQpfVxcbmA7XG5cdFx0fSlcblx0XHQuam9pbihcIlwiKTtcblxuXHRyZXR1cm4gYFxuTWV0YSBGaWxlIHwgT3V0IEZpbGUgIHwgU2l6ZSAocmF3KSB8IE5vdGUgXG4tLS0tLS0tLS0tfC0tLS0tLS0tLS18LS0tLS0tLS0tLS06fC0tLS0tLVxuJHtyb3dzfWA7XG59XG5cbi8qKlxuICogRmluZCB0aGUgdG9wIE4gbGFyZ2VzdCBub2RlcyBpbiByb290IHRyZWUuXG4gKiBEaWcgbm9kZXMgdW50aWwgdGhlIGRlcHRoIG9mIDMuXG4gKi9cbmZ1bmN0aW9uIGZpbmRMYXJnZURpcmVjdG9yaWVzKHJvb3Q6IFRyZWVNYXBOb2RlLCBOOiBudW1iZXIpIHtcblx0Y29uc3Qgbm9kZXM6IFRyZWVNYXBOb2RlW10gPSBbXTtcblx0Y29uc3QgcXVldWU6IEFycmF5PHsgbm9kZTogVHJlZU1hcE5vZGU7IGRlcHRoOiBudW1iZXIgfT4gPSBbXG5cdFx0eyBub2RlOiByb290LCBkZXB0aDogMCB9LFxuXHRdO1xuXHR3aGlsZSAocXVldWUubGVuZ3RoID4gMCkge1xuXHRcdGNvbnN0IHNoaWZ0ID0gcXVldWUuc2hpZnQoKTtcblx0XHRpZiAoIXNoaWZ0KSB7XG5cdFx0XHRicmVhaztcblx0XHR9XG5cdFx0Y29uc3QgeyBub2RlLCBkZXB0aCB9ID0gc2hpZnQ7XG5cdFx0aWYgKGRlcHRoID09PSAzKSB7XG5cdFx0XHRub2Rlcy5wdXNoKG5vZGUpO1xuXHRcdFx0Y29udGludWU7XG5cdFx0fVxuXHRcdGlmIChub2RlLmNoaWxkcmVuLmxlbmd0aCA9PT0gMCkge1xuXHRcdFx0bm9kZXMucHVzaChub2RlKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0Zm9yIChjb25zdCBpdGVtIG9mIG5vZGUuY2hpbGRyZW4pIHtcblx0XHRcdFx0cXVldWUucHVzaCh7IG5vZGU6IGl0ZW0sIGRlcHRoOiBkZXB0aCArIDEgfSk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cdGNvbnN0IGxhcmdlTm9kZXMgPSBub2Rlcy5zb3J0KChhLCBiKSA9PiBiLnZhbHVlIC0gYS52YWx1ZSkuc2xpY2UoMCwgTik7XG5cdHJldHVybiB7XG5cdFx0bGFyZ2VOb2Rlcyxcblx0XHRoYXNPdGhlcjogbm9kZXMubGVuZ3RoID4gTixcblx0fTtcbn1cblxuZnVuY3Rpb24gZml4ZWRQZXJjZW50KG46IG51bWJlciwgZDogbnVtYmVyKTogbnVtYmVyIHtcblx0cmV0dXJuIE51bWJlci5wYXJzZUZsb2F0KCgobiAvIGQpICogMTAwKS50b0ZpeGVkKDEpKTtcbn1cblxuZnVuY3Rpb24gZmlsZVNpemVUYWJsZShcblx0ZGF0YTogQXJyYXk8Q29tcGFyZVJlc3VsdD4sXG5cdHRvcE5MYXJnZXN0UGF0aHM6IG51bWJlcixcbik6IHN0cmluZyB7XG5cdGlmIChkYXRhLmxlbmd0aCA9PT0gMCB8fCB0b3BOTGFyZ2VzdFBhdGhzIDw9IDApIHtcblx0XHRyZXR1cm4gXCJcIjtcblx0fVxuXHRsZXQgb3V0cHV0ID0gXCJcIjtcblx0b3V0cHV0ICs9IFwiPGRldGFpbHM+XFxuXCI7XG5cdG91dHB1dCArPSBcIjxzdW1tYXJ5Pkxhcmdlc3QgcGF0aHM8L3N1bW1hcnk+XFxuXCI7XG5cdG91dHB1dCArPSBgVGhlc2UgdmlzdWFsaXphdGlvbiBzaG93cyB0b3AgJHt0b3BOTGFyZ2VzdFBhdGhzfSBsYXJnZXN0IHBhdGhzIGluIHRoZSBidW5kbGUuXFxuYDtcblx0Zm9yIChjb25zdCBkIG9mIGRhdGEpIHtcblx0XHRvdXRwdXQgKz0gXCJcXG5cIjtcblx0XHRvdXRwdXQgKz0gYCMjIE1ldGEgZmlsZTogJHtkLm1ldGFmaWxlfSwgT3V0IGZpbGU6ICR7ZC5vdXRmaWxlfVxcbmA7XG5cdFx0aWYgKCFkLnRyZWUpIHtcblx0XHRcdG91dHB1dCArPSBcIlx1RkUwRlx1RkUwRlx1RDgzRFx1REREMVx1RkUwRkRlbGV0ZWRcXG5cIjtcblx0XHRcdGNvbnRpbnVlO1xuXHRcdH1cblx0XHRvdXRwdXQgKz0gXCJ8IFBhdGggfCBTaXplIHxcXG5cIjtcblx0XHRvdXRwdXQgKz0gXCJ8LS0tLS0tfC0tLS0tLS18XFxuXCI7XG5cdFx0Y29uc3QgdG90YWxTaXplID0gZC50cmVlLnZhbHVlO1xuXHRcdGNvbnN0IHsgbGFyZ2VOb2RlcywgaGFzT3RoZXIgfSA9IGZpbmRMYXJnZURpcmVjdG9yaWVzKFxuXHRcdFx0ZC50cmVlLFxuXHRcdFx0dG9wTkxhcmdlc3RQYXRocyxcblx0XHQpO1xuXHRcdGZvciAoY29uc3QgeyBwYXRoLCB2YWx1ZSB9IG9mIGxhcmdlTm9kZXMpIHtcblx0XHRcdGNvbnN0IHBlcmNlbnQgPSBmaXhlZFBlcmNlbnQodmFsdWUsIHRvdGFsU2l6ZSk7XG5cdFx0XHRvdXRwdXQgKz0gYHwgJHtwYXRofSB8ICR7cmVuZGVyQmFyKHBlcmNlbnQsIHZhbHVlKX0gfFxcbmA7XG5cdFx0fVxuXHRcdGlmIChoYXNPdGhlcikge1xuXHRcdFx0Y29uc3Qgb3RoZXJTaXplID0gdG90YWxTaXplIC0gbGFyZ2VOb2Rlc1swXS52YWx1ZTtcblx0XHRcdGNvbnN0IG90aGVyUGVyY2VudCA9IGZpeGVkUGVyY2VudChvdGhlclNpemUsIHRvdGFsU2l6ZSk7XG5cdFx0XHRvdXRwdXQgKz0gYHwgKG90aGVyKSB8ICR7cmVuZGVyQmFyKG90aGVyUGVyY2VudCwgb3RoZXJTaXplKX0gfFxcbmA7XG5cdFx0fVxuXHR9XG5cdG91dHB1dCArPSBcIjwvZGV0YWlscz5cXG5cIjtcblx0cmV0dXJuIG91dHB1dDtcbn1cblxuZnVuY3Rpb24gcmVuZGVyQmFyKHBlcmNlbnQ6IG51bWJlciwgYnl0ZXM6IG51bWJlcik6IHN0cmluZyB7XG5cdGNvbnN0IGJhciA9IHByb2dyZXNzKHBlcmNlbnQgLyAxMDApO1xuXHRyZXR1cm4gYFxcJHt7XFxcXGNvbG9ye0dvbGRlbnJvZH17ICR7YmFyfSB9fX1cXCQgJHtwZXJjZW50LnRvRml4ZWQoXG5cdFx0MSxcblx0KX0lLCAke2ZpbGVzaXplKGJ5dGVzKX1gO1xufVxuXG4vLyBCbG9jayBwcm9ncmVzc2lvbiBpcyAxLzggPSAwLjEyNVxuY29uc3QgYmxvY2tzID0gW1wiXCIsIFwiXHUyNThGXCIsIFwiXHUyNThFXCIsIFwiXHUyNThEXCIsIFwiXHUyNThDXCIsIFwiXHUyNThCXCIsIFwiXHUyNThBXCIsIFwiXHUyNTg5XCIsIFwiXHUyNTg4XCJdO1xuY29uc3QgcHJvZ3Jlc3Npb24gPSAxIC8gKGJsb2Nrcy5sZW5ndGggLSAxKTtcbmZ1bmN0aW9uIHByb2dyZXNzKHZhbHVlOiBudW1iZXIsIGxlbmd0aCA9IDI1LCB2bWluID0gMC4wLCB2bWF4ID0gMS4wKSB7XG5cdGNvbnN0IHYgPSB2YWx1ZSAqIGxlbmd0aDtcblx0Y29uc3QgaW50ZWdlclBhcnQgPSBNYXRoLmZsb29yKHYpO1xuXHRjb25zdCBmcmFjdGlvbmFsUGFydCA9IHYgLSBpbnRlZ2VyUGFydDtcblx0Y29uc3QgaSA9IE1hdGgucm91bmQoXG5cdFx0KHByb2dyZXNzaW9uICogTWF0aC5mbG9vcihmcmFjdGlvbmFsUGFydCAvIHByb2dyZXNzaW9uKSkgLyBwcm9ncmVzc2lvbixcblx0KTtcblx0cmV0dXJuIFwiXHUyNTg4XCIucmVwZWF0KGludGVnZXJQYXJ0KSArIGJsb2Nrc1tpXTtcbn1cblxuZnVuY3Rpb24gcmVuZGVyU2l6ZShkOiBDb21wYXJlUmVzdWx0KTogc3RyaW5nIHtcblx0cmV0dXJuIGZpbGVzaXplKGQuYnl0ZXMpO1xufVxuXG5mdW5jdGlvbiByZW5kZXJOb3RlKGQ6IENvbXBhcmVSZXN1bHQsIHJlZFRocmVzaG9sZDogbnVtYmVyKTogc3RyaW5nIHtcblx0aWYgKGQucmVtYXJrID09PSBcImRlbGV0ZWRcIikge1xuXHRcdHJldHVybiBcIlx1RDgzRFx1REREMVx1RkUwRiBEZWxldGVkXCI7XG5cdH1cblx0aWYgKGQucmVtYXJrID09PSBcImFkZGVkXCIpIHtcblx0XHRyZXR1cm4gXCJcdUQ4M0NcdUREOTUgQWRkZWRcIjtcblx0fVxuXHRpZiAoZC5kaWZmKSB7XG5cdFx0Y29uc3QgcGVyY2VudENoYW5nZSA9IChkLmRpZmYgLyBkLmJ5dGVzKSAqIDEwMDtcblx0XHRyZXR1cm4gYCR7cmVuZGVyU3RhdHVzSW5kaWNhdG9yKHBlcmNlbnRDaGFuZ2UsIHJlZFRocmVzaG9sZCl9JHtmaWxlc2l6ZShcblx0XHRcdGQuZGlmZixcblx0XHQpfSAoJHtzaWduKHBlcmNlbnRDaGFuZ2UpfSR7cGVyY2VudENoYW5nZS50b0ZpeGVkKDEpfSUpYDtcblx0fVxuXHRyZXR1cm4gXCJcdTI3MDUgIE5vIGNoYW5nZVwiO1xufVxuXG5mdW5jdGlvbiBzaWduKG51bTogbnVtYmVyKTogc3RyaW5nIHtcblx0cmV0dXJuIG51bSA8IDAgPyBcIlwiIDogXCIrXCI7XG59XG5cbmZ1bmN0aW9uIHJlbmRlclN0YXR1c0luZGljYXRvcihcblx0cGVyY2VudENoYW5nZTogbnVtYmVyLFxuXHRyZWRUaHJlc2hvbGQ6IG51bWJlcixcbik6IHN0cmluZyB7XG5cdGxldCByZXM6IHN0cmluZztcblx0aWYgKHBlcmNlbnRDaGFuZ2UgPiAwICYmIHBlcmNlbnRDaGFuZ2UgPCByZWRUaHJlc2hvbGQpIHtcblx0XHRyZXMgPSBcIlx1MjZBMFx1RkUwRlwiO1xuXHR9IGVsc2UgaWYgKHBlcmNlbnRDaGFuZ2UgPj0gcmVkVGhyZXNob2xkKSB7XG5cdFx0cmVzID0gXCJcdTIwM0NcdUZFMEZcIjtcblx0fSBlbHNlIHtcblx0XHRyZXMgPSBcIlx1MjcwNSBcIjtcblx0fVxuXHRyZXR1cm4gYCR7cmVzfSAke3NpZ24ocGVyY2VudENoYW5nZSl9YDtcbn1cbiIsICJpbXBvcnQgZnMgZnJvbSBcIm5vZGU6ZnNcIjtcbmltcG9ydCBwYXRoIGZyb20gXCJub2RlOnBhdGhcIjtcbmltcG9ydCBwcm9jZXNzIGZyb20gXCJub2RlOnByb2Nlc3NcIjtcblxuaW1wb3J0ICogYXMgY29uc29sZSBmcm9tIFwibm9kZTpjb25zb2xlXCI7XG5pbXBvcnQgeyBnbG9iU3luYyB9IGZyb20gXCJnbG9iXCI7XG5pbXBvcnQgdHlwZSB7IElucHV0LCBSZXBvcnQgfSBmcm9tIFwiLi90eXBlc1wiO1xuaW1wb3J0IHsgbG9hZE1ldGFGaWxlIH0gZnJvbSBcIi4vdXRpbHNcIjtcblxuZXhwb3J0IGZ1bmN0aW9uIHJlcG9ydChpbnB1dDogSW5wdXQpOiB2b2lkIHtcblx0Y29uc3QgYWxsUGFnZVNpemVzID0gZ2V0QWxsUGFnZVNpemVzKGlucHV0KTtcblx0ZnMubWtkaXJTeW5jKHBhdGguam9pbihwcm9jZXNzLmN3ZCgpLCBpbnB1dC5hbmFseXplckRpcmVjdG9yeSksIHtcblx0XHRyZWN1cnNpdmU6IHRydWUsXG5cdH0pO1xuXHRjb25zdCByZXN1bHRKc29uUGF0aCA9IHBhdGguam9pbihcblx0XHRwcm9jZXNzLmN3ZCgpLFxuXHRcdGlucHV0LmFuYWx5emVyRGlyZWN0b3J5LFxuXHRcdFwiYnVuZGxlX2FuYWx5c2lzLmpzb25cIixcblx0KTtcblx0ZnMud3JpdGVGaWxlU3luYyhyZXN1bHRKc29uUGF0aCwgSlNPTi5zdHJpbmdpZnkoYWxsUGFnZVNpemVzLCBudWxsLCAyKSk7XG5cdGNvbnNvbGUubG9nKGBXcm90ZSAke3Jlc3VsdEpzb25QYXRofWApO1xufVxuXG5pbnRlcmZhY2UgTWV0YWZpbGVQYXRoIHtcblx0cmVhZG9ubHkgcmVsYXRpdmVQYXRoOiBzdHJpbmc7XG5cdHJlYWRvbmx5IGFic29sdXRlUGF0aDogc3RyaW5nO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZmluZE1ldGFmaWxlcyhpbnB1dDogSW5wdXQpOiBNZXRhZmlsZVBhdGhbXSB7XG5cdHJldHVybiBpbnB1dC5tZXRhZmlsZXMuZmxhdE1hcCgobWV0YWZpbGUpID0+IHtcblx0XHRyZXR1cm4gZ2xvYlN5bmMocGF0aC5qb2luKHByb2Nlc3MuY3dkKCksIG1ldGFmaWxlKSwge1xuXHRcdFx0bm9kaXI6IHRydWUsXG5cdFx0fSkubWFwKChtZXRhRmlsZVBhdGgpID0+IHtcblx0XHRcdHJldHVybiB7XG5cdFx0XHRcdHJlbGF0aXZlUGF0aDogcGF0aC5yZWxhdGl2ZShwcm9jZXNzLmN3ZCgpLCBtZXRhRmlsZVBhdGgpLFxuXHRcdFx0XHRhYnNvbHV0ZVBhdGg6IG1ldGFGaWxlUGF0aCxcblx0XHRcdH07XG5cdFx0fSk7XG5cdH0pO1xufVxuXG5mdW5jdGlvbiBnZXRBbGxQYWdlU2l6ZXMoaW5wdXQ6IElucHV0KTogUmVwb3J0IHtcblx0Y29uc3QgYWNjOiBSZXBvcnQgPSB7fTtcblx0cmV0dXJuIGZpbmRNZXRhZmlsZXMoaW5wdXQpLnJlZHVjZSgoYWNjLCB7IHJlbGF0aXZlUGF0aCwgYWJzb2x1dGVQYXRoIH0pID0+IHtcblx0XHR0cnkge1xuXHRcdFx0ZnMuYWNjZXNzU3luYyhhYnNvbHV0ZVBhdGgsIGZzLmNvbnN0YW50cy5SX09LKTtcblx0XHR9IGNhdGNoIChlcnIpIHtcblx0XHRcdGNvbnNvbGUuZXJyb3IoXG5cdFx0XHRcdGBObyBtZXRhIGZpbGUgZm91bmQgYXQgXCIke2Fic29sdXRlUGF0aH1cIiAtIGEgcGF0aCB0byBtZXRhIGZpbGUgbWF5IGJlIHdyb25nLCBvciBlc2J1aWxkIGlzIG5vdCBleGVjdXRlZC5gLFxuXHRcdFx0KTtcblx0XHRcdHByb2Nlc3MuZXhpdCgxKTtcblx0XHR9XG5cblx0XHRjb25zdCBtZXRhRmlsZUpzb24gPSBsb2FkTWV0YUZpbGUoYWJzb2x1dGVQYXRoKTtcblx0XHRPYmplY3QuZW50cmllcyhtZXRhRmlsZUpzb24ub3V0cHV0cykucmVkdWNlKChhY2MsIG91dHB1dCkgPT4ge1xuXHRcdFx0Y29uc3QgW291dGZpbGUsIGJ1aWxkTWV0YV0gPSBvdXRwdXQ7XG5cdFx0XHRpZiAoXG5cdFx0XHRcdCFpbnB1dC5pbmNsdWRlRXh0ZW5zaW9ucy5zb21lKChleHQpID0+XG5cdFx0XHRcdFx0b3V0ZmlsZS50b0xvd2VyQ2FzZSgpLmVuZHNXaXRoKGV4dCksXG5cdFx0XHRcdClcblx0XHRcdCkge1xuXHRcdFx0XHRyZXR1cm4gYWNjO1xuXHRcdFx0fVxuXHRcdFx0YWNjW2Ake3JlbGF0aXZlUGF0aH0gLT4gJHtvdXRmaWxlfWBdID0ge1xuXHRcdFx0XHRieXRlczogYnVpbGRNZXRhLmJ5dGVzLFxuXHRcdFx0XHRtZXRhZmlsZTogcmVsYXRpdmVQYXRoLFxuXHRcdFx0XHRvdXRmaWxlLFxuXHRcdFx0fTtcblx0XHRcdHJldHVybiBhY2M7XG5cdFx0fSwgYWNjKTtcblx0XHRyZXR1cm4gYWNjO1xuXHR9LCBhY2MpO1xufVxuIiwgImltcG9ydCBmcyBmcm9tIFwibm9kZTpmc1wiO1xuXG5pbXBvcnQgdHlwZSB7IE1ldGFmaWxlIH0gZnJvbSBcImVzYnVpbGRcIjtcbmltcG9ydCB0eXBlIHsgUmVwb3J0IH0gZnJvbSBcIi4vdHlwZXNcIjtcblxuZnVuY3Rpb24gbG9hZEpzb25GaWxlKHBhdGg6IHN0cmluZykge1xuXHRyZXR1cm4gSlNPTi5wYXJzZShmcy5yZWFkRmlsZVN5bmMocGF0aCkudG9TdHJpbmcoXCJ1dGYtOFwiKSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBsb2FkTWV0YUZpbGUocGF0aDogc3RyaW5nKTogTWV0YWZpbGUge1xuXHRyZXR1cm4gbG9hZEpzb25GaWxlKHBhdGgpIGFzIE1ldGFmaWxlO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbG9hZEFuYWx5c2lzSnNvbihwYXRoOiBzdHJpbmcpOiBSZXBvcnQge1xuXHRyZXR1cm4gbG9hZEpzb25GaWxlKHBhdGgpIGFzIFJlcG9ydDtcbn1cblxuLy8gaHR0cHM6Ly9naXRodWIuY29tL2FjdGlvbnMvdG9vbGtpdC9ibG9iLzgxYTczYWJhOGJlZGQ1MzJmNmVkZGNjNDFlZDNhMGZhZDhiMWNmZWIvcGFja2FnZXMvY29yZS9zcmMvY29yZS50cyNMMTI2XG5leHBvcnQgZnVuY3Rpb24gZ2V0U2luZ2xlSW5wdXQobmFtZTogc3RyaW5nKTogc3RyaW5nIHtcblx0Y29uc3QgdmFsID0gcHJvY2Vzcy5lbnZbYElOUFVUXyR7bmFtZS50b1VwcGVyQ2FzZSgpfWBdIHx8IFwiXCI7XG5cdHJldHVybiB2YWwudHJpbSgpO1xufVxuIl0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLFNBQVMscUJBQXFCOzs7QUNBOUIsT0FBT0EsU0FBUTtBQUNmLE9BQU9DLFdBQVU7OztBQ0RqQixPQUFPQyxTQUFRO0FBQ2YsT0FBT0MsV0FBVTtBQUNqQixPQUFPQyxjQUFhO0FBRXBCLFlBQVlDLGNBQWE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUNKekIsT0FBTyxRQUFRO0FBS2YsU0FBUyxhQUFhQyxPQUFjO0FBQ25DLFNBQU8sS0FBSyxNQUFNLEdBQUcsYUFBYUEsS0FBSSxFQUFFLFNBQVMs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QUMsR0FBRztBQUFBLE1BQzlELEVBQUU7QUFBQSxJQUNILENBQUMsS0FBSyxLQUFLLGFBQWEsQ0FBQyxHQUFHLGNBQWMsUUFBUSxDQUFDLENBQUM7QUFBQSxFQUNyRDtBQUNBLFNBQU87QUFDUjtBQUVBLFNBQVMsS0FBSyxLQUFxQjtBQUNsQyxTQUFPLE1BQU0sSUFBSSxLQUFLO0FBQ3ZCO0FBRUEsU0FBUyxzQkFDUixlQUNBLGNBQ1M7QUFDVCxNQUFJO0FBQ0osTUFBSSxnQkFBZ0IsS0FBSyxnQkFBZ0IsY0FBYztBQUN0RCxVQUFNO0FBQUEsRUFDUCxXQUFXLGlCQUFpQixjQUFjO0FBQ3pDLFVBQU07QUFBQSxFQUNQLE9BQU87QUFDTixVQUFNO0FBQUEsRUFDUDtBQUNBLFNBQU8sR0FBRyxHQUFHLElBQUksS0FBSyxhQUFhLENBQUM7QUFDckM7OztBRHhWQSxTQUFTLFdBQWtCO0FBQzFCLFFBQU0sZUFBZSxlQUFlLFdBQVc7QUFDL0MsTUFBSSxDQUFDLGNBQWM7QUFDbEIsVUFBTSxJQUFJLE1BQU0sNEJBQTRCO0FBQUEsRUFDN0M7QUFDQSxRQUFNLE9BQU8sZUFBZSxNQUFNO0FBQ2xDLE1BQUksQ0FBQyxNQUFNO0FBQ1YsVUFBTSxJQUFJLE1BQU0sdUJBQXVCO0FBQUEsRUFDeEM7QUFDQSxTQUFPO0FBQUEsSUFDTix1QkFBdUIsT0FBTztBQUFBLE1BQzdCLGVBQWUseUJBQXlCLEtBQUs7QUFBQSxNQUM3QztBQUFBLElBQ0Q7QUFBQSxJQUNBLGFBQWEsQ0FBQyxRQUFRLFFBQVEsTUFBTSxFQUFFO0FBQUEsTUFDckMsZUFBZSxjQUFjLEtBQUs7QUFBQSxJQUNuQztBQUFBLElBQ0Esa0JBQWtCLE9BQU87QUFBQSxNQUN4QixlQUFlLHFCQUFxQixLQUFLO0FBQUEsTUFDekM7QUFBQSxJQUNEO0FBQUEsSUFDQSxvQkFDQyxlQUFlLG9CQUFvQixLQUFLLGlCQUN2QyxNQUFNLEdBQUc7QUFBQSxJQUNYO0FBQUEsSUFDQSxtQkFBbUIsZUFBZSxtQkFBbUIsS0FBSztBQUFBLElBQzFELFdBQVcsYUFBYSxNQUFNLEdBQUc7QUFBQSxFQUNsQztBQUNEO0FBRU8sU0FBUyxJQUFJLFFBQWUsU0FBUyxHQUFTO0FBQ3BELFNBQU8sS0FBSztBQUNaLFVBQVEsS0FBSztBQUNkO0FBRUEsSUFBSSxZQUFZLFFBQVEsY0FBYyxRQUFRLEtBQUssQ0FBQyxDQUFDLEVBQUUsTUFBTTtBQUM1RCxNQUFJO0FBQ0w7IiwKICAibmFtZXMiOiBbImZzIiwgInBhdGgiLCAiZnMiLCAicGF0aCIsICJwcm9jZXNzIiwgImNvbnNvbGUiLCAicGF0aCIsICJmcyIsICJwYXRoIiwgInByb2Nlc3MiLCAiYWNjIiwgImV4dCIsICJwYXRoIiwgImZzIiwgImlucHV0IiwgImNoaWxkIiwgInNpZ24iXQp9Cg== diff --git a/package-lock.json b/package-lock.json index 79ef479..ee689fd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,9 @@ "name": "esbuild-bundle-analyzer", "version": "0.5.0", "license": "MIT", + "dependencies": { + "glob": "^10.3.12" + }, "devDependencies": { "@biomejs/biome": "^1.7.2", "@types/node": "^20.12.7", @@ -539,6 +542,22 @@ "node": ">=12" } }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/@jest/schemas": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", @@ -557,6 +576,15 @@ "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", "dev": true }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "optional": true, + "engines": { + "node": ">=14" + } + }, "node_modules/@rollup/rollup-android-arm-eabi": { "version": "4.17.2", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.17.2.tgz", @@ -937,6 +965,17 @@ "node": ">= 6.0.0" } }, + "node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, "node_modules/ansi-styles": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", @@ -966,6 +1005,19 @@ "optional": true, "peer": true }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, "node_modules/browser-process-hrtime": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", @@ -1013,6 +1065,22 @@ "node": "*" } }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -1037,7 +1105,6 @@ "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -1183,6 +1250,16 @@ "node": ">=8" } }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" + }, "node_modules/esbuild": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz", @@ -1299,6 +1376,21 @@ "optional": true, "peer": true }, + "node_modules/foreground-child": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", + "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/form-data": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", @@ -1338,6 +1430,27 @@ "node": "*" } }, + "node_modules/glob": { + "version": "10.3.12", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.12.tgz", + "integrity": "sha512-TCNv8vJ+xz4QiqTpfOJA7HvYv+tNIRHKfUWw/q+v2jdgN4ebz+KY9tGx5J4rHP0o84mNP+ApH66HRX8us3Khqg==", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.3.6", + "minimatch": "^9.0.1", + "minipass": "^7.0.4", + "path-scurry": "^1.10.2" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/html-encoding-sniffer": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", @@ -1397,6 +1510,14 @@ "node": ">=0.10.0" } }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, "node_modules/is-potential-custom-element-name": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", @@ -1408,8 +1529,24 @@ "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + }, + "node_modules/jackspeak": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", + "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } }, "node_modules/jsdom": { "version": "16.6.0", @@ -1507,6 +1644,14 @@ "get-func-name": "^2.0.1" } }, + "node_modules/lru-cache": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.2.tgz", + "integrity": "sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==", + "engines": { + "node": "14 || >=16.14" + } + }, "node_modules/magic-string": { "version": "0.30.10", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz", @@ -1547,6 +1692,28 @@ "node": ">= 0.6" } }, + "node_modules/minimatch": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", + "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minipass": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.0.tgz", + "integrity": "sha512-oGZRv2OT1lO2UF1zUcwdTb3wqUwI0kBGTgt/T7OdSj6M6N5m3o5uPf0AIW6lVxGGoiWUR7e2AwTE+xiwK8WQig==", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, "node_modules/mlly": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.6.1.tgz", @@ -1637,11 +1804,25 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, "engines": { "node": ">=8" } }, + "node_modules/path-scurry": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.2.tgz", + "integrity": "sha512-7xTavNy5RQXnsjANvVvMkEjvloOinkAjv/Z6Ildz9v2RinZ4SBKTWFOVRbaF8p0vpHnyjV/UwNDdKuUv6M5qcA==", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/pathe": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", @@ -1829,7 +2010,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, "dependencies": { "shebang-regex": "^3.0.0" }, @@ -1841,7 +2021,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, "engines": { "node": ">=8" } @@ -1852,6 +2031,17 @@ "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", "dev": true }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -1884,6 +2074,94 @@ "integrity": "sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==", "dev": true }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/string-width-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, "node_modules/strip-literal": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-2.1.0.tgz", @@ -2297,18 +2575,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/vitest/node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/vitest/node_modules/strip-final-newline": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", @@ -2396,7 +2662,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, "dependencies": { "isexe": "^2.0.0" }, @@ -2434,6 +2699,101 @@ "node": ">=0.10.0" } }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, "node_modules/ws": { "version": "7.5.3", "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.3.tgz", @@ -2720,6 +3080,19 @@ "dev": true, "optional": true }, + "@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "requires": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + } + }, "@jest/schemas": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", @@ -2735,6 +3108,12 @@ "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", "dev": true }, + "@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "optional": true + }, "@rollup/rollup-android-arm-eabi": { "version": "4.17.2", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.17.2.tgz", @@ -2985,6 +3364,11 @@ "debug": "4" } }, + "ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==" + }, "ansi-styles": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", @@ -3005,6 +3389,19 @@ "optional": true, "peer": true }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "requires": { + "balanced-match": "^1.0.0" + } + }, "browser-process-hrtime": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", @@ -3043,6 +3440,19 @@ "get-func-name": "^2.0.2" } }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, "combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -3064,7 +3474,6 @@ "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, "requires": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -3182,6 +3591,16 @@ } } }, + "eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" + }, + "emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" + }, "esbuild": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz", @@ -3269,6 +3688,15 @@ "optional": true, "peer": true }, + "foreground-child": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", + "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "requires": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + } + }, "form-data": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", @@ -3295,6 +3723,18 @@ "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", "dev": true }, + "glob": { + "version": "10.3.12", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.12.tgz", + "integrity": "sha512-TCNv8vJ+xz4QiqTpfOJA7HvYv+tNIRHKfUWw/q+v2jdgN4ebz+KY9tGx5J4rHP0o84mNP+ApH66HRX8us3Khqg==", + "requires": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.3.6", + "minimatch": "^9.0.1", + "minipass": "^7.0.4", + "path-scurry": "^1.10.2" + } + }, "html-encoding-sniffer": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", @@ -3342,6 +3782,11 @@ "safer-buffer": ">= 2.1.2 < 3" } }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + }, "is-potential-custom-element-name": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", @@ -3353,8 +3798,16 @@ "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + }, + "jackspeak": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", + "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", + "requires": { + "@isaacs/cliui": "^8.0.2", + "@pkgjs/parseargs": "^0.11.0" + } }, "jsdom": { "version": "16.6.0", @@ -3432,6 +3885,11 @@ "get-func-name": "^2.0.1" } }, + "lru-cache": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.2.tgz", + "integrity": "sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==" + }, "magic-string": { "version": "0.30.10", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz", @@ -3466,6 +3924,19 @@ "mime-db": "1.48.0" } }, + "minimatch": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", + "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "requires": { + "brace-expansion": "^2.0.1" + } + }, + "minipass": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.0.tgz", + "integrity": "sha512-oGZRv2OT1lO2UF1zUcwdTb3wqUwI0kBGTgt/T7OdSj6M6N5m3o5uPf0AIW6lVxGGoiWUR7e2AwTE+xiwK8WQig==" + }, "mlly": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.6.1.tgz", @@ -3534,8 +4005,16 @@ "path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" + }, + "path-scurry": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.2.tgz", + "integrity": "sha512-7xTavNy5RQXnsjANvVvMkEjvloOinkAjv/Z6Ildz9v2RinZ4SBKTWFOVRbaF8p0vpHnyjV/UwNDdKuUv6M5qcA==", + "requires": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + } }, "pathe": { "version": "1.1.2", @@ -3683,7 +4162,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, "requires": { "shebang-regex": "^3.0.0" } @@ -3691,8 +4169,7 @@ "shebang-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" }, "siginfo": { "version": "2.0.0", @@ -3700,6 +4177,11 @@ "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", "dev": true }, + "signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==" + }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -3726,6 +4208,69 @@ "integrity": "sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==", "dev": true }, + "string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "requires": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + } + }, + "string-width-cjs": { + "version": "npm:string-width@4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "requires": { + "ansi-regex": "^5.0.1" + } + } + } + }, + "strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "requires": { + "ansi-regex": "^6.0.1" + } + }, + "strip-ansi-cjs": { + "version": "npm:strip-ansi@6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "requires": { + "ansi-regex": "^5.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" + } + } + }, "strip-literal": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-2.1.0.tgz", @@ -3973,12 +4518,6 @@ "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", "dev": true }, - "signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true - }, "strip-final-newline": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", @@ -4053,7 +4592,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, "requires": { "isexe": "^2.0.0" } @@ -4076,6 +4614,71 @@ "optional": true, "peer": true }, + "wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "requires": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "dependencies": { + "ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==" + } + } + }, + "wrap-ansi-cjs": { + "version": "npm:wrap-ansi@7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "requires": { + "ansi-regex": "^5.0.1" + } + } + } + }, "ws": { "version": "7.5.3", "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.3.tgz", diff --git a/package.json b/package.json index b33b058..405ace8 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ }, "homepage": "https://github.com/exoego/esbuild-bundle-analysis#readme", "dependencies": { + "glob": "^10.3.12" }, "devDependencies": { "@types/node": "^20.12.7", diff --git a/src/compare.ts b/src/compare.ts index f33684c..6ed57d2 100644 --- a/src/compare.ts +++ b/src/compare.ts @@ -1,5 +1,6 @@ import fs from "node:fs"; import path from "node:path"; +import { findMetafiles } from "./report"; import type { CompareResult, Input, Report, TreeMapNode } from "./types"; import { loadAnalysisJson, loadMetaFile } from "./utils"; @@ -160,11 +161,11 @@ function buildFileTree(input: Input) { // Skip building tree if we don't need it. return trees; } - for (const metafile of input.metafiles) { - const metafileJson = loadMetaFile(path.join(process.cwd(), metafile)); + for (const { relativePath, absolutePath } of findMetafiles(input)) { + const metafileJson = loadMetaFile(absolutePath); for (const [outfile, buildMeta] of Object.entries(metafileJson.outputs)) { const tree = buildRoot(buildMeta.inputs); - trees.set(treeKey(metafile, outfile), tree); + trees.set(treeKey(relativePath, outfile), tree); fs.writeFileSync( path.join(process.cwd(), input.analyzerDirectory, "tree.json"), diff --git a/src/report.ts b/src/report.ts index 158dcd3..a21fd66 100644 --- a/src/report.ts +++ b/src/report.ts @@ -2,6 +2,8 @@ import fs from "node:fs"; import path from "node:path"; import process from "node:process"; +import * as console from "node:console"; +import { globSync } from "glob"; import type { Input, Report } from "./types"; import { loadMetaFile } from "./utils"; @@ -19,20 +21,37 @@ export function report(input: Input): void { console.log(`Wrote ${resultJsonPath}`); } +interface MetafilePath { + readonly relativePath: string; + readonly absolutePath: string; +} + +export function findMetafiles(input: Input): MetafilePath[] { + return input.metafiles.flatMap((metafile) => { + return globSync(path.join(process.cwd(), metafile), { + nodir: true, + }).map((metaFilePath) => { + return { + relativePath: path.relative(process.cwd(), metaFilePath), + absolutePath: metaFilePath, + }; + }); + }); +} + function getAllPageSizes(input: Input): Report { const acc: Report = {}; - return input.metafiles.reduce((acc, metafile) => { - const metaFilePath = path.join(process.cwd(), metafile); + return findMetafiles(input).reduce((acc, { relativePath, absolutePath }) => { try { - fs.accessSync(metaFilePath, fs.constants.R_OK); + fs.accessSync(absolutePath, fs.constants.R_OK); } catch (err) { console.error( - `No meta file found at "${metaFilePath}" - a path to meta file may be wrong, or esbuild is not executed.`, + `No meta file found at "${absolutePath}" - a path to meta file may be wrong, or esbuild is not executed.`, ); process.exit(1); } - const metaFileJson = loadMetaFile(metaFilePath); + const metaFileJson = loadMetaFile(absolutePath); Object.entries(metaFileJson.outputs).reduce((acc, output) => { const [outfile, buildMeta] = output; if ( @@ -42,9 +61,9 @@ function getAllPageSizes(input: Input): Report { ) { return acc; } - acc[`${metafile} -> ${outfile}`] = { + acc[`${relativePath} -> ${outfile}`] = { bytes: buildMeta.bytes, - metafile, + metafile: relativePath, outfile, }; return acc;