From 5e0b38d5868a6c299681be28116ee43203d8139b Mon Sep 17 00:00:00 2001 From: shaadcode Date: Sun, 19 Jul 2026 15:53:29 +0330 Subject: [PATCH 1/8] feat(build): update deps --- bun.lock | 598 +++++++++++++++++++++++++-------------------------- package.json | 66 +++--- 2 files changed, 328 insertions(+), 336 deletions(-) diff --git a/bun.lock b/bun.lock index f3aa118..b516e23 100644 --- a/bun.lock +++ b/bun.lock @@ -5,45 +5,45 @@ "": { "name": "payload-auditor", "devDependencies": { - "@antfu/eslint-config": "^7.4.3", - "@commitlint/cli": "^20.4.1", - "@commitlint/config-conventional": "^20.4.1", - "@eslint-react/eslint-plugin": "^2.12.4", - "@next/eslint-plugin-next": "^16.0.6", - "@payloadcms/db-mongodb": "^3.76.1", - "@payloadcms/next": "^3.76.1", - "@payloadcms/richtext-lexical": "^3.76.1", - "@payloadcms/translations": "^3.76.1", - "@payloadcms/ui": "^3.76.1", - "@release-it/conventional-changelog": "^10.0.1", - "@swc-node/register": "^1.11.1", - "@swc/cli": "^0.8.0", - "@swc/core": "^1.15.11", - "@types/node": "^25.2.3", - "@types/react": "^19.2.14", + "@antfu/eslint-config": "^9.1.0", + "@commitlint/cli": "^21.2.1", + "@commitlint/config-conventional": "^21.2.0", + "@eslint-react/eslint-plugin": "^5.17.1", + "@next/eslint-plugin-next": "^16.2.10", + "@payloadcms/db-mongodb": "^3.86.0", + "@payloadcms/next": "^3.86.0", + "@payloadcms/richtext-lexical": "^3.86.0", + "@payloadcms/translations": "^3.86.0", + "@payloadcms/ui": "^3.86.0", + "@release-it/conventional-changelog": "^11.0.1", + "@swc-node/register": "^1.12.1", + "@swc/cli": "^0.8.1", + "@swc/core": "^1.15.43", + "@types/node": "^26.1.1", + "@types/react": "^19.2.17", "@types/react-dom": "^19.2.3", - "@typescript/native-preview": "^7.0.0-dev.20260629.1", - "conventional-changelog-conventionalcommits": "^8.0.0", + "@typescript/native-preview": "^7.0.0-dev.20260707.2", + "conventional-changelog-conventionalcommits": "^10.2.1", "copyfiles": "2.4.1", "cross-env": "^10.1.0", - "cz-git": "^1.11.1", - "eslint": "^9.39.1", - "eslint-plugin-perfectionist": "^5.5.0", - "eslint-plugin-react-hooks": "^7.0.1", - "eslint-plugin-react-refresh": "^0.5.0", - "graphql": "^16.12.0", + "cz-git": "^1.13.1", + "eslint": "^10.7.0", + "eslint-plugin-perfectionist": "^5.10.0", + "eslint-plugin-react-hooks": "^7.1.1", + "eslint-plugin-react-refresh": "^0.5.3", + "graphql": "^17.0.2", "lefthook": "^2.1.10", - "next": "^16.2.0-canary.10", - "payload": "^3.76.1", + "next": "^16.2.10", + "payload": "^3.86.0", "payload-auditor": "^1.11.0", - "react": "^19.2.4", - "react-dom": "^19.2.4", - "release-it": "^19.0.6", - "rimraf": "^6.1.2", - "sharp": "^0.34.5", + "react": "^19.2.7", + "react-dom": "^19.2.7", + "release-it": "^20.2.1", + "rimraf": "^6.1.3", + "sharp": "^0.35.3", "type-fest": "^5.8.0", - "typescript": "^5.9.3", - "vitest": "^4.0.18", + "typescript": "6", + "vitest": "^4.1.10", }, "peerDependencies": { "payload": "^3.76.1", @@ -51,7 +51,7 @@ }, }, "packages": { - "@antfu/eslint-config": ["@antfu/eslint-config@7.7.3", "", { "dependencies": { "@antfu/install-pkg": "^1.1.0", "@clack/prompts": "^1.1.0", "@e18e/eslint-plugin": "^0.2.0", "@eslint-community/eslint-plugin-eslint-comments": "^4.7.1", "@eslint/markdown": "^7.5.1", "@stylistic/eslint-plugin": "^5.10.0", "@typescript-eslint/eslint-plugin": "^8.57.0", "@typescript-eslint/parser": "^8.57.0", "@vitest/eslint-plugin": "^1.6.10", "ansis": "^4.2.0", "cac": "^7.0.0", "eslint-config-flat-gitignore": "^2.2.1", "eslint-flat-config-utils": "^3.0.2", "eslint-merge-processors": "^2.0.0", "eslint-plugin-antfu": "^3.2.2", "eslint-plugin-command": "^3.5.2", "eslint-plugin-import-lite": "^0.5.2", "eslint-plugin-jsdoc": "^62.7.1", "eslint-plugin-jsonc": "^3.1.1", "eslint-plugin-n": "^17.24.0", "eslint-plugin-no-only-tests": "^3.3.0", "eslint-plugin-perfectionist": "^5.6.0", "eslint-plugin-pnpm": "^1.6.0", "eslint-plugin-regexp": "^3.1.0", "eslint-plugin-toml": "^1.3.1", "eslint-plugin-unicorn": "^63.0.0", "eslint-plugin-unused-imports": "^4.4.1", "eslint-plugin-vue": "^10.8.0", "eslint-plugin-yml": "^3.3.1", "eslint-processor-vue-blocks": "^2.0.0", "globals": "^17.4.0", "local-pkg": "^1.1.2", "parse-gitignore": "^2.0.0", "toml-eslint-parser": "^1.0.3", "vue-eslint-parser": "^10.4.0", "yaml-eslint-parser": "^2.0.0" }, "peerDependencies": { "@angular-eslint/eslint-plugin": "^21.1.0", "@angular-eslint/eslint-plugin-template": "^21.1.0", "@angular-eslint/template-parser": "^21.1.0", "@eslint-react/eslint-plugin": "^2.11.0", "@next/eslint-plugin-next": ">=15.0.0", "@prettier/plugin-xml": "^3.4.1", "@unocss/eslint-plugin": ">=0.50.0", "astro-eslint-parser": "^1.0.2", "eslint": "^9.10.0 || ^10.0.0", "eslint-plugin-astro": "^1.2.0", "eslint-plugin-format": ">=0.1.0", "eslint-plugin-jsx-a11y": ">=6.10.2", "eslint-plugin-react-hooks": "^7.0.0", "eslint-plugin-react-refresh": "^0.5.0", "eslint-plugin-solid": "^0.14.3", "eslint-plugin-svelte": ">=2.35.1", "eslint-plugin-vuejs-accessibility": "^2.4.1", "prettier-plugin-astro": "^0.14.0", "prettier-plugin-slidev": "^1.0.5", "svelte-eslint-parser": ">=0.37.0" }, "optionalPeers": ["@angular-eslint/eslint-plugin", "@angular-eslint/eslint-plugin-template", "@angular-eslint/template-parser", "@eslint-react/eslint-plugin", "@next/eslint-plugin-next", "@prettier/plugin-xml", "@unocss/eslint-plugin", "astro-eslint-parser", "eslint-plugin-astro", "eslint-plugin-format", "eslint-plugin-jsx-a11y", "eslint-plugin-react-hooks", "eslint-plugin-react-refresh", "eslint-plugin-solid", "eslint-plugin-svelte", "eslint-plugin-vuejs-accessibility", "prettier-plugin-astro", "prettier-plugin-slidev", "svelte-eslint-parser"], "bin": { "eslint-config": "bin/index.mjs" } }, "sha512-BtroDxTvmWtvr3yJkdWVCvwsKlnEdkreoeOyrdNezc/W5qaiQNf2xjcsQ3N5Yy0x27h+0WFfW8rG8YlVioG6dw=="], + "@antfu/eslint-config": ["@antfu/eslint-config@9.1.0", "", { "dependencies": { "@antfu/install-pkg": "^1.1.0", "@clack/prompts": "^1.6.0", "@e18e/eslint-plugin": "^0.5.1", "@eslint-community/eslint-plugin-eslint-comments": "^4.7.2", "@eslint/markdown": "^8.0.2", "@stylistic/eslint-plugin": "^5.10.0", "@typescript-eslint/eslint-plugin": "^8.62.0", "@typescript-eslint/parser": "^8.62.0", "@vitest/eslint-plugin": "^1.6.20", "ansis": "^4.3.1", "cac": "^7.0.0", "eslint-config-flat-gitignore": "^2.3.0", "eslint-flat-config-utils": "^3.2.0", "eslint-merge-processors": "^2.0.0", "eslint-plugin-antfu": "^3.2.3", "eslint-plugin-command": "^3.5.2", "eslint-plugin-import-lite": "^0.6.0", "eslint-plugin-jsdoc": "^63.0.7", "eslint-plugin-jsonc": "^3.2.0", "eslint-plugin-n": "^18.1.0", "eslint-plugin-no-only-tests": "^3.4.0", "eslint-plugin-perfectionist": "^5.9.1", "eslint-plugin-pnpm": "^1.6.1", "eslint-plugin-regexp": "^3.1.0", "eslint-plugin-toml": "^1.4.0", "eslint-plugin-unicorn": "^68.0.0", "eslint-plugin-unused-imports": "^4.4.1", "eslint-plugin-vue": "^10.9.2", "eslint-plugin-yml": "^3.5.0", "eslint-processor-vue-blocks": "^2.0.0", "globals": "^17.7.0", "local-pkg": "^1.2.1", "parse-gitignore": "^2.0.0", "toml-eslint-parser": "^1.0.3", "vue-eslint-parser": "^10.4.1", "yaml-eslint-parser": "^2.0.0" }, "peerDependencies": { "@angular-eslint/eslint-plugin": "^21.1.0", "@angular-eslint/eslint-plugin-template": "^21.1.0", "@angular-eslint/template-parser": "^21.1.0", "@eslint-react/eslint-plugin": "^5.6.0", "@next/eslint-plugin-next": ">=15.0.0", "@prettier/plugin-xml": "^3.4.1", "@unocss/eslint-plugin": ">=0.50.0", "astro-eslint-parser": "^1.0.2", "eslint": "^9.10.0 || ^10.0.0", "eslint-plugin-astro": "^1.2.0", "eslint-plugin-format": ">=0.1.0", "eslint-plugin-jsx-a11y": ">=6.10.2", "eslint-plugin-react-refresh": "^0.5.0", "eslint-plugin-solid": "^0.14.3", "eslint-plugin-svelte": ">=2.35.1", "eslint-plugin-vuejs-accessibility": "^2.4.1", "prettier-plugin-astro": "^0.14.0", "prettier-plugin-slidev": "^1.0.5", "svelte-eslint-parser": ">=0.37.0" }, "optionalPeers": ["@angular-eslint/eslint-plugin", "@angular-eslint/eslint-plugin-template", "@angular-eslint/template-parser", "@eslint-react/eslint-plugin", "@next/eslint-plugin-next", "@prettier/plugin-xml", "@unocss/eslint-plugin", "astro-eslint-parser", "eslint-plugin-astro", "eslint-plugin-format", "eslint-plugin-jsx-a11y", "eslint-plugin-react-refresh", "eslint-plugin-solid", "eslint-plugin-svelte", "eslint-plugin-vuejs-accessibility", "prettier-plugin-astro", "prettier-plugin-slidev", "svelte-eslint-parser"], "bin": { "eslint-config": "./bin/index.mjs" } }, "sha512-Vtjt+W/6/bV9hgQG8AiWG66OpAeLKmpo5bZaAmUdRvZsMyirVvIJeHnbM4XUJf4urIuLvK0gGSvXD74PI3ZnGQ=="], "@antfu/install-pkg": ["@antfu/install-pkg@1.1.0", "", { "dependencies": { "package-manager-detector": "^1.3.0", "tinyexec": "^1.0.1" } }, "sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ=="], @@ -97,42 +97,44 @@ "@clack/prompts": ["@clack/prompts@1.7.0", "", { "dependencies": { "@clack/core": "1.4.3", "fast-string-width": "^3.0.2", "fast-wrap-ansi": "^0.2.0", "sisteransi": "^1.0.5" } }, "sha512-y7/yvZ2TPAnR9+jnc00klvNNLkJiXFFrQA/hlLCcxA9a2A4zQIOimyFQ9XfwYKiGD1fb5GY8vbKIIgO8d5Tb2A=="], - "@commitlint/cli": ["@commitlint/cli@20.5.3", "", { "dependencies": { "@commitlint/format": "^20.5.0", "@commitlint/lint": "^20.5.3", "@commitlint/load": "^20.5.3", "@commitlint/read": "^20.5.0", "@commitlint/types": "^20.5.0", "tinyexec": "^1.0.0", "yargs": "^17.0.0" }, "bin": { "commitlint": "./cli.js" } }, "sha512-OJdL0EXWD5y9LPa0nr/geOwzaS8BsdaybKkcloB0JgsguGxNv2R+hC2FTPqrAcprg35zF33KOQerY0x8W1aesA=="], + "@commitlint/cli": ["@commitlint/cli@21.2.1", "", { "dependencies": { "@commitlint/config-conventional": "^21.2.0", "@commitlint/format": "^21.2.0", "@commitlint/lint": "^21.2.0", "@commitlint/load": "^21.2.0", "@commitlint/read": "^21.2.1", "@commitlint/types": "^21.2.0", "tinyexec": "^1.0.0", "yargs": "^18.0.0" }, "bin": { "commitlint": "cli.js" } }, "sha512-blsZGe29hJ72VGEFVl72IVYX+1vsfINpjA9yWQA6i7OKD/McGEOXg08sKIRKjFk4JvzhV/9n0l3i6NooPLTNfg=="], - "@commitlint/config-conventional": ["@commitlint/config-conventional@20.5.3", "", { "dependencies": { "@commitlint/types": "^20.5.0", "conventional-changelog-conventionalcommits": "^9.2.0" } }, "sha512-j34Qqeaa152chJgz2ysyk0BCpHenJn1lV0Rx0VXf8k3ccQcED+48EZrzMvo9jLmJUyBrrBwvu89I+2er4gW7QQ=="], + "@commitlint/config-conventional": ["@commitlint/config-conventional@21.2.0", "", { "dependencies": { "@commitlint/types": "^21.2.0", "conventional-changelog-conventionalcommits": "^10.0.0" } }, "sha512-Qf8WRDVcyVd14if6VTWenebxFbKnVnbzPUJjlzjkyJGeHK2xCGd63Dr1XZzj0plXKQb9P0BfOxoc1HVeCo2BWQ=="], - "@commitlint/config-validator": ["@commitlint/config-validator@20.5.0", "", { "dependencies": { "@commitlint/types": "^20.5.0", "ajv": "^8.11.0" } }, "sha512-T/Uh6iJUzyx7j35GmHWdIiGRQB+ouZDk0pwAaYq4SXgB54KZhFdJ0vYmxiW6AMYICTIWuyMxDBl1jK74oFp/Gw=="], + "@commitlint/config-validator": ["@commitlint/config-validator@21.2.0", "", { "dependencies": { "@commitlint/types": "^21.2.0", "ajv": "^8.11.0" } }, "sha512-t7AzNHAKeIdo/3NRGwzpufKHsKkPHmFs/56N2Fnsh0/r0rGtnQzTxk6vnFgjaGr4hdSQKNB50/KAhR9Yk4LJKA=="], - "@commitlint/ensure": ["@commitlint/ensure@20.5.3", "", { "dependencies": { "@commitlint/types": "^20.5.0", "es-toolkit": "^1.46.0" } }, "sha512-4i4AgNvH62owG9MwSiWKrle7HGNpBHHdLnWFIp5fTsHUYe5kRuh15t08L/0pdbbrRk8JKXQxxN4hZQcn+szkrw=="], + "@commitlint/ensure": ["@commitlint/ensure@21.2.0", "", { "dependencies": { "@commitlint/types": "^21.2.0", "es-toolkit": "^1.46.0" } }, "sha512-76IF9vDNS13lAzEEik9eKwzt8f9hYhWiwVXZ2AnyLCz5/f511FsEQ3pw1X3/zSQpdRLQU7i5qDMVKyXi1GWjSg=="], - "@commitlint/execute-rule": ["@commitlint/execute-rule@20.0.0", "", {}, "sha512-xyCoOShoPuPL44gVa+5EdZsBVao/pNzpQhkzq3RdtlFdKZtjWcLlUFQHSWBuhk5utKYykeJPSz2i8ABHQA+ZZw=="], + "@commitlint/execute-rule": ["@commitlint/execute-rule@21.0.1", "", {}, "sha512-RifH+FmImozKBE6mozhF4K3r2RRKP7SMi/Q/zLCmExtp5e05lhHOUYqGBlFBAGNHaZxU/WYw1XuugYK9jQzqnA=="], - "@commitlint/format": ["@commitlint/format@20.5.0", "", { "dependencies": { "@commitlint/types": "^20.5.0", "picocolors": "^1.1.1" } }, "sha512-TI9EwFU/qZWSK7a5qyXMpKPPv3qta7FO4tKW+Wt2al7sgMbLWTsAcDpX1cU8k16TRdsiiet9aOw0zpvRXNJu7Q=="], + "@commitlint/format": ["@commitlint/format@21.2.0", "", { "dependencies": { "@commitlint/types": "^21.2.0", "picocolors": "^1.1.1" } }, "sha512-c4q64xaav2U83t7k7RyzJerBZurPer7FxUOY0RL5L/6CZijZ7K+s6HIBGIghj0ey1P2+seRX0J9XQYtDued6tg=="], - "@commitlint/is-ignored": ["@commitlint/is-ignored@20.5.0", "", { "dependencies": { "@commitlint/types": "^20.5.0", "semver": "^7.6.0" } }, "sha512-JWLarAsurHJhPozbuAH6GbP4p/hdOCoqS9zJMfqwswne+/GPs5V0+rrsfOkP68Y8PSLphwtFXV0EzJ+GTXTTGg=="], + "@commitlint/is-ignored": ["@commitlint/is-ignored@21.2.0", "", { "dependencies": { "@commitlint/types": "^21.2.0", "semver": "^7.6.0" } }, "sha512-4/eB0vBN7L88O/oC4ajAEqi7j2ZfNgxl/+11RfAV9YosejZgDXhY2C9VcHnHJhOzPLoSy5P3Mg/46kqeyJfXKw=="], - "@commitlint/lint": ["@commitlint/lint@20.5.3", "", { "dependencies": { "@commitlint/is-ignored": "^20.5.0", "@commitlint/parse": "^20.5.0", "@commitlint/rules": "^20.5.3", "@commitlint/types": "^20.5.0" } }, "sha512-M7JbWBNr2gXKaPc4i/KipsuW1gkDHpj35KPjWtKy3Z+2AQw5wu1gBi1LIO0uoaij67CqY4K8PxPZSGens4evCw=="], + "@commitlint/lint": ["@commitlint/lint@21.2.0", "", { "dependencies": { "@commitlint/is-ignored": "^21.2.0", "@commitlint/parse": "^21.2.0", "@commitlint/rules": "^21.2.0", "@commitlint/types": "^21.2.0" } }, "sha512-ceO5dp9pLjEZ6y6qbq/uXWXDPykqqlTsyzoQ0NzecpisSJhK3kTy9qzQoPeJuWG/IMNdV1lO0RgmzqoAlSi1uw=="], - "@commitlint/load": ["@commitlint/load@20.5.3", "", { "dependencies": { "@commitlint/config-validator": "^20.5.0", "@commitlint/execute-rule": "^20.0.0", "@commitlint/resolve-extends": "^20.5.3", "@commitlint/types": "^20.5.0", "cosmiconfig": "^9.0.1", "cosmiconfig-typescript-loader": "^6.1.0", "es-toolkit": "^1.46.0", "is-plain-obj": "^4.1.0", "picocolors": "^1.1.1" } }, "sha512-1FDZWuKyu98Myb8i7Tp31jPU2rZpOwAdYRyJcy2KoGg7Xk2A+bgHN8smhMaaNSNkmE8fwt53BokywZq8Gv/5XQ=="], + "@commitlint/load": ["@commitlint/load@21.2.0", "", { "dependencies": { "@commitlint/config-validator": "^21.2.0", "@commitlint/execute-rule": "^21.0.1", "@commitlint/resolve-extends": "^21.2.0", "@commitlint/types": "^21.2.0", "cosmiconfig": "^9.0.1", "cosmiconfig-typescript-loader": "^6.1.0", "es-toolkit": "^1.46.0", "is-plain-obj": "^4.1.0", "picocolors": "^1.1.1" } }, "sha512-RjlzWQqruRwIenJEfZtq7kG97co97nKoHpflE5YnF61tDLXxHPrdWImgzw6VL6MlFyaOcVlk74eBV8ZQmc3oIA=="], - "@commitlint/message": ["@commitlint/message@20.4.3", "", {}, "sha512-6akwCYrzcrFcTYz9GyUaWlhisY4lmQ3KvrnabmhoeAV8nRH4dXJAh4+EUQ3uArtxxKQkvxJS78hNX2EU3USgxQ=="], + "@commitlint/message": ["@commitlint/message@21.2.0", "", {}, "sha512-YxGoiXD/HXNXLJPrQwE5poXa+XH0CBEm+mdvbHQP0g6MV/dmJyUFCzPNzZbxL93GvZ70TmtTK0Z0/IBpAqHv8g=="], - "@commitlint/parse": ["@commitlint/parse@20.5.0", "", { "dependencies": { "@commitlint/types": "^20.5.0", "conventional-changelog-angular": "^8.2.0", "conventional-commits-parser": "^6.3.0" } }, "sha512-SeKWHBMk7YOTnnEWUhx+d1a9vHsjjuo6Uo1xRfPNfeY4bdYFasCH1dDpAv13Lyn+dDPOels+jP6D2GRZqzc5fA=="], + "@commitlint/parse": ["@commitlint/parse@21.2.0", "", { "dependencies": { "@commitlint/types": "^21.2.0", "conventional-changelog-angular": "^9.0.0", "conventional-commits-parser": "^7.0.0" } }, "sha512-QHWxG4d0PLTF634/AdyZ0MQS+CLn5YOuJlCFhMMlSGKFxzYGUetkHBj18xgBD+6fVzUrA2lrCdi/vlS2f/oYXg=="], - "@commitlint/read": ["@commitlint/read@20.5.0", "", { "dependencies": { "@commitlint/top-level": "^20.4.3", "@commitlint/types": "^20.5.0", "git-raw-commits": "^5.0.0", "minimist": "^1.2.8", "tinyexec": "^1.0.0" } }, "sha512-JDEIJ2+GnWpK8QqwfmW7O42h0aycJEWNqcdkJnyzLD11nf9dW2dWLTVEa8Wtlo4IZFGLPATjR5neA5QlOvIH1w=="], + "@commitlint/read": ["@commitlint/read@21.2.1", "", { "dependencies": { "@commitlint/top-level": "^21.2.0", "@commitlint/types": "^21.2.0", "@conventional-changelog/git-client": "^3.0.0", "tinyexec": "^1.0.0" } }, "sha512-hUW7EJQnNTL0vPOmVMNK4CrnrNBN0nN+JJHReFkdHO5y4iyHeEmTBwuC15OCqUTjxWo7idnH1LftfpWVIaPWIA=="], - "@commitlint/resolve-extends": ["@commitlint/resolve-extends@20.5.3", "", { "dependencies": { "@commitlint/config-validator": "^20.5.0", "@commitlint/types": "^20.5.0", "es-toolkit": "^1.46.0", "global-directory": "^5.0.0", "import-meta-resolve": "^4.0.0", "resolve-from": "^5.0.0" } }, "sha512-+ogW9v/u9JqpvAgTrLra/YTFo0KkjU6iNblF89pPsj4NebNc+DAWctsludwezI8YnsjBmfHpApSwcXprN/f/ew=="], + "@commitlint/resolve-extends": ["@commitlint/resolve-extends@21.2.0", "", { "dependencies": { "@commitlint/config-validator": "^21.2.0", "@commitlint/types": "^21.2.0", "es-toolkit": "^1.46.0", "global-directory": "^5.0.0", "resolve-from": "^5.0.0" } }, "sha512-4O/1j51+79Wth9s/MGxt/5gs0XYLDgNlYpltQfhAvLE0itusLKs9zruxbiNg1oOkmkb9L9L4USYGjEj7n87NxA=="], - "@commitlint/rules": ["@commitlint/rules@20.5.3", "", { "dependencies": { "@commitlint/ensure": "^20.5.3", "@commitlint/message": "^20.4.3", "@commitlint/to-lines": "^20.0.0", "@commitlint/types": "^20.5.0" } }, "sha512-MPlMnb9D3wbszYMp+1hPtuhtPJndRo6I6yfkZVA4+jR8w7Kqp0u2u/Y+gzbaItx5Lltq5rw7FSZQWJMoXUC4NQ=="], + "@commitlint/rules": ["@commitlint/rules@21.2.0", "", { "dependencies": { "@commitlint/ensure": "^21.2.0", "@commitlint/message": "^21.2.0", "@commitlint/to-lines": "^21.0.1", "@commitlint/types": "^21.2.0" } }, "sha512-C2yXMNpiB8ETZKfx5JD8+ExgF8vTU1VQMKPSUUYwqKpw9oJWQBrlXBpdU038mj2WPjof7o9UzFpmTyBeGMZwZg=="], - "@commitlint/to-lines": ["@commitlint/to-lines@20.0.0", "", {}, "sha512-2l9gmwiCRqZNWgV+pX1X7z4yP0b3ex/86UmUFgoRt672Ez6cAM2lOQeHFRUTuE6sPpi8XBCGnd8Kh3bMoyHwJw=="], + "@commitlint/to-lines": ["@commitlint/to-lines@21.0.1", "", {}, "sha512-bd1BFII7p1EQZre9Kaj+kKaMFP3cFCdt21K7DItVux9XP5WjLgJ0/Uy1pJJh9aPwVJ6SKg62PxqlZaHI8hQAXw=="], - "@commitlint/top-level": ["@commitlint/top-level@20.4.3", "", { "dependencies": { "escalade": "^3.2.0" } }, "sha512-qD9xfP6dFg5jQ3NMrOhG0/w5y3bBUsVGyJvXxdWEwBm8hyx4WOk3kKXw28T5czBYvyeCVJgJJ6aoJZUWDpaacQ=="], + "@commitlint/top-level": ["@commitlint/top-level@21.2.0", "", { "dependencies": { "escalade": "^3.2.0" } }, "sha512-Y5gmQ+KxzqCrBFJfLvFEPvvwD3LDiNZoTT2yeFBm96M8qhmqSzQc5DvX3rheAaAMjyIvMXOCLS/mWfdpONsjyQ=="], - "@commitlint/types": ["@commitlint/types@20.5.0", "", { "dependencies": { "conventional-commits-parser": "^6.3.0", "picocolors": "^1.1.1" } }, "sha512-ZJoS8oSq2CAZEpc/YI9SulLrdiIyXeHb/OGqGrkUP6Q7YV+0ouNAa7GjqRdXeQPncHQIDz/jbCTlHScvYvO/gA=="], + "@commitlint/types": ["@commitlint/types@21.2.0", "", { "dependencies": { "conventional-commits-parser": "^7.0.0", "picocolors": "^1.1.1" } }, "sha512-7zVFCDB2reMvJH5dmbKnOQPjZEvjdJTH8jc0U/PIPU1r3/+vf5pD1HlfitV2MWsWXrvu7u39iY1lyLUPOaN0Gw=="], "@conventional-changelog/git-client": ["@conventional-changelog/git-client@2.7.0", "", { "dependencies": { "@simple-libs/child-process-utils": "^1.0.0", "@simple-libs/stream-utils": "^1.2.0", "semver": "^7.5.2" }, "peerDependencies": { "conventional-commits-filter": "^5.0.0", "conventional-commits-parser": "^6.4.0" }, "optionalPeers": ["conventional-commits-filter", "conventional-commits-parser"] }, "sha512-j7A8/LBEQ+3rugMzPXoKYzyUPpw/0CBQCyvtTR7Lmu4olG4yRC/Tfkq79Mr3yuPs0SUitlO2HwGP3gitMJnRFw=="], + "@conventional-changelog/template": ["@conventional-changelog/template@1.2.1", "", {}, "sha512-TzlTVpKPjaqW6qOYjQcYUDuGsLCNsvFHVBXkYGTAnf5V37jCWrE5haKNXzz0WZUtVHjrpV76L1buANjwXMfT8w=="], + "@date-fns/tz": ["@date-fns/tz@1.2.0", "", {}, "sha512-LBrd7MiJZ9McsOgxqWX7AaxrDjcFVjWH/tIKJd7pnR7McaslGYOP1QmmiBXdJH/H/yLCT+rcQ7FaPBUxRGUtrg=="], "@dnd-kit/accessibility": ["@dnd-kit/accessibility@3.1.1", "", { "dependencies": { "tslib": "^2.0.0" }, "peerDependencies": { "react": ">=16.8.0" } }, "sha512-2P+YgaXF+gRsIihwwY1gCsQSYnu9Zyj2py8kY5fFvUM1qm2WA2u639R6YNVfU4GWr+ZM5mqEsfHZZLoRONbemw=="], @@ -145,7 +147,7 @@ "@dnd-kit/utilities": ["@dnd-kit/utilities@3.2.2", "", { "dependencies": { "tslib": "^2.0.0" }, "peerDependencies": { "react": ">=16.8.0" } }, "sha512-+MKAJEOfaBe5SmV6t34p80MMKhjvUz0vRrvVJbPT0WElzaOJ/1xs+D+KDv+tD/NE5ujfrChEcshd4fLn0wpiqg=="], - "@e18e/eslint-plugin": ["@e18e/eslint-plugin@0.2.0", "", { "dependencies": { "eslint-plugin-depend": "^1.4.0" }, "peerDependencies": { "eslint": "^9.0.0 || ^10.0.0", "oxlint": "^1.41.0" }, "optionalPeers": ["eslint", "oxlint"] }, "sha512-mXgODVwhuDjTJ+UT+XSvmMmCidtGKfrV5nMIv1UtpWex2pYLsIM3RSpT8HWIMAebS9qANbXPKlSX4BE7ZvuCgA=="], + "@e18e/eslint-plugin": ["@e18e/eslint-plugin@0.5.1", "", { "dependencies": { "empathic": "^2.0.1", "module-replacements": "^3.0.0-beta.8", "semver": "^7.8.2" }, "peerDependencies": { "eslint": "^9.0.0 || ^10.0.0", "oxlint": "^1.68.0" }, "optionalPeers": ["eslint", "oxlint"] }, "sha512-mqUozeyNI9xvJbjrOO7y765dT7Kud3bwCm/DHwctxdEngPdJWQaS9BNGgpM1wCCzZfOtlKQh4ZRhm3VRomT9KA=="], "@emnapi/core": ["@emnapi/core@1.11.2", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.2", "tslib": "^2.4.0" } }, "sha512-TC8MkTuZUtcTSiFeuC0ksCh9QIJ5+F21MvZ4Wn4ORfYaFJ/0dsiudv5tVkejgwZlwQ39jL9WWDe2lz8x0WglOA=="], @@ -239,35 +241,33 @@ "@eslint-community/regexpp": ["@eslint-community/regexpp@4.12.2", "", {}, "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew=="], - "@eslint-react/ast": ["@eslint-react/ast@2.13.0", "", { "dependencies": { "@eslint-react/eff": "2.13.0", "@typescript-eslint/types": "^8.55.0", "@typescript-eslint/typescript-estree": "^8.55.0", "@typescript-eslint/utils": "^8.55.0", "string-ts": "^2.3.1" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-43+5gmqV3MpatTzKnu/V2i/jXjmepvwhrb9MaGQvnXHQgq9J7/C7VVCCcwp6Rvp2QHAFquAAdvQDSL8IueTpeA=="], + "@eslint-react/ast": ["@eslint-react/ast@5.17.1", "", { "dependencies": { "@typescript-eslint/types": "^8.64.0", "@typescript-eslint/typescript-estree": "^8.64.0", "@typescript-eslint/utils": "^8.64.0", "string-ts": "^2.3.1" }, "peerDependencies": { "eslint": "*", "typescript": "*" } }, "sha512-C/Xu7inuG//EU4+LfDWO79GE71y94Ae0X1SSzGFu7IoplTH10tyjd6jQNMG4VYxI1zSMgCg0h+QcCWoBGV+ZWA=="], - "@eslint-react/core": ["@eslint-react/core@2.13.0", "", { "dependencies": { "@eslint-react/ast": "2.13.0", "@eslint-react/eff": "2.13.0", "@eslint-react/shared": "2.13.0", "@eslint-react/var": "2.13.0", "@typescript-eslint/scope-manager": "^8.55.0", "@typescript-eslint/types": "^8.55.0", "@typescript-eslint/utils": "^8.55.0", "ts-pattern": "^5.9.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-m62XDzkf1hpzW4sBc7uh7CT+8rBG2xz/itSADuEntlsg4YA7Jhb8hjU6VHf3wRFDwyfx5VnbV209sbJ7Azey0Q=="], + "@eslint-react/core": ["@eslint-react/core@5.17.1", "", { "dependencies": { "@eslint-react/ast": "5.17.1", "@eslint-react/eslint": "5.17.1", "@eslint-react/jsx": "5.17.1", "@eslint-react/shared": "5.17.1", "@eslint-react/var": "5.17.1", "@typescript-eslint/scope-manager": "^8.64.0", "@typescript-eslint/types": "^8.64.0", "@typescript-eslint/utils": "^8.64.0", "ts-pattern": "^5.9.0" }, "peerDependencies": { "eslint": "*", "typescript": "*" } }, "sha512-bf2XjVvqxiKF0B1h6csLWiKG5dQvDgltki6voRSfK5oGMyiwYD27ODczLAwVubggqTeZNOStQY+dZzfVE1ePCQ=="], - "@eslint-react/eff": ["@eslint-react/eff@2.13.0", "", {}, "sha512-rEH2R8FQnUAblUW+v3ZHDU1wEhatbL1+U2B1WVuBXwSKqzF7BGaLqCPIU7o9vofumz5MerVfaCtJgI8jYe2Btg=="], + "@eslint-react/eslint": ["@eslint-react/eslint@5.17.1", "", { "dependencies": { "@typescript-eslint/utils": "^8.64.0" }, "peerDependencies": { "eslint": "*", "typescript": "*" } }, "sha512-8HH62nFp1AoESCQaQUHtRvs3SBDn28NWIg818+c4AAFTCTkUYjLEqBrJHJxc/eSF4MduLCy06xnWMXE4J6LtDQ=="], - "@eslint-react/eslint-plugin": ["@eslint-react/eslint-plugin@2.13.0", "", { "dependencies": { "@eslint-react/eff": "2.13.0", "@eslint-react/shared": "2.13.0", "@typescript-eslint/scope-manager": "^8.55.0", "@typescript-eslint/type-utils": "^8.55.0", "@typescript-eslint/types": "^8.55.0", "@typescript-eslint/utils": "^8.55.0", "eslint-plugin-react-dom": "2.13.0", "eslint-plugin-react-hooks-extra": "2.13.0", "eslint-plugin-react-naming-convention": "2.13.0", "eslint-plugin-react-rsc": "2.13.0", "eslint-plugin-react-web-api": "2.13.0", "eslint-plugin-react-x": "2.13.0", "ts-api-utils": "^2.4.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-iaMXpqnJCTW7317hg8L4wx7u5aIiPzZ+d1p59X8wXFgMHzFX4hNu4IfV8oygyjmWKdLsjKE9sEpv/UYWczlb+A=="], + "@eslint-react/eslint-plugin": ["@eslint-react/eslint-plugin@5.17.1", "", { "dependencies": { "@eslint-react/shared": "5.17.1", "eslint-plugin-react-dom": "5.17.1", "eslint-plugin-react-jsx": "5.17.1", "eslint-plugin-react-naming-convention": "5.17.1", "eslint-plugin-react-rsc": "5.17.1", "eslint-plugin-react-web-api": "5.17.1", "eslint-plugin-react-x": "5.17.1" }, "peerDependencies": { "eslint": "*", "typescript": "*" } }, "sha512-wXd5WHjSbWlAUye+Y1P0KSf5xpuKTikLimZBXlRNlV2sgatSYnLgxyS7JfNJmD02gSMRMu8vJ7tgZlgBO9mVpA=="], - "@eslint-react/shared": ["@eslint-react/shared@2.13.0", "", { "dependencies": { "@eslint-react/eff": "2.13.0", "@typescript-eslint/utils": "^8.55.0", "ts-pattern": "^5.9.0", "zod": "^3.25.0 || ^4.0.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-IOloCqrZ7gGBT4lFf9+0/wn7TfzU7JBRjYwTSyb9SDngsbeRrtW95ZpgUpS8/jen1wUEm6F08duAooTZ2FtsWA=="], + "@eslint-react/jsx": ["@eslint-react/jsx@5.17.1", "", { "dependencies": { "@eslint-react/ast": "5.17.1", "@eslint-react/eslint": "5.17.1", "@eslint-react/shared": "5.17.1", "@eslint-react/var": "5.17.1", "@typescript-eslint/types": "^8.64.0", "@typescript-eslint/utils": "^8.64.0", "ts-pattern": "^5.9.0" }, "peerDependencies": { "eslint": "*", "typescript": "*" } }, "sha512-1uTcGS+yevc/RW7A25z+X8P9qq7HC8zYEO3lXHrVBruHyY8jhd7k+/iLQI3JpKlE/QPmPjxo+H/p0/FFyBU0bQ=="], - "@eslint-react/var": ["@eslint-react/var@2.13.0", "", { "dependencies": { "@eslint-react/ast": "2.13.0", "@eslint-react/eff": "2.13.0", "@eslint-react/shared": "2.13.0", "@typescript-eslint/scope-manager": "^8.55.0", "@typescript-eslint/types": "^8.55.0", "@typescript-eslint/utils": "^8.55.0", "ts-pattern": "^5.9.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-dM+QaeiHR16qPQoJYg205MkdHYSWVa2B7ore5OFpOPlSwqDV3tLW7I+475WjbK7potq5QNPTxRa7VLp9FGeQqA=="], - - "@eslint/compat": ["@eslint/compat@2.1.0", "", { "dependencies": { "@eslint/core": "^1.2.1" }, "peerDependencies": { "eslint": "^8.40 || 9 || 10" }, "optionalPeers": ["eslint"] }, "sha512-LgaSCymEpw7tF53xvDw9SNsraPb1IBHxpdABIOM0hW8UAlP8znrjYtuxfR58FSJ3L9BhwD+FaPRFQpZq84Nh6g=="], + "@eslint-react/shared": ["@eslint-react/shared@5.17.1", "", { "dependencies": { "@eslint-react/eslint": "5.17.1", "@typescript-eslint/utils": "^8.64.0", "ts-pattern": "^5.9.0", "zod": "^3.25.0 || ^4.0.0" }, "peerDependencies": { "eslint": "*", "typescript": "*" } }, "sha512-3210sOtv7b18qVo0QCCl+bmgb3r1pmeLkcF2JwqnTGH5jPNReWYX524xQqMdQqy7O73BBO5nPG0MnBMPdMHT/Q=="], - "@eslint/config-array": ["@eslint/config-array@0.21.2", "", { "dependencies": { "@eslint/object-schema": "^2.1.7", "debug": "^4.3.1", "minimatch": "^3.1.5" } }, "sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw=="], + "@eslint-react/var": ["@eslint-react/var@5.17.1", "", { "dependencies": { "@eslint-react/ast": "5.17.1", "@eslint-react/eslint": "5.17.1", "@typescript-eslint/scope-manager": "^8.64.0", "@typescript-eslint/types": "^8.64.0", "@typescript-eslint/utils": "^8.64.0", "ts-pattern": "^5.9.0" }, "peerDependencies": { "eslint": "*", "typescript": "*" } }, "sha512-UPfhOHUHGecm7QFc2KLf+XoW7NOgR6A2me9SGvo5DRu4GZAbJ1bvn3/3h+10sCK5MS5pS16m9hilZLfQfYdE4w=="], - "@eslint/config-helpers": ["@eslint/config-helpers@0.4.2", "", { "dependencies": { "@eslint/core": "^0.17.0" } }, "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw=="], + "@eslint/compat": ["@eslint/compat@2.1.0", "", { "dependencies": { "@eslint/core": "^1.2.1" }, "peerDependencies": { "eslint": "^8.40 || 9 || 10" }, "optionalPeers": ["eslint"] }, "sha512-LgaSCymEpw7tF53xvDw9SNsraPb1IBHxpdABIOM0hW8UAlP8znrjYtuxfR58FSJ3L9BhwD+FaPRFQpZq84Nh6g=="], - "@eslint/core": ["@eslint/core@0.17.0", "", { "dependencies": { "@types/json-schema": "^7.0.15" } }, "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ=="], + "@eslint/config-array": ["@eslint/config-array@0.23.5", "", { "dependencies": { "@eslint/object-schema": "^3.0.5", "debug": "^4.3.1", "minimatch": "^10.2.4" } }, "sha512-Y3kKLvC1dvTOT+oGlqNQ1XLqK6D1HU2YXPc52NmAlJZbMMWDzGYXMiPRJ8TYD39muD/OTjlZmNJ4ib7dvSrMBA=="], - "@eslint/eslintrc": ["@eslint/eslintrc@3.3.6", "", { "dependencies": { "ajv": "^6.14.0", "debug": "^4.3.2", "espree": "^10.0.1", "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.3.0", "minimatch": "^3.1.5", "strip-json-comments": "^3.1.1" } }, "sha512-l2Ul9PrHsPCKcEY/ac7VgFj9D80C7S68sOKc618SyHDPK36s1XcFebXY0iTzUVn4Yq+YbwvSnDmCz9yxjX+QrA=="], + "@eslint/config-helpers": ["@eslint/config-helpers@0.6.0", "", { "dependencies": { "@eslint/core": "^1.2.1" } }, "sha512-ii6Bw9jJ2zi2cWA2Z+9/QZ/+3DX6kwaV5Q986D/CdP3Lap3w/pgQZ373FV7byY/i7L4IRH/G43I5dz1ClsCbpA=="], - "@eslint/js": ["@eslint/js@9.39.5", "", {}, "sha512-QywQuszQh77pIXCsq998c8hbhSTI/azTty1Z6N53dmAudKHhy573j3yvRLsX2BSp8YpLtoCEG8E9DJe+8zUh4A=="], + "@eslint/core": ["@eslint/core@1.2.1", "", { "dependencies": { "@types/json-schema": "^7.0.15" } }, "sha512-MwcE1P+AZ4C6DWlpin/OmOA54mmIZ/+xZuJiQd4SyB29oAJjN30UW9wkKNptW2ctp4cEsvhlLY/CsQ1uoHDloQ=="], - "@eslint/markdown": ["@eslint/markdown@7.5.1", "", { "dependencies": { "@eslint/core": "^0.17.0", "@eslint/plugin-kit": "^0.4.1", "github-slugger": "^2.0.0", "mdast-util-from-markdown": "^2.0.2", "mdast-util-frontmatter": "^2.0.1", "mdast-util-gfm": "^3.1.0", "micromark-extension-frontmatter": "^2.0.0", "micromark-extension-gfm": "^3.0.0", "micromark-util-normalize-identifier": "^2.0.1" } }, "sha512-R8uZemG9dKTbru/DQRPblbJyXpObwKzo8rv1KYGGuPUPtjM4LXBYM9q5CIZAComzZupws3tWbDwam5AFpPLyJQ=="], + "@eslint/markdown": ["@eslint/markdown@8.0.3", "", { "dependencies": { "@eslint/core": "^1.2.1", "@eslint/plugin-kit": "^0.7.2", "github-slugger": "^2.0.0", "mdast-util-from-markdown": "^2.0.2", "mdast-util-frontmatter": "^2.0.1", "mdast-util-gfm": "^3.1.0", "mdast-util-math": "^3.0.0", "micromark-extension-frontmatter": "^2.0.0", "micromark-extension-gfm": "^3.0.0", "micromark-extension-math": "^3.1.0", "micromark-util-normalize-identifier": "^2.0.1" } }, "sha512-rBTSSShrq7e4O+PWfeE4azH4/CWPNrC+VGxBXiW00o3vYVJnznsZiDayj3KC9JztIMVRZxZHn2nrDIUau/4j7A=="], - "@eslint/object-schema": ["@eslint/object-schema@2.1.7", "", {}, "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA=="], + "@eslint/object-schema": ["@eslint/object-schema@3.0.5", "", {}, "sha512-vqTaUEgxzm+YDSdElad6PiRoX4t8VGDjCtt05zn4nU810UIx/uNEV7/lZJ6KwFThKZOzOxzXy48da+No7HZaMw=="], - "@eslint/plugin-kit": ["@eslint/plugin-kit@0.4.1", "", { "dependencies": { "@eslint/core": "^0.17.0", "levn": "^0.4.1" } }, "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA=="], + "@eslint/plugin-kit": ["@eslint/plugin-kit@0.7.2", "", { "dependencies": { "@eslint/core": "^1.2.1", "levn": "^0.4.1" } }, "sha512-+CNAzxglkrpNf/kKywqQfk74QjtceuOE7Qm+AF8miRvPF/wmmK5+OJOgVh3AVTT3RP2mH3+FOaxlE5v72owk0A=="], "@faceless-ui/modal": ["@faceless-ui/modal@3.0.0", "", { "dependencies": { "body-scroll-lock": "4.0.0-beta.0", "focus-trap": "7.5.4", "react-transition-group": "4.4.5" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-o3oEFsot99EQ8RJc1kL3s/nNMHX+y+WMXVzSSmca9L0l2MR6ez2QM1z1yIelJX93jqkLXQ9tW+R9tmsYa+O4Qg=="], @@ -297,85 +297,89 @@ "@img/colour": ["@img/colour@1.1.0", "", {}, "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ=="], - "@img/sharp-darwin-arm64": ["@img/sharp-darwin-arm64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-arm64": "1.2.4" }, "os": "darwin", "cpu": "arm64" }, "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w=="], + "@img/sharp-darwin-arm64": ["@img/sharp-darwin-arm64@0.35.3", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-arm64": "1.3.2" }, "os": "darwin", "cpu": "arm64" }, "sha512-RMnFX7YQsMoh7lWfcM4NEHHymBX/rLuKNPVM84XE9ONPcaSCDgE7CHIHpSgPcO2xcRthgBy1HfNO319mwhIAkg=="], + + "@img/sharp-darwin-x64": ["@img/sharp-darwin-x64@0.35.3", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-x64": "1.3.2" }, "os": "darwin", "cpu": "x64" }, "sha512-Xo+5uFBtLN0BKqieTxiFzFPQAUlBbbH5iBKyRX/z1JrbnYsHTfKJnUfL8+p2TPXr1pXqao4eeL4Rl144uDpK9w=="], - "@img/sharp-darwin-x64": ["@img/sharp-darwin-x64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-x64": "1.2.4" }, "os": "darwin", "cpu": "x64" }, "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw=="], + "@img/sharp-freebsd-wasm32": ["@img/sharp-freebsd-wasm32@0.35.3", "", { "dependencies": { "@img/sharp-wasm32": "0.35.3" }, "os": "freebsd" }, "sha512-lUxcqWIj2wMQ9BrwNjngcr1gWUr5xgaGThBRqPPalIC2n67Cqj1uPh8NnA/ZhAg8hUbKl+kVHKwgUIwe6ZYPrg=="], - "@img/sharp-libvips-darwin-arm64": ["@img/sharp-libvips-darwin-arm64@1.2.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g=="], + "@img/sharp-libvips-darwin-arm64": ["@img/sharp-libvips-darwin-arm64@1.3.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-9J6ypZFpQBj4YnePGoq/S38w6nz+vqg5WZLrLGY4YuSemdMq47GMLBPO42MzwdGwpg/agZ7xzZcFHa48xlywfg=="], - "@img/sharp-libvips-darwin-x64": ["@img/sharp-libvips-darwin-x64@1.2.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg=="], + "@img/sharp-libvips-darwin-x64": ["@img/sharp-libvips-darwin-x64@1.3.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-m2pW1n6cns9VaubNwsZ+c3CRYjxNQWgJ5gPlnL1nbBcpkBvFm6SCFN5o0psFHI8w9n11NKhFkeEDns98tiqbEw=="], - "@img/sharp-libvips-linux-arm": ["@img/sharp-libvips-linux-arm@1.2.4", "", { "os": "linux", "cpu": "arm" }, "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A=="], + "@img/sharp-libvips-linux-arm": ["@img/sharp-libvips-linux-arm@1.3.2", "", { "os": "linux", "cpu": "arm" }, "sha512-1eMLzy92I4J6rmi4mAT8yC3HxOtniyGELlzGbNMLLeqe052ahFQ0h6LFq+lh5DsDIdYViIDst08abvSbcEdLXQ=="], - "@img/sharp-libvips-linux-arm64": ["@img/sharp-libvips-linux-arm64@1.2.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw=="], + "@img/sharp-libvips-linux-arm64": ["@img/sharp-libvips-linux-arm64@1.3.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-dqVSFynCox4C/J8kT16V7SIFAns0IjgLwkvYT7p8LQVmJ5OS5b6tI9IGflxTeuBS//zXeFIUbwt5dwxyZ17cnA=="], - "@img/sharp-libvips-linux-ppc64": ["@img/sharp-libvips-linux-ppc64@1.2.4", "", { "os": "linux", "cpu": "ppc64" }, "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA=="], + "@img/sharp-libvips-linux-ppc64": ["@img/sharp-libvips-linux-ppc64@1.3.2", "", { "os": "linux", "cpu": "ppc64" }, "sha512-3z0NHDxD6n5I9gc05U1eW1AyRm+Gznzq3naMrthPNqE6oYykcogW0l/jfpJdjYnuNl8R7yI9pNbE1XiUeyq0Aw=="], - "@img/sharp-libvips-linux-riscv64": ["@img/sharp-libvips-linux-riscv64@1.2.4", "", { "os": "linux", "cpu": "none" }, "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA=="], + "@img/sharp-libvips-linux-riscv64": ["@img/sharp-libvips-linux-riscv64@1.3.2", "", { "os": "linux", "cpu": "none" }, "sha512-bsb4rI+NldGOsXuej2r8OdSS8+zXDVaCWxyWrcv6kneTOlgAHtZABRzBBCwdsPiD90J4myNJuHpg6kA20ImW/w=="], - "@img/sharp-libvips-linux-s390x": ["@img/sharp-libvips-linux-s390x@1.2.4", "", { "os": "linux", "cpu": "s390x" }, "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ=="], + "@img/sharp-libvips-linux-s390x": ["@img/sharp-libvips-linux-s390x@1.3.2", "", { "os": "linux", "cpu": "s390x" }, "sha512-/ABshyj8gCpyIrNXnHn4LorDJ0HHm1VhXPBlxZ8zAtfVPAaSafXPGn+sUSIRiwaSBy0mmFjSjiXI5mkcwdChKQ=="], - "@img/sharp-libvips-linux-x64": ["@img/sharp-libvips-linux-x64@1.2.4", "", { "os": "linux", "cpu": "x64" }, "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw=="], + "@img/sharp-libvips-linux-x64": ["@img/sharp-libvips-linux-x64@1.3.2", "", { "os": "linux", "cpu": "x64" }, "sha512-ITPEtgffGJ0S6G9dRyw/366tJQqFRcHWPHhC+Stpg3Z8AEMrDrTr2lhdz4f/Y/HMbRh//7Z5mBzEpVdi62Oc3w=="], - "@img/sharp-libvips-linuxmusl-arm64": ["@img/sharp-libvips-linuxmusl-arm64@1.2.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw=="], + "@img/sharp-libvips-linuxmusl-arm64": ["@img/sharp-libvips-linuxmusl-arm64@1.3.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-zE9EdiUzUmg5mDT5a1rk5fYJ6GWPloTwWBYDS14naqHsL+EaMpDj1AWnpLgh3u0YCORv2Tt50wrcrpYqkP97Kw=="], - "@img/sharp-libvips-linuxmusl-x64": ["@img/sharp-libvips-linuxmusl-x64@1.2.4", "", { "os": "linux", "cpu": "x64" }, "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg=="], + "@img/sharp-libvips-linuxmusl-x64": ["@img/sharp-libvips-linuxmusl-x64@1.3.2", "", { "os": "linux", "cpu": "x64" }, "sha512-m0lrLiUt+lBYnCFr8qV/65yMR4E/c7/wf78I5eKTdkEakFAlZ9QlzEM3QIhhAwVeUhLAHLcCq7a7Vszq/oFNZQ=="], - "@img/sharp-linux-arm": ["@img/sharp-linux-arm@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm": "1.2.4" }, "os": "linux", "cpu": "arm" }, "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw=="], + "@img/sharp-linux-arm": ["@img/sharp-linux-arm@0.35.3", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm": "1.3.2" }, "os": "linux", "cpu": "arm" }, "sha512-affVWCTLooy8TSxbDx2qkzuDeaWLNVBA+P//FNBirHsXpP2fuBhk5AuboYUnrDnzoXes8GFjpTx0SBFOCRg+FA=="], - "@img/sharp-linux-arm64": ["@img/sharp-linux-arm64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm64": "1.2.4" }, "os": "linux", "cpu": "arm64" }, "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg=="], + "@img/sharp-linux-arm64": ["@img/sharp-linux-arm64@0.35.3", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm64": "1.3.2" }, "os": "linux", "cpu": "arm64" }, "sha512-QgKDspHPnrU+GQ55XPhGwyhC8acLVOOSyAvo1oVfFmrIXLkDNmGWzAfDZ4xK8oSA1qBQrALcHX0G5UZni/SuFQ=="], - "@img/sharp-linux-ppc64": ["@img/sharp-linux-ppc64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-ppc64": "1.2.4" }, "os": "linux", "cpu": "ppc64" }, "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA=="], + "@img/sharp-linux-ppc64": ["@img/sharp-linux-ppc64@0.35.3", "", { "optionalDependencies": { "@img/sharp-libvips-linux-ppc64": "1.3.2" }, "os": "linux", "cpu": "ppc64" }, "sha512-sMd8rDxmpLOwv/7N44klFjOD5DUO7FLdjiXDI0hoxYaf7Ar262dQIEkosE98bps+5HPLtp/EvNqeqQtOycP/IA=="], - "@img/sharp-linux-riscv64": ["@img/sharp-linux-riscv64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-riscv64": "1.2.4" }, "os": "linux", "cpu": "none" }, "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw=="], + "@img/sharp-linux-riscv64": ["@img/sharp-linux-riscv64@0.35.3", "", { "optionalDependencies": { "@img/sharp-libvips-linux-riscv64": "1.3.2" }, "os": "linux", "cpu": "none" }, "sha512-0Eob78yjlYPfL5vMNWAW55l3R9Y6BQS/gOfe0ZcP9mEz9ohhKSt4im1hayiknXgf8AWrFqMvJcKIdmLmEe7yeQ=="], - "@img/sharp-linux-s390x": ["@img/sharp-linux-s390x@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-s390x": "1.2.4" }, "os": "linux", "cpu": "s390x" }, "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg=="], + "@img/sharp-linux-s390x": ["@img/sharp-linux-s390x@0.35.3", "", { "optionalDependencies": { "@img/sharp-libvips-linux-s390x": "1.3.2" }, "os": "linux", "cpu": "s390x" }, "sha512-KgAxQ0DxpNOq1rG2t5cgTgShJFGSuU7XO45cqC+1NVOuZnP6tlgZRuSYOfNupGkHID0o3cJOsw4DVeJpMovcGw=="], - "@img/sharp-linux-x64": ["@img/sharp-linux-x64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-x64": "1.2.4" }, "os": "linux", "cpu": "x64" }, "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ=="], + "@img/sharp-linux-x64": ["@img/sharp-linux-x64@0.35.3", "", { "optionalDependencies": { "@img/sharp-libvips-linux-x64": "1.3.2" }, "os": "linux", "cpu": "x64" }, "sha512-8pqvxubL2PGdhlPy6GLqzDYMUjyRmKAwKHYKixpdJYBUK7PJ0C029XdsnpFIdgRZG68fZiGdHVWcKPvtiPB4cA=="], - "@img/sharp-linuxmusl-arm64": ["@img/sharp-linuxmusl-arm64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-arm64": "1.2.4" }, "os": "linux", "cpu": "arm64" }, "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg=="], + "@img/sharp-linuxmusl-arm64": ["@img/sharp-linuxmusl-arm64@0.35.3", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-arm64": "1.3.2" }, "os": "linux", "cpu": "arm64" }, "sha512-Vz0iQjzzcSX3HCbfwFfCSG/9SCIqyO0mH2sXyiHaAYfBk0cRsCWXRyQYX0ovCK/PAQBbTzQ0dsPQHh5MAFL59w=="], - "@img/sharp-linuxmusl-x64": ["@img/sharp-linuxmusl-x64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-x64": "1.2.4" }, "os": "linux", "cpu": "x64" }, "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q=="], + "@img/sharp-linuxmusl-x64": ["@img/sharp-linuxmusl-x64@0.35.3", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-x64": "1.3.2" }, "os": "linux", "cpu": "x64" }, "sha512-6O1NPKcDVj9QEdg7Hx549EX8U0rp6yXQERqru6yRN7fGBn32UvIRJUlWnk+8xDCiG76hXVBbX82NZ/ZKr0euIg=="], "@img/sharp-wasm32": ["@img/sharp-wasm32@0.34.5", "", { "dependencies": { "@emnapi/runtime": "^1.7.0" }, "cpu": "none" }, "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw=="], - "@img/sharp-win32-arm64": ["@img/sharp-win32-arm64@0.34.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g=="], + "@img/sharp-webcontainers-wasm32": ["@img/sharp-webcontainers-wasm32@0.35.3", "", { "dependencies": { "@img/sharp-wasm32": "0.35.3" }, "cpu": "none" }, "sha512-2rnq7bX3NzeR2T4YWgz8qiG4h3TSdMe+vN1iQXpJleSJ3SM5zQ8Fy2SyyXAWlbxpEZ2Y+Z4u1BePgJEYbSy80Q=="], - "@img/sharp-win32-ia32": ["@img/sharp-win32-ia32@0.34.5", "", { "os": "win32", "cpu": "ia32" }, "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg=="], + "@img/sharp-win32-arm64": ["@img/sharp-win32-arm64@0.35.3", "", { "os": "win32", "cpu": "arm64" }, "sha512-4bPwFdMbeC4JQ8L8LOyWp6nsHcboP5fxkp6iPOXz2Vg49R42TuMs2whkJ5OAP4/Ul035qOzy0AecOF9VOscn4w=="], - "@img/sharp-win32-x64": ["@img/sharp-win32-x64@0.34.5", "", { "os": "win32", "cpu": "x64" }, "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw=="], + "@img/sharp-win32-ia32": ["@img/sharp-win32-ia32@0.35.3", "", { "os": "win32", "cpu": "ia32" }, "sha512-r53mXsBN6lFUDiST764SvgwUdHAqM4rPAiDzAmf4fLoB6X/rkfyTrLCg6+g17wJJiCmB3JYgHuUldCWUIRFSXw=="], - "@inquirer/ansi": ["@inquirer/ansi@1.0.2", "", {}, "sha512-S8qNSZiYzFd0wAcyG5AXCvUHC5Sr7xpZ9wZ2py9XR88jUz8wooStVx5M6dRzczbBWjic9NP7+rY0Xi7qqK/aMQ=="], + "@img/sharp-win32-x64": ["@img/sharp-win32-x64@0.35.3", "", { "os": "win32", "cpu": "x64" }, "sha512-D4y1vNeZrIIJCN+uHaWVtH86B+aCrdMYYjicy9pXHvbGZeGYLLSd3wdVuC37FxVXlU1ARsk84eKWfWMXGYEqvA=="], - "@inquirer/checkbox": ["@inquirer/checkbox@4.3.2", "", { "dependencies": { "@inquirer/ansi": "^1.0.2", "@inquirer/core": "^10.3.2", "@inquirer/figures": "^1.0.15", "@inquirer/type": "^3.0.10", "yoctocolors-cjs": "^2.1.3" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-VXukHf0RR1doGe6Sm4F0Em7SWYLTHSsbGfJdS9Ja2bX5/D5uwVOEjr07cncLROdBvmnvCATYEWlHqYmXv2IlQA=="], + "@inquirer/ansi": ["@inquirer/ansi@2.0.7", "", {}, "sha512-3eTuUO1vH2cZm2ZKHeQxnOqlTi9EfZDGgIe3BL3I4u+rJHocr9Fz86M4fjYABPvFnQG/gGK551HqDiIcETwU6Q=="], - "@inquirer/confirm": ["@inquirer/confirm@5.1.21", "", { "dependencies": { "@inquirer/core": "^10.3.2", "@inquirer/type": "^3.0.10" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-KR8edRkIsUayMXV+o3Gv+q4jlhENF9nMYUZs9PA2HzrXeHI8M5uDag70U7RJn9yyiMZSbtF5/UexBtAVtZGSbQ=="], + "@inquirer/checkbox": ["@inquirer/checkbox@5.2.1", "", { "dependencies": { "@inquirer/ansi": "^2.0.7", "@inquirer/core": "^11.2.1", "@inquirer/figures": "^2.0.7", "@inquirer/type": "^4.0.7" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-b6xmA/VlTe0ZgDQHDui+Nav470u7u49nRd8/iuhOcQPO9Ch7lGuogydhi2VOmNlZ+zXcM8IcPuNSwQcdJaF/kw=="], - "@inquirer/core": ["@inquirer/core@10.3.2", "", { "dependencies": { "@inquirer/ansi": "^1.0.2", "@inquirer/figures": "^1.0.15", "@inquirer/type": "^3.0.10", "cli-width": "^4.1.0", "mute-stream": "^2.0.0", "signal-exit": "^4.1.0", "wrap-ansi": "^6.2.0", "yoctocolors-cjs": "^2.1.3" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-43RTuEbfP8MbKzedNqBrlhhNKVwoK//vUFNW3Q3vZ88BLcrs4kYpGg+B2mm5p2K/HfygoCxuKwJJiv8PbGmE0A=="], + "@inquirer/confirm": ["@inquirer/confirm@6.1.1", "", { "dependencies": { "@inquirer/core": "^11.2.1", "@inquirer/type": "^4.0.7" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-eb8DBZcz/2qHWQda4rk2JiQk5h9QV/cVHi1yjt0f69WFZMRFn0sJTye3EAP8icut8UDMjQPsaH5KbcOogefrFQ=="], - "@inquirer/editor": ["@inquirer/editor@4.2.23", "", { "dependencies": { "@inquirer/core": "^10.3.2", "@inquirer/external-editor": "^1.0.3", "@inquirer/type": "^3.0.10" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-aLSROkEwirotxZ1pBaP8tugXRFCxW94gwrQLxXfrZsKkfjOYC1aRvAZuhpJOb5cu4IBTJdsCigUlf2iCOu4ZDQ=="], + "@inquirer/core": ["@inquirer/core@11.2.1", "", { "dependencies": { "@inquirer/ansi": "^2.0.7", "@inquirer/figures": "^2.0.7", "@inquirer/type": "^4.0.7", "cli-width": "^4.1.0", "fast-wrap-ansi": "^0.2.0", "mute-stream": "^3.0.0", "signal-exit": "^4.1.0" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-Qd6GJT1yVyrZZCfN8W2qKF5ApmqryXRhRKCuip8h01x2w/esJQ2XIYc6f9abMIHgKQdBfFTSOdbHRLAhuM09UA=="], - "@inquirer/expand": ["@inquirer/expand@4.0.23", "", { "dependencies": { "@inquirer/core": "^10.3.2", "@inquirer/type": "^3.0.10", "yoctocolors-cjs": "^2.1.3" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-nRzdOyFYnpeYTTR2qFwEVmIWypzdAx/sIkCMeTNTcflFOovfqUk+HcFhQQVBftAh9gmGrpFj6QcGEqrDMDOiew=="], + "@inquirer/editor": ["@inquirer/editor@5.2.2", "", { "dependencies": { "@inquirer/core": "^11.2.1", "@inquirer/external-editor": "^3.0.3", "@inquirer/type": "^4.0.7" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-ZRVd/oD+sYsUd5zVm0NflqEzlqfYCyHNsqkHl2oWXEUHs12tCbcSFi+wVFEvD8+LGRaMUsVrE7qeo6lSG/S1Vg=="], - "@inquirer/external-editor": ["@inquirer/external-editor@1.0.3", "", { "dependencies": { "chardet": "^2.1.1", "iconv-lite": "^0.7.0" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA=="], + "@inquirer/expand": ["@inquirer/expand@5.1.1", "", { "dependencies": { "@inquirer/core": "^11.2.1", "@inquirer/type": "^4.0.7" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-YmQpenjbFSHAK3sOd44puHh3V1KXXr+JiNpUztoSQ4drLh2rTVzTap/YtlAVu/5xavifIlBfNEzJ/neZJ1a/1g=="], - "@inquirer/figures": ["@inquirer/figures@1.0.15", "", {}, "sha512-t2IEY+unGHOzAaVM5Xx6DEWKeXlDDcNPeDyUpsRc6CUhBfU3VQOEl+Vssh7VNp1dR8MdUJBWhuObjXCsVpjN5g=="], + "@inquirer/external-editor": ["@inquirer/external-editor@3.0.3", "", { "dependencies": { "chardet": "^2.1.1", "iconv-lite": "^0.7.2" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-6thf5I8q7lZwzGLAxPaaGEREEkZ3nyePPDQ1oyobblxmEE8mqTLguScP7pDjUTAibiyb4hfXl+qjUEJ+di/aNA=="], - "@inquirer/input": ["@inquirer/input@4.3.1", "", { "dependencies": { "@inquirer/core": "^10.3.2", "@inquirer/type": "^3.0.10" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-kN0pAM4yPrLjJ1XJBjDxyfDduXOuQHrBB8aLDMueuwUGn+vNpF7Gq7TvyVxx8u4SHlFFj4trmj+a2cbpG4Jn1g=="], + "@inquirer/figures": ["@inquirer/figures@2.0.7", "", {}, "sha512-aJ8TBPOGB6f/2qziPfElISTCEd5XOYTFckA2SGjhNmiKzfK/u4ot3v0DUzGVdUnKjN10EqnnEPck36BkyfLnJw=="], - "@inquirer/number": ["@inquirer/number@3.0.23", "", { "dependencies": { "@inquirer/core": "^10.3.2", "@inquirer/type": "^3.0.10" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-5Smv0OK7K0KUzUfYUXDXQc9jrf8OHo4ktlEayFlelCjwMXz0299Y8OrI+lj7i4gCBY15UObk76q0QtxjzFcFcg=="], + "@inquirer/input": ["@inquirer/input@5.1.2", "", { "dependencies": { "@inquirer/core": "^11.2.1", "@inquirer/type": "^4.0.7" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-9K/DDBSQpOyZSkt6sOVP9Vo0TR7atX2kuILsUu0x3wVcVbe97lJwIJKMLdMw25tDYuXl/qp6erT0Xs1rfmcfZg=="], - "@inquirer/password": ["@inquirer/password@4.0.23", "", { "dependencies": { "@inquirer/ansi": "^1.0.2", "@inquirer/core": "^10.3.2", "@inquirer/type": "^3.0.10" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-zREJHjhT5vJBMZX/IUbyI9zVtVfOLiTO66MrF/3GFZYZ7T4YILW5MSkEYHceSii/KtRk+4i3RE7E1CUXA2jHcA=="], + "@inquirer/number": ["@inquirer/number@4.1.1", "", { "dependencies": { "@inquirer/core": "^11.2.1", "@inquirer/type": "^4.0.7" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-XF4IXAbPnGPgw0wsbC/i2tPcyfdZgDpUlhsqU0SfT4IRIGWha6Xm9VRgN5yYxJq+jnyXlfXI/nQ3ulfk0iEICA=="], - "@inquirer/prompts": ["@inquirer/prompts@7.10.1", "", { "dependencies": { "@inquirer/checkbox": "^4.3.2", "@inquirer/confirm": "^5.1.21", "@inquirer/editor": "^4.2.23", "@inquirer/expand": "^4.0.23", "@inquirer/input": "^4.3.1", "@inquirer/number": "^3.0.23", "@inquirer/password": "^4.0.23", "@inquirer/rawlist": "^4.1.11", "@inquirer/search": "^3.2.2", "@inquirer/select": "^4.4.2" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-Dx/y9bCQcXLI5ooQ5KyvA4FTgeo2jYj/7plWfV5Ak5wDPKQZgudKez2ixyfz7tKXzcJciTxqLeK7R9HItwiByg=="], + "@inquirer/password": ["@inquirer/password@5.1.1", "", { "dependencies": { "@inquirer/ansi": "^2.0.7", "@inquirer/core": "^11.2.1", "@inquirer/type": "^4.0.7" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-3XBfF7DAsp5qeDsvN5Rd1HmbNokVvEQoUM0QLrRcybC9nX96w3Pbmu7qUsb3IT3J3jBvs2+mTXaKHOUsgHMLzg=="], - "@inquirer/rawlist": ["@inquirer/rawlist@4.1.11", "", { "dependencies": { "@inquirer/core": "^10.3.2", "@inquirer/type": "^3.0.10", "yoctocolors-cjs": "^2.1.3" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-+LLQB8XGr3I5LZN/GuAHo+GpDJegQwuPARLChlMICNdwW7OwV2izlCSCxN6cqpL0sMXmbKbFcItJgdQq5EBXTw=="], + "@inquirer/prompts": ["@inquirer/prompts@8.4.2", "", { "dependencies": { "@inquirer/checkbox": "^5.1.4", "@inquirer/confirm": "^6.0.12", "@inquirer/editor": "^5.1.1", "@inquirer/expand": "^5.0.13", "@inquirer/input": "^5.0.12", "@inquirer/number": "^4.0.12", "@inquirer/password": "^5.0.12", "@inquirer/rawlist": "^5.2.8", "@inquirer/search": "^4.1.8", "@inquirer/select": "^5.1.4" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-XJmn/wY4AX56l1BRU+ZjDrFtg9+2uBEi4JvJQj82kwJDQKiPgSn4CEsbfGGygS4Gw6rkL4W18oATjfVfaqub2Q=="], - "@inquirer/search": ["@inquirer/search@3.2.2", "", { "dependencies": { "@inquirer/core": "^10.3.2", "@inquirer/figures": "^1.0.15", "@inquirer/type": "^3.0.10", "yoctocolors-cjs": "^2.1.3" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-p2bvRfENXCZdWF/U2BXvnSI9h+tuA8iNqtUKb9UWbmLYCRQxd8WkvwWvYn+3NgYaNwdUkHytJMGG4MMLucI1kA=="], + "@inquirer/rawlist": ["@inquirer/rawlist@5.3.1", "", { "dependencies": { "@inquirer/core": "^11.2.1", "@inquirer/type": "^4.0.7" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-QqdTqQddL3qPX/PPrjobpsO25NZ4dWXgTLenrR445L2ptLEYE6Z+PD5c5CNDJNx4ugRgELAIpSIJxZaO2jJ2Og=="], - "@inquirer/select": ["@inquirer/select@4.4.2", "", { "dependencies": { "@inquirer/ansi": "^1.0.2", "@inquirer/core": "^10.3.2", "@inquirer/figures": "^1.0.15", "@inquirer/type": "^3.0.10", "yoctocolors-cjs": "^2.1.3" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-l4xMuJo55MAe+N7Qr4rX90vypFwCajSakx59qe/tMaC1aEHWLyw68wF4o0A4SLAY4E0nd+Vt+EyskeDIqu1M6w=="], + "@inquirer/search": ["@inquirer/search@4.2.1", "", { "dependencies": { "@inquirer/core": "^11.2.1", "@inquirer/figures": "^2.0.7", "@inquirer/type": "^4.0.7" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-xJj8QWKRSrfKoBIITLZK61dD3zwo0Rz11fgDImku30/Oe81zMdIdGgrLY2h6RkJ+KZ/GhNYIRMKnH/62qBTA5g=="], - "@inquirer/type": ["@inquirer/type@3.0.10", "", { "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-BvziSRxfz5Ov8ch0z/n3oijRSEcEsHnhggm4xFZe93DHcUCTlutlq9Ox4SVENAfcRD22UQq7T/atg9Wr3k09eA=="], + "@inquirer/select": ["@inquirer/select@5.2.1", "", { "dependencies": { "@inquirer/ansi": "^2.0.7", "@inquirer/core": "^11.2.1", "@inquirer/figures": "^2.0.7", "@inquirer/type": "^4.0.7" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-FlDndEUww8m7BfukO2nJa25vhD+H5jxxCv4oGioKqzyWz3nPHhhw4LKdYRSlXuAx7DsdWia7iyaBPKKS95Evfw=="], + + "@inquirer/type": ["@inquirer/type@4.0.7", "", { "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-t28inv14nMQ1PhKpsJPY+kEs/c00qzeCOS2gTNRyTjG5d6qsVA2fItxW4hkvGZ5lvanGLdtCzVIx5dwdRpN1+g=="], "@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.13", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA=="], @@ -537,8 +541,6 @@ "@nodelib/fs.walk": ["@nodelib/fs.walk@1.2.8", "", { "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg=="], - "@nodeutils/defaults-deep": ["@nodeutils/defaults-deep@1.1.0", "", { "dependencies": { "lodash": "^4.15.0" } }, "sha512-gG44cwQovaOFdSR02jR9IhVRpnDP64VN6JdjYJTfNz4J4fWn7TQnmrf22nSjRqlwlxPcW8PL/L3KbJg3tdwvpg=="], - "@octokit/auth-token": ["@octokit/auth-token@6.0.0", "", {}, "sha512-P4YJBPdPSpWTQ1NU4XYdvHvXJJDxM6YwpS0FZHRgP7YFkdVxsWcpWGy/NVqlAA7PcPCnMacXlRm1y2PFZRWL/w=="], "@octokit/core": ["@octokit/core@7.0.6", "", { "dependencies": { "@octokit/auth-token": "^6.0.0", "@octokit/graphql": "^9.0.3", "@octokit/request": "^10.0.6", "@octokit/request-error": "^7.0.2", "@octokit/types": "^16.0.0", "before-after-hook": "^4.0.0", "universal-user-agent": "^7.0.0" } }, "sha512-DhGl4xMVFGVIyMwswXeyzdL4uXD5OGILGX5N8Y+f6W7LhC1Ze2poSNrkF/fedpVDHEEZ+PHFW0vL14I+mm8K3Q=="], @@ -625,7 +627,7 @@ "@preact/signals-core": ["@preact/signals-core@1.14.4", "", {}, "sha512-HNB6HYeYKhQbJ1aKl+YRjrS4+QWHLKX6qKoUsfS/m0vqzsVaEBiZiaKbG/e+NKk2ch5ALQr/ihWaMHxiCuuWHA=="], - "@release-it/conventional-changelog": ["@release-it/conventional-changelog@10.0.6", "", { "dependencies": { "@conventional-changelog/git-client": "^2.6.0", "concat-stream": "^2.0.0", "conventional-changelog": "^7.2.0", "conventional-changelog-angular": "^8.3.0", "conventional-changelog-conventionalcommits": "^9.3.0", "conventional-recommended-bump": "^11.2.0", "semver": "^7.7.4" }, "peerDependencies": { "release-it": "^18.0.0 || ^19.0.0" } }, "sha512-aUb0IkcsBTMcOH5PPQ9Jv9lEOOVu2+rSgkE1ny+dzsTziQm2BhDRAtaFK/dw/HflthuXMWrqhhyfJhAV1AOEPQ=="], + "@release-it/conventional-changelog": ["@release-it/conventional-changelog@11.0.1", "", { "dependencies": { "@conventional-changelog/git-client": "^2.7.0", "concat-stream": "^2.0.0", "conventional-changelog": "^7.2.0", "conventional-changelog-angular": "^8.3.1", "conventional-changelog-conventionalcommits": "^9.3.1", "conventional-recommended-bump": "^11.2.0", "semver": "^7.7.4" }, "peerDependencies": { "release-it": "^18.0.0 || ^19.0.0 || ^20.0.0" } }, "sha512-SHAnHfOFhazpDeYuQSqH8Qm8RJa2oREn2ILSod+9s8dqiA18mBgpPyYlpvRaqISCVerSmLzEZghQBKphkrf4IQ=="], "@rolldown/binding-android-arm64": ["@rolldown/binding-android-arm64@1.1.5", "", { "os": "android", "cpu": "arm64" }, "sha512-lZg8fqIv2v7FF237bwMgzGZEJvGL79/s5knJ/i6FmsGF4XXlzccZ4jb+TrFIxtSSxFtIpdsgrPZeMk1I9AFcyQ=="], @@ -679,7 +681,7 @@ "@swc-node/core": ["@swc-node/core@1.15.0", "", { "peerDependencies": { "@swc/core": ">= 1.13.3", "@swc/types": ">= 0.1" } }, "sha512-WAerrrl087WgenB92XG4Th2t0NQFfMNLYSe0sW2cEMMqM/LQmP4rozsDJl0vuzTrbewjpKQryxFXI+aYig/dBg=="], - "@swc-node/register": ["@swc-node/register@1.12.0", "", { "dependencies": { "@node-rs/xxhash": "^1.7.6", "@swc-node/core": "1.15.0", "@swc-node/sourcemap-support": "^0.6.1", "colorette": "^2.0.20", "debug": "^4.4.1", "json-stable-stringify": "^1.3.0", "oxc-resolver": "^11.6.1", "pirates": "^4.0.7", "tslib": "^2.8.1" }, "peerDependencies": { "@swc/core": ">= 1.4.13", "typescript": ">= 4.3 < 7" } }, "sha512-RnkF4NOHqv3JAKJS9YguLeFH81NPv8VQKTXt5lMJfOujB7qvZXJRei5LJeulihF0ZMD1UIruIA0gm9it/bH37g=="], + "@swc-node/register": ["@swc-node/register@1.12.1", "", { "dependencies": { "@node-rs/xxhash": "^1.7.6", "@swc-node/core": "1.15.0", "@swc-node/sourcemap-support": "^0.6.1", "colorette": "^2.0.20", "debug": "^4.4.1", "fast-json-stable-stringify": "^2.1.0", "oxc-resolver": "^11.6.1", "pirates": "^4.0.7", "tslib": "^2.8.1" }, "peerDependencies": { "@swc/core": ">= 1.4.13", "typescript": ">= 4.3 < 7" } }, "sha512-t6t+0bDos+bj0+jcSqKl7+ys/i1an5cEViC0LuIskJFSHONX871nXN8j+gxdKVOgCCpjs0buXUPNnp/0DaV4EQ=="], "@swc-node/sourcemap-support": ["@swc-node/sourcemap-support@0.6.1", "", { "dependencies": { "source-map-support": "^0.5.21", "tslib": "^2.8.1" } }, "sha512-ovltDVH5QpdHXZkW138vG4+dgcNsxfwxHVoV6BtmTbz2KKl1A8ZSlbdtxzzfNjCjbpayda8Us9eMtcHobm38dA=="], @@ -721,8 +723,6 @@ "@tokenizer/token": ["@tokenizer/token@0.3.0", "", {}, "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A=="], - "@tootallnate/quickjs-emscripten": ["@tootallnate/quickjs-emscripten@0.23.0", "", {}, "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA=="], - "@tybys/wasm-util": ["@tybys/wasm-util@0.10.3", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg=="], "@types/acorn": ["@types/acorn@4.0.6", "", { "dependencies": { "@types/estree": "*" } }, "sha512-veQTnWP+1D/xbxVrPC3zHnCZRjSrKfhbMUlEA43iMZLu7EsnTtkJklIuwrCPbOi8YkvDQAiW05VQQFvvz9oieQ=="], @@ -735,6 +735,8 @@ "@types/deep-eql": ["@types/deep-eql@4.0.2", "", {}, "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw=="], + "@types/esrecurse": ["@types/esrecurse@4.3.1", "", {}, "sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw=="], + "@types/estree": ["@types/estree@1.0.9", "", {}, "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg=="], "@types/estree-jsx": ["@types/estree-jsx@1.0.5", "", { "dependencies": { "@types/estree": "*" } }, "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg=="], @@ -745,13 +747,15 @@ "@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="], + "@types/katex": ["@types/katex@0.16.8", "", {}, "sha512-trgaNyfU+Xh2Tc+ABIb44a5AYUpicB3uwirOioeOkNPPbmgRNtcWyDeeFRzjPZENO9Vq8gvVqfhaaXWLlevVwg=="], + "@types/lodash": ["@types/lodash@4.17.24", "", {}, "sha512-gIW7lQLZbue7lRSWEFql49QJJWThrTFFeIMJdp3eH4tKoxm1OvEPg02rm4wCCSHS0cL3/Fizimb35b7k8atwsQ=="], "@types/mdast": ["@types/mdast@4.0.4", "", { "dependencies": { "@types/unist": "*" } }, "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA=="], "@types/ms": ["@types/ms@2.1.0", "", {}, "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA=="], - "@types/node": ["@types/node@25.9.5", "", { "dependencies": { "undici-types": ">=7.24.0 <7.24.7" } }, "sha512-OScDchr2fwuUmWdf4kZ9h7PcJiYDVInhJizG/biAq3cAvqwYktuy/TYGGdZNMtNTFUP7rnb0NU4TUdm82kt4Rg=="], + "@types/node": ["@types/node@26.1.1", "", { "dependencies": { "undici-types": "~8.3.0" } }, "sha512-nxAkRSVkN1Y0JC1W8ky/fTfkGsMmcrRsbx+3XoZE+rMOX71kLYTV7fLXpqud1GpbpP5TuffXFqfX7fH2GgZREw=="], "@types/normalize-package-data": ["@types/normalize-package-data@2.4.4", "", {}, "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA=="], @@ -863,13 +867,13 @@ "acorn-jsx": ["acorn-jsx@5.3.2", "", { "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ=="], - "agent-base": ["agent-base@7.1.4", "", {}, "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ=="], + "agent-base": ["agent-base@8.0.0", "", {}, "sha512-QT8i0hCz6C/KQ+KTAbSNwCHDGdmUJl2tp2ZpNlGSWCfhUNVbYG2WLE3MdZGBAgXPV4GAvjGMxo+C1hroyxmZEg=="], "ajv": ["ajv@6.15.0", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw=="], "ansi-regex": ["ansi-regex@6.2.2", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="], - "ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], + "ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="], "ansis": ["ansis@4.3.1", "", {}, "sha512-BJ8/l4R5LRE7hW9WdSuGYrLSHi2ynxeFpDFbH0K/CgNeY/tyhk+vO6TYxXC5r5CpUhNVX310xzPsN/H9lCdfOA=="], @@ -879,6 +883,8 @@ "argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="], + "argue-cli": ["argue-cli@3.1.0", "", {}, "sha512-DhBpBfXL4SS2uC0N922MMajKR3CdrTG0u2or1PNYgXMsrSzViJrbtvT0nCLlLGUI0plam/ZZCs7aAauHtW9thw=="], + "array-ify": ["array-ify@1.0.0", "", {}, "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng=="], "assertion-error": ["assertion-error@2.0.1", "", {}, "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA=="], @@ -949,12 +955,6 @@ "cacheable-request": ["cacheable-request@13.0.19", "", { "dependencies": { "@types/http-cache-semantics": "^4.2.0", "get-stream": "^9.0.1", "http-cache-semantics": "^4.2.0", "keyv": "^5.6.0", "mimic-response": "^4.0.0", "normalize-url": "^8.1.1", "responselike": "^4.0.2" } }, "sha512-SVXGH037+Mo1aIMO5B2UcleR43FGjFdN+M8JObSyEoQ2Mn4CODRWx28gN5jiTF0n5ItsgtIZfyargMNs8GX4kg=="], - "call-bind": ["call-bind@1.0.9", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", "get-intrinsic": "^1.3.0", "set-function-length": "^1.2.2" } }, "sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ=="], - - "call-bind-apply-helpers": ["call-bind-apply-helpers@1.0.2", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" } }, "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ=="], - - "call-bound": ["call-bound@1.0.4", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "get-intrinsic": "^1.3.0" } }, "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg=="], - "callsites": ["callsites@3.1.0", "", {}, "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="], "caniuse-lite": ["caniuse-lite@1.0.30001806", "", {}, "sha512-72Cuvd95zbSYPKq6Fhg8eDJRlzgWDf7/mtoZv6Qe/DYNCEBdNxoA3+rZAU2ZhGCpZlns3EssFavaZomckT5Uuw=="], @@ -963,7 +963,7 @@ "chai": ["chai@6.2.2", "", {}, "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg=="], - "chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="], + "chalk": ["chalk@5.6.2", "", {}, "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA=="], "change-case": ["change-case@5.4.4", "", {}, "sha512-HRQyTk2/YPEkt9TnUPbOpr64Uw3KOicFWPVBb+xiHvd6eBx/qPr9xqfBFDT8P2vWsvvz4jbEkfDe71W3VyNu2w=="], @@ -985,8 +985,6 @@ "citty": ["citty@0.1.6", "", { "dependencies": { "consola": "^3.2.3" } }, "sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ=="], - "clean-regexp": ["clean-regexp@1.0.0", "", { "dependencies": { "escape-string-regexp": "^1.0.5" } }, "sha512-GfisEZEJvzKrmGWkvfhgzcz/BllN1USeqD2V6tg14OAOgaCD2Z/PUEuxnAZ/nPvmaHRG7a8y77p1T/IRQ4D1Hw=="], - "cli-cursor": ["cli-cursor@5.0.0", "", { "dependencies": { "restore-cursor": "^5.0.0" } }, "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw=="], "cli-spinners": ["cli-spinners@3.4.0", "", {}, "sha512-bXfOC4QcT1tKXGorxL3wbJm6XJPDqEnij2gQ2m7ESQuE+/z9YFIWnl/5RpTiKWbMq3EVKR4fRLJGn6DVfu0mpw=="], @@ -995,7 +993,7 @@ "client-only": ["client-only@0.0.1", "", {}, "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA=="], - "cliui": ["cliui@8.0.1", "", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" } }, "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ=="], + "cliui": ["cliui@9.0.1", "", { "dependencies": { "string-width": "^7.2.0", "strip-ansi": "^7.1.0", "wrap-ansi": "^9.0.0" } }, "sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w=="], "clsx": ["clsx@2.1.1", "", {}, "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA=="], @@ -1007,7 +1005,7 @@ "commander": ["commander@8.3.0", "", {}, "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww=="], - "comment-parser": ["comment-parser@1.4.6", "", {}, "sha512-ObxuY6vnbWTN6Od72xfwN9DbzC7Y2vv8u1Soi9ahRKL37gb6y1qk6/dgjs+3JWuXJHWvsg3BXIwzd/rkmAwavg=="], + "comment-parser": ["comment-parser@1.4.7", "", {}, "sha512-0h+uSNtQGW3D98eQt3jJ8L06Fves8hncB4V/PKdw/Qb8Hnk19VaKuTr55UNRYiSoVa7WwrFls+rh3ux9agmkeQ=="], "compare-func": ["compare-func@2.0.0", "", { "dependencies": { "array-ify": "^1.0.0", "dot-prop": "^5.1.0" } }, "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA=="], @@ -1031,7 +1029,7 @@ "conventional-changelog-angular": ["conventional-changelog-angular@8.3.1", "", { "dependencies": { "compare-func": "^2.0.0" } }, "sha512-6gfI3otXK5Ph5DfCOI1dblr+kN3FAm5a97hYoQkqNZxOaYa5WKfXH+AnpsmS+iUH2mgVC2Cg2Qw9m5OKcmNrIg=="], - "conventional-changelog-conventionalcommits": ["conventional-changelog-conventionalcommits@8.0.0", "", { "dependencies": { "compare-func": "^2.0.0" } }, "sha512-eOvlTO6OcySPyyyk8pKz2dP4jjElYunj9hn9/s0OB+gapTO8zwS9UQWrZ1pmF2hFs3vw1xhonOLGcGjy/zgsuA=="], + "conventional-changelog-conventionalcommits": ["conventional-changelog-conventionalcommits@10.2.1", "", { "dependencies": { "@conventional-changelog/template": "^1.2.1" } }, "sha512-n4Kr1HFMTf3iMbES0TMxKIcYtUUv4rKqyQQp2JwfOEfFCOfGT3Tq4mCyJ8S9/YPyWhydjfKrrvnyl+gCjA+mJQ=="], "conventional-changelog-preset-loader": ["conventional-changelog-preset-loader@5.0.0", "", {}, "sha512-SetDSntXLk8Jh1NOAl1Gu5uLiCNSYenB5tm0YVeZKePRIgDW9lQImromTwLa3c/Gae298tsgOM+/CYT9XAl0NA=="], @@ -1039,7 +1037,7 @@ "conventional-commits-filter": ["conventional-commits-filter@5.0.0", "", {}, "sha512-tQMagCOC59EVgNZcC5zl7XqO30Wki9i9J3acbUvkaosCT6JX3EeFwJD7Qqp4MCikRnzS18WXV3BLIQ66ytu6+Q=="], - "conventional-commits-parser": ["conventional-commits-parser@6.4.0", "", { "dependencies": { "@simple-libs/stream-utils": "^1.2.0", "meow": "^13.0.0" }, "bin": { "conventional-commits-parser": "dist/cli/index.js" } }, "sha512-tvRg7FIBNlyPzjdG8wWRlPHQJJHI7DylhtRGeU9Lq+JuoPh5BKpPRX83ZdLrvXuOSu5Eo/e7SzOQhU4Hd2Miuw=="], + "conventional-commits-parser": ["conventional-commits-parser@7.1.0", "", { "dependencies": { "@simple-libs/stream-utils": "^2.0.0", "argue-cli": "^3.1.0" }, "bin": { "conventional-commits-parser": "./dist/cli/index.js" } }, "sha512-DPp6hkUjvwIivxbkrTiLXeRswNv1A/4GFA2X6scXma0AMa9632V3TwxmrlkUIEtUktiM3Ln+RrSH2xlP3/jUTw=="], "conventional-recommended-bump": ["conventional-recommended-bump@11.2.0", "", { "dependencies": { "@conventional-changelog/git-client": "^2.5.1", "conventional-changelog-preset-loader": "^5.0.0", "conventional-commits-filter": "^5.0.0", "conventional-commits-parser": "^6.1.0", "meow": "^13.0.0" }, "bin": { "conventional-recommended-bump": "dist/cli/index.js" } }, "sha512-lqIdmw330QdMBgfL0e6+6q5OMKyIpy4OZNmepit6FS3GldhkG+70drZjuZ0A5NFpze5j85dlYs3GabQXl6sMHw=="], @@ -1073,7 +1071,7 @@ "cz-git": ["cz-git@1.13.1", "", {}, "sha512-xeMA5ci+gkBY6uKmqc6nzhG/Q4pmK1DKbVVUgByOTBgregoiYE0f3otEF0ADelyEWH4vNsO1W2o7QZYEe7Nwlw=="], - "data-uri-to-buffer": ["data-uri-to-buffer@6.0.2", "", {}, "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw=="], + "data-uri-to-buffer": ["data-uri-to-buffer@7.0.0", "", {}, "sha512-CuRUx0TXGSbbWdEci3VK/XOZGP3n0P4pIKpsqpVtBqaIIuj3GKK8H45oAqA4Rg8FHipc+CzRdUzmD4YQXxv66Q=="], "dataloader": ["dataloader@2.2.3", "", {}, "sha512-y2krtASINtPFS1rSDjacrFgn1dcUuoREVabwlOGOe4SdxenREqwjwjElAdwvbGM7kgZz9a3KVicWR7vcz8rnzA=="], @@ -1095,18 +1093,18 @@ "default-browser-id": ["default-browser-id@5.0.1", "", {}, "sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q=="], - "define-data-property": ["define-data-property@1.1.4", "", { "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", "gopd": "^1.0.1" } }, "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A=="], - "define-lazy-prop": ["define-lazy-prop@3.0.0", "", {}, "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg=="], "defu": ["defu@6.1.7", "", {}, "sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ=="], - "degenerator": ["degenerator@5.0.1", "", { "dependencies": { "ast-types": "^0.13.4", "escodegen": "^2.1.0", "esprima": "^4.0.1" } }, "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ=="], + "degenerator": ["degenerator@6.0.0", "", { "dependencies": { "ast-types": "^0.13.4", "escodegen": "^2.1.0", "esprima": "^4.0.1" }, "peerDependencies": { "quickjs-wasi": "^0.0.1" } }, "sha512-j5MdXdefrecJeSqTpUrgZd4fBsD2IxZx0JlJD+n1Q7+aTf7/HcyXSfHsicPW6ekPurX159v1ZYla6OJgSPh2Dw=="], "dequal": ["dequal@2.0.3", "", {}, "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA=="], "destr": ["destr@2.0.5", "", {}, "sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA=="], + "detect-indent": ["detect-indent@7.0.2", "", {}, "sha512-y+8xyqdGLL+6sh0tVeHcfP/QDd8gUgbasolJJpY7NgeQGSZ739bDtSiaiDgtoicy+mtYB81dKLxO9xRhCyIB3A=="], + "detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="], "devlop": ["devlop@1.1.0", "", { "dependencies": { "dequal": "^2.0.0" } }, "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA=="], @@ -1121,11 +1119,9 @@ "dotenv": ["dotenv@17.4.2", "", {}, "sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw=="], - "dunder-proto": ["dunder-proto@1.0.1", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="], - "electron-to-chromium": ["electron-to-chromium@1.5.393", "", {}, "sha512-kiDJdIUawuEIcp9XoICKp1iTYDEbgguIPq526N1Q7jIQDeQ3CqoMx71025PI/7E48Ddtw2HuWsVjY7afEgNxmg=="], - "emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], + "emoji-regex": ["emoji-regex@10.6.0", "", {}, "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A=="], "empathic": ["empathic@2.0.1", "", {}, "sha512-YGRs8knHhKHVShLkFET/rWAU8kmHbOV5LwN938RHI0pljAJ1Gf6SzXsSmRaEzcXTtOOmVqJ5+WtQPL5uigY50Q=="], @@ -1139,14 +1135,10 @@ "error-ex": ["error-ex@1.3.4", "", { "dependencies": { "is-arrayish": "^0.2.1" } }, "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ=="], - "es-define-property": ["es-define-property@1.0.1", "", {}, "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g=="], - "es-errors": ["es-errors@1.3.0", "", {}, "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="], "es-module-lexer": ["es-module-lexer@2.3.1", "", {}, "sha512-shc1dbU90Yl/xq1QrC7QRtfcwURZuVRfPhZbDoldJ1cn1gzDvBaBWlv0eFolj5+0znnPJz5TXLxsN77X/12KTA=="], - "es-object-atoms": ["es-object-atoms@1.1.2", "", { "dependencies": { "es-errors": "^1.3.0" } }, "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw=="], - "es-toolkit": ["es-toolkit@1.49.0", "", {}, "sha512-G5iZ6Pc/FNRY/soKZHC+TxGDD83rHUDXxzaWhGCX44vAv/tMs56WMusnm/KMNK+luUPsgA9U28cGr4RDlSzL2g=="], "esbuild": ["esbuild@0.28.1", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.28.1", "@esbuild/android-arm": "0.28.1", "@esbuild/android-arm64": "0.28.1", "@esbuild/android-x64": "0.28.1", "@esbuild/darwin-arm64": "0.28.1", "@esbuild/darwin-x64": "0.28.1", "@esbuild/freebsd-arm64": "0.28.1", "@esbuild/freebsd-x64": "0.28.1", "@esbuild/linux-arm": "0.28.1", "@esbuild/linux-arm64": "0.28.1", "@esbuild/linux-ia32": "0.28.1", "@esbuild/linux-loong64": "0.28.1", "@esbuild/linux-mips64el": "0.28.1", "@esbuild/linux-ppc64": "0.28.1", "@esbuild/linux-riscv64": "0.28.1", "@esbuild/linux-s390x": "0.28.1", "@esbuild/linux-x64": "0.28.1", "@esbuild/netbsd-arm64": "0.28.1", "@esbuild/netbsd-x64": "0.28.1", "@esbuild/openbsd-arm64": "0.28.1", "@esbuild/openbsd-x64": "0.28.1", "@esbuild/openharmony-arm64": "0.28.1", "@esbuild/sunos-x64": "0.28.1", "@esbuild/win32-arm64": "0.28.1", "@esbuild/win32-ia32": "0.28.1", "@esbuild/win32-x64": "0.28.1" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw=="], @@ -1159,7 +1151,7 @@ "escodegen": ["escodegen@2.1.0", "", { "dependencies": { "esprima": "^4.0.1", "estraverse": "^5.2.0", "esutils": "^2.0.2" }, "optionalDependencies": { "source-map": "~0.6.1" }, "bin": { "esgenerate": "bin/esgenerate.js", "escodegen": "bin/escodegen.js" } }, "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w=="], - "eslint": ["eslint@9.39.5", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.21.2", "@eslint/config-helpers": "^0.4.2", "@eslint/core": "^0.17.0", "@eslint/eslintrc": "^3.3.6", "@eslint/js": "9.39.5", "@eslint/plugin-kit": "^0.4.1", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", "ajv": "^6.14.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", "eslint-scope": "^8.4.0", "eslint-visitor-keys": "^4.2.1", "espree": "^10.4.0", "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.5", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, "peerDependencies": { "jiti": "*" }, "optionalPeers": ["jiti"], "bin": { "eslint": "bin/eslint.js" } }, "sha512-DgZS62aPLXKlnxILS/AYCoRvHaZeXceIzlXPkkGGzJWSow1aEk0lbTlxUSlyjC8jcaKxAdOnTDz+o1JFSBsyjw=="], + "eslint": ["eslint@10.7.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.2", "@eslint/config-array": "^0.23.5", "@eslint/config-helpers": "^0.6.0", "@eslint/core": "^1.2.1", "@eslint/plugin-kit": "^0.7.2", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", "ajv": "^6.14.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", "eslint-scope": "^9.1.2", "eslint-visitor-keys": "^5.0.1", "espree": "^11.2.0", "esquery": "^1.7.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", "minimatch": "^10.2.4", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, "peerDependencies": { "jiti": "*" }, "optionalPeers": ["jiti"], "bin": { "eslint": "bin/eslint.js" } }, "sha512-GVTD7s1vdIl6UYvAfriOPeY1Df8LIZjfofLvHwde+erDHGGuHyuM6xoxRxmHiebhYuD2p1vN4wWh0XzPARSGDQ=="], "eslint-compat-utils": ["eslint-compat-utils@0.5.1", "", { "dependencies": { "semver": "^7.5.4" }, "peerDependencies": { "eslint": ">=6.0.0" } }, "sha512-3z3vFexKIEnjHE3zCMRo6fn/e44U7T1khUjg+Hp0ZQMCigh28rALD0nPFBcGZuiLC5rLZa2ubQHDRln09JfU2Q=="], @@ -1175,17 +1167,15 @@ "eslint-plugin-command": ["eslint-plugin-command@3.5.3", "", { "dependencies": { "@es-joy/jsdoccomment": "^0.88.0" }, "peerDependencies": { "@typescript-eslint/typescript-estree": "*", "@typescript-eslint/utils": "*", "eslint": "*" } }, "sha512-JIhmUOW2K2Dw1K+p4mtj5potkqTZ4ZaicrTkgCygPZCWErP2+O2F46n7ZwGKapeEjiwcVqoY8u01SxNUUXWPeQ=="], - "eslint-plugin-depend": ["eslint-plugin-depend@1.5.0", "", { "dependencies": { "empathic": "^2.0.0", "module-replacements": "^2.10.1", "semver": "^7.6.3" }, "peerDependencies": { "eslint": ">=8.40.0" } }, "sha512-i3UeLYmclf1Icp35+6W7CR4Bp2PIpDgBuf/mpmXK5UeLkZlvYJ21VuQKKHHAIBKRTPivPGX/gZl5JGno1o9Y0A=="], - "eslint-plugin-es-x": ["eslint-plugin-es-x@7.8.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.1.2", "@eslint-community/regexpp": "^4.11.0", "eslint-compat-utils": "^0.5.1" }, "peerDependencies": { "eslint": ">=8" } }, "sha512-7Ds8+wAAoV3T+LAKeu39Y5BzXCrGKrcISfgKEqTS4BDN8SFEDQd0S43jiQ8vIa3wUKD07qitZdfzlenSi8/0qQ=="], - "eslint-plugin-import-lite": ["eslint-plugin-import-lite@0.5.2", "", { "peerDependencies": { "eslint": ">=9.0.0" } }, "sha512-XvfdWOC5dSLEI9krIPRlNmKSI2ViIE9pVylzfV9fCq0ZpDaNeUk6o0wZv0OzN83QdadgXp1NsY0qjLINxwYCsw=="], + "eslint-plugin-import-lite": ["eslint-plugin-import-lite@0.6.0", "", { "peerDependencies": { "eslint": "^9.0.0 || ^10.0.0" } }, "sha512-80vevx2A7i3H7n1/6pqDO8cc5wRz6OwLDvIyVl9UflBV1N1f46e9Ihzi65IOLYoSxM6YykK2fTw1xm0Ixx6aTQ=="], - "eslint-plugin-jsdoc": ["eslint-plugin-jsdoc@62.9.0", "", { "dependencies": { "@es-joy/jsdoccomment": "~0.86.0", "@es-joy/resolve.exports": "1.2.0", "are-docs-informative": "^0.0.2", "comment-parser": "1.4.6", "debug": "^4.4.3", "escape-string-regexp": "^4.0.0", "espree": "^11.2.0", "esquery": "^1.7.0", "html-entities": "^2.6.0", "object-deep-merge": "^2.0.0", "parse-imports-exports": "^0.2.4", "semver": "^7.7.4", "spdx-expression-parse": "^4.0.0", "to-valid-identifier": "^1.0.0" }, "peerDependencies": { "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0" } }, "sha512-PY7/X4jrVgoIDncUmITlUqK546Ltmx/Pd4Hdsu4CvSjryQZJI2mEV4vrdMufyTetMiZ5taNSqvK//BTgVUlNkA=="], + "eslint-plugin-jsdoc": ["eslint-plugin-jsdoc@63.1.0", "", { "dependencies": { "@es-joy/jsdoccomment": "~0.88.0", "@es-joy/resolve.exports": "1.2.0", "are-docs-informative": "^0.0.2", "comment-parser": "1.4.7", "debug": "^4.4.3", "escape-string-regexp": "^4.0.0", "espree": "^11.2.0", "esquery": "^1.7.0", "html-entities": "^2.6.0", "object-deep-merge": "^2.0.1", "parse-imports-exports": "^0.2.4", "semver": "^7.8.5", "spdx-expression-parse": "^4.0.0", "to-valid-identifier": "^1.0.0" }, "peerDependencies": { "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0" } }, "sha512-Vo0Mvhxi6B63gLIDI86QChkiKE79MxxM0I16gMN/HJn0rvJvMIG/nmn+KPcsx+GWYDQq6X0UfNRjRK1+97NYVg=="], "eslint-plugin-jsonc": ["eslint-plugin-jsonc@3.3.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.5.1", "@eslint/core": "^1.0.1", "@eslint/plugin-kit": "^0.7.0", "@ota-meshi/ast-token-store": "^0.3.0", "diff-sequences": "^29.6.3", "eslint-json-compat-utils": "^0.2.3", "jsonc-eslint-parser": "^3.1.0", "natural-compare": "^1.4.0", "synckit": "^0.11.12" }, "peerDependencies": { "eslint": ">=9.38.0" } }, "sha512-CsTR8aDcShDg6A71ZppLaWiPoSo2J1Ivjm5/c4Mnb9sxgwWq+WG2PgeoAnj7SwzDPJB75tlHvLrGy6ntooIitg=="], - "eslint-plugin-n": ["eslint-plugin-n@17.24.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.5.0", "enhanced-resolve": "^5.17.1", "eslint-plugin-es-x": "^7.8.0", "get-tsconfig": "^4.8.1", "globals": "^15.11.0", "globrex": "^0.1.2", "ignore": "^5.3.2", "semver": "^7.6.3", "ts-declaration-location": "^1.0.6" }, "peerDependencies": { "eslint": ">=8.23.0" } }, "sha512-/gC7/KAYmfNnPNOb3eu8vw+TdVnV0zhdQwexsw6FLXbhzroVj20vRn2qL8lDWDGnAQ2J8DhdfvXxX9EoxvERvw=="], + "eslint-plugin-n": ["eslint-plugin-n@18.2.2", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.5.0", "enhanced-resolve": "^5.17.1", "eslint-plugin-es-x": "^7.8.0", "get-tsconfig": "^4.8.1", "globals": "^15.11.0", "globrex": "^0.1.2", "ignore": "^5.3.2", "semver": "^7.6.3" }, "peerDependencies": { "eslint": ">=8.57.1", "ts-declaration-location": "^1.0.6", "typescript": ">=5.0.0" }, "optionalPeers": ["ts-declaration-location", "typescript"] }, "sha512-gOO0lIqwEjZ750kv9/SptCWArUoAZXJoBr0vYWTO2dCBxctHUXlBIigiC8xuxxr/NKqgIT6Ehz1xRcilj8a5cA=="], "eslint-plugin-no-only-tests": ["eslint-plugin-no-only-tests@3.4.0", "", {}, "sha512-4S3/9Nb7A2tiMcpzEQE9bQSlpeOz6WJkgryBuou/SA8W2x2c8Zf4j0NvTKBjv6qNhF9T79tmkecm/0CHqV0UGg=="], @@ -1193,27 +1183,27 @@ "eslint-plugin-pnpm": ["eslint-plugin-pnpm@1.6.1", "", { "dependencies": { "empathic": "^2.0.1", "jsonc-eslint-parser": "^3.1.0", "pathe": "^2.0.3", "pnpm-workspace-yaml": "1.6.1", "tinyglobby": "^0.2.16", "yaml": "^2.9.0", "yaml-eslint-parser": "^2.0.0" }, "peerDependencies": { "eslint": "^9.0.0 || ^10.0.0" } }, "sha512-pgcaJclu3YxZ/WMsiKMF58bHQasbGVARSMqCJvFaETYxSc7KcR2H74UVWV6exuGv9nNv9c0KKqn4PVHQlzMSEg=="], - "eslint-plugin-react-dom": ["eslint-plugin-react-dom@2.13.0", "", { "dependencies": { "@eslint-react/ast": "2.13.0", "@eslint-react/core": "2.13.0", "@eslint-react/eff": "2.13.0", "@eslint-react/shared": "2.13.0", "@eslint-react/var": "2.13.0", "@typescript-eslint/scope-manager": "^8.55.0", "@typescript-eslint/types": "^8.55.0", "@typescript-eslint/utils": "^8.55.0", "compare-versions": "^6.1.1", "ts-pattern": "^5.9.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-+2IZzQ1WEFYOWatW+xvNUqmZn55YBCufzKA7hX3XQ/8eu85Mp4vnlOyNvdVHEOGhUnGuC6+9+zLK+IlEHKdKLQ=="], + "eslint-plugin-react-dom": ["eslint-plugin-react-dom@5.17.1", "", { "dependencies": { "@eslint-react/ast": "5.17.1", "@eslint-react/eslint": "5.17.1", "@eslint-react/jsx": "5.17.1", "@eslint-react/shared": "5.17.1", "@typescript-eslint/types": "^8.64.0", "@typescript-eslint/utils": "^8.64.0", "compare-versions": "^6.1.1" }, "peerDependencies": { "eslint": "*", "typescript": "*" } }, "sha512-Tb1Tahle1L03x3JnU88Te7P13V695zdPE86pAElMbfJqN9Wz+hSxXt0l7HRzFSw9zzY2LmbLEWs5Tfj2aJ15CQ=="], "eslint-plugin-react-hooks": ["eslint-plugin-react-hooks@7.1.1", "", { "dependencies": { "@babel/core": "^7.24.4", "@babel/parser": "^7.24.4", "hermes-parser": "^0.25.1", "zod": "^3.25.0 || ^4.0.0", "zod-validation-error": "^3.5.0 || ^4.0.0" }, "peerDependencies": { "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 || ^10.0.0" } }, "sha512-f2I7Gw6JbvCexzIInuSbZpfdQ44D7iqdWX01FKLvrPgqxoE7oMj8clOfto8U6vYiz4yd5oKu39rRSVOe1zRu0g=="], - "eslint-plugin-react-hooks-extra": ["eslint-plugin-react-hooks-extra@2.13.0", "", { "dependencies": { "@eslint-react/ast": "2.13.0", "@eslint-react/core": "2.13.0", "@eslint-react/eff": "2.13.0", "@eslint-react/shared": "2.13.0", "@eslint-react/var": "2.13.0", "@typescript-eslint/scope-manager": "^8.55.0", "@typescript-eslint/type-utils": "^8.55.0", "@typescript-eslint/types": "^8.55.0", "@typescript-eslint/utils": "^8.55.0", "ts-pattern": "^5.9.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-qIbha1nzuyhXM9SbEfrcGVqmyvQu7GAOB2sy9Y4Qo5S8nCqw4fSBxq+8lSce5Tk5Y7XzIkgHOhNyXEvUHRWFMQ=="], + "eslint-plugin-react-jsx": ["eslint-plugin-react-jsx@5.17.1", "", { "dependencies": { "@eslint-react/ast": "5.17.1", "@eslint-react/core": "5.17.1", "@eslint-react/eslint": "5.17.1", "@eslint-react/jsx": "5.17.1", "@eslint-react/shared": "5.17.1", "@typescript-eslint/types": "^8.64.0", "@typescript-eslint/utils": "^8.64.0" }, "peerDependencies": { "eslint": "*", "typescript": "*" } }, "sha512-BkDgTNQz8IjoebL9BKK8FyQn0GNnGN6dNDIm+ne6uLwnHf4SPpeBciC1kEnCygiCX5Y8XmAj3NEDLHxRAFJn1Q=="], - "eslint-plugin-react-naming-convention": ["eslint-plugin-react-naming-convention@2.13.0", "", { "dependencies": { "@eslint-react/ast": "2.13.0", "@eslint-react/core": "2.13.0", "@eslint-react/eff": "2.13.0", "@eslint-react/shared": "2.13.0", "@eslint-react/var": "2.13.0", "@typescript-eslint/scope-manager": "^8.55.0", "@typescript-eslint/type-utils": "^8.55.0", "@typescript-eslint/types": "^8.55.0", "@typescript-eslint/utils": "^8.55.0", "compare-versions": "^6.1.1", "string-ts": "^2.3.1", "ts-pattern": "^5.9.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-uSd25JzSg2R4p81s3Wqck0AdwRlO9Yc+cZqTEXv7vW8exGGAM3mWnF6hgrgdqVJqBEGJIbS/Vx1r5BdKcY/MHA=="], + "eslint-plugin-react-naming-convention": ["eslint-plugin-react-naming-convention@5.17.1", "", { "dependencies": { "@eslint-react/ast": "5.17.1", "@eslint-react/core": "5.17.1", "@eslint-react/eslint": "5.17.1", "@eslint-react/var": "5.17.1", "@typescript-eslint/types": "^8.64.0", "@typescript-eslint/utils": "^8.64.0", "ts-pattern": "^5.9.0" }, "peerDependencies": { "eslint": "*", "typescript": "*" } }, "sha512-Y8Czg68OHg/zfP1p+JMaCMeEhW1Pv9PUGnuQJsP/0kDCCjHb6aXI2pRHIQPcwAeFEAgOFUsB2DURESlsx6XUAA=="], "eslint-plugin-react-refresh": ["eslint-plugin-react-refresh@0.5.3", "", { "peerDependencies": { "eslint": "^9 || ^10" } }, "sha512-5EMmLCV98Pi4o/f/3DP/v/tNqLHMIc9I8LKClNDWhZ9JTho89/kQcitCXQBMG7sAfVRK0Ie3T2EDOzp1YXYiVA=="], - "eslint-plugin-react-rsc": ["eslint-plugin-react-rsc@2.13.0", "", { "dependencies": { "@eslint-react/ast": "2.13.0", "@eslint-react/shared": "2.13.0", "@eslint-react/var": "2.13.0", "@typescript-eslint/types": "^8.55.0", "@typescript-eslint/utils": "^8.55.0", "ts-pattern": "^5.9.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-RaftgITDLQm1zIgYyvR51sBdy4FlVaXFts5VISBaKbSUB0oqXyzOPxMHasfr9BCSjPLKus9zYe+G/Hr6rjFLXQ=="], + "eslint-plugin-react-rsc": ["eslint-plugin-react-rsc@5.17.1", "", { "dependencies": { "@eslint-react/ast": "5.17.1", "@eslint-react/core": "5.17.1", "@eslint-react/eslint": "5.17.1", "@eslint-react/shared": "5.17.1", "@eslint-react/var": "5.17.1", "@typescript-eslint/types": "^8.64.0", "@typescript-eslint/utils": "^8.64.0" }, "peerDependencies": { "eslint": "*", "typescript": "*" } }, "sha512-4numrKqQd2ld62sAVZDmcXkS3bOmzSCNNz5Tlpu7q8hjLt9cgD4+yFdx3zHdC1WZt8JV0emfM1Xwea8Bkoxvnw=="], - "eslint-plugin-react-web-api": ["eslint-plugin-react-web-api@2.13.0", "", { "dependencies": { "@eslint-react/ast": "2.13.0", "@eslint-react/core": "2.13.0", "@eslint-react/eff": "2.13.0", "@eslint-react/shared": "2.13.0", "@eslint-react/var": "2.13.0", "@typescript-eslint/scope-manager": "^8.55.0", "@typescript-eslint/types": "^8.55.0", "@typescript-eslint/utils": "^8.55.0", "birecord": "^0.1.1", "ts-pattern": "^5.9.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-nmJbzIAte7PeAkp22CwcKEASkKi49MshSdiDGO1XuN3f4N4/8sBfDcWbQuLPde6JiuzDT/0+l7Gi8wwTHtR1kg=="], + "eslint-plugin-react-web-api": ["eslint-plugin-react-web-api@5.17.1", "", { "dependencies": { "@eslint-react/ast": "5.17.1", "@eslint-react/core": "5.17.1", "@eslint-react/eslint": "5.17.1", "@eslint-react/shared": "5.17.1", "@eslint-react/var": "5.17.1", "@typescript-eslint/types": "^8.64.0", "@typescript-eslint/utils": "^8.64.0", "birecord": "^0.1.2", "ts-pattern": "^5.9.0" }, "peerDependencies": { "eslint": "*", "typescript": "*" } }, "sha512-QUVp4mRpsnFgdVAx58lv5+tKmbuKkJgaHRSTELRCKyVePPGWwqF++MW1YXcqp1nY7XTuio21iLLDQJBd4h6Kiw=="], - "eslint-plugin-react-x": ["eslint-plugin-react-x@2.13.0", "", { "dependencies": { "@eslint-react/ast": "2.13.0", "@eslint-react/core": "2.13.0", "@eslint-react/eff": "2.13.0", "@eslint-react/shared": "2.13.0", "@eslint-react/var": "2.13.0", "@typescript-eslint/scope-manager": "^8.55.0", "@typescript-eslint/type-utils": "^8.55.0", "@typescript-eslint/types": "^8.55.0", "@typescript-eslint/utils": "^8.55.0", "compare-versions": "^6.1.1", "is-immutable-type": "^5.0.1", "ts-api-utils": "^2.4.0", "ts-pattern": "^5.9.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-cMNX0+ws/fWTgVxn52qAQbaFF2rqvaDAtjrPUzY6XOzPjY0rJQdR2tSlWJttz43r2yBfqu+LGvHlGpWL2wfpTQ=="], + "eslint-plugin-react-x": ["eslint-plugin-react-x@5.17.1", "", { "dependencies": { "@eslint-react/ast": "5.17.1", "@eslint-react/core": "5.17.1", "@eslint-react/eslint": "5.17.1", "@eslint-react/jsx": "5.17.1", "@eslint-react/shared": "5.17.1", "@eslint-react/var": "5.17.1", "@typescript-eslint/scope-manager": "^8.64.0", "@typescript-eslint/type-utils": "^8.64.0", "@typescript-eslint/types": "^8.64.0", "@typescript-eslint/typescript-estree": "^8.64.0", "@typescript-eslint/utils": "^8.64.0", "compare-versions": "^6.1.1", "string-ts": "^2.3.1", "ts-api-utils": "^2.5.0", "ts-pattern": "^5.9.0" }, "peerDependencies": { "eslint": "*", "typescript": "*" } }, "sha512-PE/PYQP8aYdLit3qt5/KsrHzmbRKqERGTLijVzOUjeAAylBS1JbrPdmmGJkTdsCqMamdS/UOpgArr5p6UYG0yA=="], "eslint-plugin-regexp": ["eslint-plugin-regexp@3.1.1", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.11.0", "comment-parser": "^1.4.0", "jsdoc-type-pratt-parser": "^7.0.0", "refa": "^0.12.1", "regexp-ast-analysis": "^0.7.1", "scslre": "^0.3.0" }, "peerDependencies": { "eslint": ">=9.38.0" } }, "sha512-MxR5nqoQCtVWmJwia0D2+NlXX1xzdpkslsVOZLEYQ4PQWEaL65PCZXURxaBc3lPnkNFpNxzMIRmYVxdl8giXRA=="], "eslint-plugin-toml": ["eslint-plugin-toml@1.4.0", "", { "dependencies": { "@eslint/core": "^1.0.1", "@eslint/plugin-kit": "^0.7.0", "@ota-meshi/ast-token-store": "^0.3.0", "debug": "^4.1.1", "toml-eslint-parser": "^1.0.1" }, "peerDependencies": { "eslint": ">=9.38.0" } }, "sha512-3ErTnfUjXq/23f72XeyRcE0Y4Sd/ME1lsZeezczqpn2R4tE7+Sgco/NUKDXm0xAMz15tzcRz/9RfJRm6AqRO+A=="], - "eslint-plugin-unicorn": ["eslint-plugin-unicorn@63.0.0", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.28.5", "@eslint-community/eslint-utils": "^4.9.0", "change-case": "^5.4.4", "ci-info": "^4.3.1", "clean-regexp": "^1.0.0", "core-js-compat": "^3.46.0", "find-up-simple": "^1.0.1", "globals": "^16.4.0", "indent-string": "^5.0.0", "is-builtin-module": "^5.0.0", "jsesc": "^3.1.0", "pluralize": "^8.0.0", "regexp-tree": "^0.1.27", "regjsparser": "^0.13.0", "semver": "^7.7.3", "strip-indent": "^4.1.1" }, "peerDependencies": { "eslint": ">=9.38.0" } }, "sha512-Iqecl9118uQEXYh7adylgEmGfkn5es3/mlQTLLkd4pXkIk9CTGrAbeUux+YljSa2ohXCBmQQ0+Ej1kZaFgcfkA=="], + "eslint-plugin-unicorn": ["eslint-plugin-unicorn@68.0.0", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.29.7", "@eslint-community/eslint-utils": "^4.9.1", "browserslist": "^4.28.2", "change-case": "^5.4.4", "ci-info": "^4.4.0", "core-js-compat": "^3.49.0", "detect-indent": "^7.0.2", "find-up-simple": "^1.0.1", "globals": "^17.6.0", "indent-string": "^5.0.0", "is-builtin-module": "^5.0.0", "jsesc": "^3.1.0", "pluralize": "^8.0.0", "regjsparser": "^0.13.1", "semver": "^7.8.4", "strip-indent": "^4.1.1" }, "peerDependencies": { "eslint": ">=10.4" } }, "sha512-mHYWvX948Q4H3bGc39bsNMxD/leOuNI+Iws9NVsoSz5VA7EGP86wnz7mZ/SPSvRhefT8L4hd8DHfDuGC+lIoCQ=="], "eslint-plugin-unused-imports": ["eslint-plugin-unused-imports@4.4.1", "", { "peerDependencies": { "@typescript-eslint/eslint-plugin": "^8.0.0-0 || ^7.0.0 || ^6.0.0 || ^5.0.0", "eslint": "^10.0.0 || ^9.0.0 || ^8.0.0" }, "optionalPeers": ["@typescript-eslint/eslint-plugin"] }, "sha512-oZGYUz1X3sRMGUB+0cZyK2VcvRX5lm/vB56PgNNcU+7ficUCKm66oZWKUubXWnOuPjQ8PvmXtCViXBMONPe7tQ=="], @@ -1223,11 +1213,11 @@ "eslint-processor-vue-blocks": ["eslint-processor-vue-blocks@2.0.0", "", { "peerDependencies": { "@vue/compiler-sfc": "^3.3.0", "eslint": ">=9.0.0" } }, "sha512-u4W0CJwGoWY3bjXAuFpc/b6eK3NQEI8MoeW7ritKj3G3z/WtHrKjkqf+wk8mPEy5rlMGS+k6AZYOw2XBoN/02Q=="], - "eslint-scope": ["eslint-scope@8.4.0", "", { "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" } }, "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg=="], + "eslint-scope": ["eslint-scope@9.1.2", "", { "dependencies": { "@types/esrecurse": "^4.3.1", "@types/estree": "^1.0.8", "esrecurse": "^4.3.0", "estraverse": "^5.2.0" } }, "sha512-xS90H51cKw0jltxmvmHy2Iai1LIqrfbw57b79w/J7MfvDfkIkFZ+kj6zC3BjtUwh150HsSSdxXZcsuv72miDFQ=="], - "eslint-visitor-keys": ["eslint-visitor-keys@4.2.1", "", {}, "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ=="], + "eslint-visitor-keys": ["eslint-visitor-keys@5.0.1", "", {}, "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA=="], - "espree": ["espree@10.4.0", "", { "dependencies": { "acorn": "^8.15.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^4.2.1" } }, "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ=="], + "espree": ["espree@11.2.0", "", { "dependencies": { "acorn": "^8.16.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^5.0.1" } }, "sha512-7p3DrVEIopW1B1avAGLuCSh1jubc01H2JHc8B4qqGblmg5gI9yumBgACjWo4JlIc04ufug4xJ3SQI8HkS/Rgzw=="], "esprima": ["esprima@4.0.1", "", { "bin": { "esparse": "./bin/esparse.js", "esvalidate": "./bin/esvalidate.js" } }, "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="], @@ -1245,7 +1235,7 @@ "esutils": ["esutils@2.0.3", "", {}, "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="], - "eta": ["eta@4.5.0", "", {}, "sha512-qifAYjuW5AM1eEEIsFnOwB+TGqu6ynU3OKj9WbUTOtUBHFPZqL03XUW34kbp3zm19Ald+U8dEyRXaVsUck+Y1g=="], + "eta": ["eta@4.5.1", "", {}, "sha512-EaNCGm+8XEIU7YNcc+THptWAO5NfKBHHARxt+wxZljj9bTr/+arRoOm9/MpGt4n6xn9fLnPFRSoLD0WFYGFUxQ=="], "events-universal": ["events-universal@1.0.1", "", { "dependencies": { "bare-events": "^2.7.0" } }, "sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw=="], @@ -1333,20 +1323,14 @@ "get-east-asian-width": ["get-east-asian-width@1.6.0", "", {}, "sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA=="], - "get-intrinsic": ["get-intrinsic@1.3.0", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", "math-intrinsics": "^1.1.0" } }, "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ=="], - - "get-proto": ["get-proto@1.0.1", "", { "dependencies": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" } }, "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g=="], - "get-stream": ["get-stream@9.0.1", "", { "dependencies": { "@sec-ant/readable-stream": "^0.4.1", "is-stream": "^4.0.1" } }, "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA=="], "get-tsconfig": ["get-tsconfig@4.8.1", "", { "dependencies": { "resolve-pkg-maps": "^1.0.0" } }, "sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg=="], - "get-uri": ["get-uri@6.0.5", "", { "dependencies": { "basic-ftp": "^5.0.2", "data-uri-to-buffer": "^6.0.2", "debug": "^4.3.4" } }, "sha512-b1O07XYq8eRuVzBNgJLstU6FYc1tS6wnMtF1I1D9lE8LxZSOGZ7LhxN54yPP6mGw5f2CkXY2BQUL9Fx41qvcIg=="], + "get-uri": ["get-uri@7.0.0", "", { "dependencies": { "basic-ftp": "^5.0.2", "data-uri-to-buffer": "7.0.0", "debug": "^4.3.4" } }, "sha512-ZsC7KQxm1Hra8yO0RvMZ4lGJT7vnBtSNpEHKq39MPN7vjuvCiu1aQ8rkXUaIXG1y/TSDez97Gmv04ibnYqCp/A=="], "giget": ["giget@2.0.0", "", { "dependencies": { "citty": "^0.1.6", "consola": "^3.4.0", "defu": "^6.1.4", "node-fetch-native": "^1.6.6", "nypm": "^0.6.0", "pathe": "^2.0.3" }, "bin": { "giget": "dist/cli.mjs" } }, "sha512-L5bGsVkxJbJgdnwyuheIunkGatUF/zssUoxxjACCseZYAVbaqdh9Tsmmlkl8vYan09H7sbvKt4pS8GqKLBrEzA=="], - "git-raw-commits": ["git-raw-commits@5.0.1", "", { "dependencies": { "@conventional-changelog/git-client": "^2.6.0", "meow": "^13.0.0" }, "bin": { "git-raw-commits": "src/cli.js" } }, "sha512-Y+csSm2GD/PCSh6Isd/WiMjNAydu0VBiG9J7EdQsNA5P9uXvLayqjmTsNlK5Gs9IhblFZqOU0yid5Il5JPoLiQ=="], - "git-up": ["git-up@8.1.1", "", { "dependencies": { "is-ssh": "^1.4.0", "parse-url": "^9.2.0" } }, "sha512-FDenSF3fVqBYSaJoYy1KSc2wosx0gCvKP+c+PRBht7cAaiCeQlBtfBDX9vgnNOHmdePlSFITVcn4pFfcgNvx3g=="], "git-url-parse": ["git-url-parse@16.1.0", "", { "dependencies": { "git-up": "^8.1.0" } }, "sha512-cPLz4HuK86wClEW7iDdeAKcCVlWXmrLpb2L+G9goW0Z1dtpNS6BXXSOckUTlJT/LDQViE1QZKstNORzHsLnobw=="], @@ -1363,13 +1347,11 @@ "globrex": ["globrex@0.1.2", "", {}, "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg=="], - "gopd": ["gopd@1.2.0", "", {}, "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg=="], - "got": ["got@14.6.6", "", { "dependencies": { "@sindresorhus/is": "^7.0.1", "byte-counter": "^0.1.0", "cacheable-lookup": "^7.0.0", "cacheable-request": "^13.0.12", "decompress-response": "^10.0.0", "form-data-encoder": "^4.0.2", "http2-wrapper": "^2.2.1", "keyv": "^5.5.3", "lowercase-keys": "^3.0.0", "p-cancelable": "^4.0.1", "responselike": "^4.0.2", "type-fest": "^4.26.1" } }, "sha512-QLV1qeYSo5l13mQzWgP/y0LbMr5Plr5fJilgAIwgnwseproEbtNym8xpLsDzeZ6MWXgNE6kdWGBjdh3zT/Qerg=="], "graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="], - "graphql": ["graphql@16.14.2", "", {}, "sha512-Chq1s4CY7jmh8gO2qvLIJyfCDIN+EHLFW/9iShnp1z8FjBQMoodWP1kDC36VAMXXIvAjj4ARa7ntfAV2BrjsbA=="], + "graphql": ["graphql@17.0.2", "", {}, "sha512-FRWbddMxfkjiB7z+aQDWIR+E34xo9I8c9mtK2RPv8PmMzKRvrdsreHL/Ui/TmwHJfhHChEtsFPyMHKI+xuarQQ=="], "graphql-http": ["graphql-http@1.22.4", "", { "peerDependencies": { "graphql": ">=0.11 <=16" } }, "sha512-OC3ucK988teMf+Ak/O+ZJ0N2ukcgrEurypp8ePyJFWq83VzwRAmHxxr+XxrMpxO/FIwI4a7m/Fzv3tWGJv0wPA=="], @@ -1383,10 +1365,6 @@ "has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="], - "has-property-descriptors": ["has-property-descriptors@1.0.2", "", { "dependencies": { "es-define-property": "^1.0.0" } }, "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg=="], - - "has-symbols": ["has-symbols@1.1.0", "", {}, "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ=="], - "hasown": ["hasown@2.0.4", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A=="], "help-me": ["help-me@5.0.0", "", {}, "sha512-7xgomUX6ADmcYzFik0HzAxh/73YlKR9bmFzf51CZwR+b6YtzU2m0u49hQCqV6SvlqIqsaxovfwdvbnsw3b/zpg=="], @@ -1403,13 +1381,13 @@ "http-cache-semantics": ["http-cache-semantics@4.2.0", "", {}, "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ=="], - "http-proxy-agent": ["http-proxy-agent@7.0.2", "", { "dependencies": { "agent-base": "^7.1.0", "debug": "^4.3.4" } }, "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig=="], + "http-proxy-agent": ["http-proxy-agent@8.0.0", "", { "dependencies": { "agent-base": "8.0.0", "debug": "^4.3.4" } }, "sha512-7pose0uGgrCJeH2Qh4JcNhWZp3u/oNrWjNYDK4ydOLxOpTw8V8ogHFAmkz0VWq96JBFj4umVJpvmQi287rSYLg=="], "http-status": ["http-status@2.1.0", "", {}, "sha512-O5kPr7AW7wYd/BBiOezTwnVAnmSNFY+J7hlZD2X5IOxVBetjcHAiTXhzj0gMrnojQlwy+UT1/Y3H3vJ3UlmvLA=="], "http2-wrapper": ["http2-wrapper@2.2.1", "", { "dependencies": { "quick-lru": "^5.1.1", "resolve-alpn": "^1.2.0" } }, "sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ=="], - "https-proxy-agent": ["https-proxy-agent@7.0.6", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "4" } }, "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw=="], + "https-proxy-agent": ["https-proxy-agent@8.0.0", "", { "dependencies": { "agent-base": "8.0.0", "debug": "^4.3.4" } }, "sha512-YYeW+iCnAS3xhvj2dvVoWgsbca3RfQy/IlaNHHOtDmU0jMqPI9euIq3Y9BJETdxk16h9NHHCKqp/KB9nIMStCQ=="], "human-signals": ["human-signals@8.0.1", "", {}, "sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ=="], @@ -1425,8 +1403,6 @@ "import-fresh": ["import-fresh@3.3.1", "", { "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" } }, "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ=="], - "import-meta-resolve": ["import-meta-resolve@4.2.0", "", {}, "sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg=="], - "imurmurhash": ["imurmurhash@0.1.4", "", {}, "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA=="], "indent-string": ["indent-string@5.0.0", "", {}, "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg=="], @@ -1437,8 +1413,6 @@ "ini": ["ini@6.0.0", "", {}, "sha512-IBTdIkzZNOpqm7q3dRqJvMaldXjDHWkEDfrwGEQTs5eaQMWV+djAhR+wahyNNMAa+qpbDUhBMVt4ZKNwpPm7xQ=="], - "inquirer": ["inquirer@12.11.1", "", { "dependencies": { "@inquirer/ansi": "^1.0.2", "@inquirer/core": "^10.3.2", "@inquirer/prompts": "^7.10.1", "@inquirer/type": "^3.0.10", "mute-stream": "^2.0.0", "run-async": "^4.0.6", "rxjs": "^7.8.2" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-9VF7mrY+3OmsAfjH3yKz/pLbJ5z22E23hENKw3/LNSaA/sAt3v49bDRY+Ygct1xwuKT+U+cBfTzjCPySna69Qw=="], - "inspect-with-kind": ["inspect-with-kind@1.0.5", "", { "dependencies": { "kind-of": "^6.0.2" } }, "sha512-MAQUJuIo7Xqk8EVNP+6d3CKq9c80hi4tjIbIAT6lmGW9W6WzlHiu9PS8uSuUYU+Do+j1baiFp3H25XEVxDIG2g=="], "ip-address": ["ip-address@10.2.0", "", {}, "sha512-/+S6j4E9AHvW9SWMSEY9Xfy66O5PWvVEJ08O0y5JGyEKQpojb0K0GKpz/v5HJ/G0vi3D2sjGK78119oXZeE0qA=="], @@ -1471,7 +1445,7 @@ "is-hexadecimal": ["is-hexadecimal@2.0.1", "", {}, "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg=="], - "is-immutable-type": ["is-immutable-type@5.0.4", "", { "dependencies": { "@typescript-eslint/type-utils": "^8.0.0", "ts-api-utils": "^2.0.0", "ts-declaration-location": "^1.0.4" }, "peerDependencies": { "eslint": "*", "typescript": ">=4.7.4" } }, "sha512-tDf0vB9dJJt/1USS2nvHJb8UsIAhs+pF6z8UZLNdhrzB+PKMrdcN45je9jhuFpaJOjJpoRhueFmFrRs5g/TNMA=="], + "is-in-ssh": ["is-in-ssh@1.0.0", "", {}, "sha512-jYa6Q9rH90kR1vKB6NM7qqd1mge3Fx4Dhw5TVlK1MUBqhEOuCagrEHMevNuCcbECmXZ0ThXkRm+Ymr51HwEPAw=="], "is-inside-container": ["is-inside-container@1.0.0", "", { "dependencies": { "is-docker": "^3.0.0" }, "bin": { "is-inside-container": "cli.js" } }, "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA=="], @@ -1491,7 +1465,7 @@ "is-wsl": ["is-wsl@3.1.1", "", { "dependencies": { "is-inside-container": "^1.0.0" } }, "sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw=="], - "isarray": ["isarray@2.0.5", "", {}, "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="], + "isarray": ["isarray@0.0.1", "", {}, "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ=="], "isexe": ["isexe@4.0.0", "", {}, "sha512-FFUtZMpoZ8RqHS3XeXEmHWLA4thH+ZxCv2lOiPIn1Xc7CxrqhWzNSDzD+/chS/zbYezmiwWLdQC09JdQKmthOw=="], @@ -1521,8 +1495,6 @@ "json-schema-traverse": ["json-schema-traverse@0.4.1", "", {}, "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="], - "json-stable-stringify": ["json-stable-stringify@1.3.0", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.4", "isarray": "^2.0.5", "jsonify": "^0.0.1", "object-keys": "^1.1.1" } }, "sha512-qtYiSSFlwot9XHtF9bD9c7rwKjr+RecWT//ZnPvSmEjpV5mmPOCN4j8UjY5hbjNkOwZ/jQv3J6R1/pL7RwgMsg=="], - "json-stable-stringify-without-jsonify": ["json-stable-stringify-without-jsonify@1.0.1", "", {}, "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw=="], "json-with-bigint": ["json-with-bigint@3.5.10", "", {}, "sha512-Vcx+JVNEBts/xfcoCS69sKrOhOk/3TVlvlT+XzUOefVKnnrbYSCKpDCm10pohsJFtsJVYnwa/cXRZ4eElzaM6w=="], @@ -1531,12 +1503,12 @@ "jsonc-eslint-parser": ["jsonc-eslint-parser@3.1.0", "", { "dependencies": { "acorn": "^8.5.0", "eslint-visitor-keys": "^5.0.0", "semver": "^7.3.5" } }, "sha512-75EA7EWZExL/j+MDKQrRbdzcRI2HOkRlmUw8fZJc1ioqFEOvBsq7Rt+A6yCxOt9w/TYNpkt52gC6nm/g5tFIng=="], - "jsonify": ["jsonify@0.0.1", "", {}, "sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg=="], - "jsox": ["jsox@1.2.121", "", { "bin": { "jsox": "lib/cli.js" } }, "sha512-9Ag50tKhpTwS6r5wh3MJSAvpSof0UBr39Pto8OnzFT32Z/pAbxAsKHzyvsyMEHVslELvHyO/4/jaQELHk8wDcw=="], "kareem": ["kareem@2.6.3", "", {}, "sha512-C3iHfuGUXK2u8/ipq9LfjFfXFxAZMQJJq7vLS45r3D9Y2xQ/m4S8zaR4zMLFWh9AsNPXmcFfUDhTEO8UIC/V6Q=="], + "katex": ["katex@0.16.47", "", { "dependencies": { "commander": "^8.3.0" }, "bin": { "katex": "cli.js" } }, "sha512-Eeo8Ys1doU1z+x8AZsPpQu+p/QcZBI5PeOo7QGQdy2x2m0MU/hYagBbGOmXwr5KVbEfVuWv9LpnQWeehogurjg=="], + "keyv": ["keyv@4.5.4", "", { "dependencies": { "json-buffer": "3.0.1" } }, "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw=="], "kind-of": ["kind-of@6.0.3", "", {}, "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw=="], @@ -1635,8 +1607,6 @@ "marked": ["marked@14.0.0", "", { "bin": { "marked": "bin/marked.js" } }, "sha512-uIj4+faQ+MgHgwUW1l2PsPglZLOLOT1uErt06dAPtx2kjteLAkbsd/0FiYg/MGS+i7ZKLb7w2WClxHkzOOuryQ=="], - "math-intrinsics": ["math-intrinsics@1.1.0", "", {}, "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="], - "md5": ["md5@2.3.0", "", { "dependencies": { "charenc": "0.0.2", "crypt": "0.0.2", "is-buffer": "~1.1.6" } }, "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g=="], "mdast-util-find-and-replace": ["mdast-util-find-and-replace@3.0.2", "", { "dependencies": { "@types/mdast": "^4.0.0", "escape-string-regexp": "^5.0.0", "unist-util-is": "^6.0.0", "unist-util-visit-parents": "^6.0.0" } }, "sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg=="], @@ -1657,6 +1627,8 @@ "mdast-util-gfm-task-list-item": ["mdast-util-gfm-task-list-item@2.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "devlop": "^1.0.0", "mdast-util-from-markdown": "^2.0.0", "mdast-util-to-markdown": "^2.0.0" } }, "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ=="], + "mdast-util-math": ["mdast-util-math@3.0.0", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", "devlop": "^1.0.0", "longest-streak": "^3.0.0", "mdast-util-from-markdown": "^2.0.0", "mdast-util-to-markdown": "^2.1.0", "unist-util-remove-position": "^5.0.0" } }, "sha512-Tl9GBNeG/AhJnQM221bJR2HPvLOSnLE/T9cJI9tlc6zwQk2nPk/4f0cHkOdEixQPC/j8UtKDdITswvLAy1OZ1w=="], + "mdast-util-mdx-jsx": ["mdast-util-mdx-jsx@3.1.3", "", { "dependencies": { "@types/estree-jsx": "^1.0.0", "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", "@types/unist": "^3.0.0", "ccount": "^2.0.0", "devlop": "^1.1.0", "mdast-util-from-markdown": "^2.0.0", "mdast-util-to-markdown": "^2.0.0", "parse-entities": "^4.0.0", "stringify-entities": "^4.0.0", "unist-util-stringify-position": "^4.0.0", "vfile-message": "^4.0.0" } }, "sha512-bfOjvNt+1AcbPLTFMFWY149nJz0OjmewJs3LQQ5pIyVGxP4CdOqNVJL6kTaM5c68p8q82Xv3nCyFfUnuEcH3UQ=="], "mdast-util-phrasing": ["mdast-util-phrasing@4.1.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "unist-util-is": "^6.0.0" } }, "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w=="], @@ -1695,6 +1667,8 @@ "micromark-extension-gfm-task-list-item": ["micromark-extension-gfm-task-list-item@2.1.0", "", { "dependencies": { "devlop": "^1.0.0", "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw=="], + "micromark-extension-math": ["micromark-extension-math@3.1.0", "", { "dependencies": { "@types/katex": "^0.16.0", "devlop": "^1.0.0", "katex": "^0.16.0", "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-lvEqd+fHjATVs+2v/8kg9i5Q0AP2k85H0WUOwpIVvUML8BapsMvh1XAogmQjOCsLpoKRCVQqEkQBB3NhVBcsOg=="], + "micromark-extension-mdx-jsx": ["micromark-extension-mdx-jsx@3.0.1", "", { "dependencies": { "@types/acorn": "^4.0.0", "@types/estree": "^1.0.0", "devlop": "^1.0.0", "estree-util-is-identifier-name": "^3.0.0", "micromark-factory-mdx-expression": "^2.0.0", "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-events-to-acorn": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0", "vfile-message": "^4.0.0" } }, "sha512-vNuFb9czP8QCtAQcEJn0UJQJZA8Dk6DXKBqx+bg/w0WGuSxDxNr7hErW89tHUY31dUW4NqEOWwmEUNhjTFmHkg=="], "micromark-factory-destination": ["micromark-factory-destination@2.0.1", "", { "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA=="], @@ -1761,7 +1735,7 @@ "mlly": ["mlly@1.8.2", "", { "dependencies": { "acorn": "^8.16.0", "pathe": "^2.0.3", "pkg-types": "^1.3.1", "ufo": "^1.6.3" } }, "sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA=="], - "module-replacements": ["module-replacements@2.11.0", "", {}, "sha512-j5sNQm3VCpQQ7nTqGeOZtoJtV3uKERgCBm9QRhmGRiXiqkf7iRFOkfxdJRZWLkqYY8PNf4cDQF/WfXUYLENrRA=="], + "module-replacements": ["module-replacements@3.0.0", "", {}, "sha512-tHIZqde+RlyNRobAIjfcH5UIgIrEbZbDGRL6J/x+HERX/g8O9mrm0p6knJbsTXmQtDvZ+eFP+xfOP3/9jHk6YA=="], "monaco-editor": ["monaco-editor@0.55.1", "", { "dependencies": { "dompurify": "3.2.7", "marked": "14.0.0" } }, "sha512-jz4x+TJNFHwHtwuV9vA9rMujcZRb0CEilTEwG2rRSpe/A7Jdkuj8xPKttCgOh+v/lkHy7HsZ64oj+q3xoAFl9A=="], @@ -1781,7 +1755,7 @@ "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], - "mute-stream": ["mute-stream@2.0.0", "", {}, "sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA=="], + "mute-stream": ["mute-stream@3.0.0", "", {}, "sha512-dkEJPVvun4FryqBmZ5KhDo0K9iDXAwn08tMLDinNdRBNPcYEDiWYysLcc6k3mjTMlbP9KyylvRpd4wFtwrT9rw=="], "nanoid": ["nanoid@3.3.16", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q=="], @@ -1819,8 +1793,6 @@ "object-deep-merge": ["object-deep-merge@2.0.1", "", {}, "sha512-aKttDKcU3pyZqKcCkDhsMn70WmZFG2JGDQLP9EcLyTSIFQRCPWLAmBZRLJnrVUrhPG1jETEEbfdgbNtJf1LyMg=="], - "object-keys": ["object-keys@1.1.1", "", {}, "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA=="], - "object-to-formdata": ["object-to-formdata@4.5.1", "", {}, "sha512-QiM9D0NiU5jV6J6tjE1g7b4Z2tcUnKs1OPUi4iMb2zH+7jwlcUrASghgkFk9GtzqNNq8rTQJtT8AzjBAvLoNMw=="], "obug": ["obug@2.1.4", "", {}, "sha512-4a+OsYv9UktOJKE+l1A4OufDgdRF9PifWj+tJnHURo/P+WOxpG4GzUFL9qCalmWauao6ogiG+QvnCovwPoyAWA=="], @@ -1833,13 +1805,13 @@ "onetime": ["onetime@7.0.0", "", { "dependencies": { "mimic-function": "^5.0.0" } }, "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ=="], - "open": ["open@10.2.0", "", { "dependencies": { "default-browser": "^5.2.1", "define-lazy-prop": "^3.0.0", "is-inside-container": "^1.0.0", "wsl-utils": "^0.1.0" } }, "sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA=="], + "open": ["open@11.0.0", "", { "dependencies": { "default-browser": "^5.4.0", "define-lazy-prop": "^3.0.0", "is-in-ssh": "^1.0.0", "is-inside-container": "^1.0.0", "powershell-utils": "^0.1.0", "wsl-utils": "^0.3.0" } }, "sha512-smsWv2LzFjP03xmvFoJ331ss6h+jixfA4UUV/Bsiyuu4YJPfN+FIQGOIiv4w9/+MoHkfkJ22UIaQWRVFRfH6Vw=="], "optionator": ["optionator@0.9.4", "", { "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", "type-check": "^0.4.0", "word-wrap": "^1.2.5" } }, "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g=="], - "ora": ["ora@9.0.0", "", { "dependencies": { "chalk": "^5.6.2", "cli-cursor": "^5.0.0", "cli-spinners": "^3.2.0", "is-interactive": "^2.0.0", "is-unicode-supported": "^2.1.0", "log-symbols": "^7.0.1", "stdin-discarder": "^0.2.2", "string-width": "^8.1.0", "strip-ansi": "^7.1.2" } }, "sha512-m0pg2zscbYgWbqRR6ABga5c3sZdEon7bSgjnlXC64kxtxLOyjRcbbUkLj7HFyy/FTD+P2xdBWu8snGhYI0jc4A=="], + "ora": ["ora@9.3.0", "", { "dependencies": { "chalk": "^5.6.2", "cli-cursor": "^5.0.0", "cli-spinners": "^3.2.0", "is-interactive": "^2.0.0", "is-unicode-supported": "^2.1.0", "log-symbols": "^7.0.1", "stdin-discarder": "^0.3.1", "string-width": "^8.1.0" } }, "sha512-lBX72MWFduWEf7v7uWf5DHp9Jn5BI8bNPGuFgtXMmr2uDz2Gz2749y3am3agSDdkhHPHYmmxEGSKH85ZLGzgXw=="], - "os-name": ["os-name@6.1.0", "", { "dependencies": { "macos-release": "^3.3.0", "windows-release": "^6.1.0" } }, "sha512-zBd1G8HkewNd2A8oQ8c6BN/f/c9EId7rSUueOLGu28govmUctXmM+3765GwsByv9nYUdrLqHphXlYIc86saYsg=="], + "os-name": ["os-name@7.0.0", "", { "dependencies": { "macos-release": "^3.4.0", "windows-release": "^7.1.0" } }, "sha512-/HfRU/lPPr4T2VigM+cvM3cU77es+XF4OEAa4aE5zpdvrxHGD2NmH0AFIWpMNAb+CsZL45rlcIO49Re0ZcRseg=="], "oxc-resolver": ["oxc-resolver@11.24.2", "", { "optionalDependencies": { "@oxc-resolver/binding-android-arm-eabi": "11.24.2", "@oxc-resolver/binding-android-arm64": "11.24.2", "@oxc-resolver/binding-darwin-arm64": "11.24.2", "@oxc-resolver/binding-darwin-x64": "11.24.2", "@oxc-resolver/binding-freebsd-x64": "11.24.2", "@oxc-resolver/binding-linux-arm-gnueabihf": "11.24.2", "@oxc-resolver/binding-linux-arm-musleabihf": "11.24.2", "@oxc-resolver/binding-linux-arm64-gnu": "11.24.2", "@oxc-resolver/binding-linux-arm64-musl": "11.24.2", "@oxc-resolver/binding-linux-ppc64-gnu": "11.24.2", "@oxc-resolver/binding-linux-riscv64-gnu": "11.24.2", "@oxc-resolver/binding-linux-riscv64-musl": "11.24.2", "@oxc-resolver/binding-linux-s390x-gnu": "11.24.2", "@oxc-resolver/binding-linux-x64-gnu": "11.24.2", "@oxc-resolver/binding-linux-x64-musl": "11.24.2", "@oxc-resolver/binding-openharmony-arm64": "11.24.2", "@oxc-resolver/binding-wasm32-wasi": "11.24.2", "@oxc-resolver/binding-win32-arm64-msvc": "11.24.2", "@oxc-resolver/binding-win32-x64-msvc": "11.24.2" } }, "sha512-FY91FiDBj7ls5MsFS9jN3tjz2o0/zsdSsymlakySaBwVJZorHhkWyICLZMKxlu1R9vYo+sd3z1jwb4J8x7bNDw=="], @@ -1853,9 +1825,9 @@ "p-timeout": ["p-timeout@6.1.4", "", {}, "sha512-MyIV3ZA/PmyBN/ud8vV9XzwTrNtR4jFrObymZYnZqMmW0zA8Z17vnT0rBgFE/TlohB+YCHqXMgZzb3Csp49vqg=="], - "pac-proxy-agent": ["pac-proxy-agent@7.2.0", "", { "dependencies": { "@tootallnate/quickjs-emscripten": "^0.23.0", "agent-base": "^7.1.2", "debug": "^4.3.4", "get-uri": "^6.0.1", "http-proxy-agent": "^7.0.0", "https-proxy-agent": "^7.0.6", "pac-resolver": "^7.0.1", "socks-proxy-agent": "^8.0.5" } }, "sha512-TEB8ESquiLMc0lV8vcd5Ql/JAKAoyzHFXaStwjkzpOpC5Yv+pIzLfHvjTSdf3vpa2bMiUQrg9i6276yn8666aA=="], + "pac-proxy-agent": ["pac-proxy-agent@8.0.0", "", { "dependencies": { "agent-base": "8.0.0", "debug": "^4.3.4", "get-uri": "7.0.0", "http-proxy-agent": "8.0.0", "https-proxy-agent": "8.0.0", "pac-resolver": "8.0.0", "quickjs-wasi": "^0.0.1", "socks-proxy-agent": "9.0.0" } }, "sha512-HyCoVbyQ/nbVlQ/R6wBu0YXhbG2oAnEK5BQ3xMyj1OffQmU5NoOnpLzgPlKHaobUzz5NK0+AZHby4TdydAEBUA=="], - "pac-resolver": ["pac-resolver@7.0.1", "", { "dependencies": { "degenerator": "^5.0.0", "netmask": "^2.0.2" } }, "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg=="], + "pac-resolver": ["pac-resolver@8.0.0", "", { "dependencies": { "degenerator": "6.0.0", "netmask": "^2.0.2" }, "peerDependencies": { "quickjs-wasi": "^0.0.1" } }, "sha512-SVNzOxVq2zuTew3WAt7U8UghwzJzuWYuJryd3y8FxyLTZdjVoCzY8kLP39PpEqQCDvlMWdQXwViu0sYT3eiU2w=="], "package-json-from-dist": ["package-json-from-dist@1.0.1", "", {}, "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw=="], @@ -1929,6 +1901,8 @@ "postcss-selector-parser": ["postcss-selector-parser@7.1.4", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-HeP7D2wyhkR+XaK6v4W8oRF62Dsz4flyuczALJp61GckGm42u1saSSJ/0auvcBqxs3jMRFEcPK34At/0JBKdOg=="], + "powershell-utils": ["powershell-utils@0.1.0", "", {}, "sha512-dM0jVuXJPsDN6DvRpea484tCUaMiXWjuCn++HGTqUWzGDjv5tZkEZldAJ/UMlqRYGFrD/etByo4/xOuC/snX2A=="], + "prelude-ls": ["prelude-ls@1.2.1", "", {}, "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g=="], "prettier": ["prettier@3.9.5", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-/FVl766LpUfB5vXgCYOYa0MeV/441Ia99AeICQIQFTY/Nw0roZwULcXpku5i1/m5kt/baz+s4Zogspd839HSMg=="], @@ -1947,7 +1921,7 @@ "protocols": ["protocols@2.0.2", "", {}, "sha512-hHVTzba3wboROl0/aWRRG9dMytgH6ow//STBZh43l/wQgmMhYhOFi0EHWAPtoCz9IAUymsyP0TSBHkhgMEGNnQ=="], - "proxy-agent": ["proxy-agent@6.5.0", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "^4.3.4", "http-proxy-agent": "^7.0.1", "https-proxy-agent": "^7.0.6", "lru-cache": "^7.14.1", "pac-proxy-agent": "^7.1.0", "proxy-from-env": "^1.1.0", "socks-proxy-agent": "^8.0.5" } }, "sha512-TmatMXdr2KlRiA2CyDu8GqR8EjahTG3aY3nXjdzFyoZbmB8hrBsTyMezhULIXKnC0jpfjlmiZ3+EaCzoInSu/A=="], + "proxy-agent": ["proxy-agent@7.0.0", "", { "dependencies": { "agent-base": "8.0.0", "debug": "^4.3.4", "http-proxy-agent": "8.0.0", "https-proxy-agent": "8.0.0", "lru-cache": "^7.14.1", "pac-proxy-agent": "8.0.0", "proxy-from-env": "^1.1.0", "socks-proxy-agent": "9.0.0" } }, "sha512-okTgt79rHTvMHkr/Ney5rZpgCHh3g1g3tI5uhkgN5b7OeI3n0Q/ui1uv9OdrnZNJM9WIZJqZPh/UJs+YtO/TMQ=="], "proxy-from-env": ["proxy-from-env@1.1.0", "", {}, "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="], @@ -1965,6 +1939,8 @@ "quick-lru": ["quick-lru@5.1.1", "", {}, "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA=="], + "quickjs-wasi": ["quickjs-wasi@0.0.1", "", {}, "sha512-fBWNLTBkxkLAhe1AzF1hyXEvuA+N+vV1WMP2D6iiMUblvmOt8Pp5t8zUcgvz7aYA1ldUdxDlgUse15dmcKjkNg=="], + "range-parser": ["range-parser@1.2.1", "", {}, "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="], "rc9": ["rc9@2.1.2", "", { "dependencies": { "defu": "^6.1.4", "destr": "^2.0.3" } }, "sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg=="], @@ -1995,11 +1971,9 @@ "regexp-ast-analysis": ["regexp-ast-analysis@0.7.1", "", { "dependencies": { "@eslint-community/regexpp": "^4.8.0", "refa": "^0.12.1" } }, "sha512-sZuz1dYW/ZsfG17WSAG7eS85r5a0dDsvg+7BiiYR5o6lKCAtUrEwdmRmaGF6rwVj3LcmAeYkOWKEPlbPzN3Y3A=="], - "regexp-tree": ["regexp-tree@0.1.27", "", { "bin": { "regexp-tree": "bin/regexp-tree" } }, "sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA=="], - "regjsparser": ["regjsparser@0.13.2", "", { "dependencies": { "jsesc": "~3.1.0" }, "bin": { "regjsparser": "bin/parser" } }, "sha512-NgRBy2Nx/bE+9F27nVHnqcN5HjyLmecqsqx2PJHu3/IEtADD4WuxuXIVExD5PoSDFVrl78dOonfcOe5O+5nbzQ=="], - "release-it": ["release-it@19.2.4", "", { "dependencies": { "@nodeutils/defaults-deep": "1.1.0", "@octokit/rest": "22.0.1", "@phun-ky/typeof": "2.0.3", "async-retry": "1.3.3", "c12": "3.3.3", "ci-info": "^4.3.1", "eta": "4.5.0", "git-url-parse": "16.1.0", "inquirer": "12.11.1", "issue-parser": "7.0.1", "lodash.merge": "4.6.2", "mime-types": "3.0.2", "new-github-release-url": "2.0.0", "open": "10.2.0", "ora": "9.0.0", "os-name": "6.1.0", "proxy-agent": "6.5.0", "semver": "7.7.3", "tinyglobby": "0.2.15", "undici": "6.23.0", "url-join": "5.0.0", "wildcard-match": "5.1.4", "yargs-parser": "21.1.1" }, "bin": { "release-it": "bin/release-it.js" } }, "sha512-BwaJwQYUIIAKuDYvpqQTSoy0U7zIy6cHyEjih/aNaFICphGahia4cjDANuFXb7gVZ51hIK9W0io6fjNQWXqICg=="], + "release-it": ["release-it@20.2.1", "", { "dependencies": { "@inquirer/prompts": "8.4.2", "@octokit/rest": "22.0.1", "@phun-ky/typeof": "2.0.3", "async-retry": "1.3.3", "c12": "3.3.3", "ci-info": "^4.4.0", "defu": "^6.1.7", "eta": "4.5.1", "git-url-parse": "16.1.0", "issue-parser": "7.0.1", "lodash.merge": "4.6.2", "mime-types": "3.0.2", "new-github-release-url": "2.0.0", "open": "11.0.0", "ora": "9.3.0", "os-name": "7.0.0", "proxy-agent": "7.0.0", "semver": "7.7.4", "tinyglobby": "0.2.15", "undici": "7.28.0", "url-join": "5.0.0", "wildcard-match": "5.1.4", "yargs-parser": "22.0.0" }, "bin": { "release-it": "bin/release-it.js" } }, "sha512-xd0mqTGduwQlEzVBKOJcoVZxDrRLzjmFv3W8tWwkPIPDYtwYBWYjULiSk6VhfuGKocfz7GmptAqViKMQV4Zzbw=="], "require-directory": ["require-directory@2.1.1", "", {}, "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q=="], @@ -2029,12 +2003,8 @@ "run-applescript": ["run-applescript@7.1.0", "", {}, "sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q=="], - "run-async": ["run-async@4.0.6", "", {}, "sha512-IoDlSLTs3Yq593mb3ZoKWKXMNu3UpObxhgA/Xuid5p4bbfi2jdY1Hj0m1K+0/tEuQTxIGMhQDqGjKb7RuxGpAQ=="], - "run-parallel": ["run-parallel@1.2.0", "", { "dependencies": { "queue-microtask": "^1.2.2" } }, "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA=="], - "rxjs": ["rxjs@7.8.2", "", { "dependencies": { "tslib": "^2.1.0" } }, "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA=="], - "safe-buffer": ["safe-buffer@5.1.2", "", {}, "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="], "safe-stable-stringify": ["safe-stable-stringify@2.5.0", "", {}, "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA=="], @@ -2059,9 +2029,7 @@ "semver-truncate": ["semver-truncate@3.0.0", "", { "dependencies": { "semver": "^7.3.5" } }, "sha512-LJWA9kSvMolR51oDE6PN3kALBNaUdkxzAGcexw8gjMA8xr5zUqK0JiR3CgARSqanYF3Z1YHvsErb1KDgh+v7Rg=="], - "set-function-length": ["set-function-length@1.2.2", "", { "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", "function-bind": "^1.1.2", "get-intrinsic": "^1.2.4", "gopd": "^1.0.1", "has-property-descriptors": "^1.0.2" } }, "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg=="], - - "sharp": ["sharp@0.34.5", "", { "dependencies": { "@img/colour": "^1.0.0", "detect-libc": "^2.1.2", "semver": "^7.7.3" }, "optionalDependencies": { "@img/sharp-darwin-arm64": "0.34.5", "@img/sharp-darwin-x64": "0.34.5", "@img/sharp-libvips-darwin-arm64": "1.2.4", "@img/sharp-libvips-darwin-x64": "1.2.4", "@img/sharp-libvips-linux-arm": "1.2.4", "@img/sharp-libvips-linux-arm64": "1.2.4", "@img/sharp-libvips-linux-ppc64": "1.2.4", "@img/sharp-libvips-linux-riscv64": "1.2.4", "@img/sharp-libvips-linux-s390x": "1.2.4", "@img/sharp-libvips-linux-x64": "1.2.4", "@img/sharp-libvips-linuxmusl-arm64": "1.2.4", "@img/sharp-libvips-linuxmusl-x64": "1.2.4", "@img/sharp-linux-arm": "0.34.5", "@img/sharp-linux-arm64": "0.34.5", "@img/sharp-linux-ppc64": "0.34.5", "@img/sharp-linux-riscv64": "0.34.5", "@img/sharp-linux-s390x": "0.34.5", "@img/sharp-linux-x64": "0.34.5", "@img/sharp-linuxmusl-arm64": "0.34.5", "@img/sharp-linuxmusl-x64": "0.34.5", "@img/sharp-wasm32": "0.34.5", "@img/sharp-win32-arm64": "0.34.5", "@img/sharp-win32-ia32": "0.34.5", "@img/sharp-win32-x64": "0.34.5" } }, "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg=="], + "sharp": ["sharp@0.35.3", "", { "dependencies": { "@img/colour": "^1.1.0", "detect-libc": "^2.1.2", "semver": "^7.8.5" }, "optionalDependencies": { "@img/sharp-darwin-arm64": "0.35.3", "@img/sharp-darwin-x64": "0.35.3", "@img/sharp-freebsd-wasm32": "0.35.3", "@img/sharp-libvips-darwin-arm64": "1.3.2", "@img/sharp-libvips-darwin-x64": "1.3.2", "@img/sharp-libvips-linux-arm": "1.3.2", "@img/sharp-libvips-linux-arm64": "1.3.2", "@img/sharp-libvips-linux-ppc64": "1.3.2", "@img/sharp-libvips-linux-riscv64": "1.3.2", "@img/sharp-libvips-linux-s390x": "1.3.2", "@img/sharp-libvips-linux-x64": "1.3.2", "@img/sharp-libvips-linuxmusl-arm64": "1.3.2", "@img/sharp-libvips-linuxmusl-x64": "1.3.2", "@img/sharp-linux-arm": "0.35.3", "@img/sharp-linux-arm64": "0.35.3", "@img/sharp-linux-ppc64": "0.35.3", "@img/sharp-linux-riscv64": "0.35.3", "@img/sharp-linux-s390x": "0.35.3", "@img/sharp-linux-x64": "0.35.3", "@img/sharp-linuxmusl-arm64": "0.35.3", "@img/sharp-linuxmusl-x64": "0.35.3", "@img/sharp-webcontainers-wasm32": "0.35.3", "@img/sharp-win32-arm64": "0.35.3", "@img/sharp-win32-ia32": "0.35.3", "@img/sharp-win32-x64": "0.35.3" }, "peerDependencies": { "@types/node": "*" }, "optionalPeers": ["@types/node"] }, "sha512-ej0zVHuZGHCiABXcNxeYhpRnPNPAcvbG8RMdBAhDAxLKkCRVSpK3Iyu7qbqw3JMzoj0REeM6f3tJLtVwl0023Q=="], "shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="], @@ -2083,7 +2051,7 @@ "socks": ["socks@2.8.9", "", { "dependencies": { "ip-address": "^10.1.1", "smart-buffer": "^4.2.0" } }, "sha512-LJhUYUvItdQ0LkJTmPeaEObWXAqFyfmP85x0tch/ez9cahmhlBBLbIqDFnvBnUJGagb0JbIQrkBs1wJ+yRYpEw=="], - "socks-proxy-agent": ["socks-proxy-agent@8.0.5", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "^4.3.4", "socks": "^2.8.3" } }, "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw=="], + "socks-proxy-agent": ["socks-proxy-agent@9.0.0", "", { "dependencies": { "agent-base": "8.0.0", "debug": "^4.3.4", "socks": "^2.8.3" } }, "sha512-fFlbMlfsXhK02ZB8aZY7Hwxh/IHBV9b1Oq9bvBk6tkFWXvdAxUgA0wbw/NYR5liU3Y5+KI6U4FH3kYJt9QYv0w=="], "sonic-boom": ["sonic-boom@4.2.1", "", { "dependencies": { "atomic-sleep": "^1.0.0" } }, "sha512-w6AxtubXa2wTXAUsZMMWERrsIRAdrK0Sc+FUytWvYAhBJLyuI4llrMIC1DtlNSdI99EI86KZum2MMq3EAZlF9Q=="], @@ -2117,7 +2085,7 @@ "std-env": ["std-env@4.2.0", "", {}, "sha512-oCUKSupKTHX53EyjDtuZQ64pjLJ6yYCtpmEw0goYxtjG9KpbRe8KAsl2tBUGU9DyMcJ0RwJ8GqJAFzMXcXW1Rw=="], - "stdin-discarder": ["stdin-discarder@0.2.2", "", {}, "sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ=="], + "stdin-discarder": ["stdin-discarder@0.3.2", "", {}, "sha512-eCPu1qRxPVkl5605OTWF8Wz40b4Mf45NY5LQmVPQ599knfs5QhASUm9GbJ5BDMDOXgrnh0wyEdvzmL//YMlw0A=="], "streamsearch": ["streamsearch@1.1.0", "", {}, "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg=="], @@ -2125,7 +2093,7 @@ "string-ts": ["string-ts@2.3.1", "", {}, "sha512-xSJq+BS52SaFFAVxuStmx6n5aYZU571uYUnUrPXkPFCfdHyZMMlbP2v2Wx5sNBnAVzq/2+0+mcBLBa3Xa5ubYw=="], - "string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], + "string-width": ["string-width@7.2.0", "", { "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" } }, "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ=="], "string_decoder": ["string_decoder@1.1.1", "", { "dependencies": { "safe-buffer": "~5.1.0" } }, "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg=="], @@ -2139,7 +2107,7 @@ "strip-indent": ["strip-indent@4.1.1", "", {}, "sha512-SlyRoSkdh1dYP0PzclLE7r0M9sgbFKKMFXpFRUMNuKhQSbC6VQIGzq3E0qsfvGJaUFJPGv6Ws1NZ/haTAjfbMA=="], - "strip-json-comments": ["strip-json-comments@3.1.1", "", {}, "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="], + "strip-json-comments": ["strip-json-comments@5.0.3", "", {}, "sha512-1tB5mhVo7U+ETBKNf92xT4hrQa3pm0MZ0PQvuDnWgAAGHDsfp4lPSpiS6psrSiet87wyGPh9ft6wmhOMQ0hDiw=="], "strtok3": ["strtok3@10.3.5", "", { "dependencies": { "@tokenizer/token": "^0.3.0" } }, "sha512-ki4hZQfh5rX0QDLLkOCj+h+CVNkqmp/CMf8v8kZpkNVK6jGQooMytqzLZYUVYIZcFZ6yDB70EfD8POcFXiF5oA=="], @@ -2197,8 +2165,6 @@ "ts-api-utils": ["ts-api-utils@2.5.0", "", { "peerDependencies": { "typescript": ">=4.8.4" } }, "sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA=="], - "ts-declaration-location": ["ts-declaration-location@1.0.7", "", { "dependencies": { "picomatch": "^4.0.2" }, "peerDependencies": { "typescript": ">=4.0.0" } }, "sha512-EDyGAwH1gO0Ausm9gV6T2nUvBgXT5kGoCMJPllOaooZ+4VvJiKBdZE7wK18N1deEowhcUptS+5GXZK8U/fvpwA=="], - "ts-essentials": ["ts-essentials@10.0.3", "", { "peerDependencies": { "typescript": ">=4.5.0" }, "optionalPeers": ["typescript"] }, "sha512-/FrVAZ76JLTWxJOERk04fm8hYENDo0PWSP3YLQKxevLwWtxemGcl5JJEzN4iqfDlRve0ckyfFaOBu4xbNH/wZw=="], "ts-pattern": ["ts-pattern@5.9.0", "", {}, "sha512-6s5V71mX8qBUmlgbrfL33xDUwO0fq48rxAu2LBE11WBeGdpCPOsXksQbZJHvHwhrd3QjUusd3mAOM5Gg0mFBLg=="], @@ -2213,7 +2179,7 @@ "typedarray": ["typedarray@0.0.6", "", {}, "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA=="], - "typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="], + "typescript": ["typescript@6.0.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw=="], "ufo": ["ufo@1.6.4", "", {}, "sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA=="], @@ -2225,7 +2191,7 @@ "undici": ["undici@7.28.0", "", {}, "sha512-cRZYrTDwWznlnRiPjggAGxZXanty6M8RV1ff8Wm4LWXBp7/IG8v5DnOm74DtUBp9OONpK75YlPnIjQqX0dBDtA=="], - "undici-types": ["undici-types@7.24.6", "", {}, "sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg=="], + "undici-types": ["undici-types@8.3.0", "", {}, "sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ=="], "unicorn-magic": ["unicorn-magic@0.3.0", "", {}, "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA=="], @@ -2233,6 +2199,8 @@ "unist-util-position-from-estree": ["unist-util-position-from-estree@2.0.0", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ=="], + "unist-util-remove-position": ["unist-util-remove-position@5.0.0", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-visit": "^5.0.0" } }, "sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q=="], + "unist-util-stringify-position": ["unist-util-stringify-position@4.0.0", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ=="], "unist-util-visit": ["unist-util-visit@5.1.0", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0", "unist-util-visit-parents": "^6.0.0" } }, "sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg=="], @@ -2285,19 +2253,19 @@ "wildcard-match": ["wildcard-match@5.1.4", "", {}, "sha512-wldeCaczs8XXq7hj+5d/F38JE2r7EXgb6WQDM84RVwxy81T/sxB5e9+uZLK9Q9oNz1mlvjut+QtvgaOQFPVq/g=="], - "windows-release": ["windows-release@6.1.0", "", { "dependencies": { "execa": "^8.0.1" } }, "sha512-1lOb3qdzw6OFmOzoY0nauhLG72TpWtb5qgYPiSh/62rjc1XidBSDio2qw0pwHh17VINF217ebIkZJdFLZFn9SA=="], + "windows-release": ["windows-release@7.1.1", "", { "dependencies": { "powershell-utils": "^0.2.0" } }, "sha512-0GBwC9WmR8Bm3WYiz3FC391054BsFHZ2gzBVdYj9uj5eIVYzbn/YPYCYW9SWdh9vwnLuzpn1UGwJKiMG4F236w=="], "word-wrap": ["word-wrap@1.2.5", "", {}, "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA=="], "wordwrap": ["wordwrap@1.0.0", "", {}, "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q=="], - "wrap-ansi": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="], + "wrap-ansi": ["wrap-ansi@9.0.2", "", { "dependencies": { "ansi-styles": "^6.2.1", "string-width": "^7.0.0", "strip-ansi": "^7.1.0" } }, "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww=="], "wrappy": ["wrappy@1.0.2", "", {}, "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="], "ws": ["ws@8.21.1", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-+0NTnW77fFN/DjQi6k/Sq/Yvk4Sgajw7urW8V+asjXnRgDs9gyGkdb7EzgfhA4goXsRIZKE28fzIXBHEzhuiWw=="], - "wsl-utils": ["wsl-utils@0.1.0", "", { "dependencies": { "is-wsl": "^3.1.0" } }, "sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw=="], + "wsl-utils": ["wsl-utils@0.3.1", "", { "dependencies": { "is-wsl": "^3.1.0", "powershell-utils": "^0.1.0" } }, "sha512-g/eziiSUNBSsdDJtCLB8bdYEUMj4jR7AGeUo96p/3dTafgjHhpF4RiCFPiRILwjQoDXx5MqkBr4fwWtR3Ky4Wg=="], "xml-name-validator": ["xml-name-validator@4.0.0", "", {}, "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw=="], @@ -2313,9 +2281,9 @@ "yaml-eslint-parser": ["yaml-eslint-parser@2.1.0", "", { "dependencies": { "eslint-visitor-keys": "^5.0.0", "yaml": "^2.0.0" } }, "sha512-1zo9KRfp6vIAXBEhWAz09ex3hUwh3T+/6dGbGteHvNseA0Uk4FgQnPES55klZ6cDzSy9FpgKS0D/CoLUvCCj4w=="], - "yargs": ["yargs@17.7.3", "", { "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.3", "y18n": "^5.0.5", "yargs-parser": "^21.1.1" } }, "sha512-GZtjxm/J/4TSxuL3FNYjCmLktBTnIw/rVmKSIyKeYAZpmJB2ig9VauCC5xsa82GNKVKDAqpOn3KVzNt0zmrU0g=="], + "yargs": ["yargs@18.0.0", "", { "dependencies": { "cliui": "^9.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "string-width": "^7.2.0", "y18n": "^5.0.5", "yargs-parser": "^22.0.0" } }, "sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg=="], - "yargs-parser": ["yargs-parser@21.1.1", "", {}, "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw=="], + "yargs-parser": ["yargs-parser@22.0.0", "", {}, "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw=="], "yauzl": ["yauzl@3.4.0", "", { "dependencies": { "pend": "~1.2.0" } }, "sha512-jIH9yLR9wqr0wOS0TpBvo/g/2UgZH5qePVbjgRliiF0BYvOZyaBknKsF+x9Iht0O6sqgnB93rCICdOZFecJuDw=="], @@ -2325,8 +2293,6 @@ "yoctocolors": ["yoctocolors@2.1.2", "", {}, "sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug=="], - "yoctocolors-cjs": ["yoctocolors-cjs@2.1.3", "", {}, "sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw=="], - "zod": ["zod@4.4.3", "", {}, "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ=="], "zod-validation-error": ["zod-validation-error@4.0.2", "", { "peerDependencies": { "zod": "^3.25.0 || ^4.0.0" } }, "sha512-Q6/nZLe6jxuU80qb/4uJ4t5v2VEZ44lzQjPDhYJNztRQ4wyWc6VF3D3Kb/fAuPetZQnhS3hnajCf9CsWesghLQ=="], @@ -2339,33 +2305,31 @@ "@babel/helper-compilation-targets/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], - "@commitlint/config-conventional/conventional-changelog-conventionalcommits": ["conventional-changelog-conventionalcommits@9.3.1", "", { "dependencies": { "compare-func": "^2.0.0" } }, "sha512-dTYtpIacRpcZgrvBYvBfArMmK2xvIpv2TaxM0/ZI5CBtNUzvF2x0t15HsbRABWprS6UPmvj+PzHVjSx4qAVKyw=="], - "@commitlint/config-validator/ajv": ["ajv@8.20.0", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA=="], + "@commitlint/parse/conventional-changelog-angular": ["conventional-changelog-angular@9.2.1", "", { "dependencies": { "@conventional-changelog/template": "^1.2.1" } }, "sha512-oWSL6ZhnXbYraOFTK3PgRAQJ8fADDAEv5K6AdeyQPLvjFmhG8+ejL0jZZp/R7vTmGJaBvZEE+sE7dB4bCv7sAw=="], + + "@commitlint/read/@conventional-changelog/git-client": ["@conventional-changelog/git-client@3.1.0", "", { "dependencies": { "@simple-libs/child-process-utils": "^2.0.0", "@simple-libs/stream-utils": "^2.0.0", "semver": "^7.5.2" }, "peerDependencies": { "conventional-commits-filter": "^6.0.1", "conventional-commits-parser": "^7.0.1" }, "optionalPeers": ["conventional-commits-filter", "conventional-commits-parser"] }, "sha512-Tqa/gHco2WJWa740NRjOrfKVvzIqxkZpecb8bemaQ8sKM5PXb1UK4uTyTb/1wIqNuOVaDOFxyBdhTIQZn6gdjQ=="], + + "@conventional-changelog/git-client/conventional-commits-parser": ["conventional-commits-parser@6.4.0", "", { "dependencies": { "@simple-libs/stream-utils": "^1.2.0", "meow": "^13.0.0" }, "bin": { "conventional-commits-parser": "dist/cli/index.js" } }, "sha512-tvRg7FIBNlyPzjdG8wWRlPHQJJHI7DylhtRGeU9Lq+JuoPh5BKpPRX83ZdLrvXuOSu5Eo/e7SzOQhU4Hd2Miuw=="], + "@emotion/babel-plugin/convert-source-map": ["convert-source-map@1.9.0", "", {}, "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A=="], "@emotion/babel-plugin/source-map": ["source-map@0.5.7", "", {}, "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ=="], "@emotion/serialize/csstype": ["csstype@3.2.3", "", {}, "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ=="], - "@es-joy/jsdoccomment/comment-parser": ["comment-parser@1.4.7", "", {}, "sha512-0h+uSNtQGW3D98eQt3jJ8L06Fves8hncB4V/PKdw/Qb8Hnk19VaKuTr55UNRYiSoVa7WwrFls+rh3ux9agmkeQ=="], - "@eslint-community/eslint-plugin-eslint-comments/ignore": ["ignore@7.0.6", "", {}, "sha512-BAg6QkE8W+TuQLrrw0Ugr7HegXduRuuj8/ti2kSOc+jz1dmx8/WNcjr6XGnq5YpDWxFwwaavqD0+jIUOKelTsw=="], "@eslint-community/eslint-utils/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="], - "@eslint/compat/@eslint/core": ["@eslint/core@1.2.1", "", { "dependencies": { "@types/json-schema": "^7.0.15" } }, "sha512-MwcE1P+AZ4C6DWlpin/OmOA54mmIZ/+xZuJiQd4SyB29oAJjN30UW9wkKNptW2ctp4cEsvhlLY/CsQ1uoHDloQ=="], - - "@eslint/config-array/minimatch": ["minimatch@3.1.5", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w=="], - - "@eslint/eslintrc/globals": ["globals@14.0.0", "", {}, "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ=="], - - "@eslint/eslintrc/minimatch": ["minimatch@3.1.5", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w=="], + "@eslint/config-array/minimatch": ["minimatch@10.2.5", "", { "dependencies": { "brace-expansion": "^5.0.5" } }, "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg=="], "@eslint/markdown/mdast-util-from-markdown": ["mdast-util-from-markdown@2.0.3", "", { "dependencies": { "@types/mdast": "^4.0.0", "@types/unist": "^3.0.0", "decode-named-character-reference": "^1.0.0", "devlop": "^1.0.0", "mdast-util-to-string": "^4.0.0", "micromark": "^4.0.0", "micromark-util-decode-numeric-character-reference": "^2.0.0", "micromark-util-decode-string": "^2.0.0", "micromark-util-normalize-identifier": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0", "unist-util-stringify-position": "^4.0.0" } }, "sha512-W4mAWTvSlKvf8L6J+VN9yLSqQ9AOAAvHuoDAmPkz4dHf553m5gVj2ejadHJhoJmcmxEnOv6Pa8XJhpxE93kb8Q=="], - "@inquirer/core/wrap-ansi": ["wrap-ansi@6.2.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA=="], + "@img/sharp-freebsd-wasm32/@img/sharp-wasm32": ["@img/sharp-wasm32@0.35.3", "", { "dependencies": { "@emnapi/runtime": "^1.11.1" } }, "sha512-cZ0XkcYGpHZkqW6iCkqTcmUC0CD9DhD5d/qeZlZkfRBn6GnHniZXLUo5+9xw8Iv76YE6LQFN9YNBlKREcCG76w=="], + + "@img/sharp-webcontainers-wasm32/@img/sharp-wasm32": ["@img/sharp-wasm32@0.35.3", "", { "dependencies": { "@emnapi/runtime": "^1.11.1" } }, "sha512-cZ0XkcYGpHZkqW6iCkqTcmUC0CD9DhD5d/qeZlZkfRBn6GnHniZXLUo5+9xw8Iv76YE6LQFN9YNBlKREcCG76w=="], "@lexical/react/react-error-boundary": ["react-error-boundary@6.1.2", "", { "peerDependencies": { "react": "^18.0.0 || ^19.0.0" } }, "sha512-3DpCr5HVdZ0caUjYE/kIHBEJN0mNP3ZCgf16c48uJ5TbWjorKVp+YG8W3XqlJ7vJAVNw6wNIImyPXmFydwmyng=="], @@ -2379,14 +2343,20 @@ "@rolldown/binding-wasm32-wasi/@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.6", "", { "dependencies": { "@tybys/wasm-util": "^0.10.3" }, "peerDependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1" } }, "sha512-ZLv/JdUfkvOy9eCnnBaGfiO+XimbjebAeO+MRQqD/B+FR1tnRN0tpKSJHRbE8sFfS6aqsXZ67TQjfwfsxULVbg=="], + "@stylistic/eslint-plugin/eslint-visitor-keys": ["eslint-visitor-keys@4.2.1", "", {}, "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ=="], + + "@stylistic/eslint-plugin/espree": ["espree@10.4.0", "", { "dependencies": { "acorn": "^8.15.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^4.2.1" } }, "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ=="], + + "@types/busboy/@types/node": ["@types/node@25.9.5", "", { "dependencies": { "undici-types": ">=7.24.0 <7.24.7" } }, "sha512-OScDchr2fwuUmWdf4kZ9h7PcJiYDVInhJizG/biAq3cAvqwYktuy/TYGGdZNMtNTFUP7rnb0NU4TUdm82kt4Rg=="], + "@types/react/csstype": ["csstype@3.2.3", "", {}, "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ=="], + "@types/ws/@types/node": ["@types/node@25.9.5", "", { "dependencies": { "undici-types": ">=7.24.0 <7.24.7" } }, "sha512-OScDchr2fwuUmWdf4kZ9h7PcJiYDVInhJizG/biAq3cAvqwYktuy/TYGGdZNMtNTFUP7rnb0NU4TUdm82kt4Rg=="], + "@typescript-eslint/eslint-plugin/ignore": ["ignore@7.0.6", "", {}, "sha512-BAg6QkE8W+TuQLrrw0Ugr7HegXduRuuj8/ti2kSOc+jz1dmx8/WNcjr6XGnq5YpDWxFwwaavqD0+jIUOKelTsw=="], "@typescript-eslint/typescript-estree/minimatch": ["minimatch@10.2.5", "", { "dependencies": { "brace-expansion": "^5.0.5" } }, "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg=="], - "@typescript-eslint/visitor-keys/eslint-visitor-keys": ["eslint-visitor-keys@5.0.1", "", {}, "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA=="], - "@vue/compiler-core/estree-walker": ["estree-walker@2.0.2", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="], "@vue/compiler-sfc/estree-walker": ["estree-walker@2.0.2", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="], @@ -2399,15 +2369,19 @@ "binary-version/execa": ["execa@8.0.1", "", { "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^8.0.1", "human-signals": "^5.0.0", "is-stream": "^3.0.0", "merge-stream": "^2.0.0", "npm-run-path": "^5.1.0", "onetime": "^6.0.0", "signal-exit": "^4.1.0", "strip-final-newline": "^3.0.0" } }, "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg=="], + "buffer-image-size/@types/node": ["@types/node@25.9.5", "", { "dependencies": { "undici-types": ">=7.24.0 <7.24.7" } }, "sha512-OScDchr2fwuUmWdf4kZ9h7PcJiYDVInhJizG/biAq3cAvqwYktuy/TYGGdZNMtNTFUP7rnb0NU4TUdm82kt4Rg=="], + "c12/chokidar": ["chokidar@5.0.0", "", { "dependencies": { "readdirp": "^5.0.0" } }, "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw=="], "cacheable-request/keyv": ["keyv@5.6.0", "", { "dependencies": { "@keyv/serialize": "^1.1.1" } }, "sha512-CYDD3SOtsHtyXeEORYRx2qBtpDJFjRTGXUtmNEMGyzYOKj1TE3tycdlho7kA1Ufx9OYWZzg52QFBGALTirzDSw=="], "chokidar/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="], - "clean-regexp/escape-string-regexp": ["escape-string-regexp@1.0.5", "", {}, "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg=="], + "conventional-changelog/conventional-commits-parser": ["conventional-commits-parser@6.4.0", "", { "dependencies": { "@simple-libs/stream-utils": "^1.2.0", "meow": "^13.0.0" }, "bin": { "conventional-commits-parser": "dist/cli/index.js" } }, "sha512-tvRg7FIBNlyPzjdG8wWRlPHQJJHI7DylhtRGeU9Lq+JuoPh5BKpPRX83ZdLrvXuOSu5Eo/e7SzOQhU4Hd2Miuw=="], + + "conventional-commits-parser/@simple-libs/stream-utils": ["@simple-libs/stream-utils@2.0.0", "", {}, "sha512-fCTuZK4QBa+39Oz9l4OGfJfz+GpwCp3AqO7Zch3to99xHPgstVsRFpeQ8LNd2o1Gv8raL2mCFwiaHh7bFSp5DQ=="], - "cliui/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], + "conventional-recommended-bump/conventional-commits-parser": ["conventional-commits-parser@6.4.0", "", { "dependencies": { "@simple-libs/stream-utils": "^1.2.0", "meow": "^13.0.0" }, "bin": { "conventional-commits-parser": "dist/cli/index.js" } }, "sha512-tvRg7FIBNlyPzjdG8wWRlPHQJJHI7DylhtRGeU9Lq+JuoPh5BKpPRX83ZdLrvXuOSu5Eo/e7SzOQhU4Hd2Miuw=="], "copyfiles/minimatch": ["minimatch@3.1.5", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w=="], @@ -2417,34 +2391,14 @@ "escodegen/source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="], - "eslint/minimatch": ["minimatch@3.1.5", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w=="], + "eslint/minimatch": ["minimatch@10.2.5", "", { "dependencies": { "brace-expansion": "^5.0.5" } }, "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg=="], "eslint-flat-config-utils/@eslint/config-helpers": ["@eslint/config-helpers@0.5.5", "", { "dependencies": { "@eslint/core": "^1.2.1" } }, "sha512-eIJYKTCECbP/nsKaaruF6LW967mtbQbsw4JTtSVkUQc9MneSkbrgPJAbKl9nWr0ZeowV8BfsarBmPpBzGelA2w=="], - "eslint-plugin-jsdoc/@es-joy/jsdoccomment": ["@es-joy/jsdoccomment@0.86.0", "", { "dependencies": { "@types/estree": "^1.0.8", "@typescript-eslint/types": "^8.58.0", "comment-parser": "1.4.6", "esquery": "^1.7.0", "jsdoc-type-pratt-parser": "~7.2.0" } }, "sha512-ukZmRQ81WiTpDWO6D/cTBM7XbrNtutHKvAVnZN/8pldAwLoJArGOvkNyxPTBGsPjsoaQBJxlH+tE2TNA/92Qgw=="], - - "eslint-plugin-jsdoc/espree": ["espree@11.2.0", "", { "dependencies": { "acorn": "^8.16.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^5.0.1" } }, "sha512-7p3DrVEIopW1B1avAGLuCSh1jubc01H2JHc8B4qqGblmg5gI9yumBgACjWo4JlIc04ufug4xJ3SQI8HkS/Rgzw=="], - - "eslint-plugin-jsonc/@eslint/core": ["@eslint/core@1.2.1", "", { "dependencies": { "@types/json-schema": "^7.0.15" } }, "sha512-MwcE1P+AZ4C6DWlpin/OmOA54mmIZ/+xZuJiQd4SyB29oAJjN30UW9wkKNptW2ctp4cEsvhlLY/CsQ1uoHDloQ=="], - - "eslint-plugin-jsonc/@eslint/plugin-kit": ["@eslint/plugin-kit@0.7.2", "", { "dependencies": { "@eslint/core": "^1.2.1", "levn": "^0.4.1" } }, "sha512-+CNAzxglkrpNf/kKywqQfk74QjtceuOE7Qm+AF8miRvPF/wmmK5+OJOgVh3AVTT3RP2mH3+FOaxlE5v72owk0A=="], - "eslint-plugin-n/get-tsconfig": ["get-tsconfig@4.14.0", "", { "dependencies": { "resolve-pkg-maps": "^1.0.0" } }, "sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA=="], "eslint-plugin-n/globals": ["globals@15.15.0", "", {}, "sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg=="], - "eslint-plugin-regexp/comment-parser": ["comment-parser@1.4.7", "", {}, "sha512-0h+uSNtQGW3D98eQt3jJ8L06Fves8hncB4V/PKdw/Qb8Hnk19VaKuTr55UNRYiSoVa7WwrFls+rh3ux9agmkeQ=="], - - "eslint-plugin-toml/@eslint/core": ["@eslint/core@1.2.1", "", { "dependencies": { "@types/json-schema": "^7.0.15" } }, "sha512-MwcE1P+AZ4C6DWlpin/OmOA54mmIZ/+xZuJiQd4SyB29oAJjN30UW9wkKNptW2ctp4cEsvhlLY/CsQ1uoHDloQ=="], - - "eslint-plugin-toml/@eslint/plugin-kit": ["@eslint/plugin-kit@0.7.2", "", { "dependencies": { "@eslint/core": "^1.2.1", "levn": "^0.4.1" } }, "sha512-+CNAzxglkrpNf/kKywqQfk74QjtceuOE7Qm+AF8miRvPF/wmmK5+OJOgVh3AVTT3RP2mH3+FOaxlE5v72owk0A=="], - - "eslint-plugin-unicorn/globals": ["globals@16.5.0", "", {}, "sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ=="], - - "eslint-plugin-yml/@eslint/core": ["@eslint/core@1.2.1", "", { "dependencies": { "@types/json-schema": "^7.0.15" } }, "sha512-MwcE1P+AZ4C6DWlpin/OmOA54mmIZ/+xZuJiQd4SyB29oAJjN30UW9wkKNptW2ctp4cEsvhlLY/CsQ1uoHDloQ=="], - - "eslint-plugin-yml/@eslint/plugin-kit": ["@eslint/plugin-kit@0.7.2", "", { "dependencies": { "@eslint/core": "^1.2.1", "levn": "^0.4.1" } }, "sha512-+CNAzxglkrpNf/kKywqQfk74QjtceuOE7Qm+AF8miRvPF/wmmK5+OJOgVh3AVTT3RP2mH3+FOaxlE5v72owk0A=="], - "eslint-plugin-yml/escape-string-regexp": ["escape-string-regexp@5.0.0", "", {}, "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw=="], "espree/acorn": ["acorn@8.17.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg=="], @@ -2459,14 +2413,14 @@ "handlebars/source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="], + "happy-dom/@types/node": ["@types/node@25.9.5", "", { "dependencies": { "undici-types": ">=7.24.0 <7.24.7" } }, "sha512-OScDchr2fwuUmWdf4kZ9h7PcJiYDVInhJizG/biAq3cAvqwYktuy/TYGGdZNMtNTFUP7rnb0NU4TUdm82kt4Rg=="], + "hosted-git-info/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="], "import-fresh/resolve-from": ["resolve-from@4.0.0", "", {}, "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="], "jsonc-eslint-parser/acorn": ["acorn@8.17.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg=="], - "jsonc-eslint-parser/eslint-visitor-keys": ["eslint-visitor-keys@5.0.1", "", {}, "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA=="], - "make-asynchronous/type-fest": ["type-fest@4.41.0", "", {}, "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA=="], "mdast-util-find-and-replace/escape-string-regexp": ["escape-string-regexp@5.0.0", "", {}, "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw=="], @@ -2485,6 +2439,8 @@ "mdast-util-gfm-task-list-item/mdast-util-from-markdown": ["mdast-util-from-markdown@2.0.3", "", { "dependencies": { "@types/mdast": "^4.0.0", "@types/unist": "^3.0.0", "decode-named-character-reference": "^1.0.0", "devlop": "^1.0.0", "mdast-util-to-string": "^4.0.0", "micromark": "^4.0.0", "micromark-util-decode-numeric-character-reference": "^2.0.0", "micromark-util-decode-string": "^2.0.0", "micromark-util-normalize-identifier": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0", "unist-util-stringify-position": "^4.0.0" } }, "sha512-W4mAWTvSlKvf8L6J+VN9yLSqQ9AOAAvHuoDAmPkz4dHf553m5gVj2ejadHJhoJmcmxEnOv6Pa8XJhpxE93kb8Q=="], + "mdast-util-math/mdast-util-from-markdown": ["mdast-util-from-markdown@2.0.3", "", { "dependencies": { "@types/mdast": "^4.0.0", "@types/unist": "^3.0.0", "decode-named-character-reference": "^1.0.0", "devlop": "^1.0.0", "mdast-util-to-string": "^4.0.0", "micromark": "^4.0.0", "micromark-util-decode-numeric-character-reference": "^2.0.0", "micromark-util-decode-string": "^2.0.0", "micromark-util-normalize-identifier": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0", "unist-util-stringify-position": "^4.0.0" } }, "sha512-W4mAWTvSlKvf8L6J+VN9yLSqQ9AOAAvHuoDAmPkz4dHf553m5gVj2ejadHJhoJmcmxEnOv6Pa8XJhpxE93kb8Q=="], + "mdast-util-mdx-jsx/mdast-util-from-markdown": ["mdast-util-from-markdown@2.0.3", "", { "dependencies": { "@types/mdast": "^4.0.0", "@types/unist": "^3.0.0", "decode-named-character-reference": "^1.0.0", "devlop": "^1.0.0", "mdast-util-to-string": "^4.0.0", "micromark": "^4.0.0", "micromark-util-decode-numeric-character-reference": "^2.0.0", "micromark-util-decode-string": "^2.0.0", "micromark-util-normalize-identifier": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0", "unist-util-stringify-position": "^4.0.0" } }, "sha512-W4mAWTvSlKvf8L6J+VN9yLSqQ9AOAAvHuoDAmPkz4dHf553m5gVj2ejadHJhoJmcmxEnOv6Pa8XJhpxE93kb8Q=="], "micromatch/picomatch": ["picomatch@2.3.2", "", {}, "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA=="], @@ -2497,14 +2453,14 @@ "new-github-release-url/type-fest": ["type-fest@2.19.0", "", {}, "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA=="], + "next/sharp": ["sharp@0.34.5", "", { "dependencies": { "@img/colour": "^1.0.0", "detect-libc": "^2.1.2", "semver": "^7.7.3" }, "optionalDependencies": { "@img/sharp-darwin-arm64": "0.34.5", "@img/sharp-darwin-x64": "0.34.5", "@img/sharp-libvips-darwin-arm64": "1.2.4", "@img/sharp-libvips-darwin-x64": "1.2.4", "@img/sharp-libvips-linux-arm": "1.2.4", "@img/sharp-libvips-linux-arm64": "1.2.4", "@img/sharp-libvips-linux-ppc64": "1.2.4", "@img/sharp-libvips-linux-riscv64": "1.2.4", "@img/sharp-libvips-linux-s390x": "1.2.4", "@img/sharp-libvips-linux-x64": "1.2.4", "@img/sharp-libvips-linuxmusl-arm64": "1.2.4", "@img/sharp-libvips-linuxmusl-x64": "1.2.4", "@img/sharp-linux-arm": "0.34.5", "@img/sharp-linux-arm64": "0.34.5", "@img/sharp-linux-ppc64": "0.34.5", "@img/sharp-linux-riscv64": "0.34.5", "@img/sharp-linux-s390x": "0.34.5", "@img/sharp-linux-x64": "0.34.5", "@img/sharp-linuxmusl-arm64": "0.34.5", "@img/sharp-linuxmusl-x64": "0.34.5", "@img/sharp-wasm32": "0.34.5", "@img/sharp-win32-arm64": "0.34.5", "@img/sharp-win32-ia32": "0.34.5", "@img/sharp-win32-x64": "0.34.5" } }, "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg=="], + "noms/readable-stream": ["readable-stream@1.0.34", "", { "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.1", "isarray": "0.0.1", "string_decoder": "~0.10.x" } }, "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg=="], "npm-run-path/path-key": ["path-key@4.0.0", "", {}, "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ=="], "nypm/citty": ["citty@0.2.2", "", {}, "sha512-+6vJA3L98yv+IdfKGZHBNiGW5KHn22e/JwID0Strsz8h4S/csAu/OuICwxrg44k5MRiZHWIo8XXuJgQTriRP4w=="], - "ora/chalk": ["chalk@5.6.2", "", {}, "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA=="], - "ora/string-width": ["string-width@8.2.2", "", { "dependencies": { "get-east-asian-width": "^1.5.0", "strip-ansi": "^7.1.2" } }, "sha512-GaPUh5gfdrYzqeVNZvUfT23vYYxXzKYidUcnMtJg/3rxRV63EFZy3k6xfKlmfeJD0176lnUV/Usr3XcwSvFzpg=="], "parse-entities/@types/unist": ["@types/unist@2.0.11", "", {}, "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA=="], @@ -2515,20 +2471,16 @@ "payload/ajv": ["ajv@8.18.0", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A=="], - "pino-pretty/strip-json-comments": ["strip-json-comments@5.0.3", "", {}, "sha512-1tB5mhVo7U+ETBKNf92xT4hrQa3pm0MZ0PQvuDnWgAAGHDsfp4lPSpiS6psrSiet87wyGPh9ft6wmhOMQ0hDiw=="], - "react-datepicker/date-fns": ["date-fns@3.6.0", "", {}, "sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww=="], "react-dom/scheduler": ["scheduler@0.27.0", "", {}, "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q=="], "readdirp/picomatch": ["picomatch@2.3.2", "", {}, "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA=="], - "release-it/semver": ["semver@7.7.3", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="], + "release-it/semver": ["semver@7.7.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="], "release-it/tinyglobby": ["tinyglobby@0.2.15", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.3" } }, "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ=="], - "release-it/undici": ["undici@6.23.0", "", {}, "sha512-VfQPToRA5FZs/qJxLIinmU59u0r7LXqoJkCzinq3ckNJp3vKEh7jTWN589YQ5+aoAC/TGRLyJLCPKcLQbM8r9g=="], - "rimraf/glob": ["glob@13.0.6", "", { "dependencies": { "minimatch": "^10.2.2", "minipass": "^7.1.3", "path-scurry": "^2.0.2" } }, "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw=="], "seek-bzip/commander": ["commander@6.2.1", "", {}, "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA=="], @@ -2539,37 +2491,37 @@ "spdx-correct/spdx-expression-parse": ["spdx-expression-parse@3.0.1", "", { "dependencies": { "spdx-exceptions": "^2.1.0", "spdx-license-ids": "^3.0.0" } }, "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q=="], - "string-width/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], - "strip-dirs/is-plain-obj": ["is-plain-obj@1.1.0", "", {}, "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg=="], "through2/readable-stream": ["readable-stream@2.3.8", "", { "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", "isarray": "~1.0.0", "process-nextick-args": "~2.0.0", "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" } }, "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA=="], - "toml-eslint-parser/eslint-visitor-keys": ["eslint-visitor-keys@5.0.1", "", {}, "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA=="], - "validate-npm-package-license/spdx-expression-parse": ["spdx-expression-parse@3.0.1", "", { "dependencies": { "spdx-exceptions": "^2.1.0", "spdx-license-ids": "^3.0.0" } }, "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q=="], "vite/postcss": ["postcss@8.5.19", "", { "dependencies": { "nanoid": "^3.3.12", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-Mz8SaolMd8nB+G13WkORcxQKHZ/NE4xXevtkJHVuG+guo9/wYKlIMTKAqGdEmYOXR2ijPjTYNHssizdaVSUNdQ=="], - "vue-eslint-parser/eslint-visitor-keys": ["eslint-visitor-keys@5.0.1", "", {}, "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA=="], + "vue-eslint-parser/eslint-scope": ["eslint-scope@8.4.0", "", { "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" } }, "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg=="], - "which/isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="], + "vue-eslint-parser/espree": ["espree@10.4.0", "", { "dependencies": { "acorn": "^8.15.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^4.2.1" } }, "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ=="], - "windows-release/execa": ["execa@8.0.1", "", { "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^8.0.1", "human-signals": "^5.0.0", "is-stream": "^3.0.0", "merge-stream": "^2.0.0", "npm-run-path": "^5.1.0", "onetime": "^6.0.0", "signal-exit": "^4.1.0", "strip-final-newline": "^3.0.0" } }, "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg=="], + "which/isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="], - "wrap-ansi/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], + "windows-release/powershell-utils": ["powershell-utils@0.2.0", "", {}, "sha512-ZlsFlG7MtSFCoc5xreOvBAozCJ6Pf06opgJjh9ONEv418xpZSAzNjstD36C6+JwOnfSqOW/9uDkqKjezTdxZhw=="], "xss/commander": ["commander@2.20.3", "", {}, "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="], - "yaml-eslint-parser/eslint-visitor-keys": ["eslint-visitor-keys@5.0.1", "", {}, "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA=="], - "@commitlint/config-validator/ajv/json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="], - "@eslint/config-array/minimatch/brace-expansion": ["brace-expansion@1.1.16", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-IDw48K2/2kRkg9LdJxurvq3lV3aBgq0REY89duEqFRthjlPdXHKMj7EnQOXVckxzgisinf3nHfrcE2FufFLXMw=="], + "@commitlint/read/@conventional-changelog/git-client/@simple-libs/child-process-utils": ["@simple-libs/child-process-utils@2.0.0", "", { "dependencies": { "@simple-libs/stream-utils": "^2.0.0" } }, "sha512-dvNoRKLijXnD0XoJAz94pbNuB5GQgDr55UhpSPhffDkTT0Cmcqh9jSCOtwfT2d4H6MI9E7c4SgtMuJXZ6F3c6A=="], + + "@commitlint/read/@conventional-changelog/git-client/@simple-libs/stream-utils": ["@simple-libs/stream-utils@2.0.0", "", {}, "sha512-fCTuZK4QBa+39Oz9l4OGfJfz+GpwCp3AqO7Zch3to99xHPgstVsRFpeQ8LNd2o1Gv8raL2mCFwiaHh7bFSp5DQ=="], + + "@eslint/config-array/minimatch/brace-expansion": ["brace-expansion@5.0.7", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-7oFy703dxfY3/NLxC1fh2SUCQ0H9rmAY+5EpDVfXjUTTs+HEwR2nYaqLv+GWcTsumwxPfiz6CzCNkwXwBUwqCA=="], - "@eslint/eslintrc/minimatch/brace-expansion": ["brace-expansion@1.1.16", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-IDw48K2/2kRkg9LdJxurvq3lV3aBgq0REY89duEqFRthjlPdXHKMj7EnQOXVckxzgisinf3nHfrcE2FufFLXMw=="], + "@stylistic/eslint-plugin/espree/acorn": ["acorn@8.17.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg=="], - "@inquirer/core/wrap-ansi/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], + "@types/busboy/@types/node/undici-types": ["undici-types@7.24.6", "", {}, "sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg=="], + + "@types/ws/@types/node/undici-types": ["undici-types@7.24.6", "", {}, "sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg=="], "@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@5.0.7", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-7oFy703dxfY3/NLxC1fh2SUCQ0H9rmAY+5EpDVfXjUTTs+HEwR2nYaqLv+GWcTsumwxPfiz6CzCNkwXwBUwqCA=="], @@ -2587,55 +2539,85 @@ "binary-version/execa/strip-final-newline": ["strip-final-newline@3.0.0", "", {}, "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw=="], - "c12/chokidar/readdirp": ["readdirp@5.0.0", "", {}, "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ=="], + "buffer-image-size/@types/node/undici-types": ["undici-types@7.24.6", "", {}, "sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg=="], - "cliui/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], + "c12/chokidar/readdirp": ["readdirp@5.0.0", "", {}, "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ=="], "copyfiles/minimatch/brace-expansion": ["brace-expansion@1.1.16", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-IDw48K2/2kRkg9LdJxurvq3lV3aBgq0REY89duEqFRthjlPdXHKMj7EnQOXVckxzgisinf3nHfrcE2FufFLXMw=="], "copyfiles/yargs/cliui": ["cliui@7.0.4", "", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", "wrap-ansi": "^7.0.0" } }, "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ=="], + "copyfiles/yargs/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], + "copyfiles/yargs/yargs-parser": ["yargs-parser@20.2.9", "", {}, "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w=="], - "eslint-flat-config-utils/@eslint/config-helpers/@eslint/core": ["@eslint/core@1.2.1", "", { "dependencies": { "@types/json-schema": "^7.0.15" } }, "sha512-MwcE1P+AZ4C6DWlpin/OmOA54mmIZ/+xZuJiQd4SyB29oAJjN30UW9wkKNptW2ctp4cEsvhlLY/CsQ1uoHDloQ=="], + "eslint/minimatch/brace-expansion": ["brace-expansion@5.0.7", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-7oFy703dxfY3/NLxC1fh2SUCQ0H9rmAY+5EpDVfXjUTTs+HEwR2nYaqLv+GWcTsumwxPfiz6CzCNkwXwBUwqCA=="], - "eslint-plugin-jsdoc/espree/acorn": ["acorn@8.17.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg=="], + "glob/minimatch/brace-expansion": ["brace-expansion@1.1.16", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-IDw48K2/2kRkg9LdJxurvq3lV3aBgq0REY89duEqFRthjlPdXHKMj7EnQOXVckxzgisinf3nHfrcE2FufFLXMw=="], - "eslint-plugin-jsdoc/espree/eslint-visitor-keys": ["eslint-visitor-keys@5.0.1", "", {}, "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA=="], + "happy-dom/@types/node/undici-types": ["undici-types@7.24.6", "", {}, "sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg=="], - "eslint/minimatch/brace-expansion": ["brace-expansion@1.1.16", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-IDw48K2/2kRkg9LdJxurvq3lV3aBgq0REY89duEqFRthjlPdXHKMj7EnQOXVckxzgisinf3nHfrcE2FufFLXMw=="], + "mlly/pkg-types/confbox": ["confbox@0.1.8", "", {}, "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w=="], - "glob/minimatch/brace-expansion": ["brace-expansion@1.1.16", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-IDw48K2/2kRkg9LdJxurvq3lV3aBgq0REY89duEqFRthjlPdXHKMj7EnQOXVckxzgisinf3nHfrcE2FufFLXMw=="], + "next/sharp/@img/sharp-darwin-arm64": ["@img/sharp-darwin-arm64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-arm64": "1.2.4" }, "os": "darwin", "cpu": "arm64" }, "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w=="], - "mlly/pkg-types/confbox": ["confbox@0.1.8", "", {}, "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w=="], + "next/sharp/@img/sharp-darwin-x64": ["@img/sharp-darwin-x64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-x64": "1.2.4" }, "os": "darwin", "cpu": "x64" }, "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw=="], - "noms/readable-stream/isarray": ["isarray@0.0.1", "", {}, "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ=="], + "next/sharp/@img/sharp-libvips-darwin-arm64": ["@img/sharp-libvips-darwin-arm64@1.2.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g=="], - "noms/readable-stream/string_decoder": ["string_decoder@0.10.31", "", {}, "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ=="], + "next/sharp/@img/sharp-libvips-darwin-x64": ["@img/sharp-libvips-darwin-x64@1.2.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg=="], - "payload/ajv/json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="], + "next/sharp/@img/sharp-libvips-linux-arm": ["@img/sharp-libvips-linux-arm@1.2.4", "", { "os": "linux", "cpu": "arm" }, "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A=="], - "rimraf/glob/minimatch": ["minimatch@10.2.5", "", { "dependencies": { "brace-expansion": "^5.0.5" } }, "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg=="], + "next/sharp/@img/sharp-libvips-linux-arm64": ["@img/sharp-libvips-linux-arm64@1.2.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw=="], - "string-width/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], + "next/sharp/@img/sharp-libvips-linux-ppc64": ["@img/sharp-libvips-linux-ppc64@1.2.4", "", { "os": "linux", "cpu": "ppc64" }, "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA=="], - "through2/readable-stream/isarray": ["isarray@1.0.0", "", {}, "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="], + "next/sharp/@img/sharp-libvips-linux-riscv64": ["@img/sharp-libvips-linux-riscv64@1.2.4", "", { "os": "linux", "cpu": "none" }, "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA=="], + + "next/sharp/@img/sharp-libvips-linux-s390x": ["@img/sharp-libvips-linux-s390x@1.2.4", "", { "os": "linux", "cpu": "s390x" }, "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ=="], + + "next/sharp/@img/sharp-libvips-linux-x64": ["@img/sharp-libvips-linux-x64@1.2.4", "", { "os": "linux", "cpu": "x64" }, "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw=="], + + "next/sharp/@img/sharp-libvips-linuxmusl-arm64": ["@img/sharp-libvips-linuxmusl-arm64@1.2.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw=="], + + "next/sharp/@img/sharp-libvips-linuxmusl-x64": ["@img/sharp-libvips-linuxmusl-x64@1.2.4", "", { "os": "linux", "cpu": "x64" }, "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg=="], + + "next/sharp/@img/sharp-linux-arm": ["@img/sharp-linux-arm@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm": "1.2.4" }, "os": "linux", "cpu": "arm" }, "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw=="], + + "next/sharp/@img/sharp-linux-arm64": ["@img/sharp-linux-arm64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm64": "1.2.4" }, "os": "linux", "cpu": "arm64" }, "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg=="], + + "next/sharp/@img/sharp-linux-ppc64": ["@img/sharp-linux-ppc64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-ppc64": "1.2.4" }, "os": "linux", "cpu": "ppc64" }, "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA=="], + + "next/sharp/@img/sharp-linux-riscv64": ["@img/sharp-linux-riscv64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-riscv64": "1.2.4" }, "os": "linux", "cpu": "none" }, "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw=="], + + "next/sharp/@img/sharp-linux-s390x": ["@img/sharp-linux-s390x@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-s390x": "1.2.4" }, "os": "linux", "cpu": "s390x" }, "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg=="], + + "next/sharp/@img/sharp-linux-x64": ["@img/sharp-linux-x64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-x64": "1.2.4" }, "os": "linux", "cpu": "x64" }, "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ=="], - "windows-release/execa/get-stream": ["get-stream@8.0.1", "", {}, "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA=="], + "next/sharp/@img/sharp-linuxmusl-arm64": ["@img/sharp-linuxmusl-arm64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-arm64": "1.2.4" }, "os": "linux", "cpu": "arm64" }, "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg=="], - "windows-release/execa/human-signals": ["human-signals@5.0.0", "", {}, "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ=="], + "next/sharp/@img/sharp-linuxmusl-x64": ["@img/sharp-linuxmusl-x64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-x64": "1.2.4" }, "os": "linux", "cpu": "x64" }, "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q=="], - "windows-release/execa/is-stream": ["is-stream@3.0.0", "", {}, "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA=="], + "next/sharp/@img/sharp-win32-arm64": ["@img/sharp-win32-arm64@0.34.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g=="], - "windows-release/execa/npm-run-path": ["npm-run-path@5.3.0", "", { "dependencies": { "path-key": "^4.0.0" } }, "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ=="], + "next/sharp/@img/sharp-win32-ia32": ["@img/sharp-win32-ia32@0.34.5", "", { "os": "win32", "cpu": "ia32" }, "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg=="], - "windows-release/execa/onetime": ["onetime@6.0.0", "", { "dependencies": { "mimic-fn": "^4.0.0" } }, "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ=="], + "next/sharp/@img/sharp-win32-x64": ["@img/sharp-win32-x64@0.34.5", "", { "os": "win32", "cpu": "x64" }, "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw=="], - "windows-release/execa/strip-final-newline": ["strip-final-newline@3.0.0", "", {}, "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw=="], + "noms/readable-stream/string_decoder": ["string_decoder@0.10.31", "", {}, "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ=="], + + "payload/ajv/json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="], + + "rimraf/glob/minimatch": ["minimatch@10.2.5", "", { "dependencies": { "brace-expansion": "^5.0.5" } }, "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg=="], + + "through2/readable-stream/isarray": ["isarray@1.0.0", "", {}, "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="], + + "vue-eslint-parser/espree/acorn": ["acorn@8.17.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg=="], - "wrap-ansi/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], + "vue-eslint-parser/espree/eslint-visitor-keys": ["eslint-visitor-keys@4.2.1", "", {}, "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ=="], - "@inquirer/core/wrap-ansi/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], + "@eslint/config-array/minimatch/brace-expansion/balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="], "@typescript-eslint/typescript-estree/minimatch/brace-expansion/balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="], @@ -2643,12 +2625,22 @@ "copyfiles/yargs/cliui/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], - "rimraf/glob/minimatch/brace-expansion": ["brace-expansion@5.0.7", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-7oFy703dxfY3/NLxC1fh2SUCQ0H9rmAY+5EpDVfXjUTTs+HEwR2nYaqLv+GWcTsumwxPfiz6CzCNkwXwBUwqCA=="], + "copyfiles/yargs/cliui/wrap-ansi": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="], + + "copyfiles/yargs/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], - "windows-release/execa/npm-run-path/path-key": ["path-key@4.0.0", "", {}, "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ=="], + "copyfiles/yargs/string-width/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], + + "eslint/minimatch/brace-expansion/balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="], + + "rimraf/glob/minimatch/brace-expansion": ["brace-expansion@5.0.7", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-7oFy703dxfY3/NLxC1fh2SUCQ0H9rmAY+5EpDVfXjUTTs+HEwR2nYaqLv+GWcTsumwxPfiz6CzCNkwXwBUwqCA=="], "copyfiles/yargs/cliui/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], + "copyfiles/yargs/cliui/wrap-ansi/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], + + "copyfiles/yargs/string-width/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], + "rimraf/glob/minimatch/brace-expansion/balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="], } } diff --git a/package.json b/package.json index da58b80..bbb3249 100644 --- a/package.json +++ b/package.json @@ -83,45 +83,45 @@ "payload": "^3.76.1" }, "devDependencies": { - "@antfu/eslint-config": "^7.4.3", - "@commitlint/cli": "^20.4.1", - "@commitlint/config-conventional": "^20.4.1", - "@eslint-react/eslint-plugin": "^2.12.4", - "@next/eslint-plugin-next": "^16.0.6", - "@payloadcms/db-mongodb": "^3.76.1", - "@payloadcms/next": "^3.76.1", - "@payloadcms/richtext-lexical": "^3.76.1", - "@payloadcms/translations": "^3.76.1", - "@payloadcms/ui": "^3.76.1", - "@release-it/conventional-changelog": "^10.0.1", - "@swc-node/register": "^1.11.1", - "@swc/cli": "^0.8.0", - "@swc/core": "^1.15.11", - "@types/node": "^25.2.3", - "@types/react": "^19.2.14", + "@antfu/eslint-config": "^9.1.0", + "@commitlint/cli": "^21.2.1", + "@commitlint/config-conventional": "^21.2.0", + "@eslint-react/eslint-plugin": "^5.17.1", + "@next/eslint-plugin-next": "^16.2.10", + "@payloadcms/db-mongodb": "^3.86.0", + "@payloadcms/next": "^3.86.0", + "@payloadcms/richtext-lexical": "^3.86.0", + "@payloadcms/translations": "^3.86.0", + "@payloadcms/ui": "^3.86.0", + "@release-it/conventional-changelog": "^11.0.1", + "@swc-node/register": "^1.12.1", + "@swc/cli": "^0.8.1", + "@swc/core": "^1.15.43", + "@types/node": "^26.1.1", + "@types/react": "^19.2.17", "@types/react-dom": "^19.2.3", - "@typescript/native-preview": "^7.0.0-dev.20260629.1", - "conventional-changelog-conventionalcommits": "^8.0.0", + "@typescript/native-preview": "^7.0.0-dev.20260707.2", + "conventional-changelog-conventionalcommits": "^10.2.1", "copyfiles": "2.4.1", "cross-env": "^10.1.0", - "cz-git": "^1.11.1", - "eslint": "^9.39.1", - "eslint-plugin-perfectionist": "^5.5.0", - "eslint-plugin-react-hooks": "^7.0.1", - "eslint-plugin-react-refresh": "^0.5.0", - "graphql": "^16.12.0", + "cz-git": "^1.13.1", + "eslint": "^10.7.0", + "eslint-plugin-perfectionist": "^5.10.0", + "eslint-plugin-react-hooks": "^7.1.1", + "eslint-plugin-react-refresh": "^0.5.3", + "graphql": "^17.0.2", "lefthook": "^2.1.10", - "next": "^16.2.0-canary.10", - "payload": "^3.76.1", + "next": "^16.2.10", + "payload": "^3.86.0", "payload-auditor": "^1.11.0", - "react": "^19.2.4", - "react-dom": "^19.2.4", - "release-it": "^19.0.6", - "rimraf": "^6.1.2", - "sharp": "^0.34.5", + "react": "^19.2.7", + "react-dom": "^19.2.7", + "release-it": "^20.2.1", + "rimraf": "^6.1.3", + "sharp": "^0.35.3", "type-fest": "^5.8.0", - "typescript": "^5.9.3", - "vitest": "^4.0.18" + "typescript": "6", + "vitest": "^4.1.10" }, "publishConfig": { "exports": { From 37452c84d2c47b45cee5201d96fe85c4c381d25d Mon Sep 17 00:00:00 2001 From: shaadcode Date: Sun, 19 Jul 2026 15:57:12 +0330 Subject: [PATCH 2/8] feat(dev): improved dev environment plugin --- dev/app/(payload)/admin/importMap.js | 1 + dev/collections/Media.ts | 5 +++-- dev/payload-types.ts | 6 ------ dev/payload.config.ts | 29 +++++++++++----------------- eslint.config.mjs | 7 +------ 5 files changed, 16 insertions(+), 32 deletions(-) diff --git a/dev/app/(payload)/admin/importMap.js b/dev/app/(payload)/admin/importMap.js index eb1ae47..af86423 100644 --- a/dev/app/(payload)/admin/importMap.js +++ b/dev/app/(payload)/admin/importMap.js @@ -1,5 +1,6 @@ import { CollectionCards as CollectionCards_f9c02e79a4aed9a3924487c0cd4cafb1 } from '@payloadcms/next/rsc' +/** @type import('payload').ImportMap */ export const importMap = { "@payloadcms/next/rsc#CollectionCards": CollectionCards_f9c02e79a4aed9a3924487c0cd4cafb1 } diff --git a/dev/collections/Media.ts b/dev/collections/Media.ts index 6ab362d..8fbf336 100644 --- a/dev/collections/Media.ts +++ b/dev/collections/Media.ts @@ -1,8 +1,9 @@ import path from 'node:path'; import { fileURLToPath } from 'node:url'; import type { CollectionConfig } from 'payload'; -import { anyone } from 'helpers/access/anyone.js'; -import { authenticated } from 'helpers/access/authenticated.js'; + +import { anyone } from '../helpers/access/anyone.js'; +import { authenticated } from '../helpers/access/authenticated.js'; const filename = fileURLToPath(import.meta.url); const dirname = path.dirname(filename); diff --git a/dev/payload-types.ts b/dev/payload-types.ts index 95aa61a..4c8272b 100644 --- a/dev/payload-types.ts +++ b/dev/payload-types.ts @@ -185,11 +185,8 @@ export interface AuditLog { id: string; operation: string; onCollection: string; - documentId?: string | null; - user: string | User; userAgent?: string | null; hook?: string | null; - type: 'info' | 'debug' | 'warning' | 'error' | 'audit' | 'security' | 'unknown'; createdAt: string; } /** @@ -420,11 +417,8 @@ export interface UsersSelect { export interface AuditLogSelect { operation?: T; onCollection?: T; - documentId?: T; - user?: T; userAgent?: T; hook?: T; - type?: T; createdAt?: T; } /** diff --git a/dev/payload.config.ts b/dev/payload.config.ts index d9c7ddf..3abc9ff 100644 --- a/dev/payload.config.ts +++ b/dev/payload.config.ts @@ -32,30 +32,23 @@ export default buildConfig({ // plugins plugins: [ auditorPlugin({ - automation: { logCleanup: { cronTime: '*/1 * * * *', queueName: 'test', olderThan: 30000 } }, + automation: { + logCleanup: { cronTime: '*/1 * * * *', queueName: 'test', olderThan: 60000 }, + }, + // customLogger collection: { - // configureRootCollection(defaults) { - // return { - // ...defaults, - // slug: 'some-name', - // labels: { - // singular: 'some-name', - // plural: 'some-names', - // }, - // }; - // }, - trackCollections: [ + track: [ { slug: 'media', + hooks: { + // customLogger afterOperation: { - updateByID: { - enabled: true, - modes: { - debug: {}, - }, - }, + updateByID: true, }, + // afterRead: { + // enabled: true, + // }, }, }, ], diff --git a/eslint.config.mjs b/eslint.config.mjs index 1f71965..dfe186e 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -8,11 +8,7 @@ const ignoreFiles = [ '**/.temp', '**/.*', // ignore all dotfiles '**/.git', - '**/.hg', - '**/.pnp.*', - '**/.svn', '**/playwright.config.ts', - '**/jest.config.js', '**/tsconfig.tsbuildinfo', '**/README.md', '**/payload-types.ts', @@ -32,8 +28,6 @@ export default antfu( semi: true, }, - typescript: true, - // Configuration preferences lessOpinionated: true, // Ignored paths @@ -74,6 +68,7 @@ export default antfu( 'import/order': 'off', 'sort-imports': 'off', 'ts/ban-ts-comment': 'off', + 'ts/consistent-type-definitions': 'off', 'unused-imports/no-unused-imports': ['error'], }, }, From c5df89315239ed5a6fc503fa3c51b74ee7816b05 Mon Sep 17 00:00:00 2001 From: shaadcode Date: Sun, 19 Jul 2026 17:51:46 +0330 Subject: [PATCH 3/8] feat(core): improve logging system - Remove rarely used properties - Additional internal collection fields - Remove access management --- src/Constant/Constant.ts | 227 -- src/collections/access/index.ts | 5 - src/collections/auditor.ts | 48 +- .../automation/tasks/cleanup/cleanup.test.ts | 28 +- src/core/automation/tasks/cleanup/cleanup.ts | 6 +- src/core/buffer/bufferManager.test.ts | 22 +- src/core/buffer/bufferManager.ts | 14 +- .../helpers/handleBufferDebugMode.test.ts | 2 +- .../buffer/helpers/handleBufferDebugMode.ts | 2 +- src/core/buffer/types.ts | 152 ++ .../customLoggingHandler.ts | 41 + .../helpers/emitWrapper/emitWrapper.ts | 64 - .../extractOperation/extractOperation.ts | 20 + .../collections/helpers/handleDebugMode.ts | 15 +- .../collections/helpers/isOperationEnabled.ts | 41 +- src/core/log-builders/collections/hooks.ts | 269 --- .../collections/logBuilderManager.ts | 62 + src/core/log-builders/collections/shared.ts | 100 - src/index.ts | 11 +- src/pluginUtils/configHelpers.ts | 109 +- src/types/pluginOptions.ts | 1817 ++--------------- src/types/types.d.ts | 4 +- src/utils/prettyDebugLog.ts | 12 +- 23 files changed, 512 insertions(+), 2559 deletions(-) delete mode 100644 src/Constant/Constant.ts delete mode 100644 src/collections/access/index.ts create mode 100644 src/core/buffer/types.ts create mode 100644 src/core/log-builders/collections/helpers/customLoggingHandler/customLoggingHandler.ts delete mode 100644 src/core/log-builders/collections/helpers/emitWrapper/emitWrapper.ts create mode 100644 src/core/log-builders/collections/helpers/extractOperation/extractOperation.ts delete mode 100644 src/core/log-builders/collections/hooks.ts create mode 100644 src/core/log-builders/collections/logBuilderManager.ts delete mode 100644 src/core/log-builders/collections/shared.ts diff --git a/src/Constant/Constant.ts b/src/Constant/Constant.ts deleted file mode 100644 index 652c995..0000000 --- a/src/Constant/Constant.ts +++ /dev/null @@ -1,227 +0,0 @@ -import type { LabelFunction, StaticLabel } from 'payload'; - -import type { AllCollectionHooks } from './../types/pluginOptions.js'; -import { sharedLogic } from './../core/log-builders/collections/shared.js'; - -interface DefaultCollectionValues { - labels: - | { - plural?: LabelFunction | StaticLabel | undefined; - singular?: LabelFunction | StaticLabel; - } - | undefined; - slug: string; -} - -export const defaultCollectionValues: DefaultCollectionValues = { - slug: 'Audit-log', - labels: { - plural: 'Audit-logs', - singular: 'Audit-log', - }, -}; - -export const defaultPluginOpts = { - collection: { - trackCollections: [], - }, - enabled: true, -}; - -export const hookMap: AllCollectionHooks = { - afterChange: async (args) => { - await sharedLogic(args, { - collection: args.collection, - context: args.context, - hook: 'afterChange', - operation: args.operation, - req: args.req, - }); - - return args.doc; - }, - afterDelete: async (args) => { - await sharedLogic(args, { - collection: args.collection, - context: args.context, - hook: 'afterDelete', - operation: 'delete', - req: args.req, - }); - - return {}; - }, - afterError: async (args) => { - await sharedLogic(args, { - collection: args.collection, - context: args.context, - hook: 'afterError', - operation: 'error', - req: args.req, - }); - - return {}; - }, - afterForgotPassword: async (args) => { - await sharedLogic(args, { - collection: args.collection, - context: args.context, - hook: 'afterForgotPassword', - operation: 'forgotPassword', - req: args.args.req, - }); - - return {}; - }, - afterLogin: async (args) => { - await sharedLogic(args, { - collection: args.collection, - context: args.context, - hook: 'afterLogin', - operation: 'delete', - req: args.req, - }); - - return {}; - }, - afterLogout: async (args) => { - await sharedLogic(args, { - collection: args.collection, - context: args.context, - hook: 'afterLogout', - operation: 'logout', - req: args.req, - }); - - return {}; - }, - afterMe: async (args) => { - await sharedLogic(args, { - collection: args.collection, - context: args.context, - hook: 'afterMe', - operation: 'me', - req: args.req, - }); - - return {}; - }, - afterOperation: async (args) => { - await sharedLogic(args, { - collection: args.collection, - // @ts-ignore - context: args.context, - hook: 'afterOperation', - // @ts-ignore - operation: args.operation, - req: args.req, - }); - return args.result; - }, - afterRead: async (args) => { - await sharedLogic(args, { - collection: args.collection, - context: args.context, - hook: 'afterRead', - operation: 'read', - req: args.req, - }); - - return args.doc; - }, - afterRefresh: async (args) => { - await sharedLogic(args, { - collection: args.collection, - context: args.context, - hook: 'afterRefresh', - operation: 'refresh', - req: args.req, - }); - return {}; - }, - beforeChange: async (args) => { - await sharedLogic(args, { - collection: args.collection, - context: args.context, - hook: 'beforeChange', - operation: args.operation, - req: args.req, - }); - - return args.data; - }, - beforeDelete: async (args) => { - await sharedLogic(args, { - collection: args.collection, - context: args.context, - hook: 'beforeDelete', - operation: 'delete', - req: args.req, - }); - - return {}; - }, - beforeLogin: async (args) => { - await sharedLogic(args, { - collection: args.collection, - context: args.context, - hook: 'beforeLogin', - operation: 'read', - req: args.req, - }); - return args.user; - }, - // @ts-ignore - beforeOperation: async (args) => { - await sharedLogic(args, { - collection: args.collection, - context: args.context, - hook: 'beforeOperation', - // @ts-ignore - operation: args.operation, - req: args.req, - }); - return args; - }, - beforeRead: async (args) => { - await sharedLogic(args, { - collection: args.collection, - context: args.context, - hook: 'beforeRead', - operation: 'read', - req: args.req, - }); - - return args.doc; - }, - beforeValidate: async (args) => { - await sharedLogic(args, { - collection: args.collection, - context: args.context, - hook: 'beforeValidate', - operation: args.operation, - req: args.req, - }); - return args.data; - }, - me: async (args) => { - await sharedLogic(args, { - collection: args.args.collection.config, - // @ts-ignore - context: args.context, - hook: 'me', - operation: 'me', - req: args.args.req, - }); - }, - refresh: async (args) => { - await sharedLogic(args, { - collection: args.args.collection.config, - // @ts-ignore - context: args.context, - hook: 'refresh', - operation: 'refresh', - req: args.args.req, - }); - }, -}; diff --git a/src/collections/access/index.ts b/src/collections/access/index.ts deleted file mode 100644 index bc7095d..0000000 --- a/src/collections/access/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -import type { Access } from 'payload'; - -export const adminAccess: Access = (): boolean => { - return true; -}; diff --git a/src/collections/auditor.ts b/src/collections/auditor.ts index 700ffca..871c3c1 100644 --- a/src/collections/auditor.ts +++ b/src/collections/auditor.ts @@ -1,36 +1,26 @@ import type { CollectionConfig } from 'payload'; -import { defaultCollectionValues } from '../Constant/Constant.js'; -import type { hookTypes } from './../pluginUtils/configHelpers.js'; -import type { AuditHookOperationType } from '../types/pluginOptions.js'; +import type { CollectionHooksKeys, CollectionHooksOperation } from '../core/log-builders/collections/logBuilderManager.js'; export interface AuditorLog { onCollection: string; - documentId?: string; - hook: (typeof hookTypes)[number]; - operation: AuditHookOperationType; + hook: CollectionHooksKeys; + operation: CollectionHooksOperation; timestamp: Date; - type: 'audit' | 'debug' | 'error' | 'info' | 'security' | 'unknown' | 'warning'; - user: unknown; userAgent?: string; } export type TypedRootCollection = typeof auditor; export const auditor: CollectionConfig = { - slug: defaultCollectionValues.slug, - access: { - admin: () => false, - create: () => false, - delete: () => false, - read: () => false, - readVersions: () => false, - unlock: () => false, - update: () => false, + slug: 'Audit-log', + labels: { + plural: 'Audit-logs', + singular: 'Audit-log', }, admin: { - defaultColumns: ['operation', 'type', 'collection', 'user', 'timestamp'], - useAsTitle: 'type', + defaultColumns: ['operation', 'hook', 'onCollection', 'timestamp', 'createdAt'], + useAsTitle: 'operation', }, fields: [ { @@ -43,16 +33,6 @@ export const auditor: CollectionConfig = { type: 'text', required: true, }, - { - name: 'documentId', - type: 'text', - }, - { - name: 'user', - type: 'relationship', - relationTo: 'users', - required: true, - }, { name: 'userAgent', type: 'text', @@ -61,15 +41,6 @@ export const auditor: CollectionConfig = { name: 'hook', type: 'text', }, - { - name: 'type', - type: 'select', - defaultValue: 'info', - options: ['info', 'debug', 'warning', 'error', 'audit', 'security', 'unknown'] as Array< - AuditorLog['type'] - >, - required: true, - }, { name: 'createdAt', type: 'date', @@ -80,7 +51,6 @@ export const auditor: CollectionConfig = { required: true, }, ], - labels: defaultCollectionValues.labels, timestamps: false, }; diff --git a/src/core/automation/tasks/cleanup/cleanup.test.ts b/src/core/automation/tasks/cleanup/cleanup.test.ts index cd6e026..ea6c338 100644 --- a/src/core/automation/tasks/cleanup/cleanup.test.ts +++ b/src/core/automation/tasks/cleanup/cleanup.test.ts @@ -1,7 +1,7 @@ import type { TaskConfig } from 'payload'; import { beforeEach, describe, expect, it, vi } from 'vitest'; -import type { PluginOptions } from '../../../../types/pluginOptions.js'; +import type { PluginConfig } from '../../../../types/pluginOptions.js'; import { CLEANUP_TASK_LABEL, CLEANUP_TASK_SLUG, cleanupLogsTask, DEFAULT_CRON_TIME, DEFAULT_OLDER_THAN, DEFAULT_QUEUE_NAME } from './cleanup.js'; const mockPluginConfig = { @@ -12,7 +12,8 @@ const mockPluginConfig = { queueName: DEFAULT_QUEUE_NAME, }, }, -} as const satisfies PluginOptions; + // @ts-expect-error +} as const satisfies PluginConfig; const mockReq = { payload: { @@ -30,6 +31,7 @@ describe('cleanupLogsTask', () => { }); it('should return expected task', () => { + // @ts-expect-error const result = cleanupLogsTask(mockPluginConfig); const expectedResultInstance = { @@ -52,7 +54,8 @@ describe('cleanupLogsTask', () => { describe('handler task', () => { it('should call payload.delete with correct parameters', async () => { - const pluginOptions: PluginOptions = {}; + const pluginOptions: Partial = {}; + // @ts-expect-error const task = cleanupLogsTask(pluginOptions); typeof task.handler === 'function' && await task @@ -74,10 +77,10 @@ describe('cleanupLogsTask', () => { it('should use configureRootCollection result when provided', async () => { const configuredSlug = 'configured-audit-logs'; - const pluginOptions: PluginOptions = { + const pluginOptions: PluginConfig = { collection: { configureRootCollection: vi.fn().mockReturnValue({ slug: configuredSlug }), - trackCollections: [], + track: [], }, }; @@ -96,7 +99,8 @@ describe('cleanupLogsTask', () => { it('should use custom olderThan value', async () => { const customOlderThan = 86400000; // 1 day - const pluginOptions: PluginOptions = { + // @ts-expect-error + const pluginOptions: PluginConfig = { automation: { logCleanup: { olderThan: customOlderThan, @@ -127,7 +131,8 @@ describe('cleanupLogsTask', () => { }); it('should return empty output object', async () => { - const pluginOptions: PluginOptions = {}; + const pluginOptions: Partial = {}; + // @ts-expect-error const task = cleanupLogsTask(pluginOptions); const result = typeof task.handler === 'function' && await task.handler({ @@ -142,7 +147,8 @@ describe('cleanupLogsTask', () => { const mockError = new Error('Database connection failed'); mockReq.payload.delete.mockRejectedValueOnce(mockError); - const pluginOptions: PluginOptions = {}; + const pluginOptions: Partial = {}; + // @ts-expect-error const task = cleanupLogsTask(pluginOptions); typeof task.handler === 'function' && await task.handler({ @@ -159,7 +165,8 @@ describe('cleanupLogsTask', () => { it('should not throw error when payload.delete fails', async () => { mockReq.payload.delete.mockRejectedValueOnce(new Error('Database error')); - const pluginOptions: PluginOptions = {}; + const pluginOptions: Partial = {}; + // @ts-expect-error const task = cleanupLogsTask(pluginOptions); await expect( @@ -173,7 +180,8 @@ describe('cleanupLogsTask', () => { it('should log error with correct message', async () => { mockReq.payload.delete.mockRejectedValueOnce(new Error('Any error')); - const pluginOptions: PluginOptions = {}; + const pluginOptions: Partial = {}; + // @ts-expect-error const task = cleanupLogsTask(pluginOptions); typeof task.handler === 'function' && await task.handler({ diff --git a/src/core/automation/tasks/cleanup/cleanup.ts b/src/core/automation/tasks/cleanup/cleanup.ts index 6c682c0..7151fac 100644 --- a/src/core/automation/tasks/cleanup/cleanup.ts +++ b/src/core/automation/tasks/cleanup/cleanup.ts @@ -1,7 +1,7 @@ import type { TaskConfig } from 'payload'; import auditor from '../../../../collections/auditor.js'; -import type { PluginOptions } from '../../../../types/pluginOptions.js'; +import type { PluginConfig } from '../../../../types/pluginOptions.js'; export const DEFAULT_OLDER_THAN = 604800000; // 1 week export const DEFAULT_CRON_TIME = '0 3 * * *'; // At 03:00 AM @@ -9,12 +9,12 @@ export const DEFAULT_QUEUE_NAME = 'payload-auditor-queue'; // default queue name export const CLEANUP_TASK_SLUG = 'cleanup-payload-auditor-log'; export const CLEANUP_TASK_LABEL = 'payload auditor - cleanup logs'; -export const cleanupLogsTask = (pluginOptions: PluginOptions): TaskConfig => { +export const cleanupLogsTask = (pluginOptions: PluginConfig): TaskConfig => { const cronTime = pluginOptions.automation?.logCleanup?.cronTime ?? DEFAULT_CRON_TIME; const queueName = pluginOptions.automation?.logCleanup?.queueName ?? DEFAULT_QUEUE_NAME; const olderThan = pluginOptions.automation?.logCleanup?.olderThan ?? DEFAULT_OLDER_THAN; const collectionSlug - = pluginOptions.collection?.slug ?? pluginOptions.collection?.configureRootCollection?.(auditor).slug ?? 'Audit-log'; + = pluginOptions.collection?.configureRootCollection?.(auditor).slug ?? 'Audit-log'; return { slug: CLEANUP_TASK_SLUG, label: CLEANUP_TASK_LABEL, diff --git a/src/core/buffer/bufferManager.test.ts b/src/core/buffer/bufferManager.test.ts index 22c1010..0dc2732 100644 --- a/src/core/buffer/bufferManager.test.ts +++ b/src/core/buffer/bufferManager.test.ts @@ -1,9 +1,9 @@ import type { Mock } from 'vitest'; import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; +import { auditor } from '../../collections/auditor.js'; import { onEventLog } from './../../core/events/emitter.js'; -import type { PluginOptions } from '../../types/pluginOptions.js'; -import { defaultCollectionValues } from '../../Constant/Constant.js'; +import type { PluginConfig } from '../../types/pluginOptions.js'; import { bufferManager, bufferStore } from './../../core/buffer/bufferManager.js'; vi.mock('../../core/events/emitter.ts', () => ({ @@ -36,7 +36,7 @@ describe('bufferManager', () => { size: 2, }, }, - } as PluginOptions; + } as PluginConfig; bufferManager(mockPayload as any, pluginOptions); @@ -57,14 +57,14 @@ describe('bufferManager', () => { flushStrategy: 'realtime', }, }, - } as PluginOptions; + } as PluginConfig; bufferManager(mockPayload as any, pluginOptions); const handler = mockOnEventLog.mock.calls[0][1]; await handler(sampleLog); expect(mockPayload.create).toHaveBeenCalledWith({ - collection: defaultCollectionValues.slug, + collection: auditor.slug, data: sampleLog, }); }); @@ -77,7 +77,7 @@ describe('bufferManager', () => { time: 2000, }, }, - } as unknown as PluginOptions; + } as unknown as PluginConfig; bufferManager(mockPayload as any, pluginOptions); const handler = mockOnEventLog.mock.calls[0][1]; @@ -87,7 +87,7 @@ describe('bufferManager', () => { vi.advanceTimersByTime(2000); expect(mockPayload.create).toHaveBeenCalledWith({ - collection: defaultCollectionValues.slug, + collection: auditor.slug, data: sampleLog, }); }); @@ -100,7 +100,7 @@ describe('bufferManager', () => { size: 1, }, }, - } as PluginOptions; + } as PluginConfig; bufferManager(mockPayload as any, pluginOptions); const handler = mockOnEventLog.mock.calls[0][1]; @@ -121,7 +121,7 @@ describe('bufferManager', () => { size: 2, }, }, - } as unknown as PluginOptions; + } as unknown as PluginConfig; bufferManager(mockPayload as any, pluginOptions); @@ -142,7 +142,7 @@ describe('bufferManager', () => { time: 2000, }, }, - } as PluginOptions; + } as PluginConfig; bufferManager(mockPayload as any, pluginOptions); @@ -164,7 +164,7 @@ describe('bufferManager', () => { flushStrategy: 'realtime', }, }, - } as PluginOptions; + } as PluginConfig; bufferManager(mockPayload as any, pluginOptions); diff --git a/src/core/buffer/bufferManager.ts b/src/core/buffer/bufferManager.ts index c9e1d4d..fe4f241 100644 --- a/src/core/buffer/bufferManager.ts +++ b/src/core/buffer/bufferManager.ts @@ -1,9 +1,10 @@ import type { Payload } from 'payload'; +import type { BufferConfig } from './types.js'; +import { auditor } from '../../collections/auditor.js'; import { onEventLog } from './../../core/events/emitter.js'; import type { AuditorLog } from '../../collections/auditor.js'; -import { defaultCollectionValues } from './../../Constant/Constant.js'; -import type { BufferConfig, PluginOptions } from './../../types/pluginOptions.js'; +import type { PluginConfig } from '../../types/pluginOptions.js'; import { handleBufferDebugMode } from './../../core/buffer/helpers/handleBufferDebugMode.js'; export const DEFAULT_INTERVAL_BUFFER = 10000 as NonNullable; @@ -14,22 +15,21 @@ export const bufferStore: AuditorLog[] = []; let payloadInstance: Payload; -const flushBuffer = async (pluginOptions: PluginOptions) => { +const flushBuffer = async (pluginOptions: PluginConfig) => { const logsToInsert = [...bufferStore]; bufferStore.length = 0; + const internalCollection = pluginOptions.collection?.configureRootCollection?.(); await Promise.all( logsToInsert.map(log => payloadInstance.create({ - collection: pluginOptions.collection?.slug - ? pluginOptions.collection?.slug - : defaultCollectionValues.slug, + collection: internalCollection?.slug ?? auditor.slug, data: log, }), ), ); }; -export const bufferManager = (payload: Payload, pluginOptions: PluginOptions) => { +export const bufferManager = (payload: Payload, pluginOptions: PluginConfig) => { const bufferConfig = pluginOptions.collection?.buffer; const size = bufferConfig?.size ?? DEFAULT_BUFFER_SIZE; const interval = bufferConfig?.time ?? DEFAULT_INTERVAL_BUFFER; diff --git a/src/core/buffer/helpers/handleBufferDebugMode.test.ts b/src/core/buffer/helpers/handleBufferDebugMode.test.ts index 8205771..392c771 100644 --- a/src/core/buffer/helpers/handleBufferDebugMode.test.ts +++ b/src/core/buffer/helpers/handleBufferDebugMode.test.ts @@ -1,8 +1,8 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'; import { prettyDebugLog } from '../../../utils/prettyDebugLog.js'; +import type { BufferConfig, BufferDebugFields } from '../types.js'; import { handleBufferDebugMode } from './handleBufferDebugMode.js'; -import type { BufferConfig, BufferDebugFields } from '../../../types/pluginOptions.js'; import { DEFAULT_BUFFER_SIZE, DEFAULT_BUFFER_STRATEGY, DEFAULT_INTERVAL_BUFFER } from '../bufferManager.js'; vi.mock('../../../utils/prettyDebugLog.js'); diff --git a/src/core/buffer/helpers/handleBufferDebugMode.ts b/src/core/buffer/helpers/handleBufferDebugMode.ts index 4391eb2..6699780 100644 --- a/src/core/buffer/helpers/handleBufferDebugMode.ts +++ b/src/core/buffer/helpers/handleBufferDebugMode.ts @@ -1,5 +1,5 @@ +import type { BufferConfig, BufferDebugFields } from '../types.js'; import { prettyDebugLog } from './../../../utils/prettyDebugLog.js'; -import type { BufferConfig, BufferDebugFields } from './../../../types/pluginOptions.js'; export const handleBufferDebugMode = ( fields: Record, diff --git a/src/core/buffer/types.ts b/src/core/buffer/types.ts new file mode 100644 index 0000000..6559e6b --- /dev/null +++ b/src/core/buffer/types.ts @@ -0,0 +1,152 @@ +export interface BufferDebugFields { + flushStrategy: boolean; + interval: boolean; + size: boolean; +} + +export interface BufferModesConfig { + /** + * 📝 Debug mode for better inspection of logging performance + * + * @default undefined + * + * + * 📦 Usage Example + * + * @example 🧪 Enable debug mode + * ```ts + * debug: { + * enabled: boolean + * } + * + * ``` + * ### ⚠️ Critical Notes + * - The generated logs are only displayed in the console and are not stored in the database. + */ + debug?: { + /** + * 📝 How to display debug logs + * + * 📖 long. + * + * 📌@type {'manual' | 'table'} + * + * @default "table" + * + */ + displayType?: 'manual' | 'table'; + /** + * 📝 Enable or disable debug mode + * + * 📖 long. + * + * 📌@type {'manual' | 'table'} + * + * @default false + * + */ + enabled?: boolean; + /** + * 📝 Select the required fields + * + * 📖 To reduce confusion, you can log only the fields you need. + * + * 📌@type {BufferDebugFields} + * + * @default undefined + * + * + * 📦 Usage Example + * + * @example 🧪 Only the size field is included in the log + * ```ts + * fields:{ + * size: true + * } + * ``` + */ + fields?: Partial; + }; +} + +export interface BufferConfig { + /** + * 📝 The basics of injecting logs into the database + * + * + * + * @default "time" + * + * + * 📦 Usage Example + * + * @example 🧪 Data injection based on log count + * ```ts + * flushStrategy: 'size', + * ``` + * ### ⚠️ Critical Notes + * - If you use the size method, your logs will be stored in RAM before being injected into the database. + * + */ + flushStrategy?: 'realtime' | 'size' | 'time'; + /** + * 📝 Auxiliary side modes + */ + modes?: BufferModesConfig; + /** + * 📝 Maximum number of logs before injection + * + * 📖 If the number of logs stored in the buffer memory reaches this number, data will be injected. + * + * 📌@type {number} + * + * @default 10 + * + * + * 📦 Usage Example + * + * @example 🧪 Up to 18 logs can be stored in memory + * ```ts + * size: 18 + * ``` + * + * --- + * ### ⚠️ Critical Notes + * - Works when flushStrategy is equal to size + * - If you enter the number 1, use the realtime method and do not define a value for this. + * ```ts + * flushStrategy: 'realtime', + * ``` + * - Very high numbers will increase RAM usage. + * - If you set a high number and on the other hand the logs produced are low, the logs will be recorded later. + * + */ + size?: number; + + /** + * 📝 Maximum time to inject logs into the buffer relative to the last injection + * + * + * 📌@type {Duration} + * + * @default 10000 + * + * + * 📦 Usage Example + * + * @example 🧪 Inject logs every 1 minute + * ```ts + * time: 5000 + * ``` + * + * --- + * ### ⚠️ Critical Notes + * - If you want to enter a value of "1s", set the flushStrategy value to time instead and do not define a value for the time property. + * ```ts + * flushStrategy: 'realtime', + * ``` + * - If you set the time too low, the CPU will be severely affected. + * - If you allow too much time, the logs will be recorded later. If the server crashes, the logs will be lost. + */ + time?: number; +} diff --git a/src/core/log-builders/collections/helpers/customLoggingHandler/customLoggingHandler.ts b/src/core/log-builders/collections/helpers/customLoggingHandler/customLoggingHandler.ts new file mode 100644 index 0000000..d0108f7 --- /dev/null +++ b/src/core/log-builders/collections/helpers/customLoggingHandler/customLoggingHandler.ts @@ -0,0 +1,41 @@ +import { emitEvent } from '../../../../events/emitter.js'; +import type { CollectionHooksKeys } from '../../logBuilderManager.js'; +import type { AuditorLog } from '../../../../../collections/auditor.js'; +import type { + HookConfigForTracking, + LogConfig, + PayloadCollectionHooksMap, + PluginConfig, +} from '../../../../../types/pluginOptions.js'; + +interface Params { + + logData: AuditorLog; + hookConfig: HookConfigForTracking[CollectionHooksKeys]; + hookName: CollectionHooksKeys; + operationConfig: LogConfig | undefined; + pluginConfig: PluginConfig; + hookArgs: Parameters[0]; +} + +export const customLoggingHandler = async (params: Params) => { + const customLogging = async (): Promise => { + const { hook, ...otherLogData } = params.logData; + + const result = { + ...params.logData, + ...(await params.pluginConfig.customLogger?.(params.hookArgs, otherLogData)), + // ...(await params.userActivatedHooks?.customLogger?.(params.hookArgs, otherLogData)), + // @ts-expect-error + ...(await params.hookConfig.customLogger?.(params.hookArgs, otherLogData)), + ...(await params.operationConfig?.customLogger?.(params.hookArgs, otherLogData)), + hook: params.logData.hook, + }; + + return result; + }; + + const log = await customLogging(); + + emitEvent('logGenerated', log); +}; diff --git a/src/core/log-builders/collections/helpers/emitWrapper/emitWrapper.ts b/src/core/log-builders/collections/helpers/emitWrapper/emitWrapper.ts deleted file mode 100644 index 53e1ead..0000000 --- a/src/core/log-builders/collections/helpers/emitWrapper/emitWrapper.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { emitEvent } from '../../../../events/emitter.js'; -import type { AuditorLog } from '../../../../../collections/auditor.js'; -import type { - AllCollectionHooks, - HookOperationConfig, - HookTrackingOperationMap, - PluginOptions, -} from '../../../../../types/pluginOptions.js'; - -export const emitWrapper = async ( - logData: AuditorLog, - hookConfig: HookTrackingOperationMap[T], - hookName: keyof AllCollectionHooks, - operationConfig: HookOperationConfig | undefined, - pluginOpts: PluginOptions, - hookArgs: Parameters[0], - userActivatedHooks: Partial | undefined, -) => { - const customLogging = async (): Promise => { - const { hook, ...otherLogData } = logData; - - let result: AuditorLog = logData; - - if (operationConfig?.customLogger) { - result = { - ...(await operationConfig.customLogger(hookArgs, otherLogData)), - hook, - }; - } - else if (hookConfig?.customLogger) { - result = { - // @ts-ignore - ...(await hookConfig.customLogger(hookArgs, otherLogData)), - hook, - }; - } - else if (userActivatedHooks?.customLogger) { - result = { - ...(await userActivatedHooks.customLogger(hookArgs, otherLogData)), - hook, - }; - } - else if (pluginOpts?.customLogger) { - result = { - ...(await pluginOpts.customLogger(hookArgs, otherLogData)), - hook, - }; - } - - return { - ...result, - type: result.type, - onCollection: result.onCollection, - documentId: result.documentId, - hook, - operation: result.operation, - timestamp: result.timestamp, - user: result.user, - userAgent: result.userAgent, - }; - }; - - emitEvent('logGenerated', await customLogging()); -}; diff --git a/src/core/log-builders/collections/helpers/extractOperation/extractOperation.ts b/src/core/log-builders/collections/helpers/extractOperation/extractOperation.ts new file mode 100644 index 0000000..d35eccf --- /dev/null +++ b/src/core/log-builders/collections/helpers/extractOperation/extractOperation.ts @@ -0,0 +1,20 @@ +import type { CollectionHooksArgsParameterUnion, CollectionHooksKeys, CollectionHooksOperation } from '../../logBuilderManager.js'; + +interface Params { + hookArgs: CollectionHooksArgsParameterUnion; + targetHookName: CollectionHooksKeys; +} + +const regex = /[A-Z]?[a-z]+/g; +const splitCamelCase = (str: string) => { + return str.match(regex) || []; +}; + +export const extractOperation = (params: Params): CollectionHooksOperation => { + const operation = params + .hookArgs + // @ts-expect-error + .operation + || splitCamelCase(params.targetHookName)[1].toLowerCase(); + return operation as CollectionHooksOperation; +}; diff --git a/src/core/log-builders/collections/helpers/handleDebugMode.ts b/src/core/log-builders/collections/helpers/handleDebugMode.ts index 3fd13fd..70dc1f0 100644 --- a/src/core/log-builders/collections/helpers/handleDebugMode.ts +++ b/src/core/log-builders/collections/helpers/handleDebugMode.ts @@ -1,17 +1,16 @@ import type { AuditorLog } from './../../../../collections/auditor.js'; import { prettyDebugLog } from './../../../../utils/prettyDebugLog.js'; +import type { CollectionHooksKeys, CollectionHooksOperation } from '../logBuilderManager.js'; import type { - AllCollectionHooks, - AuditHookOperationType, - HookOperationConfig, - HookTrackingOperationMap, + HookConfigForTracking, + LogConfig, } from './../../../../types/pluginOptions.js'; -export const handleDebugMode = ( - hookConfig: HookTrackingOperationMap[T] | undefined, - operationConfig: HookOperationConfig | undefined, +export const handleDebugMode = ( + hookConfig: HookConfigForTracking[T] | undefined, + operationConfig: LogConfig | undefined, allFields: AuditorLog, - operation: AuditHookOperationType, + operation: CollectionHooksOperation, ) => { const hookDebugConfig = hookConfig?.modes?.debug; const operationDebugConfig = operationConfig?.modes?.debug; diff --git a/src/core/log-builders/collections/helpers/isOperationEnabled.ts b/src/core/log-builders/collections/helpers/isOperationEnabled.ts index 57478c3..b738cfa 100644 --- a/src/core/log-builders/collections/helpers/isOperationEnabled.ts +++ b/src/core/log-builders/collections/helpers/isOperationEnabled.ts @@ -1,24 +1,25 @@ -import type { - AllCollectionHooks, - HookOperationConfig, - HookTrackingOperationMap, - // @ts-expect-error -} from 'src/types/pluginOptions.js'; +import type { CollectionConfig } from 'payload'; -export const checkOperationEnabled = ( - userHookOperationConfig: HookOperationConfig | undefined, - userHookConfig: HookTrackingOperationMap[T] | undefined, -): boolean => { - if (userHookConfig?.enabled === false) { - return false; - } - else if (userHookConfig?.enabled === true && userHookOperationConfig?.enabled !== false) { - return true; - } - else if (userHookConfig?.enabled === true && userHookOperationConfig?.enabled === false) { - return false; - } - else if (userHookOperationConfig?.enabled) { +import type { HookConfigForTracking, LogConfig } from '../../../../types/pluginOptions.js'; + +type CollectionHooksKeys = keyof NonNullable; + +interface Params { + hookOperationLevelConfig?: LogConfig | true; + hookLevelConfig?: HookConfigForTracking[CollectionHooksKeys]; +} + +export const checkIsOperationEnabled = (params: Params): boolean => { + const hookLevelEnabled = params.hookLevelConfig?.enabled; + const operationLevelEnabled = typeof params.hookOperationLevelConfig === 'boolean' + ? params.hookOperationLevelConfig + : params.hookOperationLevelConfig?.enabled; + + if ( + (hookLevelEnabled && operationLevelEnabled) + || (hookLevelEnabled === undefined && operationLevelEnabled) + || (hookLevelEnabled && operationLevelEnabled === undefined) + ) { return true; } else { diff --git a/src/core/log-builders/collections/hooks.ts b/src/core/log-builders/collections/hooks.ts deleted file mode 100644 index c24d6cf..0000000 --- a/src/core/log-builders/collections/hooks.ts +++ /dev/null @@ -1,269 +0,0 @@ -import type { - CollectionAfterChangeHook, - CollectionAfterDeleteHook, - CollectionAfterErrorHook, - CollectionAfterForgotPasswordHook, - CollectionAfterLoginHook, - CollectionAfterLogoutHook, - CollectionAfterMeHook, - CollectionAfterOperationHook, - CollectionAfterReadHook, - CollectionAfterRefreshHook, - CollectionBeforeChangeHook, - CollectionBeforeDeleteHook, - CollectionBeforeLoginHook, - CollectionBeforeOperationHook, - CollectionBeforeReadHook, - CollectionBeforeValidateHook, - CollectionMeHook, - CollectionRefreshHook, -} from 'payload'; - -import type { SharedArgs } from './shared.js'; -import { handleDebugMode } from './helpers/handleDebugMode.js'; -import { emitWrapper } from './helpers/emitWrapper/emitWrapper.js'; -import type { AuditorLog } from './../../../collections/auditor.js'; -import type { - AllCollectionHooks, - HookOperationConfig, - HookTrackingOperationMap, - PluginOptions, -} from './../../../types/pluginOptions.js'; - -export const hookHandlers = { - afterChange: ( - args: Parameters[0], - sharedArgs: SharedArgs, - baseLog: Partial, - ) => { - baseLog.type = 'audit'; - baseLog.documentId = args.doc.id; - baseLog.user = sharedArgs.req?.user?.id || 'anonymous'; - - return args.doc; - }, - afterDelete: ( - args: Parameters[0], - sharedArgs: SharedArgs, - baseLog: Partial, - ) => { - baseLog.type = 'audit'; - baseLog.documentId = args.doc.id; - baseLog.user = sharedArgs.req?.user?.id || 'anonymous'; - }, - afterError: ( - args: Parameters[0], - sharedArgs: SharedArgs, - baseLog: Partial, - ) => { - baseLog.type = 'error'; - baseLog.documentId = 'unknown'; - baseLog.user = sharedArgs.req?.user?.id || null; - }, - afterForgotPassword: async ( - args: Parameters[0], - sharedArgs: SharedArgs, - baseLog: Partial, - ) => { - baseLog.type = 'security'; - baseLog.user = 'anonymous'; - - const email = args.args.data?.email; - const userDoc = await sharedArgs.req.payload.find({ - collection: sharedArgs.collection.slug, - limit: 1, - where: { email: { equals: email } }, - }); - - const userId = userDoc?.docs?.[0]?.id; - baseLog.user = userId; - }, - afterLogin: ( - args: Parameters[0], - sharedArgs: SharedArgs, - baseLog: Partial, - ) => { - baseLog.type = 'security'; - baseLog.operation = 'login'; - baseLog.user = args.user.id || 'anonymous'; - }, - afterLogout: ( - args: Parameters[0], - sharedArgs: SharedArgs, - baseLog: Omit, - ) => { - baseLog.type = 'security'; - baseLog.user = sharedArgs.req.user?.id || 'anonymous'; - }, - afterMe: ( - args: Parameters[0], - sharedArgs: SharedArgs, - baseLog: Omit, - ) => { - baseLog.user = sharedArgs.req?.user?.id || 'anonymous'; - baseLog.type = 'info'; - }, - afterOperation: async ( - args: Parameters[0], - sharedArgs: SharedArgs, - baseLog: Partial, - data: { - pluginOpts: PluginOptions; - userActivatedHooks: Partial | undefined; - userHookConfig: HookTrackingOperationMap; - userHookOperationConfig: HookOperationConfig; - }, - ) => { - baseLog.type = 'audit'; - baseLog.documentId = 'unknown'; - baseLog.user = sharedArgs.req?.user?.id || 'anonymous'; - - switch (args.operation) { - case 'create': - case 'deleteByID': - case 'findByID': - case 'updateByID': { - baseLog.documentId = args.result ? args.result?.id.toString() : 'unknown'; - - break; - } - case 'delete': - case 'update': { - if (args.result?.docs?.length) { - for (const doc of args.result.docs) { - baseLog.documentId = doc.id.toString(); - - handleDebugMode( - data.userHookConfig as HookTrackingOperationMap[T], - data.userHookOperationConfig, - baseLog as AuditorLog, - args.operation, - ); - await emitWrapper( - baseLog as AuditorLog, - data.userHookConfig as HookTrackingOperationMap[T], - sharedArgs.hook, - data.userHookOperationConfig, - data.pluginOpts, - args, - data.userActivatedHooks, - ); - } - } - break; - } - case 'login': - case 'refresh': { - baseLog.user = args.result.user.id.toString(); - break; - } - } - }, - afterRead: ( - args: Parameters[0], - sharedArgs: SharedArgs, - baseLog: Partial, - ) => { - baseLog.type = 'info'; - baseLog.user = sharedArgs.req?.user?.id || 'anonymous'; - }, - afterRefresh: ( - args: Parameters[0], - sharedArgs: SharedArgs, - baseLog: Partial, - ) => { - baseLog.type = 'info'; - baseLog.user = sharedArgs.req.user?.id || 'anonymous'; - }, - beforeChange: ( - args: Parameters[0], - sharedArgs: SharedArgs, - baseLog: Partial, - ) => { - baseLog.type = 'audit'; - baseLog.documentId = args.originalDoc?.id; - baseLog.user = sharedArgs.req?.user?.id || 'anonymous'; - }, - beforeDelete: ( - args: Parameters[0], - sharedArgs: SharedArgs, - baseLog: Partial, - ) => { - baseLog.type = 'audit'; - baseLog.documentId = args.id.toString(); - baseLog.user = sharedArgs.req?.user?.id || 'anonymous'; - }, - beforeLogin: ( - args: Parameters[0], - sharedArgs: SharedArgs, - baseLog: Partial, - ) => { - baseLog.type = 'security'; - baseLog.user = args.user.id || 'anonymous'; - }, - beforeOperation: async ( - args: Parameters[0], - sharedArgs: SharedArgs, - baseLog: Partial, - ) => { - baseLog.type = 'audit'; - baseLog.user = sharedArgs.req?.user?.id || 'anonymous'; - - switch (args.operation) { - case 'create': - case 'refresh': - case 'update': - break; - case 'delete': - // @ts-ignore - baseLog.documentId = args.args.id ? args.args.id.toString() : 'unknown'; - break; - case 'forgotPassword': - case 'login': { - const email = args.args.data?.email; - const result = await args.req.payload.find({ - collection: sharedArgs.collection.slug, - limit: 1, - where: { email: { equals: email } }, - }); - const userId = result?.docs?.[0]?.id; - baseLog.user = userId || 'anonymous'; - break; - } - } - }, - beforeRead: ( - args: Parameters[0], - sharedArgs: SharedArgs, - baseLog: Partial, - ) => { - baseLog.type = 'info'; - baseLog.documentId = args.doc.id; - baseLog.user = sharedArgs.req?.user?.id || 'anonymous'; - }, - beforeValidate: ( - args: Parameters[0], - sharedArgs: SharedArgs, - baseLog: Partial, - ) => { - baseLog.type = 'debug'; - baseLog.documentId = args.operation === 'update' ? args.originalDoc?.id : 'unknown'; - baseLog.user = sharedArgs.req?.user?.id || 'anonymous'; - }, - me: ( - args: Parameters[0], - sharedArgs: SharedArgs, - baseLog: Partial, - ) => { - baseLog.type = 'info'; - baseLog.user = args.user.id || 'anonymous'; - }, - refresh: ( - args: Parameters[0], - sharedArgs: SharedArgs, - baseLog: Partial, - ) => { - baseLog.type = 'info'; - baseLog.user = args.user?.id || 'anonymous'; - }, -}; diff --git a/src/core/log-builders/collections/logBuilderManager.ts b/src/core/log-builders/collections/logBuilderManager.ts new file mode 100644 index 0000000..10c0b7c --- /dev/null +++ b/src/core/log-builders/collections/logBuilderManager.ts @@ -0,0 +1,62 @@ +import type { AllOperations, CollectionConfig } from 'payload'; + +import type { AuditorLog } from '../../../collections/auditor.js'; +import { checkIsOperationEnabled } from './helpers/isOperationEnabled.js'; +import { extractOperation } from './helpers/extractOperation/extractOperation.js'; +import { customLoggingHandler } from './helpers/customLoggingHandler/customLoggingHandler.js'; +import type { + HookConfigForTracking, + LogConfig, + PluginConfig, +} from '../../../types/pluginOptions.js'; + +export type CollectionHooksKeys = keyof NonNullable; +export type CollectionHooksOperation = AllOperations | 'read' | 'delete' | 'error' | 'login' | 'logout' | 'me' | 'refresh' | 'forgotPassword' | ''; + +export type CollectionHooksArgsParameterUnion = Parameters< + NonNullable< + NonNullable< + CollectionConfig['hooks'] + >[CollectionHooksKeys] + >[number] +>[0]; + +type LogBuilderManager = { + hookArgs: CollectionHooksArgsParameterUnion; + pluginConfig: PluginConfig; + targetHookName: CollectionHooksKeys; + targetHookLevelConfig: HookConfigForTracking[CollectionHooksKeys]; + collectionSlug: string; +}; + +export const logBuilderManager = async (params: LogBuilderManager) => { + const operation = extractOperation(params); + // @ts-expect-error + const hookOperationLevelConfig = params + .targetHookLevelConfig?.[operation] as LogConfig | undefined; + + const isOperationEnabled = checkIsOperationEnabled({ + hookLevelConfig: params.targetHookLevelConfig, + hookOperationLevelConfig, + }); + + const baseLog: AuditorLog = { + onCollection: params.collectionSlug, + hook: params.targetHookName, + operation, + timestamp: new Date(), + // @ts-expect-error + userAgent: params.hookArgs.req.headers.get('user-agent') || 'unknown', + }; + + if (isOperationEnabled) { + await customLoggingHandler({ + hookName: params.targetHookName, + pluginConfig: params.pluginConfig, + hookArgs: params.hookArgs, + hookConfig: params.targetHookLevelConfig, + logData: baseLog, + operationConfig: hookOperationLevelConfig, + }); + } +}; diff --git a/src/core/log-builders/collections/shared.ts b/src/core/log-builders/collections/shared.ts deleted file mode 100644 index 234c0d6..0000000 --- a/src/core/log-builders/collections/shared.ts +++ /dev/null @@ -1,100 +0,0 @@ -import type { PayloadRequest, RequestContext, SanitizedCollectionConfig } from 'payload'; - -import { hookHandlers } from './hooks.js'; -import { handleDebugMode } from './helpers/handleDebugMode.js'; -import { emitWrapper } from './helpers/emitWrapper/emitWrapper.js'; -import type { AuditorLog } from './../../../collections/auditor.js'; -import { checkOperationEnabled } from './helpers/isOperationEnabled.js'; -import type { hookTypes } from './../../../pluginUtils/configHelpers.js'; -import type { - AllCollectionHooks, - AuditHookOperationType, - HookOperationConfig, - HookTrackingOperationMap, -} from './../../../types/pluginOptions.js'; - -export interface SharedArgs { - collection: SanitizedCollectionConfig; - context: RequestContext; - hook: (typeof hookTypes)[number]; - operation: AuditHookOperationType; - req: PayloadRequest; -} - -interface ExceptionsParams { - hookName: (typeof hookTypes)[number]; - operation: AuditHookOperationType; -} - -const exceptions = (params: ExceptionsParams): boolean => { - let result: boolean = false; - switch (params.hookName) { - case 'afterOperation': - if (params.operation === 'delete' || params.operation === 'update') { - result = true; - } - break; - - default: - break; - } - return result; -}; - -export const sharedLogic = async ( - args: Parameters[0], - sharedArgs: SharedArgs, -) => { - const pluginOpts = sharedArgs.context.pluginOptions; - const userActivatedHooks = sharedArgs.context.userHookConfig?.hooks; - const userHookConfig = sharedArgs.context.userHookConfig?.hooks?.[sharedArgs.hook]; - const userHookOperationConfig = ( - userHookConfig as Record | undefined> - )?.[sharedArgs.operation]; - - const isOperationEnabled = checkOperationEnabled( - userHookOperationConfig, - userHookConfig, - ); - - const baseLog: AuditorLog = { - type: 'unknown', - onCollection: sharedArgs.collection.slug, - documentId: 'unknown', - hook: sharedArgs.hook, - operation: sharedArgs.operation, - timestamp: new Date(), - user: 'anonymous', - userAgent: sharedArgs.req.headers.get('user-agent') || 'unknown', - }; - - if (!exceptions({ hookName: sharedArgs.hook, operation: sharedArgs.operation })) { - handleDebugMode( - userHookConfig as HookTrackingOperationMap[T], - userHookOperationConfig, - baseLog, - sharedArgs.operation, - ); - } - - if (isOperationEnabled) { - // @ts-ignore - await hookHandlers[sharedArgs.hook](args, sharedArgs, baseLog, { - pluginOpts, - userActivatedHooks, - userHookConfig, - userHookOperationConfig, - }); - if (!exceptions({ hookName: sharedArgs.hook, operation: sharedArgs.operation })) { - await emitWrapper( - baseLog, - userHookConfig as HookTrackingOperationMap[T], - sharedArgs.hook, - userHookOperationConfig, - pluginOpts, - args, - userActivatedHooks, - ); - } - } -}; diff --git a/src/index.ts b/src/index.ts index 51d0792..92ca03a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,11 +1,9 @@ import type { Config, Plugin } from 'payload'; -import { defaultPluginOpts } from './Constant/Constant.js'; -import type { PluginOptions } from './types/pluginOptions.js'; +import type { PluginConfig } from './types/pluginOptions.js'; import { cleanupLogsTask } from './core/automation/tasks/cleanup/cleanup.js'; import { attachCollectionConfig, - buildAccessControl, onInitManager, } from './pluginUtils/configHelpers.js'; /** @@ -18,21 +16,20 @@ import { * */ export const auditorPlugin - = (opts: PluginOptions = defaultPluginOpts): Plugin => + = (opts: PluginConfig): Plugin => async (incomingConfig: Config): Promise => { const config = { ...incomingConfig }; if (opts.enabled === false) { return config; } - // Accessibility customization - // TODO: combine to attachCollectionConfig function - buildAccessControl(opts); config.collections = attachCollectionConfig(config.collections, opts); + config.jobs = { ...config.jobs, tasks: [...(config.jobs?.tasks ?? []), cleanupLogsTask(opts)], }; + config.onInit = onInitManager(config, opts); return config; diff --git a/src/pluginUtils/configHelpers.ts b/src/pluginUtils/configHelpers.ts index 8980fd7..9def125 100644 --- a/src/pluginUtils/configHelpers.ts +++ b/src/pluginUtils/configHelpers.ts @@ -1,90 +1,27 @@ -import type { Access, BasePayload, Config } from 'payload'; +import type { BasePayload, Config } from 'payload'; import auditor from '../collections/auditor.js'; +import type { PluginConfig } from './../types/pluginOptions.js'; import { bufferManager } from './../core/buffer/bufferManager.js'; -import { defaultCollectionValues, hookMap } from './../Constant/Constant.js'; import { DEFAULT_QUEUE_NAME } from '../core/automation/tasks/cleanup/cleanup.js'; -import type { AllCollectionHooks, PluginOptions } from './../types/pluginOptions.js'; - -type AccessOps = 'create' | 'delete' | 'read' | 'update'; - -type RoleAccessMap = Partial>; - -type CustomAccessMap = Partial>; - -export const hookTypes = [ - 'beforeOperation', - 'beforeValidate', - 'beforeDelete', - 'beforeChange', - 'beforeRead', - 'afterChange', - 'afterRead', - 'afterDelete', - 'afterOperation', - 'afterError', - 'beforeLogin', - 'afterLogin', - 'afterLogout', - 'afterRefresh', - 'afterMe', - 'afterForgotPassword', - 'refresh', - 'me', -] as const; - -export const buildAccessControl = (pluginOpts: PluginOptions) => { - const roles: RoleAccessMap = pluginOpts?.collection?.Accessibility?.roles ?? {}; - const customAccess: CustomAccessMap = pluginOpts?.collection?.Accessibility?.customAccess ?? {}; - - const defaultAccess: Access = ({ req }) => req.user?.role === 'admin'; - - const accessOps: AccessOps[] = ['read']; - - const access: Partial> = {}; - - accessOps.forEach((op) => { - if (roles[op] && roles[op].length > 0) { - access[op] = ({ req }) => roles[op]!.includes(req.user?.role); - } - else if (customAccess[op]) { - access[op] = customAccess[op]; - } - else { - access[op] = defaultAccess; - } - }); - - auditor.access = { ...auditor.access, ...access }; -}; +import { logBuilderManager } from '../core/log-builders/collections/logBuilderManager.js'; +import type { CollectionHooksKeys } from '../core/log-builders/collections/logBuilderManager.js'; export const attachCollectionConfig = ( userCollectionsConfig: Config['collections'], - pluginOpts: PluginOptions, + pluginOpts: PluginConfig, ) => { const pluginCollectionsConfig = pluginOpts.collection; if (!pluginCollectionsConfig) { return userCollectionsConfig; } - // attach localization - for (const field of auditor.fields) { - // @ts-ignore - field.label = pluginCollectionsConfig.locale?.collection?.fields?.[field.name] ?? field.label; - } - - // Attach Slug - if (pluginCollectionsConfig.slug && pluginCollectionsConfig.slug.length > 0) { - auditor.slug = pluginCollectionsConfig.slug; - } + const trackedCollections = pluginCollectionsConfig.track ?? []; // Attaching Log Builders - if ( - pluginCollectionsConfig.trackCollections - && pluginCollectionsConfig.trackCollections.length > 0 - ) { + if (trackedCollections.length) { userCollectionsConfig = (userCollectionsConfig || []).map((collection) => { - const tracked = pluginCollectionsConfig.trackCollections.find( + const tracked = pluginCollectionsConfig.track.find( tc => tc.slug === collection.slug, ); @@ -93,18 +30,18 @@ export const attachCollectionConfig = ( if (tracked.hooks) { for (const hookName in tracked?.hooks) { - const typedHookName = hookName as keyof AllCollectionHooks; - // @ts-ignore + const typedHookName = hookName as CollectionHooksKeys; + // @ts-expect-error collection.hooks[typedHookName] = [ ...(collection.hooks[typedHookName] || []), - async (args: any) => - await hookMap[typedHookName]({ - ...args, - context: { - pluginOptions: pluginOpts, - userHookConfig: tracked, - }, - }), + // @ts-ignore + async args => logBuilderManager({ + collectionSlug: collection.slug, + hookArgs: args, + pluginConfig: pluginOpts, + targetHookLevelConfig: tracked.hooks?.[typedHookName], + targetHookName: typedHookName, + }), ]; } } @@ -122,20 +59,16 @@ export const attachCollectionConfig = ( } : auditor; - // attach collection slug - const collectionSlug = rootCollection.slug ? rootCollection.slug : pluginCollectionsConfig.slug; - pluginCollectionsConfig.slug = collectionSlug; - userCollectionsConfig = [ ...(userCollectionsConfig || []), - { ...rootCollection, slug: collectionSlug || defaultCollectionValues.slug }, + rootCollection, ]; - // Attaching settings to plugin's internal collection hooks + // Attaching settings to plugin's internal collection hooks return userCollectionsConfig; }; -export const onInitManager = (incomingConfig: Config, pluginOptions: PluginOptions) => { +export const onInitManager = (incomingConfig: Config, pluginOptions: PluginConfig) => { const originalOnInit = incomingConfig.onInit; return async (payload: BasePayload) => { diff --git a/src/types/pluginOptions.ts b/src/types/pluginOptions.ts index a36f25f..186ef54 100644 --- a/src/types/pluginOptions.ts +++ b/src/types/pluginOptions.ts @@ -1,102 +1,33 @@ import type { - Access, - CollectionAfterChangeHook, - CollectionAfterDeleteHook, - CollectionAfterErrorHook, - CollectionAfterForgotPasswordHook, - CollectionAfterLoginHook, - CollectionAfterLogoutHook, - CollectionAfterMeHook, - CollectionAfterOperationHook, - CollectionAfterReadHook, - CollectionAfterRefreshHook, - CollectionBeforeChangeHook, - CollectionBeforeDeleteHook, - CollectionBeforeLoginHook, - CollectionBeforeOperationHook, - CollectionBeforeReadHook, - CollectionBeforeValidateHook, CollectionConfig, - CollectionMeHook, - CollectionRefreshHook, - HookOperationType, LabelFunction, StaticLabel, } from 'payload'; +import type { BufferConfig } from '../core/buffer/types.js'; import type { AuditorLog } from './../collections/auditor.js'; +import type { CollectionHooksKeys } from '../core/log-builders/collections/logBuilderManager.js'; -export type HookStage - = | 'afterChange' - | 'afterDelete' - | 'afterError' - | 'afterForgotPassword' - | 'afterLogin' - | 'afterLogout' - | 'afterMe' - | 'afterRead' - | 'afterRefresh' - | 'beforeChange' - | 'beforeDelete' - | 'beforeLogin' - | 'beforeOperation' - | 'beforeRead' - | 'beforeValidate' - | 'refresh'; +export type PayloadCollectionHooksMap = { + [K in CollectionHooksKeys]: NonNullable[K]>[number] +}; -export type AuditHookOperationType - = | 'deleteByID' - | 'error' - | 'find' - | 'findByID' - | 'forgotPassword' - | 'logout' - | 'me' - | 'refresh' - | 'updateByID' - | HookOperationType; +export type HookConfigForTracking = { + [K in keyof NonNullable]: + Partial< + { + // @ts-expect-error + [O in Parameters< + NonNullable< + NonNullable< + CollectionConfig['hooks'] + >[K] + >[number] + >[0]['operation']]: LogConfig | boolean + } & LogConfig + > -export interface HookOperations { - afterChange: Parameters[0]['operation']; - afterDelete: 'delete'; - afterError: 'error'; - afterForgotPassword: 'afterForgotPassword'; - afterLogin: 'login'; - afterLogout: 'logout'; - afterMe: 'me'; - afterOperation: Parameters[0]['operation']; - afterRead: 'read'; - afterRefresh: 'refresh'; - beforeChange: Parameters[0]['operation']; - beforeDelete: 'delete'; - beforeLogin: 'login'; - beforeOperation: Parameters[0]['operation']; - beforeRead: 'read'; - beforeValidate: Parameters[0]['operation']; - me: 'me'; - refresh: 'refresh'; -} - -export interface AllCollectionHooks { - afterChange: CollectionAfterChangeHook; - afterDelete: CollectionAfterDeleteHook; - afterError: CollectionAfterErrorHook; - afterForgotPassword: CollectionAfterForgotPasswordHook; - afterLogin: CollectionAfterLoginHook; - afterLogout: CollectionAfterLogoutHook; - afterMe: CollectionAfterMeHook; - afterOperation: CollectionAfterOperationHook; - afterRead: CollectionAfterReadHook; - afterRefresh: CollectionAfterRefreshHook; - beforeChange: CollectionBeforeChangeHook; - beforeDelete: CollectionBeforeDeleteHook; - beforeLogin: CollectionBeforeLoginHook; - beforeOperation: CollectionBeforeOperationHook; - beforeRead: CollectionBeforeReadHook; - beforeValidate: CollectionBeforeValidateHook; - me: CollectionMeHook; - refresh: CollectionRefreshHook; -} +}; export interface HookOperationDebugModeConfig { /** @@ -114,1467 +45,55 @@ export interface HookOperationDebugModeConfig { * * --- * - * ### ⚠️ Critical Notes - * - The timeStamp field is not displayed in the table type - * - */ - displayType?: 'manual' | 'table'; - /** - * 📝 Enable or disable debug mode - * - * 📖 long. - * - * 📌@type {'manual' | 'table'} - * - * @default false - * - * ``` - * - * ``` - * - * --- - * - * ### ⚠️ Critical Notes - * - The timeStamp field is not displayed in the table type - * - */ - enabled?: boolean; - /** - * 📝 Select the required fields - * - * 📖 To reduce confusion, you can log only the fields you need. - * - * 📌@type {Partial>} - * - * @default undefined - * - * - * 📦 Usage Example - * - * @example 🧪 Only the true field is included in the log - * ```ts - * fields:{ - * type:true - * } - * ``` - * - */ - fields?: Partial>; -} - -export interface HookModesConfig { - /** - * 📝 Debug mode for better inspection of logging performance - * - * @default undefined - * - * - * 📦 Usage Example - * - * @example 🧪 Enable debug mode - * ```ts - * debug: { - * enabled: boolean - * } - * - * ``` - * ### ⚠️ Critical Notes - * - The generated logs are only displayed in the console and are not stored in the database. - */ - debug?: HookOperationDebugModeConfig; -} - -export interface HookOperationConfig { - /** - * 📝 Custom log creation at a operation level - * - * @default undefined - * - * - * 📦 Usage Example - * - * @example 🧪 Change the user value for the create operation - * ```ts - * create: { - * customLogger: (args, fields) => { - * return { ...fields, user: null } - * }, - * enabled: true, - * }, - * ``` - * - * --- - * ### ⚠️ Critical Notes - * - Only works for the current operation - * - Has the highest priority in execution - */ - customLogger?: ( - args: Parameters[0], - fields: Omit, - ) => Omit | Promise>; - /** - * 📝 Specifies whether logging is enabled or disabled for this operation within the hook - * - * 📌@type {boolean} - * - * @default undefined - * - * - * 📦 Usage Example - * - * @example 🧪 Activating the create operation - * ```ts - * create: { - * enabled: true, - * }, - * ``` - * - * --- - * ### ⚠️ Critical Notes - * - If the enabled value is not entered, it is considered false. - * - */ - enabled?: boolean; - - /** - * 📝 Auxiliary side modes - * - * - - */ - modes?: HookModesConfig; -} - -export interface HookTrackingOperationMap { - afterChange: { - /** - * Create operation - * - * Triggered when a new item is created. - */ - create?: HookOperationConfig<'afterChange'>; - - /** - * 📝 Custom log creation at a hook level - * - * @default undefined - * - * - * 📦 Usage Example - * - * @example 🧪 Change the user value for all afterChange hook operations - * ```ts - * customLogger: (args, fields) => { - * return { ...fields, user: null } - * } - * ``` - * - * --- - * ### ⚠️ Critical Notes - * - Only works for active operations - * - This function is only executed for operations that do not have a dedicated customLogger - * - Do not confuse this customLogger with the hooks-level customLogger (which is for all hooks)! - */ - customLogger?: ( - args: Parameters[0], - fields: Omit, - ) => Omit | Promise>; - - /** - * 📝 Enabling all supported operations within the afterChange hook - * - * 📌@type {boolean} - * - * @default undefined - * - * - * 📦 Usage Example - * - * @example 🧪 Enabling all operations - * ```ts - * enabled: true - * ``` - * - * --- - * ### ⚠️ Critical Notes - * - Only works for operations whose enabled property value is not false - * - If the value is false, it disables all operations (even explicitly enabled operations) - * - */ - enabled?: boolean; - - /** - * 📝 Auxiliary side modes - * - * ### ⚠️ Critical Notes - * - By enabling debug mode at the hook level, all operations of that hook are logged - */ - modes?: HookModesConfig; - /** - * Update operation - * - * Triggered when an existing item is updated. - */ - update?: HookOperationConfig<'afterChange'>; - }; - afterDelete: { - /** - * 📝 Custom log creation at a hook level - * - * @default undefined - * - * - * 📦 Usage Example - * - * @example 🧪 Change the user value for all afterDelete hook operations - * ```ts - * customLogger: (args, fields) => { - * return { ...fields, user: null } - * } - * ``` - * - * --- - * ### ⚠️ Critical Notes - * - Only works for active operations - * - This function is only executed for operations that do not have a dedicated customLogger - * - Do not confuse this customLogger with the hooks-level customLogger (which is for all hooks)! - */ - customLogger?: ( - args: Parameters[0], - fields: Omit, - ) => Omit | Promise>; - /** - * Delete operation - * - * Triggered when an item is deleted. - */ - delete?: HookOperationConfig<'afterDelete'>; - /** - * 📝 Enabling all supported operations within the afterChange hook - * - * 📌@type {boolean} - * - * @default undefined - * - * - * 📦 Usage Example - * - * @example 🧪 Enabling all operations - * ```ts - * enabled: true - * ``` - * - * --- - * ### ⚠️ Critical Notes - * - Only works for operations whose enabled property value is not false - * - If the value is false, it disables all operations (even explicitly enabled operations) - * - */ - enabled?: boolean; - /** - * 📝 Auxiliary side modes - * - * ### ⚠️ Critical Notes - * - By enabling debug mode at the hook level, all operations of that hook are logged - */ - modes?: HookModesConfig; - }; - afterError: { - /** - * 📝 Custom log creation at a hook level - * - * @default undefined - * - * - * 📦 Usage Example - * - * @example 🧪 Change the user value for all afterError hook operations - * ```ts - * customLogger: (args, fields) => { - * return { ...fields, user: null } - * } - * ``` - * - * --- - * ### ⚠️ Critical Notes - * - Only works for active operations - * - This function is only executed for operations that do not have a dedicated customLogger - * - Do not confuse this customLogger with the hooks-level customLogger (which is for all hooks)! - */ - customLogger?: ( - args: Parameters[0], - fields: Omit, - ) => Omit | Promise>; - /** - * 📝 Enabling all supported operations within the afterChange hook - * - * 📌@type {boolean} - * - * @default undefined - * - * - * 📦 Usage Example - * - * @example 🧪 Enabling all operations - * ```ts - * enabled: true - * ``` - * - * --- - * ### ⚠️ Critical Notes - * - Only works for operations whose enabled property value is not false - * - If the value is false, it disables all operations (even explicitly enabled operations) - * - */ - enabled?: boolean; - /** - * Error operation - * - * Triggered when an error occurs during another operation. - */ - error?: HookOperationConfig<'afterError'>; - /** - * 📝 Auxiliary side modes - * - * ### ⚠️ Critical Notes - * - By enabling debug mode at the hook level, all operations of that hook are logged - */ - modes?: HookModesConfig; - }; - afterForgotPassword: { - /** - * 📝 Custom log creation at a hook level - * - * @default undefined - * - * - * 📦 Usage Example - * - * @example 🧪 Change the user value for all afterForgotPassword hook operations - * ```ts - * customLogger: (args, fields) => { - * return { ...fields, user: null } - * } - * ``` - * - * --- - * ### ⚠️ Critical Notes - * - Only works for active operations - * - This function is only executed for operations that do not have a dedicated customLogger - * - Do not confuse this customLogger with the hooks-level customLogger (which is for all hooks)! - */ - customLogger?: ( - args: Parameters[0], - fields: Omit, - ) => Omit | Promise>; - - /** - * 📝 Enabling all supported operations within the afterChange hook - * - * 📌@type {boolean} - * - * @default undefined - * - * - * 📦 Usage Example - * - * @example 🧪 Enabling all operations - * ```ts - * enabled: true - * ``` - * - * --- - * ### ⚠️ Critical Notes - * - Only works for operations whose enabled property value is not false - * - If the value is false, it disables all operations (even explicitly enabled operations) - * - */ - enabled?: boolean; - /** - * Forgot password operation - * - * Triggered when a password recovery request is made. - */ - forgotPassword?: HookOperationConfig<'afterForgotPassword'>; - /** - * 📝 Auxiliary side modes - * - * ### ⚠️ Critical Notes - * - By enabling debug mode at the hook level, all operations of that hook are logged - */ - modes?: HookModesConfig; - }; - afterLogin: { - /** - * 📝 Custom log creation at a hook level - * - * @default undefined - * - * - * 📦 Usage Example - * - * @example 🧪 Change the user value for all afterLogin hook operations - * ```ts - * customLogger: (args, fields) => { - * return { ...fields, user: null } - * } - * ``` - * - * --- - * ### ⚠️ Critical Notes - * - Only works for active operations - * - This function is only executed for operations that do not have a dedicated customLogger - * - Do not confuse this customLogger with the hooks-level customLogger (which is for all hooks)! - */ - customLogger?: ( - args: Parameters[0], - fields: Omit, - ) => Omit | Promise>; - /** - * 📝 Enabling all supported operations within the afterChange hook - * - * 📌@type {boolean} - * - * @default undefined - * - * - * 📦 Usage Example - * - * @example 🧪 Enabling all operations - * ```ts - * enabled: true - * ``` - * - * --- - * ### ⚠️ Critical Notes - * - Only works for operations whose enabled property value is not false - * - If the value is false, it disables all operations (even explicitly enabled operations) - * - */ - enabled?: boolean; - /** - * Login operation - * - * Triggered when a user logs in. - */ - login?: HookOperationConfig<'afterLogin'>; - /** - * 📝 Auxiliary side modes - * - * ### ⚠️ Critical Notes - * - By enabling debug mode at the hook level, all operations of that hook are logged - */ - modes?: HookModesConfig; - }; - afterLogout: { - /** - * 📝 Custom log creation at a hook level - * - * @default undefined - * - * - * 📦 Usage Example - * - * @example 🧪 Change the user value for all afterLogout hook operations - * ```ts - * customLogger: (args, fields) => { - * return { ...fields, user: null } - * } - * ``` - * - * --- - * ### ⚠️ Critical Notes - * - Only works for active operations - * - This function is only executed for operations that do not have a dedicated customLogger - * - Do not confuse this customLogger with the hooks-level customLogger (which is for all hooks)! - */ - customLogger?: ( - args: Parameters[0], - fields: Omit, - ) => Omit | Promise>; - /** - * 📝 Enabling all supported operations within the afterChange hook - * - * 📌@type {boolean} - * - * @default undefined - * - * - * 📦 Usage Example - * - * @example 🧪 Enabling all operations - * ```ts - * enabled: true - * ``` - * - * --- - * ### ⚠️ Critical Notes - * - Only works for operations whose enabled property value is not false - * - If the value is false, it disables all operations (even explicitly enabled operations) - * - */ - enabled?: boolean; - /** - * Logout operation - * - * Triggered when a user logs out. - */ - logout?: HookOperationConfig<'afterLogout'>; - /** - * 📝 Auxiliary side modes - * - * ### ⚠️ Critical Notes - * - By enabling debug mode at the hook level, all operations of that hook are logged - */ - modes?: HookModesConfig; - }; - afterMe: { - /** - * 📝 Custom log creation at a hook level - * - * @default undefined - * - * - * 📦 Usage Example - * - * @example 🧪 Change the user value for all afterMe hook operations - * ```ts - * customLogger: (args, fields) => { - * return { ...fields, user: null } - * } - * ``` - * - * --- - * ### ⚠️ Critical Notes - * - Only works for active operations - * - This function is only executed for operations that do not have a dedicated customLogger - * - Do not confuse this customLogger with the hooks-level customLogger (which is for all hooks)! - */ - customLogger?: ( - args: Parameters[0], - fields: Omit, - ) => Omit | Promise>; - /** - * 📝 Enabling all supported operations within the afterChange hook - * - * 📌@type {boolean} - * - * @default undefined - * - * - * 📦 Usage Example - * - * @example 🧪 Enabling all operations - * ```ts - * enabled: true - * ``` - * - * --- - * ### ⚠️ Critical Notes - * - Only works for operations whose enabled property value is not false - * - If the value is false, it disables all operations (even explicitly enabled operations) - * - */ - enabled?: boolean; - /** - * Me operation - * - * Triggered when a user fetches their own profile information. - */ - me?: HookOperationConfig<'afterMe'>; - /** - * 📝 Auxiliary side modes - * - * ### ⚠️ Critical Notes - * - By enabling debug mode at the hook level, all operations of that hook are logged - */ - modes?: HookModesConfig; - }; - afterOperation: { - countVersions?: HookOperationConfig<'afterOperation'>; - /** - * Create operation - * - * Triggered when a new item is created. - */ - create?: HookOperationConfig<'afterOperation'>; - /** - * 📝 Custom log creation at a hook level - * - * @default undefined - * - * - * 📦 Usage Example - * - * @example 🧪 Change the user value for all afterOperation hook operations - * ```ts - * customLogger: (args, fields) => { - * return { ...fields, user: null } - * } - * ``` - * - * --- - * ### ⚠️ Critical Notes - * - Only works for active operations - * - This function is only executed for operations that do not have a dedicated customLogger - * - Do not confuse this customLogger with the hooks-level customLogger (which is for all hooks)! - */ - customLogger?: ( - args: Parameters[0], - fields: Omit, - ) => Omit | Promise>; - /** - * Delete operation - * - * Triggered when an item is deleted. - */ - delete?: HookOperationConfig<'afterOperation'>; - /** - * Delete by ID operation - * - * Triggered when a specific item is deleted by its ID. - */ - deleteByID?: HookOperationConfig<'afterOperation'>; - /** - * 📝 Enabling all supported operations within the afterChange hook - * - * 📌@type {boolean} - * - * @default undefined - * - * - * 📦 Usage Example - * - * @example 🧪 Enabling all operations - * ```ts - * enabled: true - * ``` - * - * --- - * ### ⚠️ Critical Notes - * - Only works for operations whose enabled property value is not false - * - If the value is false, it disables all operations (even explicitly enabled operations) - * - */ - enabled?: boolean; - /** - * Find operation - * - * Triggered when items are queried based on specific conditions. - */ - find?: HookOperationConfig<'afterOperation'>; - /** - * Find by ID operation - * - * Triggered when a specific item is retrieved by its ID. - */ - findByID?: HookOperationConfig<'afterOperation'>; - /** - * Forgot password operation - * - * Triggered when a password recovery request is made. - */ - forgotPassword?: HookOperationConfig<'afterOperation'>; - /** - * Login operation - * - * Triggered when a user logs in. - */ - login?: HookOperationConfig<'afterOperation'>; - /** - * 📝 Auxiliary side modes - * - * ### ⚠️ Critical Notes - * - By enabling debug mode at the hook level, all operations of that hook are logged - */ - modes?: HookModesConfig; - /** - * Refresh operation - * - * Triggered when authentication tokens are refreshed. - */ - refresh?: HookOperationConfig<'afterOperation'>; - - /** - * Update operation - * - * Triggered when an existing item is updated. - */ - update?: HookOperationConfig<'afterOperation'>; - /** - * Update by ID operation - * - * Triggered when a specific item is updated by its ID. - */ - updateByID?: HookOperationConfig<'afterOperation'>; - }; - afterRead: { - /** - * 📝 Custom log creation at a hook level - * - * @default undefined - * - * - * 📦 Usage Example - * - * @example 🧪 Change the user value for all afterRead hook operations - * ```ts - * customLogger: (args, fields) => { - * return { ...fields, user: null } - * } - * ``` - * - * --- - * ### ⚠️ Critical Notes - * - Only works for active operations - * - This function is only executed for operations that do not have a dedicated customLogger - * - Do not confuse this customLogger with the hooks-level customLogger (which is for all hooks)! - */ - customLogger?: ( - args: Parameters[0], - fields: Omit, - ) => Omit | Promise>; - /** - * 📝 Enabling all supported operations within the afterChange hook - * - * 📌@type {boolean} - * - * @default undefined - * - * - * 📦 Usage Example - * - * @example 🧪 Enabling all operations - * ```ts - * enabled: true - * ``` - * - * --- - * ### ⚠️ Critical Notes - * - Only works for operations whose enabled property value is not false - * - If the value is false, it disables all operations (even explicitly enabled operations) - * - */ - enabled?: boolean; - /** - * 📝 Auxiliary side modes - * - * ### ⚠️ Critical Notes - * - By enabling debug mode at the hook level, all operations of that hook are logged - */ - modes?: HookModesConfig; - /** - * Read operation - * - * Triggered when data is read. - */ - read?: HookOperationConfig<'afterRead'>; - }; - afterRefresh: { - /** - * 📝 Custom log creation at a hook level - * - * @default undefined - * - * - * 📦 Usage Example - * - * @example 🧪 Change the user value for all afterRefresh hook operations - * ```ts - * customLogger: (args, fields) => { - * return { ...fields, user: null } - * } - * ``` - * - * --- - * ### ⚠️ Critical Notes - * - Only works for active operations - * - This function is only executed for operations that do not have a dedicated customLogger - * - Do not confuse this customLogger with the hooks-level customLogger (which is for all hooks)! - */ - customLogger?: ( - args: Parameters[0], - fields: Omit, - ) => Omit | Promise>; - /** - * 📝 Enabling all supported operations within the afterChange hook - * - * 📌@type {boolean} - * - * @default undefined - * - * - * 📦 Usage Example - * - * @example 🧪 Enabling all operations - * ```ts - * enabled: true - * ``` - * - * --- - * ### ⚠️ Critical Notes - * - Only works for operations whose enabled property value is not false - * - If the value is false, it disables all operations (even explicitly enabled operations) - * - */ - enabled?: boolean; - /** - * 📝 Auxiliary side modes - * - * ### ⚠️ Critical Notes - * - By enabling debug mode at the hook level, all operations of that hook are logged - */ - modes?: HookModesConfig; - /** - * Refresh operation - * - * Triggered when authentication tokens are refreshed. - */ - refresh?: HookOperationConfig<'afterRefresh'>; - }; - beforeChange: { - /** - * Create operation - * - * Triggered when a new item is created. - */ - create?: HookOperationConfig<'beforeChange'>; - /** - * 📝 Custom log creation at a hook level - * - * @default undefined - * - * - * 📦 Usage Example - * - * @example 🧪 Change the user value for all beforeChange hook operations - * ```ts - * customLogger: (args, fields) => { - * return { ...fields, user: null } - * } - * ``` - * - * --- - * ### ⚠️ Critical Notes - * - Only works for active operations - * - This function is only executed for operations that do not have a dedicated customLogger - * - Do not confuse this customLogger with the hooks-level customLogger (which is for all hooks)! - */ - customLogger?: ( - args: Parameters[0], - fields: Omit, - ) => Omit | Promise>; - /** - * 📝 Enabling all supported operations within the afterChange hook - * - * 📌@type {boolean} - * - * @default undefined - * - * - * 📦 Usage Example - * - * @example 🧪 Enabling all operations - * ```ts - * enabled: true - * ``` - * - * --- - * ### ⚠️ Critical Notes - * - Only works for operations whose enabled property value is not false - * - If the value is false, it disables all operations (even explicitly enabled operations) - * - */ - enabled?: boolean; - /** - * 📝 Auxiliary side modes - * - * ### ⚠️ Critical Notes - * - By enabling debug mode at the hook level, all operations of that hook are logged - */ - modes?: HookModesConfig; - /** - * Update operation - * - * Triggered when an existing item is updated. - */ - update?: HookOperationConfig<'beforeChange'>; - }; - beforeDelete: { - /** - * 📝 Custom log creation at a hook level - * - * @default undefined - * - * - * 📦 Usage Example - * - * @example 🧪 Change the user value for all beforeDelete hook operations - * ```ts - * customLogger: (args, fields) => { - * return { ...fields, user: null } - * } - * ``` - * - * --- - * ### ⚠️ Critical Notes - * - Only works for active operations - * - This function is only executed for operations that do not have a dedicated customLogger - * - Do not confuse this customLogger with the hooks-level customLogger (which is for all hooks)! - */ - customLogger?: ( - args: Parameters[0], - fields: Omit, - ) => Omit | Promise>; - /** - * Delete operation - * - * Triggered when an item is deleted. - */ - delete?: HookOperationConfig<'beforeDelete'>; - /** - * 📝 Enabling all supported operations within the afterChange hook - * - * 📌@type {boolean} - * - * @default undefined - * - * - * 📦 Usage Example - * - * @example 🧪 Enabling all operations - * ```ts - * enabled: true - * ``` - * - * --- - * ### ⚠️ Critical Notes - * - Only works for operations whose enabled property value is not false - * - If the value is false, it disables all operations (even explicitly enabled operations) - * - */ - enabled?: boolean; - /** - * 📝 Auxiliary side modes - * - * ### ⚠️ Critical Notes - * - By enabling debug mode at the hook level, all operations of that hook are logged - */ - modes?: HookModesConfig; - }; - beforeLogin: { - /** - * 📝 Custom log creation at a hook level - * - * @default undefined - * - * - * 📦 Usage Example - * - * @example 🧪 Change the user value for all beforeLogin hook operations - * ```ts - * customLogger: (args, fields) => { - * return { ...fields, user: null } - * } - * ``` - * - * --- - * ### ⚠️ Critical Notes - * - Only works for active operations - * - This function is only executed for operations that do not have a dedicated customLogger - * - Do not confuse this customLogger with the hooks-level customLogger (which is for all hooks)! - */ - customLogger?: ( - args: Parameters[0], - fields: Omit, - ) => Omit | Promise>; - /** - * 📝 Enabling all supported operations within the afterChange hook - * - * 📌@type {boolean} - * - * @default undefined - * - * - * 📦 Usage Example - * - * @example 🧪 Enabling all operations - * ```ts - * enabled: true - * ``` - * - * --- - * ### ⚠️ Critical Notes - * - Only works for operations whose enabled property value is not false - * - If the value is false, it disables all operations (even explicitly enabled operations) - * - */ - enabled?: boolean; - /** - * Login operation - * - * Triggered when a user logs in. - */ - login?: HookOperationConfig<'beforeLogin'>; - /** - * 📝 Auxiliary side modes - * - * ### ⚠️ Critical Notes - * - By enabling debug mode at the hook level, all operations of that hook are logged - */ - modes?: HookModesConfig; - }; - beforeOperation: { - /** - * Create operation - * - * Triggered when a new item is created. - */ - create?: HookOperationConfig<'beforeOperation'>; - /** - * 📝 Custom log creation at a hook level - * - * @default undefined - * - * - * 📦 Usage Example - * - * @example 🧪 Change the user value for all beforeOperation hook operations - * ```ts - * customLogger: (args, fields) => { - * return { ...fields, user: null } - * } - * ``` - * - * --- - * ### ⚠️ Critical Notes - * - Only works for active operations - * - This function is only executed for operations that do not have a dedicated customLogger - * - Do not confuse this customLogger with the hooks-level customLogger (which is for all hooks)! - */ - customLogger?: ( - args: Parameters[0], - fields: Omit, - ) => Omit | Promise>; - /** - * Delete operation - * - * Triggered when an item is deleted. - */ - delete?: HookOperationConfig<'beforeOperation'>; - /** - * 📝 Enabling all supported operations within the afterChange hook - * - * 📌@type {boolean} - * - * @default undefined - * - * - * 📦 Usage Example - * - * @example 🧪 Enabling all operations - * ```ts - * enabled: true - * ``` - * - * --- - * ### ⚠️ Critical Notes - * - Only works for operations whose enabled property value is not false - * - If the value is false, it disables all operations (even explicitly enabled operations) - * - */ - enabled?: boolean; - /** - * Forgot password operation - * - * Triggered when a password recovery request is made. - */ - forgotPassword?: HookOperationConfig<'beforeOperation'>; - /** - * Login operation - * - * Triggered when a user logs in. - */ - login?: HookOperationConfig<'beforeOperation'>; - /** - * 📝 Auxiliary side modes - * - * ### ⚠️ Critical Notes - * - By enabling debug mode at the hook level, all operations of that hook are logged - */ - modes?: HookModesConfig; - /** - * Read operation - * - * Triggered when data is read. - */ - read?: HookOperationConfig<'beforeOperation'>; - /** - * Refresh operation - * - * Triggered when authentication tokens are refreshed. - */ - refresh?: HookOperationConfig<'beforeOperation'>; - /** - * Update operation - * - * Triggered when an existing item is updated. - */ - update?: HookOperationConfig<'beforeOperation'>; - }; - beforeRead: { - /** - * 📝 Custom log creation at a hook level - * - * @default undefined - * - * - * 📦 Usage Example - * - * @example 🧪 Change the user value for all beforeRead hook operations - * ```ts - * customLogger: (args, fields) => { - * return { ...fields, user: null } - * } - * ``` - * - * --- - * ### ⚠️ Critical Notes - * - Only works for active operations - * - This function is only executed for operations that do not have a dedicated customLogger - * - Do not confuse this customLogger with the hooks-level customLogger (which is for all hooks)! - */ - customLogger?: ( - args: Parameters[0], - fields: Omit, - ) => Omit | Promise>; - /** - * 📝 Enabling all supported operations within the afterChange hook - * - * 📌@type {boolean} - * - * @default undefined - * - * - * 📦 Usage Example - * - * @example 🧪 Enabling all operations - * ```ts - * enabled: true - * ``` - * - * --- - * ### ⚠️ Critical Notes - * - Only works for operations whose enabled property value is not false - * - If the value is false, it disables all operations (even explicitly enabled operations) - * - */ - enabled?: boolean; - /** - * 📝 Auxiliary side modes - * - * ### ⚠️ Critical Notes - * - By enabling debug mode at the hook level, all operations of that hook are logged - */ - modes?: HookModesConfig; - /** - * Read operation - * - * Triggered when data is read. - */ - read?: HookOperationConfig<'beforeRead'>; - }; - beforeValidate: { - /** - * Create operation - * - * Triggered when a new item is created. - */ - create?: HookOperationConfig<'beforeValidate'>; - /** - * 📝 Custom log creation at a hook level - * - * @default undefined - * - * - * 📦 Usage Example - * - * @example 🧪 Change the user value for all beforeValidate hook operations - * ```ts - * customLogger: (args, fields) => { - * return { ...fields, user: null } - * } - * ``` - * - * --- - * ### ⚠️ Critical Notes - * - Only works for active operations - * - This function is only executed for operations that do not have a dedicated customLogger - * - Do not confuse this customLogger with the hooks-level customLogger (which is for all hooks)! - */ - customLogger?: ( - args: Parameters[0], - fields: Omit, - ) => Omit | Promise>; - /** - * 📝 Enabling all supported operations within the afterChange hook - * - * 📌@type {boolean} - * - * @default undefined - * - * - * 📦 Usage Example - * - * @example 🧪 Enabling all operations - * ```ts - * enabled: true - * ``` - * - * --- - * ### ⚠️ Critical Notes - * - Only works for operations whose enabled property value is not false - * - If the value is false, it disables all operations (even explicitly enabled operations) - * - */ - enabled?: boolean; - /** - * 📝 Auxiliary side modes - * - * ### ⚠️ Critical Notes - * - By enabling debug mode at the hook level, all operations of that hook are logged - */ - modes?: HookModesConfig; - /** - * Update operation - * - * Triggered when an existing item is updated. - */ - update?: HookOperationConfig<'beforeValidate'>; - }; - /** - * 📝 Custom log creation at a hooks level - * - * @default undefined - * - * - * 📦 Usage Example - * - * @example 🧪 Change the type value for all operations within all hooks - * ```ts - * customLogger: (args, fields) => { - * return { ...fields, type: 'error' } - * } - * ``` - * - * --- - * ### ⚠️ Critical Notes - * - Only works for active operations - * - This function is only executed for all operations and hooks that do not have a dedicated customLogger - * - Do not confuse this customLogger with the hook-level customLogger (which is only for a specific hook)! - */ - customLogger?: ( - args: Parameters[0], - fields: Omit, - ) => Omit | Promise>; - - me: { - /** - * 📝 Custom log creation at a hook level - * - * @default undefined - * - * - * 📦 Usage Example - * - * @example 🧪 Change the user value for all me hook operations - * ```ts - * customLogger: (args, fields) => { - * return { ...fields, user: null } - * } - * ``` - * - * --- - * ### ⚠️ Critical Notes - * - Only works for active operations - * - This function is only executed for operations that do not have a dedicated customLogger - * - Do not confuse this customLogger with the hooks-level customLogger (which is for all hooks)! - */ - customLogger?: ( - args: Parameters[0], - fields: Omit, - ) => Omit | Promise>; - /** - * 📝 Enabling all supported operations within the afterChange hook - * - * 📌@type {boolean} - * - * @default undefined - * - * - * 📦 Usage Example - * - * @example 🧪 Enabling all operations - * ```ts - * enabled: true - * ``` - * - * --- - * ### ⚠️ Critical Notes - * - Only works for operations whose enabled property value is not false - * - If the value is false, it disables all operations (even explicitly enabled operations) - * - */ - enabled?: boolean; - /** - * Me operation - * - * Triggered when a user fetches their own profile information. - */ - me?: HookOperationConfig<'me'>; - /** - * 📝 Auxiliary side modes - * - * ### ⚠️ Critical Notes - * - By enabling debug mode at the hook level, all operations of that hook are logged - */ - modes?: HookModesConfig; - }; - refresh: { - /** - * 📝 Custom log creation at a hook level - * - * @default undefined - * - * - * 📦 Usage Example - * - * @example 🧪 Change the user value for all refresh hook operations - * ```ts - * customLogger: (args, fields) => { - * return { ...fields, user: null } - * } - * ``` - * - * --- - * ### ⚠️ Critical Notes - * - Only works for active operations - * - This function is only executed for operations that do not have a dedicated customLogger - * - Do not confuse this customLogger with the hooks-level customLogger (which is for all hooks)! - */ - customLogger?: ( - args: Parameters[0], - fields: Omit, - ) => Omit | Promise>; - /** - * 📝 Enabling all supported operations within the afterChange hook - * - * 📌@type {boolean} - * - * @default undefined - * - * - * 📦 Usage Example - * - * @example 🧪 Enabling all operations - * ```ts - * enabled: true - * ``` - * - * --- - * ### ⚠️ Critical Notes - * - Only works for operations whose enabled property value is not false - * - If the value is false, it disables all operations (even explicitly enabled operations) - * - */ - enabled?: boolean; - /** - * 📝 Auxiliary side modes - * - * ### ⚠️ Critical Notes - * - By enabling debug mode at the hook level, all operations of that hook are logged - */ - modes?: HookModesConfig; - /** - * Refresh operation - * - * Triggered when authentication tokens are refreshed. - */ - refresh?: HookOperationConfig<'refresh'>; - }; -} - -export interface TrackedCollection { - /** - * 📝 Globally disable tracking for this collection - * - * 📌@type {boolean} - * - * @default undefined + * ### ⚠️ Critical Notes + * - The timeStamp field is not displayed in the table type * */ - disabled?: boolean; - + displayType?: 'manual' | 'table'; /** - * 📝 Define payload cms hooks for each collection being tracked - * + * 📝 Enable or disable debug mode * - * 📌@type {Partial} + * 📖 long. * - * @default undefined + * 📌@type {'manual' | 'table'} * + * @default false * - * 📦 Usage Example + * ``` * - * @example 🧪 Define an afterChange hook for a collection - * ```ts - * hooks: { afterChange: { create: { enabled: true } } } * ``` * * --- + * * ### ⚠️ Critical Notes - * - Each hook performs only its own operations - * - Authentication hooks are only triggered when authentication is enabled for the collection + * - The timeStamp field is not displayed in the table type * - * Read more: - * @see {@link https://payloadcms.com/docs/hooks/collections} */ - hooks?: Partial; - /** Optional label or description for UI/doc */ - label?: string; - + enabled?: boolean; /** - * 📝 The original name of your collection for tracking + * 📝 Select the required fields * - * 📌@type {string} + * 📖 To reduce confusion, you can log only the fields you need. + * + * 📌@type {Partial>} * * @default undefined * * * 📦 Usage Example * - * @example 🧪 Collection tracking posts + * @example 🧪 Only the true field is included in the log * ```ts - * { slug: 'posts' }, + * fields:{ + * type:true + * } * ``` * - * --- - * ### ⚠️ Critical Notes - * - Make sure the value entered exactly matches the value in your main collection configuration. - * @see {@link https://payloadcms.com/docs/configuration/collections#config-options} */ - slug: string; -} - -// eslint-disable-next-line unused-imports/no-unused-vars -const allowedSlugs = ['activities', 'auditor', 'logger'] as const; - -export interface BufferDebugFields { - flushStrategy: boolean; - interval: boolean; - size: boolean; + fields?: Partial>; } -export interface BufferModesConfig { +export interface HookModesConfig { /** * 📝 Debug mode for better inspection of logging performance * @@ -1593,132 +112,131 @@ export interface BufferModesConfig { * ### ⚠️ Critical Notes * - The generated logs are only displayed in the console and are not stored in the database. */ - debug?: { - /** - * 📝 How to display debug logs - * - * 📖 long. - * - * 📌@type {'manual' | 'table'} - * - * @default "table" - * - */ - displayType?: 'manual' | 'table'; - /** - * 📝 Enable or disable debug mode - * - * 📖 long. - * - * 📌@type {'manual' | 'table'} - * - * @default false - * - */ - enabled?: boolean; - /** - * 📝 Select the required fields - * - * 📖 To reduce confusion, you can log only the fields you need. - * - * 📌@type {BufferDebugFields} - * - * @default undefined - * - * - * 📦 Usage Example - * - * @example 🧪 Only the size field is included in the log - * ```ts - * fields:{ - * size: true - * } - * ``` - */ - fields?: Partial; - }; + debug?: HookOperationDebugModeConfig; } -export interface BufferConfig { +export interface LogConfig< + HookName extends CollectionHooksKeys = CollectionHooksKeys, +> { /** - * 📝 The basics of injecting logs into the database + * 📝 Custom log creation at a operation level + * + * @default undefined + * + * + * 📦 Usage Example + * + * @example 🧪 Change the user value for the create operation + * ```ts + * create: { + * customLogger: (args, fields) => { + * return { ...fields, user: null } + * }, + * enabled: true, + * }, + * ``` * + * --- + * ### ⚠️ Critical Notes + * - Only works for the current operation + * - Has the highest priority in execution + */ + customLogger?: ( + args: Parameters[0], + fields: Omit, + ) => Omit | Promise>; + /** + * 📝 Specifies whether logging is enabled or disabled for this operation within the hook * + * 📌@type {boolean} * - * @default "time" + * @default undefined * * * 📦 Usage Example * - * @example 🧪 Data injection based on log count + * @example 🧪 Activating the create operation * ```ts - * flushStrategy: 'size', + * create: { + * enabled: true, + * }, * ``` + * + * --- * ### ⚠️ Critical Notes - * - If you use the size method, your logs will be stored in RAM before being injected into the database. + * - If the enabled value is not entered, it is considered false. * */ - flushStrategy?: 'realtime' | 'size' | 'time'; + enabled?: boolean; + /** * 📝 Auxiliary side modes + * + * - */ - modes?: BufferModesConfig; + modes?: HookModesConfig; +} + +export interface TrackedCollection { + /** + * 📝 Globally disable tracking for this collection + * + * 📌@type {boolean} + * + * @default undefined + * + */ + disabled?: boolean; + /** - * 📝 Maximum number of logs before injection + * 📝 Define payload cms hooks for each collection being tracked * - * 📖 If the number of logs stored in the buffer memory reaches this number, data will be injected. * - * 📌@type {number} + * 📌@type {Partial} * - * @default 10 + * @default undefined * * * 📦 Usage Example * - * @example 🧪 Up to 18 logs can be stored in memory + * @example 🧪 Define an afterChange hook for a collection * ```ts - * size: 18 + * hooks: { afterChange: { create: { enabled: true } } } * ``` * * --- * ### ⚠️ Critical Notes - * - Works when flushStrategy is equal to size - * - If you enter the number 1, use the realtime method and do not define a value for this. - * ```ts - * flushStrategy: 'realtime', - * ``` - * - Very high numbers will increase RAM usage. - * - If you set a high number and on the other hand the logs produced are low, the logs will be recorded later. + * - Each hook performs only its own operations + * - Authentication hooks are only triggered when authentication is enabled for the collection * + * Read more: + * @see {@link https://payloadcms.com/docs/hooks/collections} */ - size?: number; + hooks?: Partial; + /** Optional label or description for UI/doc */ + label?: string; /** - * 📝 Maximum time to inject logs into the buffer relative to the last injection - * + * 📝 The original name of your collection for tracking * - * 📌@type {Duration} + * 📌@type {string} * - * @default 10000 + * @default undefined * * * 📦 Usage Example * - * @example 🧪 Inject logs every 1 minute + * @example 🧪 Collection tracking posts * ```ts - * time: 5000 + * { slug: 'posts' }, * ``` * * --- * ### ⚠️ Critical Notes - * - If you want to enter a value of "1s", set the flushStrategy value to time instead and do not define a value for the time property. - * ```ts - * flushStrategy: 'realtime', - * ``` - * - If you set the time too low, the CPU will be severely affected. - * - If you allow too much time, the logs will be recorded later. If the server crashes, the logs will be lost. + * - Make sure the value entered exactly matches the value in your main collection configuration. + * @see {@link https://payloadcms.com/docs/configuration/collections#config-options} */ - time?: number; + slug: string; } export interface Localization { @@ -1727,71 +245,6 @@ export interface Localization { }; } export interface PluginCollectionConfig { - /** - * 📝 auditor Collection Accessibility Settings - * - * 📖 Determine who can access the collection for what purposes. You can even fully customize each operation. - * - * - * @default undefined - * - * --- - * ### ⚠️ Critical Notes - * - If you do not define a value, the default access rule is used, which is as follows: - * ```({ req }) => req.user?.role === 'admin'``` - * - Currently only read operations are available - */ - Accessibility?: { - /** - * 📝 Full accessibility customization for collections in every operation - * - * - * @default undefined - * - * - * 📦 Usage Example - * - * @example 🧪 Allow only specific users to read. - * ```ts - * customAccess: { - * read: ({ req }) => req.user?.email === 'admin@example.com', - * } - * ``` - * - * --- - * ### ⚠️ Critical Notes - * - For any operation (such as reading), it works when you have not defined any custom roles in roles for that operation. - * - */ - customAccess?: { - read?: Access; - }; - /** - * 📝 Define which roles are allowed for each operation. - * - * - * - * @default undefined - * - * - * 📦 Usage Example - * - * @example 🧪 Only super-admin and CEO roles can view (read) logs - * ```ts - * roles: { - * read: ['CEO', 'super-admin'], - * }, - * ``` - * - * --- - * ### ⚠️ Critical Notes - * - When you have defined specific roles for an operation, customAccess values for that operation are ignored. - * - */ - roles?: { - read: string[]; - }; - }; /** * 📝 Buffer management for injecting data into the database * @@ -1864,27 +317,7 @@ export interface PluginCollectionConfig { * }, * ``` */ - configureRootCollection?: (defaults: CollectionConfig) => Partial; - /** - * 📝 Internationalization for the plugin - * - * 📌@type {Localization} - * - * @default undefined - */ - locale?: Localization; - /** - * 📝 Uses internal payload CMS configuration for slug - * - * 📖 You can customize the plugin's built-in collection slug. - * - * @see {@link https://payloadcms.com/docs/configuration/collections#config-options} - * - * ### ⚠️ Critical Notes - * - If you define a slug name in the `configureRootCollection` property, this value is ignored. - * - */ - slug?: (typeof allowedSlugs)[number] | ({} & string); + configureRootCollection?: (defaults?: CollectionConfig) => Partial; /** * 📝 Collection tracking management * @@ -1916,7 +349,7 @@ export interface PluginCollectionConfig { * - To temporarily disable tracking for any collection, you can use the disabled key. * */ - trackCollections: TrackedCollection[]; + track: TrackedCollection[]; } export interface AutomationConfig { @@ -1954,7 +387,7 @@ export interface AutomationConfig { }; } -export interface PluginOptions { +export interface PluginConfig { /** * 📝 Automatic plugin process management * @@ -2001,7 +434,7 @@ export interface PluginOptions { * - If defined, you must also enter the value of trackCollections. * */ - collection?: PluginCollectionConfig; + collection: PluginCollectionConfig; /** * 📝 Custom log creation at a global level * @@ -2023,8 +456,8 @@ export interface PluginOptions { * - This function is only executed for all operations and hooks that do not have a dedicated customLogger * - It works for both collection hooks and globals hooks */ - customLogger?: ( - args: Parameters[0], + customLogger?: ( + args: Parameters[0], fields: Omit, ) => Omit | Promise>; diff --git a/src/types/types.d.ts b/src/types/types.d.ts index 0e12af0..3e054cf 100644 --- a/src/types/types.d.ts +++ b/src/types/types.d.ts @@ -1,11 +1,11 @@ import type { RequestContext as OriginalRequestContext } from 'payload'; -import type { PluginOptions, TrackedCollection } from './../types/pluginOptions.ts'; +import type { PluginConfig, TrackedCollection } from './../types/pluginOptions.ts'; declare module 'payload' { // Create a new interface that merges your additional fields with the original one export interface RequestContext extends OriginalRequestContext { - pluginOptions: PluginOptions; + pluginOptions: PluginConfig; userHookConfig?: TrackedCollection; } } diff --git a/src/utils/prettyDebugLog.ts b/src/utils/prettyDebugLog.ts index d75ba08..a535468 100644 --- a/src/utils/prettyDebugLog.ts +++ b/src/utils/prettyDebugLog.ts @@ -1,10 +1,12 @@ -import type { hookTypes } from './../pluginUtils/configHelpers.js'; -import type { AuditHookOperationType } from './../types/pluginOptions.js'; - /* eslint-disable no-console */ + +import type { LiteralUnion } from 'type-fest'; + +import type { CollectionHooksKeys, CollectionHooksOperation } from '../core/log-builders/collections/logBuilderManager.js'; + export const prettyDebugLog = ( - title: (typeof hookTypes)[number] | ({} & string), - subtitle: ({} & string) | AuditHookOperationType, + title: LiteralUnion, + subtitle: LiteralUnion, data: Record, type: 'manual' | 'table' = 'table', ) => { From e0c816e2c2787dcf89ce0e214d79e0ba85157a0c Mon Sep 17 00:00:00 2001 From: shaadcode Date: Sun, 19 Jul 2026 18:06:09 +0330 Subject: [PATCH 4/8] chore(ci): change require branch for release-it --- .release-it.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.release-it.ts b/.release-it.ts index 3acfaca..9f62003 100644 --- a/.release-it.ts +++ b/.release-it.ts @@ -1,4 +1,4 @@ -import type { Config } from 'release-it' +import type { Config } from 'release-it'; export default { git: { @@ -6,7 +6,7 @@ export default { tagName: 'v${version}', push: true, pushRepo: 'origin', - requireBranch: 'release/latest', + requireBranch: 'release/*', getLatestTagFromAllRefs: true }, hooks: { From f937096d0fe8471dbbb559ec191e8ff7ec0d6ec6 Mon Sep 17 00:00:00 2001 From: shaadcode Date: Tue, 21 Jul 2026 18:47:59 +0330 Subject: [PATCH 5/8] feat: add 4 level logging --- .github/workflows/release.yml | 67 ++++- .release-it.prerelease.ts | 147 +++++----- .release-it.ts | 108 +++---- dev/collections/media/after-middleplage.png | Bin 0 -> 138433 bytes dev/payload.config.ts | 19 +- package.json | 4 +- .../collections/helpers/isOperationEnabled.ts | 28 -- .../isOperationEnabled.test.ts | 274 ++++++++++++++++++ .../isOperationEnabled/isOperationEnabled.ts | 33 +++ .../collections/logBuilderManager.ts | 8 +- src/pluginUtils/configHelpers.ts | 40 ++- src/types/pluginOptions.ts | 24 +- 12 files changed, 556 insertions(+), 196 deletions(-) create mode 100644 dev/collections/media/after-middleplage.png delete mode 100644 src/core/log-builders/collections/helpers/isOperationEnabled.ts create mode 100644 src/core/log-builders/collections/helpers/isOperationEnabled/isOperationEnabled.test.ts create mode 100644 src/core/log-builders/collections/helpers/isOperationEnabled/isOperationEnabled.ts diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index dfb3abb..de6aac5 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,30 +1,65 @@ -name: release and publish +name: release on: workflow_dispatch: + inputs: + mode: + type: choice + required: true + options: + - prerelease + - release + version-type: + type: choice + required: true + options: + - patch + - minor + - major + prerelease-type: + type: choice + required: true + options: + - rc + - beta + - alpha + dry-run: + type: choice + default: "" + options: + - -d + - "" + +permissions: + id-token: write + contents: write + packages: write + jobs: release: runs-on: ubuntu-latest steps: - - name: Checkout source code - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: - ref: release/latest fetch-depth: 0 - - name: Install dependencies - run: npm ci + - uses: oven-sh/setup-bun@v2 + with: + bun-version: latest - - name: initialize git user + - name: git config run: | - git config --global user.email "shaadcode@gmail.com" - git config --global user.name "shaadcode" - - name: initialize the npm config - run: npm config set //registry.npmjs.org/:_authToken $NPM_TOKEN + git config user.name "${GITHUB_ACTOR}" + git config user.email "${GITHUB_ACTOR}@users.noreply.github.com" + + - run: bun i --frozen-lockfile + - run: bun i -g npm@latest + - if: inputs.mode == 'prerelease' + run: npm run pre-release -- -i ${{ inputs.version-type }} --preRelease=${{ inputs.prerelease-type }} ${{inputs.dry-run}} env: - NPM_TOKEN: ${{secrets.NPM_TOKEN}} - - name: Run release - run: npm run release + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - if: inputs.mode == 'release' + run: npm run release -- -i ${{ inputs.version-type }} ${{inputs.dry-run}} env: - NPM_TOKEN: ${{secrets.NPM_TOKEN}} - GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.release-it.prerelease.ts b/.release-it.prerelease.ts index 257f7c9..ee39a3c 100644 --- a/.release-it.prerelease.ts +++ b/.release-it.prerelease.ts @@ -1,68 +1,85 @@ -import type { Config } from 'release-it' +import type { Config } from 'release-it'; +import { execSync } from 'child_process'; +function getCommitAuthor(commitHash: string): string { + try { + const author = execSync( + `git show -s --format="%an" ${commitHash}`, + { encoding: 'utf-8' } + ).trim(); + return author || 'unknown'; + } catch { + return 'unknown'; + } +} export default { - git: { - commitMessage: 'chore: release v${version}', - tagName: 'v${version}', - push: true, - }, - github: { - releaseName: 'v${version}', - release: true, - preRelease: true, - }, - npm: { - publish: true, - }, - plugins: { - '@release-it/conventional-changelog': { - infile: 'CHANGELOG.md', - header: '# Changelog', - preset: { - name: 'conventionalcommits', - types: [ - { - type: 'feat', - section: '🚀 Features', - hidden: false, - }, - { - type: 'fix', - section: '🐞 Bug Fixes', - hidden: false, - }, - { - type: 'chore', - section: '🧹 Chores', - hidden: false, - }, - { - type: 'docs', - section: '📚 Documentation', - hidden: false, - }, - { - type: 'refactor', - section: '🔧 Refactoring', - hidden: false, - }, - { - type: 'perf', - section: '⚡ Performance', - hidden: false, - }, - { - type: 'test', - section: '✅ Tests', - hidden: false, - }, - { - type: 'style', - section: '🎨 Styles', - hidden: false, - }, - ], - }, + git: { + requireBranch: "main" }, - }, -} satisfies Config + hooks: { + "before:init": ["git pull"] + }, + github: { + "preRelease": true, + release: true, + }, + "npm": { + "publish": true, + skipChecks: true, + publishArgs: ["--registry", "https://registry.npmjs.org/"], + }, + "plugins": { + "@release-it/conventional-changelog": { + "infile": "CHANGELOG.md", + "header": "# Changelog", + writerOpts: { + commitPartial: (ctx: any, commit: any) => { + const scope = ctx.scope + const subject = ctx.subject + const shortHash = ctx.raw.hash + const hash = ctx.hash + const owner = getCommitAuthor(hash) + const type = ctx.raw.type + return `- ${type}${scope ? `(${scope})` : ""}: ${subject} by **${owner}** in ${shortHash}\n`; + } + }, + "preset": { + "name": "conventionalcommits", + "types": [ + { + "type": "feat", + "section": "🚀 Features", + }, + { + "type": "fix", + "section": "🐞 Bug Fixes", + }, + { + "type": "chore", + "section": "🧹 Chores", + }, + { + "type": "docs", + "section": "📚 Documentation", + }, + { + "type": "refactor", + "section": "🔧 Refactoring", + }, + { + "type": "perf", + "section": "⚡ Performance", + }, + { + "type": "test", + "section": "✅ Tests", + }, + { + "type": "style", + "section": "🎨 Styles", + } + ] + } + } + } +} satisfies Config; diff --git a/.release-it.ts b/.release-it.ts index 9f62003..b3f3e46 100644 --- a/.release-it.ts +++ b/.release-it.ts @@ -1,76 +1,86 @@ +import { execSync } from 'child_process'; import type { Config } from 'release-it'; +function getCommitAuthor(commitHash: string): string { + try { + const author = execSync( + `git show -s --format="%an" ${commitHash}`, + { encoding: 'utf-8' } + ).trim(); + return author || 'unknown'; + } catch { + return 'unknown'; + } +} export default { git: { - commitMessage: 'chore: release v${version}', - tagName: 'v${version}', - push: true, - pushRepo: 'origin', - requireBranch: 'release/*', - getLatestTagFromAllRefs: true + // requireBranch: "main" }, hooks: { - 'before:init': ['git fetch --tags', 'git pull'], + "before:init": ["git pull"], }, github: { - release: true, - releaseName: 'v${version}', + "release": true, }, - npm: { - publish: true, + "npm": { + "publish": true, + skipChecks: true, + publishArgs: ["--registry", "https://registry.npmjs.org/"], + }, - plugins: { - '@release-it/conventional-changelog': { - infile: 'CHANGELOG.md', - header: '# Changelog', + "plugins": { + "@release-it/conventional-changelog": { + "infile": "CHANGELOG.md", + "header": "# Changelog", + strictSemVer: true, writerOpts: { - commitPartial: - '{{subject}}{{#if references}} in {{#each references}}#{{this.issue}}{{/each}}{{/if}} ({{shortHash}})\n', + commitPartial: (ctx: any, commit: any) => { + const scope = ctx.scope + const subject = ctx.subject + const shortHash = ctx.raw.hash + const hash = ctx.hash + const owner = getCommitAuthor(hash) + const type = ctx.raw.type + return `- ${type}${scope ? `(${scope})` : ""}: ${subject} by **${owner}** in ${shortHash}\n`; + } }, - preset: { - name: 'conventionalcommits', - types: [ + "preset": { + "name": "conventionalcommits", + "types": [ { - type: 'feat', - section: '🚀 Features', - hidden: false, + "type": "feat", + "section": "🚀 Features", }, { - type: 'fix', - section: '🐞 Bug Fixes', - hidden: false, + "type": "fix", + "section": "🐞 Bug Fixes", }, { - type: 'chore', - hidden: true, + "type": "chore", + "section": "🧹 Chores", }, { - type: 'docs', - section: '📚 Documentation', - hidden: false, + "type": "docs", + "section": "📚 Documentation", }, { - type: 'refactor', - section: '🔧 Refactoring', - hidden: false, + "type": "refactor", + "section": "🔧 Refactoring", }, { - type: 'perf', - section: '⚡ Performance', - hidden: false, + "type": "perf", + "section": "⚡ Performance", }, { - type: 'test', - section: '✅ Tests', - hidden: true, + "type": "test", + "section": "✅ Tests", }, { - type: 'style', - section: '🎨 Styles', - hidden: true, - }, - ], - }, - }, - }, -} satisfies Config + "type": "style", + "section": "🎨 Styles", + } + ] + } + } + } +} satisfies Config; diff --git a/dev/collections/media/after-middleplage.png b/dev/collections/media/after-middleplage.png new file mode 100644 index 0000000000000000000000000000000000000000..a120d575058accf75b63e2462f5fdfff3c57fe6a GIT binary patch literal 138433 zcmbrm2|U#K|2Q7;>DrVE<*H>%C8Smi25q8Ekwna3l%$MXh%uN?yGzcsLc~lv{qxT4+m^Zh^mkA3X!c)wrA^L{1QbB`@*4XBrG-PvoWlmhG{t@ABQ@8{%j7ULwhiS29JG?jf5yQIEEE zPf3Z^mt-X@wI?hY25%7%6xzP`h~CPNdS$zy4S({Vlja3|F7e-L2}{4A?YO70Hi0B2 zIIuQvZGi!amlr;-hY@rCb+~Zxu7X~-k|5{DFZWWh3;A-dG~qIl>tO#7ag#3wKiF|e zZWYEa_qw-B<5DZ3>B8EK@lyi1N53+51>VdZ8kf8!v3~%&9~Arb%dP7F0WKTiD6LE0 zR2hiG8uqJnb59Pw{3Q}A1Vbh4)VRcMmT+rdeUB>M*{1%*^wX8WGW*tv*e2I~q*Ywa z9^l6~NZ{=L^%pBYrgpV``^Efm0aW;&>qxthjPJg{SXunE%ol@KH?z|b*p@wj$n?=) zqu9%vq=%omwhXRapn%rrC9iGQxMUvu5O_fPMv(KxPTT*9V6OyywJ&*(h?vWNF?#H{ z-PNxU%n)D;JB#Y@YW+P|^yR*P1MFdJ@S_`U{_UL0!CO$)B=A2YyoTm7B%OlM;7hH< z3y;?~S@}V-7e1A|SsC^|g^@&d>^t%ZwfA-g0*J4PBcE5OABCh}B=udS z{Re=kQS@5e+Qd~*Ru|q#8r0sWyd&l#*Vd$aO((r}wS9$;-GTsE%6jL7*Re(&6+nK8 z)|&S6pSuU~5m}1L`xSu4SK_74ztMI@<~{<-#a3I;BAowXZ1*mK^?g@jpy4t}=M%@`%qwSU(r|&&P8ChE)1Lfh33dwxt&sN{vu#laVp30iI zt!}#U7;@#$7=^_M^Ob|NAiQiWHtzQ~UfTHp@^UxmEtnU(eh6;@Vv~rj$PGyunBy~X z=*nl_k<0}LzFnQSHe-W~k`(ypzo=N2`0lHMe4D=sjSXyHc|L9j>>)cpnQv3}>Ho~i zdw{^S{?=std2!N|P~OwcTdkc8%g`$Dy@`E!1d*I=Mkaxcgp8ex2NO zd4OC9I)3H&L0u=E-7u98<3=S}7AL(-Kx+~>o~jrNSw)=5kb!1{QED5uF>lOpen`+ z=Qf?`6rt&_yP)pAz>KlQU-F`tVbDHLlKdB0T$a38z?V>)-9;ek2w443rmr5b9R6`< zNVeR_H){pEV;lblNV&m`>l_Ctylvv@)ny5xAGIs~AA6w~d`G>**RlWRuBR*5d}hwq zBwz0Wpep}~xVsS!ZBtUx*J+?(2+Z)ZHeU@*2s;j5+^mj&^C(Kv0nQf(D2cPJ1r-0M z@~#jeAPtz~7Qp0e5E9aB;Suy_1zi@(&v>D30gU|R!#Aq}sH0>TxDlz%#9fwqQY)Zb zHcGBKf-u-O%TGQpzR>`!nH&CI3j5uEbt;f>(%Q%j4Ff%~ukYmvz~#A{yE1{KE$H(v z=ln8G8rJ{{Z&i(xbAJ&G*|^U?T9p+6BZ~rN6~wB&ypeJ4>H^HKo|HIWA9D zu%0Ol7XLaDD~5va5+jX+YUlPW{iQn}^xro%x?6QZ0%hjDnfb~;^-G7wqloqxfldD` z-W^e1%LROXgPPUdx~;NTSLQ*}pGUiom`lWdw+W!OlXlXZEYSvAhC0NLRQ^(;ZCx4R zo)Jv@AEZO6Y|9SVzWs`d-J}08lD{P1>Nx_6?@f3)w`urGe31A(%HHV#CUi&2S|OTCCW#&nmZm z{B<7yW*FZxUzN!tFU?6Bn`B^5jGd@9w^r690o-8UTT#3U55#g0dIB z@qdypRLuwgS55iJU7JJ%#oJ*ix{-bWH`ZJW5)^>TzwQ~qWEC2{t9nvj8M|t8|6JGj zv6FT-U**F_nQ;%1(Y)jxQf#+-)9}-U!Nji#{*@zu6bq>|iLb50*qOD#MP7zwT^Lt* zrE#hM?AIlH)6UDo6j%VYVo`Bl9CTno&$T^Q=d2$wV|`e1DaN^862>Up$Af^`*H!M4N#IO^fV1_K}v=@Op*zYxrDhqES- zUX+2H`a+>z{zy8qw)5(%HFpw);Rh>4?(1&!>4f0TRt5lP-Kg-*8R{*-d(DXJ-vTR2 zD?OL}Vy`tt-^epxQ4Q9SRvVvtGGEHBpWw-_IN-MYOtFz|k;|F|+ukBv1pMwE64VWx z*SNFGuoZMiHSDwf)3DS7eMS-tpv6A^0q}81Na4JQHE6ou2@Z{$mAR&0>g|<$g^%*! z1LU3*{KuDo2@4+9x#ayu5X6zuRUlXOrs>vbE{xK zDs!^5_=bx$7F%o!Hc|X%qIAy!P=S|ZXe&WT*3PQGvO`-EyE4z+6co}FegTMJh@Lb$ z?9%R8q>~pI_T1;sq4r|8XUC#EMEkpG(hgCMpD{Gs(e};SHY6r+2>CA5T@PjUH+7Pluh2%9?;*G+CwqK6v&^8-x@z z0Rj`Z5Q9|)1#PeTJzrP0W0~TpM?yW5vxBXxDJRsib}{ zI+wzG=qBpOs`MEg3I)NvWim8>u-FZ-t3#i3<}-vV)XN}!zb!jStEEY)dyBbxT-8>g zp6(lATWe38?>>#vuq?#4p0B7nb-6BE7Eo8W?{u6pLC-4hdvTL5tTc~7E?21 zx*R&I88Y81#3{#t?W5b@;Np75Z-l`Rblw5hiFb!~-aLFK2LQt!26dABO4@4X3E$iM zt@2a3N9gcfqXKCFU~A>QA#g}+#@kD?`1;6-f(E`TxD%xdu6`4)tF}n|R_6MT)JpZ) z%8;E!bPs0*V%NOnsGmM;aRjZmJ)r0L$JUV2+nCS!QPKtBQ_t2Fke?I$cgJ zO`nZ=_S#kE`P||H@20-ja}oX<{pVcw8*X%?Hs@H9D@xX#s80IOL0MA(h~*3(c`3Knk^a>h29_ND5lb*KJrC#5OTjmpYk1 zYkrfMo*YvVpfnWd5>RVI#m^V$M#63C=JAXeO@tSf^4naU-*tpvWO>2ppszJWcMin) zQ_8TOc#isB+5zk7yo?sbtJZ`Hu^rB}fzRU4ZA)-EN&77Q_21e_tP_n31kA&MtiEQk z^hahMktGi%rLKr?dmtAdzi&a*2;>0kGkh{S>oslI=K>u|Gth@SPhTvWgOA1>Hf7ee z%PCx>2Tm^pEfp_4c<{l7-Shlnt{#5?tC?O{jZUr(OlmMao0|B%S5y$pda2;(QfMll z8Yh7i#V*RzFh0-6Lctg-d71At5K;KKS5f$6`8ldcy|YaXq*IC`W9`83uG+5XR0-yHugyqcB4bnF(L(QU~TAWR1CJSgJAr1=IlOZa$?9*+j1uv z%&~^AELZx_O4&;8LM$k^}aGU~1T=~{u=oJ+6~TzpUhyOrWo zOh_^>88FQ+1>T;()TtV=?VS@3yA)mwcvG%0mLz~Xv6c%M6y0{Y_B|Ek-}ZZa*oCQD=I%q^Kal6>pXIfXso8m#nY-l~fh86J- zqu#fVdBU`uuS4O0`66`Oj4(3g#P!Onq}DT$%1n0DGmwfl+@l2zA5eu^RZ=XZpi#MC zLu_a{E})SI;i?{shS<_ET~tqe?I$md z&Z@D<%^$gM!EIJ^+L!FL<{;eTI_v4aP9NEvR-j) zxC{POe+kX2CG0(~mQjxLK5Rdk)!)A`i&VO~5&=9lCslmbV*VLMiUo`ujYEj=&(a%x zd0o2As@>S6@!lvp$uJL&t)?%^b6)xGz8Qg&5qkVq99x<&2eHq0g+Y3+chS9Fv%#7f zoC;2U`wUDtp8nx_7tWk!V%T!;CUxpZl*T1@&b*P=DRv4mzqkc<#&)=!S(wfle2U%X z%NZNJ+M58(fZ>`%)%+R1sYeD!e)a)Z+>cdvb&($n?AfU+Fx^y=6Y`4%j7`%SNxYi&@Hx7)|M^Y(FwGmug;F$50q; z<6YUuu&G4yER^U@xMT3oodbH$<(@xYKi-b>gXrIGFk%E9WzW&Bzvh@>b#_QGAJ6nj z)+3`x@sExp_I%81uo{K6Ez;Sio>1^|r|0rhleuC$+vO|l==<9p1L^OTwtYM1^R(A* zSoh}qjwL*ZIv13`$koDxbjj#UkehtP;K>Wfg_#L?0?7P@F1b0Q2h{m`xtbL&?3}U& z%u19B_#fwU_QQT^=I(Ppa*xN`{`x?B?!npbQA!~W2Hb;QFD#{`{NSKDmV7s|lVM}| z0V7P1rp$PWDM5wv$D={l^RQcfHDrY>K<@(ZlwK6Owla^ zobbe6aC`p;L67%?eJ7MpbWNER-Nv0zwrbgZEOA0%s0!`hb9_;858z-;dc#1zI;?u` zt&aU?rP|tkP)!)wv;OzwhPhQ7nJb{lmsigP4wpYyZVBHx`5qJOtHBwNm(Gf&uR4nF3YFBbY%8wR5`-ajWOR4wEb za<%8VKK61hF+MkvlqjeZ?l_#YW)}XQRn&k1t4>8GIR0q_l)^opo=kQ0^LU=4U?PGd z3I>+7*q-mjoE-11iN=9FYLGSOK_r2l({}AaPc-ybdTlmEu)C7 z@*!eogJyykrsB61{PG{8V|sSQdeSf2Z1e>L)ejusbEnh&as2ca)Xa{b_gH2eU5?{W zCOe*fQ3oE`2b?kzUFMG(ynZ6Ji!4ds%BU_EG|@SJL)IBFX^WoQVZYd-&i&-g*mkMs zdCT- z|D49@umX6gRVf44vgxj0lJ1PBi6BxIYxg{}8$I#?vPAzm*(QiJr=wc&{fRx+O4#gp zC<(+vHiQ}z7uj8h*?WVOQ{5usf62X8l+*+OR3^sh5%57_Xv;-G8?PlKFgz>ktlvHmnzM(iLXE1CN2lbbI)mU(sX4DdO zi9D-DlfMoP#LysAS^$0mPq1jnZBL+xBSmlG?lS|hz#`D85m0$c&Zm!K-Dc6vhMrgc zxfCC836P;ZZ@L_4KvX-LE7mWGn5y;gMYzgXhP~Bv=!2Ue{h)rZ+?48ms%J+g#@?l0 zG8HT4;HpjK$d0C&K0E8AkFaKmd%Ty6PNODJqj+Ed7vEId7VO38^w7lzU1bKwVP_QZ zneb0R(_U~KeCkxB5uA*JvkB7-c5g+oK_4acT!p&I;r4>;)-XbVGZ4LY4(U*=4DwWH zJtqNkci}&x;6jQ>R8`4ASoolk=)zDSS#9`B*JVu1nNI`JkV%DdmRZpa0W zmB(Saf{+V&(xbYVVc(e8)cQ++1IIbM&_QF;w2gY3X;VxHQE9<%p@fAMEyZU=vKs1Y z2+mIURHegE9R||3EZRF>lo?Jaag8k818N-(8rGv)$oHgz5O%$)0RE11@JpNVF;U>whkFve;QH`V7zITjSvV{6WczORC z16O^wKy#a@$Bju z2m*^$FIHC>*d7~N!g`FS0jrzk#_jKwhb;IZ`Y!gl_?GH=*_djj`r=}wnx0`8E;0$! zl1UwkRMT0fg)VkILk&2Olg z$cWCFS>SPT#EGok65)}LKz=XA%9X~%K~tq(+s z-yZ{K!kxMhSJ};Ktw!XbB$_TVa;w;hW=OM_wOKm_-f~G)tr=s^D1L`@>hi+M_-mHYW45J4*|N|?Nuw1Y~oa+6QLwPW5=SkkQn9s|~< zx;^!v#;k=ZHLCRO!=m_#CIapEj5HC2*5Q@`DVxH8Wd%8n3r^W|jI4FiM7Kpt0-EzM zloT}Yw!}<`)7&z(D`cDCVTsVUV84KX^RcJ8v)&$zbx$scoaq?&Igueb#yWCMtK){2 zkXiwSHbc{vS3`K>o~Aj<;2K_e{G$_U$2ZL1Du3XssJjGea&M~*#R14ZCj%`ob+~-B z=*e+1PJSRj)BdJ3`I`CEHz=CG3)-zLbSb>oiH&gLCyv)#$zW2G;P4tM`Fv}2*=4zY z%1;&PiJ6M~cblZ0EbdMuO$!pY-SD5v*w+5?ypPnMi=gjDya&m81JM8AX8#- zM8xD`%U$o#oQ%{+5<}Q&+qItOwU8%@xYiS1^cicfY&@~)?j7>bl%>?$!i>~WSHYpv z*UQFix=g(}`EO^mc3AG>C&M=Q?JI8QuRuI^d0#&N&G;pOkSy6*+NrsVf`~n-BQi_> z89se^;+F*xmPc>!=}wK7(}D@Rq`hZ`vNXY4ZZ@_S%7Qkms15iwYyRUle&^WU7iajd z-LZPo&%;W5C``w*@<3IdAbshvs_5B~rF!sbO@vIRQbBhbM*kc~bzw?wbP3 z>1lu$GEKF@Yq@|G_}%va;y*Sad)MY?r07Gup7i90-qwTLoOOyLcv~-@JReN@SdVBtnS}W2)0kZB8_1{)l zH>PCgy@3kL+WNP?xJ-WOSM$}5e{DQk7rkZ9JS+p?G6{M_S*tMfqwjycn9$wNkHF@) z+VRmnGA=H_+YqfTi}i+XwH0Y=GVL+J*%x;+a&ji~IFj?|+66UyF!~Yz++EAs#$HlRu zVS~#?f(nnUr=V9Ad%YE73yR-<$9_+}+qAqzx0m4E&#m3d`1(rBO!U?a8AX7uC+mFL zcI@=gjYOjJi+fUCbFaD18-4uG2$8~td)&>Ob!~bVvqF;2zAfH-f{-j?^l9irr>JX0ri@%gvIK&!F=@GrBE}TT5?LqD@|PTcMB|2_0I#L zx+Zehe*i3!^^UzIm3o1}C&%Q+DxDPh_aQn2@sEtVDv-|*A2IZl*^TTyod|#(OT5+& zTJCeISe)4Zv?sjtz!gBvlz$DBQL-t%p~7^@zV!_%S2(~GC$4^&kNBw_gYtTIvZ%9r zOz}=N-(n9;U83z+rwD3RXe5*r3al&-@#OE;%@*|7(#_t!rA)YIYG2dY=d0;cKCGFf zYS>3^M})cPLsT$EhyC9K=WwCz+Lxbu|2dR*6{xQjI_0jMpC<*AR>T*zi{E;)m)B^v zz-f1b!95skC_l}Wzi;O7(ri$rQ%*a1KWvVxkC6A`{?zbZBzndM+H1+q!3BNGvw!~KCsA-Pn%v(bB zSpj^9Fv!6+PqC*K)S!kTiRmik_&kK`{HXQ0(|a7ql^z{80Tgp_$3(S}bOfz{h3zHO zJJgp8dbpo_SN^)F@Q_eX_{Re#pG@Xb&*dB9{7f2v3KhNP6Wa+9Nj8Pk(<|g_ik$8P z*QWeYGv1hN1J1E;X0zQG+iAKz5#o4Mi2?w|~{flv( z9?`Eduv+bBeVEC3k5^F#@PRHu@k05Ue?EBkS6(`Dc%^k^y{iIc&o9SRPk5L^LVm9Z zT3U>&={_=B&zW?87jY}sf_iW9M~U9 zHmC~FDg=5A?(S=w;@ub}zbsHf%U>?M7k<2*o0pl_pST6(CDik)X_)6PGebW*v{R{g zC9GNzMLM^R*P}zLVhc`;$>n4GDh}c1?%$aD@M&XDPP=eKz#~A#+#c3Nf-|;WAEI6Q zxYE3kBZyb|1^$@mhkr#IJF$1$mg^l}KU-W3CcO+6cq=$WE`A`RY{!>f5%EE=bn7$U z@kv`7Wf9}_hiX+Ho^d~B8UM#(xfgR_@5@~)=eV6YKmzmB(*6E>OxXiqbD$VD$AV$o z3NtMl?j6QT*-sv?VIXIbiRzQd)a*`Hwz(AanLNIAQnxc+M6@Vho~a0bVqdp7Z9Tx& z$(-oN`vxQyTV#%ykR4L^Wi%g|>{w5@H^k-s6&60vEJ~60(JPVaZ#+8$sWU?2;Yzx0 z;i|J<9hil5kNQtxPb(wR83o3PP);V}4C^ZS!*g$}mA)(1roBYZQu*DbcLl~E0)KH^ zmX{>V7EzPn2luW8cBdTjGgfn=#%P`Zc5jWZp0=&i>@O+M1t<7n8BZ|z`0|#UuPKvM znv?e=0Y8x)#Kf4X-ppz88coSm$2m5pc{WST4M8YZNBi;hP=940x}ZI6xoHb8#S%Q7 z7ds>iDQM~-5tjRD7?#^5sZOi--oy=CVBliCT%x1WCMWPb`~+goP(*gr3JN0N2i`04 z3@DaSHvUnil-u_Mu(&*GY;1IPKMvpD3+KXnsdI3(DIh5_xLorq7Q@fu2{Dk*)jZ~K zrYZi;fLrl~OO1e;0lhYZ~Gg zxIsJT)xCWpGgAd9uz3RWT6OIaBkH%SiC_m4@FK7>FY^EE z%F&Cn```?~X#O>vpy~y6*S7r{xCu5mynyz({ zb*fO2IsHg5oUZ9ukGM1P>1_=2Jv=h+{`bD$=~51`vLo)fy}P&2G*2mSs=!-}s8mN+ zQ)Vaq<{cN-8lvrR!4oU~SSR0|i9VORG+XXv9P-Na+S_v&+DD@N!2gl)9JiK9A0IFBC@ZgI`2@N{UpfAzHUAy8BfDQ z;4c0Cl!4<@a5fZV*plDidly=opvC&#nrWqs^%KF*GJ5Jt8=v-K%)oQMy?((9xR7p7 z_hlpJ9l@NcRwj_HoVqeL1c}OxJmFQ#@Vt^ELp`I8uA9H7m=?ER&FqOiK_|g0ea-{h zdTPqhGxcs*3{W`DrPVHEuxs#yU(QsNpJ5n2Ytu4jL`I*C~b} zjl>MpF%6)L9bWu$W#os|n(OV9SxC?F8H?sh`8ntVFc1M4?hvEydL ztD>k`e%&+XwK#uU#s6R1x|%?9OzRqWJr(hVnOFvLEPLt6tBHPZ{R;Xdhy^W+_Bc^n zK3O+sVGD8{1r7IsCZuD4Ob;lis8z07`J&4eH>k^Q)tjJ-<=QVCY)A|(*Ig+(K>PS?hsipxH&$^lb2Ah?FlR8o$9Y z9S;!DD!~Ch0vD-XZ2O7J>T)AiPPO*;ot}FxDJC~apT3) z@G1id!>8En{Hc-hbTwr*o}%XTWY{@TF>+zrn@oF~E8dUx9~k`bfmvNXI~6--$eqh3 zDq+2{agId58}Mq;*~70-$Keez#VxWjX6>v&O>%8C;HuVw<}-ziM9F+z8UH~5x)Miz z1ma7z(Oj^r{n-V_g($Pqpmg=a?wY-$5dlL!)$@kBsE|n)VRysO+8%K5uLUnk) z{xFQ?5-l0N&|e3lofXlH^Rk{uUQFo?E3IG2!K?;&LEC3)3<0lyZaeSnv6Ruhaa+%~ z>-yeGxQ&S8MwZtl+`+4i)4AtH_;((sw$DsCpnYctQu0Q@i%TjeD4yg&-5#n{UZr)r zsCQjbA-E=C>crjlcKX6kMsAU5dz7Xd5f^Pol-`L=#d%FPf+s6#L1S~t99vr!khJw~ zn5i(}bj3;;oS;m~yD2%E1WDhcoegBRX^`S>!*{QgK}hXFBP(@K;7Zl`9EA!sctwhy z^qI2G)N`k@7@7Cp*_t^&y`A*!#5+rqD}{gUas4h?SA&>sBK~lY2e#@j>^JOsd_kb5 z0yoZjZ10G4#JdMF8d-QIy6ZxZO}fTywkb1I(`jUX+tg8nbWfW)Z^57jsJaI#>bhM7 zV`4g-S(k5DSd3ta-|KLG<<>|}GEBN^=B@|$D?u41OxWwOY~3?HLozjzhE6FluZt?u z7>Zm(e}@s`@gs;|i)XK%Ip8io5ZrKqI+(%Rwtt5M=9&(Rld>@Tm{N?2|Rxcm;4gVtWoU5-lwy*}3rO6Oin z?+jg1n?WDv@&hdL_A1s1(V+SY_x+W+N)PsU137Z)pGhzBB>WI?gWc!58-S4aXlhM& z-djoH6a(II=Gft-Y+n4WkxX$6gwZ*$yZB74+ApwA=a^H^IGRkYB9-Nk$UQOm@v^Xz z8UQ&h`?PCz+EY4pZd$6OYks-rzq8Bd>B)+3+V?5xjtY&P+>4odoj*Fp^lzT)0UJi- z`F$Vsg7eJlt+!G6r+PYL|M8&RMLw2VFI#Gr+PM)*@P0DB>=j1428>G5lh$b4hliXk zjx)d#t8c|ybfwVhysH-}6l!dtg}u>I=0Ilw#q&xY(&&lzB;$sP8}xOwDjeiC+%-8H z6dO&{*__jRY6J*uDV>qusiBWgQ4x`JIgG4}X}I{#Rz7Km=62~*-E}pO&hI&XllR+0 zxE0Gcx5Kf<&ke&?=cx+n)YNF$njWQ_SD{NeQLMz*97eC$6erJxARQul7m?P^-H-V> zbX1HJd1}vpM{)_s=|=DQGaguqLS&Ft$D_mkyAe~eS3GFVy$UU83+r1e;pK`?q7B@^ z`wu`&Nm3Gsy*ngJdNFZ!f4~CW3HHRMGOXed5=CWv7fxyyp6sIba3j+nzHUwAk-Od| zPDz_;>Bt+lm_8!uppa>GFfXVs)gi^Ql>$-qQR=Dd(WXqYyMSiwhYsW%nd-JQsxG0X zv>r5P!^LrkiH?a3?_RLVJ1G0@cU=hA_+q!xCC+Gj{H^L$TN*9)(tU;LDZpV$wd(T8 zP?t`1`U^9QNo&8}ehWu=)*M)*H(FN_5QSgV=4SC?RHTaY++Hl2B9hXL8(izO2H9=b zUlXe7vpPw>u^)<`cHJ3TvNQ;IT%fRMTBR!@YRNl=WgjjGO@05KwFgR3zg}sXRP&>d z6Xw}jT?voioEN$HIFO@u0_<0es-ath60EW7{sNKL5nKH39yy>e5=_J8sZaU=VG{f9 zRAqZ${xto}&C#=-3U574d||AVk-Yvlg7F*rC`kOIihq5srsMB!I{I{mA=wB!VV3CRhi-HmZeVqp!BwY4Bc>#_@&@xUGR+o@_~v6Mx`PPn zpNoE4Y>}4i$SRwfz-XQpgCDP)jv|;;4v~l)8*HH#qJc}vu(O$a8_BO&*ElfFCdNak< z`Y`?6CBWCiRnlmwN zs+J1AjdgVk%C*P^iCHXXuw4pE!*bBG@zn+}eUlW3afD4ct%Odd6$ulY{OY>z$NDo=8>c>>83}*7io=`+=s7bB1;2$k={;;+aWRd9Fjs zv~_OG+$3Cym1;Q1NNuvB1Q!W| z=VHHgihE_jFk8U0Yaq4kOa{>1;W89BqagD)9zzXVoS)6&Wl1%e;RuTdp#~;ch_P+v z2pI@+Ms(*&2~@DxO!f`Lbi~5u3y<#G0IrOUi|762iNb~i`d732o=DNpWaPbKfCi%5 zAod<3KQuLY`08B2zibG4(D_$*MT}ZR-=h5^twq%{)Jv|A=6KcnBeA$NUX)5cf};gd z$CaM*!Rq4T#)>0;w6_V`IpQ(0FfyOqU~|=usnw>LPxuAvA`d_Kp|cGAz3ZL)m<}cO z$ESz#(=4!E@~OsE7O`0S;;8nrMync`g>pV2mcWy(heEPzlkk3+k$a=dlDZl+4~joLpZe&A%EJ$iE)zU1 z%Q3Fv#n^JM$e@j-n=8=&2Q1&%xne-V<4^Sr!s-ycT1DZKX6~W&l)dwwJCCl>;H-Hr@i-A?jhmdF@b^MB|=1u1Fs(UHLjOdx@ zKHI+}nO4s-6&$e!)7+M!504>!(@~GhLjy+I#|$}@@lp$-#9#R7|E^~eY6!3B+V(S! zOrv%S-XH`~5zP8U>N zMJ|SxFE%6l3{LeskA|0>;Iy=9`nYrq()=go9q-W5^JsrKD7(_P;(hp~-uV0&iC0fz zxffl-%887{!M8V{)TTm;yytDCVaxqijbZW|3*;&hN!EfsE7w>kz~KYgpH!kN^26xk zL-%^@jAiee_(3~>o_2UdojhQD(<{;e8`-JSZwLc!GTdW62C}pFukiapD!56*>F}Hc z^hY&(SHC1IuwRr}i|N&&`OA6MSxTuVVTSvA{o8L}sg)_ME;(@D+CK{JBt@)l({7%D zK!>5P2keVGR9bPZ(Aww<&nrbPk1bLxc<-gLl2{I%hMn+3xMAPd)ui+8!NQ&-AY ziD0D9TfidP_hZZ8qZ1Au`hD-z-U0#hU?@r zDl+ey7}uK*w9;ym>5Qy6L&@dl71(P7*RUtg_&YVL(d3$^;^7fw`PTRRt{kqd{S{eN z<)A3uy>>~}z!L;Yq=!T2z3}(#y?) zJWx-Vca^rNV?8jgF$)ZBa1YaPf|)AzWci<^fabQCHyp3%j>=+p5|t=29u&=J9er~s zBas|(Q<)Yf`TOJQ)obrgw1^NtnWOemSAD= z%#F#CH&wiSze1hUx@fIE`O*x#D3vmrxK<|Q8xf=+xzY32;ZH2`@LC!6nQ+gzne4M& zhgNFAZ3?K$T}2|g8g1jg(o4n1uLb%9+!Zf%{d9(B})5B z98PyE%}2KB*lOhbqmc9RCkt%(1%O;wWy9*_Kev4vUbsNd`ouD)!+_!O* z-hK&h!`OQd=`+xlV&g3O@FPp=X5b=O`-*ukvAx&bzu9$>fpwxZr+K%?iD>n)VIjJJF73vj47uzY~4c&F^gL#$%QS42NB z9{prLFX}kZ-pZ)d9>1ZJz&zxqQ$TrNzFaR}HMd7j|4wo#?mN=z0*m~4t$(LcENkIF zw#IjO@%|hq?^*Sk!;Da}hZWLBn@z%sqPO8H4kx$8JC9_-6JMEA$ZO_MVNW6TlIY!dF^^jVcorAJ-bHF=u~7qQwkK|lS@KIDmbbZ6+#t5PJy*_E|i_uj+rqC%-O{I({=7_rm*`=A^B?9CU6AM!si z!a^{7zPw=#2-n(O=8X#sNN79+KII_uP0kk|2GRIIZ?(HkZt;yW96_80#I~jKTWCn*kf_`u)+31&cFlxUXzRA`0dG zvQgK8$7?Mr-Dd!wN;&P^dI4AOME54Uuwm>9R@xT(;uj4{am}@I}QSR%vyquejeTGuDVmni8e}6||rbpJh?P?Y#s$QpFaNBK)`t zHtCgM4ses&4mHDlt}Rf48+jD}Nh1K7GWFEbFSf8*19&4e{oEpnWS@#qK|A z*rUGNyM%r+X0r^|XXk@28o)B!vK!gv{Hr!d!Geuq3!sG(6fu(t^}BNdzxl-$6m*v~ zV7@6@Ma!Qqd1~>T^Ns{uz^Isf>N9oDAecmjEpc>TZ(aTbtF-*{odQ9NbmrOaF60kD(u3U7zBRrOd$zPz8n!b zu0b=Qcnvpwmn}f71txSJp+9VM} zi3Pq6K*b17e2SR))We6hJ=d1A+DtQsXNr=dQ!u#%Pf1K_C++G7gCGbtiN<*Q#kc22*wZ{WFuL_0f#? zkD1P*yxO!5*fK~)igU-7>ugv;fVE$j)=Mb}t8^F!T+prr3T=tSt<{D>SRzHd6q^M!VMMmjp1mf-x4;@> zX;bjNKC(%9H2BFYLUhx7fi0*aKzXVcQ?$231{ejIYQ#^vYqx%AQcZR7jcpscd3VF5ePfZ&ocfC97r#LFC#_7taxjfNG_Z z{l}*V567V4)WPU1c4X1T$WY2tAO=$f_X78{b14e#2nr=Omg8>Wnp4Rx>*sd0)zJdL zAiSiiaw?^`nbIl)Z2Map&;sIU1Z#R-;C?@JJ`55yvCLIl{|*RWPp%8J z1D+KL%TJ!SGG87Pv=<}>eQJNEevZfbWJm#gK~^qwi7}WApM@{L6=|A*%o3V^RGxY6 z5{EDzdC=ov0}G3^=%mjA_c7p-4Kg31@$V9TbbJEV&6pw{e6;wm*FIE6^P|BAw7ych}BK%N>Zm4Qy}eTE&1;# zv#AvHE7ibi;QmGo@!e}h`#a^+Gcr|jm#``03ACcvr0Ug|KHQ=^0Ml4mJ1qwpPSe-uRoU=iPN zBO0jVk9nS>rKT?64V?{)2z&yNE;h6}JF0|B88d^G86e7*`tbM=OS3%Hi`vl!5e+p} z%g9vzKgPa1psA~QyHa@FS{Gb!0bCFf5fLdOJGKfcB4tr_f>K3@5F`bJ5RkWvqAV)1 zC`+t}$dW{a1X&VjMGz2Dgd`XsP=Q1UNraFD2qE9OVG(Tm{=R?OD@pD>_nbL%W}caO zru2y!|E7fDK5AZzE>C2nAIuY~3L9S|Z34P113wdOVfSO+t%U)=V#& z8oV6-v;XD^cg)3cP@@?&!CPLcGzP?Jk(Q2Gb_#WSC`qm2o$mMQj~HIx$9|{u7B2NmnPQZPtQUF$0db1_#sigD zyp~Wk!%-nAd-WCUt6Ise*F9clc{fBak~r>1y>A{Yqk6Nb*=-#^avR(lu?c!Ht8ZjJ zT}w9$0NDu>=|H`mj@Ryl`)c5|8r?zpc_R0|MqRG!)}BV4dO|je*0#k1o+NB%_-3ys zOqZ4Za-^J|>h{iis|W3Y(0Jd@QE3XOQGbgDHRr69I&4))7pU`YK+a@HgiHfu1k|y! zQ$Md`ulB8-+&M~kg}iwwN%8`BtUq@T(t~@!n`@k4N6*g8?E+;Oe)|IMl|$v_QJ&c9 zvs!icxFDT^4se{J4V1MJr@O>&*7iBprkgd6V5_3uyhXbqw9E4JXiiPHA{^T%d){vR z&w#hb#S5sw%WfPe3P>=Pw70Vs74!}&>;{ViSaSgxqo(wB#QQ&;H&1}rj{_)T;#q0| zK@TF|%_W;5nxyv$zUIp`+Lz4b1=! zIQQjSL8~y8#b_%lZOJ8P8;cY5*qhL0HWUor&z9S&Pmr?U9URV=8wdpJ22@dhBe6Jt)?V9fV zIc^4(a9^)_YOiMisz0J4)mS}RYhq52@qbL@_)V`I76|JuUUDmAaHx2ALiKpkrRJ;b z@0_uQaG6&xuiB^^jjq;-Mx%%5L6oXH>+aAhe*Bt$BUcq|sYG-oFpm{V*_SC*o#&l- zKc3C#V6U}suragm<$*i`jxA!!soHYv%~s>J{#aZ3$3)l0R3=$I%AVTOyg~ks^G`9a8jpDIAFt0+x*?1KL`L7Eq;Vc(i@8 zl&f+>yynhc5KU+nhQ}Ia5T<(yr=}@)x_WG)(A`}6ks_^~SiV19m*4A;>Z)Ms9txk_ zSA?rpC<&jrp)I2_`?+^yV(8Jw>|A)!j`P|!JyNCjJxM!x)s9fo`@Go(c%B-;I`n=4 z#Tu+K^N&uo=dZ`2U;S2a79*Nae6QCEzd}9Tr#A(3WC>Apsne0;~HN03}c* z>`X%S)zxeLs2D;}dTx4X5?pc&MsI!uPPf8qtwGAG}}k2T^3f zq@R0o1|-FMO%5l}w%ji>3in5o3?l`N zQeKv6U7oA^cVN@;+9cNEEz#lKNKQ{2ZQ5%HCn?6&FLym4f75w&ezgjCnuYl9zg^b8 z%IR2Ty6yJq(ZlcaD{m5P%tEEbyz!M2H(tPQb--)gnMKmUTi4vgMiuz+eMjRHQQt*# z>CR0B)an1^g(SIn)S_9NxPO&baxa9<~JC10q?X=Zvov_*-7~6>_R{&YC_}nc%{(un;%TVoiL>{sF6_X`od6kDDoAr8;;`s2XC*t*}gsXKK#urnj zr_Ae$i{46%hnjUb+s2CC*eXTwyeHoWE~q4$?RcUGq0z7OdT5Xn*Slp2tRmi+PR>*> z{GQUnsWWxE8TreE2S^XN0MY|0ExoswC5oS|ms~V@P-CDNJvBa(QlEOJ9-pJz$28e3 zLw`8_Q&mt^a_->}rWSQYauliDjmew78rx;UeCeoaDKXGtRU6ey4Z_b+<*(iQwSs7# z&>Zlh9x1?vB*z1%zGwHlxWKVxwXhZ9{)UJotEemA*I~mgTi^eIe#GsH)^UkM+~@GB zEz?k2+z`e@_RHrNPT6Y^zbTWbQ(mdhq5}vXx{-)#x?O`sNwuwszi*nQEUI`REnJO2hwL{^fDkfEI4~w}v zfSW*%r4-X(tg`H+g0=#@)Fqa|{^p=Ne+NTjr=NB}s7IeW*H(y^kY2t&t15kewV%JJsPndG=cJFlTZg<(L61Y~|56}V>y<$%4^dY*lE;k;t zM!gHGmk0j|lu<@D2#(%&0r?4y?5I=GFxD%9drW`SPWNB2LTgkl!yPUk6dXA=Ru)jk z5Vyw{I~eWcl^q39ecjNu^ru-o0US#btrF^k z!(*L}?W6Eecpwy74D>8L_Bhj={pQpI$O}sPG3L-Y7(m3aRUQ^7rL*ufXv_zAjs4x`Cwn%u3~&amdbwWWLgAi16&E7o$$cK+$vW;U29G|;8triP79$= zCKeG6xnM1uVH}jL$HC)t206{*y0&FP5*)xlmzp#PNuF@{Yxon%od@RS`9T%5x^`OX z=y}fyd-^5#vBn0xtx!-^!uQ}jOHb>@Fv|HWQdM2;#Wkrsjy^NZhxSwYzxys0(pjWiYG- zeYSbu5JT0l_lL&fISnU-jc^LX_f0BbY=|q*Rz``-{G#|B+2T$Q9cI(!!WnyAh}bg&aOR zmw4>3>b(NCwmC0Ft*rO(nhmWUa(ah>EWJMkD%Ix3{<-Gmch;@-1yqLoHRhbS%p0zV ziaM#|aKw9_2#1s<-8r}j)fB2$?K zPVjARF8$W+L;ZmyV{JVz!Im7chG8TUKudnQ5dFkf<2xBUvuz%U#br->oB+W^WQgS* zWIyB4+1d{l#CUD?;YZd5-s#p|zN+Vj2ESN5u2TCu^d3#lM z;Ls`~jWkC01v{&2YXS|`&WqHG9ZMr$vD3LFS)Y#ubPKNx6XL+7u9pWl-?I8i7l=a# z^;_Vx>VOs{k9k(I`ufOk;)v@nz|8UhDI_uXc*Nj?kT!^S!JJ-oHX0PDXw|1${uXdf zcN_mCbMV2&dr%gD*t0GD#gnNQ_IDU>3DoRK6fWPo;)(vCv6mByZa$URPwQ$7&j zjY;tSI>TdTdB+0*zXb~K@5y0!_-X4=6EmkQvN3D?o3Ge$5}=o4Kd2k?L=EW<+(SO@ zsxl{V%V~g)!kYEEz8<}0D-?S-r;k6f*cng@MfGn)VXt5U>Ogd!#CG560=FeN!XlX= zc7}jT<2Xd60X?ds?!}K7Tr1JgF@Y8e@80A>iznWwGS9ZzxvetH(lK1yh@~xo1Nsb( zab4=2kS5X9(`XdlLFZUO3N$%*FQ;fv4I`X3sPF(vs-20l>vN|wO$^x7X*B0`PmUk4 zq%3Jg`ez-Tz5>XvVQpwyKa#%o`jee4S;vG1if>`#>Ss`oz5CS-`3|Ay?bezLBL$HG zYFX>xw+>eXdGm)SCp>MKl(96?$f})*qjByt-+-&R=`}}KH#=8`VVlc@d8uLvBhN|-(rIQ zE_|xs56$=Ejl!GyE=Nh>MZ%{hz9rMyUKuD3TOht!FDn6bz2k1q3*E;rV*8Z9A3zT$ zKt(?oIK#a#yzz$K>d_8>EZMBAP4kE_i!@Ntv*;SthQriZQeM5%ABU4hR;=E14s>v< za@;N>>GEK4&#tuPrdh@qeY^jwm3?L#9k;a-#`qR~+m4%8PHT8yJ2q>2RIeP@nstMK zmRg#>JMumeio+PK00xv8F;>bZ)?|=h$LpzdDo676e0)M-t4Xnd^If3G9Ft^N#!w`x zS!X8fFqD$7sG6WJ9B1yVoyEx@)Nz-74>b|k*`QIxb*NE9IHFX%vXNQUy|ThBwj=y# z`97F(>Q1&9eHd;aWKrt^K=7$XOEEI0XQ)|HtKO1nAX0N^(f`Os7`F?qSv8XnRT<$A ziH3;d;+z{A>;z0y3f;6K+PiacyE|v4Z$RF_9mqaBk|B?kwt%?8Yy7M7l7i^)Scb~& z5zP+wdy)b`g^@j#X%>J=NAn5hFzVS7JO24WcN`uB@XN&|fKB~Ch80(wo7+QogbjXQ z=)^LcC@1hc+J;d{=Fxith=X4Hyqbixp?k(IW|HuSI`^7q>kH&Txfy2zbZh|Xzt7xF z&IQl~NXdiro{4R7q&~#z(q}bBe01!|>}0P~zH-QHgVW+~JE#lmcZ*;$b*-XnOCnS0;5wr`!kC><8@0k@Yz4 z-FavOTu|0MJFftu@_^{M=X)iEG+>p|Qm-`B?gocl%`Sxj{%>$f^5shS*4$(C?I*6U zxX1V5PW;(`@Z5(SKPfiy<_*}|?w$~i9!tMnbJJ>iVz?ZpZFDAlP@l?De|~>dt;pQ+ z2anV_LJiQh#!d zwk7WWX(r+>-6z3{!BL3JVt!N1CF-~TTP{ayng zLg+dvwuJG&n{v*~nVi!@8)FMv`&srVw520mKAA5wz>Kbb6vo9Phq|3#sH z7;3`x^2CNN9Un7rGv0nVW8(U7SfOy7YIKnVEzHNYu|Edy z#cgxDc0%rY2Px1#kGXzo+ECL3C9S_(S>^?`tQ_a`OtW2Tjj3m(kF8WQZvuwSmir!O z{;w5`T?@p}y0o8ZQ*#nC4(|=Fl+W#ub6_!FSMh%5pR9O%UWJv|7Epd%UeC1|Hk6vJio>5ZshH2* znG=GK!9Z@*rxlVs$+9Athak~BM%pQxDmX@_J-6iR@SD1>?gzg0>xP_R7^996IvGvS?qnK;aS^yu^QY5whZC1 zVAMk9RxOGC;(f0zJQSi&thPl_wxB|+#p?_;tn0n9dLZI#Mg>&Lu7|jlxjsVj8odPr zv#D#EHPnAq+%>1b=LBt*Y#019_z^gnwccCgmx6l1%(4wj9V5?nX3(8DALMj(IIIBj zFS&!;+}Ov1Kqa_k-O6tpQ7VHWR~zfEB<3``+U5@b-_}>G7`xxl$DQUW2`qAM@*@5d2I>B5OJsW-vV;>wi}(^4G1IshO-i z(W4XG)q)AD$qidGd^lnHWO!)hE&J;J$cs%CRI>L-S3K>n{BH`sb3XCM0;Lxlx@7bG z?wPrO)X!n4U7G=!8f*S428Y=0wHNdcA*w!khw8W#*g}|od8o(XQj@zidZ*7aYM-2I=l)@a#t%T6LG(w9Ck|sB`UJ;NgTdm+EMb67+b?txU z{nb=LryE`3-4!_XbHUkrUka+8Q$XtmG2qZ~UTdzC0Qiq1LYA4GuKDjm75`7>)0bd6 zzxHXqw`J*X7a5eT;?Xhl`W@N2BV%YWF6Ne9{2&%Hdj1q}JF84iow<2+p<=BuRJgbR zDUoYGuuv~0(19UOAbX&2<Qpho3!moE4V;)x)pm8!#k0!QQ~1Yf2QS ze$E*Xzw&!$qZi9jeDi~uy0@x~Pyka*s%RT}t@(in?`YW8N*Zjd6Wp}mG?sWs!D!txsCUOg74lhHY_Ae@ zM)qoUzVA}F;;NZ6(!D?FHN0LLA__rp54gtPs36=RuW!ZhJm{}aIItcAO)5cwyo6Er ztsbmeK(mQ3ZOS_oUP{;rbE-gKb%k=m@p+Y9)2%eyDD%@8ARAl^a+L`#e_mBkSrM;# zadU&6$EM8&cQc0Sg+o{L*~#y}!hkFz>N!dW7RkKO1#&^7-5Q}dL4;^lEqm_q+54|= zwhgkqU+UG2DOxKIXjh&fl^;{AuN>`439*-@M9=dgg~88@;C09tD; zchDQMu9c=<0`)zJ`!6>s*egGq3BAu92O!O8QHyx1-gjUI%_UMV;v^(W16SVF?k-qS zd*t4F?H%UzhJ-+fb=0A+XL?i*Hh~1-H4%VNcaHbH1t6FNTr!XQM&d|@f~xEaTjL09 zw&eNQ_kaT-L>;$xM zC9Cs}N()tSnVbT1HDijK1t@cP4d`WCaIlu}_7d5>9*4U#{o-N^72o`;ncQmz)KN>x z8F}b$_xc+kIkEm{kJ4QG73m8CUvep)%TJ!QalrWrx_P1vH(K{bD4ab7TF6_b1k{xU z*e{UF;k5@+=VfN*A|2L?1&zLjum~m@(o7FMYR(k|?VV{~-@9A^V!4~!H1dmii{2+0 zJTRl9{9IwY{Qu}MJSPk3FrPm_OF6^8 zYzd2#ygRgfzF9Q51^LdP!|ss+$6ABfIK>$&rT(Z#iM$=C>&8Fl;u&+6+Wbq+yeufA z-cJ4fA;>)l{`nfjmpb=7=;D*=`1JQTdLN6x2!%!B3xq{q{|5|b{^-1#0wxe2*?nkk zG~?R6bGfjeUcF}3f&=3NV1zH|Ik_7gEdR6F@chVFDleK>sXeY}E_^0$=|2A=>A>Ng z|JKaKyu*7Da&uCR{O4LH#~LWM{~yQnG?a>NxoPSrkhZThd~31D{LPkxBxXVh2W7mw z?8*2n$^Rd+!scu-Gb^yBORIL-&W)zaqh{#e-a`I&uvj1hC`;tt{vy_J36!ZkKLh`| zl+Tc$c7dz-&1a~p=MEpJUD3iD%&DkY3dCXQ7E>~3pEGy*U>1M%GqLGyg|ykE&<*(D z^yT{~W3p+O3^>FgsowHu9N4`khIlkS;qE-=Gbr9U{h6Wk)T_5CoCvna9pVkvplY~jlUUgc1eyg z&Fm;+it=&(AsofMoT?1?KBp>9UXfAv;}1yRDboi|krbm4VB*>T zOyj&tw(y6xialmO9a{2^`o)9Q506;w-ugZ93r78#LqDi_Ja7LcC;P)xfPrgq&Q1dj z_Y{ihsb@E5yjTQSq#D7s|Idy^8@vS_6aB(3Dm)=(LJeAS6Jpo#Fc5G5~$(CE|i5=5o0gk-fiy$0R8GpYsW>Oi?3w>O7yrq!ydb|~bFVecB zZ+oYz){&_uDd7Wtz`IW8wZlte#=H_~pz-1~-DPWzFaEALW?C8(1shr=Oa1bM={=Lu zqqOpGem~yg`1NO+w)aPcjkB)8R{-xeJf#UCHe%)1X&o+I4zw)S5)ok{hmcfYY7(P| zXnsIr;TkB6kY~Rol-j>yOg3N&2t+g-JB;9ZHuRXl>eM&nfV^=I7TMfkSWYUp=nfMK z@xsoE9&8^Che(=IEn?)fbO(42^tL_-#Wj#RC8gVDm1m8cQqiLGi4V=H*IU+(kEkWO zGUeAtepZ$RFobvY{5h_BvkChKy0Dh0{jHrIQ;}SLP=<$%TMW*FMonx&syP|5Y2O&K zo{E_6L+1VDtV*LN&G#culMW4a84~hBIFq5=5KBYcn4T9*t=c)J)Ka3_Y`zoGxP!BI zWT=W{e3Bay$o`Pvk7SNy3aNtr^27=}*|KSpW2kn;l0acR?J5)Gkpj1(TRN0;e62@S z)3-QGP6{ox52sE{6fu8)I&}a7n-m`D5K8N0*9a9wt>t-nSV-=|veg?-L{B^?lAiFXoATeW?y+51JnHdI9m5{;Lmazy0jvBd1Bu}{ z?!q6!Zql_y~6b;V(Es{7*d8G@T4xC(iHR<&0Rb|PRj}Od}y)ko`m_jRQxEd6E3j;+iHLzD!ZO=H~Esl zVxkMD4)(~R$yT(n2gJq*MTy2?Xagb8m(hQ`AZ3H&hO6!&KXibnumt*w*)=B~wC!?L_` za_g%WYC2~tR+e9-gO_$+EMn?LPeqY_I$lqyi2fD20~XV;Y*zAsmAo?j_N*$CD`ZpX zO#1TuI@^9L;BrXg%rlTNu{x^fJ7Va2nQpzqn86Y}KI)J~=(9d2K`Oe8PNE}I#62cg zqj5Dovaxy|Xg5^Zuo`a0S+Xm}Vd&hpqn(<;UoP>OQ}=VW3Zy*PP&1(^{s*qk)Ib`H z%(yDqdFr^&_Yb9i^r(n_3N|_p?~#5@EbZJ#?8qGSW3S`D9w76p(Gh;5m+7KGHX+qb zkFv*8Ym}@^cN^imJowHj?yXZ#+95h$fx4rB|8;YPifaWOl_1Gx@EBK=ghUzlL&D zvN1-cnxkCJmlkVASQ0(^v@v`G+}MijV$Q40=9Yvf47L;eYA93n;mIm@wtpYeC%={| z$_|AEHq++p>g~_0t@h8K%;16r%#sJe!3TNMKc&+lHJMn&?tNtBoAvVNq~ z`RgIuv>j;GKXzBVX!kM*b7PT9Iu~7%FFq{-8?il8+;NSqO06 z8jv!1H^!u|+?@2C^2ku!DS|kJ&#ZfIfjG=Rcm<=ztxlfGJ|6F!c;Wmmmli4D>Ru>M z3lG*<9cZEl%KQLRzD|Z*N7XmOWa1^#0&0?vei(Z7Ms&_-zEEm^l9sum2fc=IN_SHGiDEM-y0y^h&y24}pw zJn?9H-O?37Urxs+T#l&U=E@3u5|sy1JX@v(oxH&}oIpAw`bOGhXB0&dx94M-YzmJ* zgnN-xiJiz=`kQxg(~^R)C_J`#1S%ypTABV&?-~TU^96j#$ojQE*!jG_Jt-3wJ#oQ5 zJz8Pg+7~a=ru-~^7`c;XqCfb$QoZ5+o}NHv4wK0*b3y!=l@s9=pS1pTH^|VVX@>WIwe;`03I4pK@ zrKk`+Xi8w_i%P0*5jcfCUglu|GJpH_a+1WmJO7FkmsA1od=g+!NNUGy%^=qv&+ykn~bM+`G38OD&{`d zFH#WC64td4?5K8hAmh0fUG>IBZdIMupuB{6TK*2l+UnomYD9Obqtm^k@mTdX zCcb%FL^T|qYM2newLx3R04-Y$E;gxp)cvr3B&TLeyLgPliLpexUTTh{_fNy~s=b-UygW?wWaw$x+}Szj zQz6zJm|+0ufO5ROjPWk}u0K-F(SaqKx;v@IYAE5RHMtLj_y+U0Q)&eIuwi*zZfFAQ zUR8)!fhoQEN!_KOQDvkcmE5n{D0pjFu9+IrIbHs8Q)ti-o#G^JustP=sX${0q;M4t zIM{U_p>@DWKM5OE9*E$EHh1K9fev3qcneNC6 zDIjG`{Z(hU^g69yoq)|Xd~7+=IJFtGDIZw!$Ak3h&lP0f1dSJGO(Fj!=Cha3(U=LP z78#HdR^v36J|5a*o8K7%V|Xp!w<2o$4p<|x)x$c&DH~ND>e0{{iG^d!5o{gbJcexy zIuI%F6pMMuPBwb%94|owl;K zhQ33`qotXWQqq=uC!2hivH@}_#Vgt6QGW{C)7GOL+$NiiYd~qT0`!16oeJvR#kuIg z2VEv7qq|cjZ=+f8Rd$-s>pa($S3CA^|6c6^H`Ie?D`_`0&e1>P`ptfcs%$0&WY*7zj>}C;&d8ndnx{aC<~YuDJgoUrDP%l9ajEiUW=Pl2?@QJ8t3+RMc0Nv8n$aM^(QNQ zqU@sx_F%dJ6|=m>XZ}sKR&+qk+2<4lbOE|kwDJEuQqWetb0q*OYRZ*DzW)J#SbQ2o zs;KHCC~Qu4HRY|Eco+VjN_t%9Ju>7T577X`YR2O6Q+ZQEuIf8Jp=UGi@*?#b6-qAz zAs&FGNwyL#<&S)pT*LU%+|&*gcM#jGxv_iy+rN)x5m@4L7Hn`g^(@e0{#cF4=O~#3 z^c4F0yV&!JNYTeu!p^Uq>KsW+MY zR|Rt)yKHzC^lx95-=jAb46J)59qS*mupkS5@w1>=ph2rIylB1n^Z@v9`e%)S=MgZ# zi3%dersc~&TapD60glN94I*5i&g}t+H<8QN9RBH=;o>Jj5$Ao_KLw2`MF$O9Zs^EHrjqAdxP8ZSUgOI zSckF2%kE2j>Bc%w%{BZ=IM~+@0mM z9rOE9H$OBC^iu+eu=A&}$=7~fR{sNDaLdnkL79-g!o>S$3BDI2gQ&D{-o)vXTnj!h z%SfgFiBMP5;fKavEgOkEvmsjV;V(6ZVnu8uFQW4+wknk;$SgDqJA*xvos{Je`su9| zy;Z*dgm~7Vpxl6@5;rghcWUy<`%LfL$_4gNjlHFGjCw0CvMaDBn%%=qV1`>-6w;&1 zNHR6;Ksxh271~5KK?*AtI1O?Yn6~EX;C8BJ*rhv#O3~93Y<#Y(SNj(VTFT=B%jt+m zRM!>IqN-~5hELzA2;gh?mQ>_Dakp9a^m9D83&e;ax$EUL9odWduN-@o1*Mmt;GHVl zukcdACdR*mhQM4`iTtZ}xLierc{g|Uihk1SCnrs-D*2Mu}wC0?s2#vOCx59 z_K0*aLdHV=c`N+*56sAHQ8^D;UHt`LYIo)nY#Xe+r0LVretZs2C%tvdoEpYY4%Jhm zP3DJ!RFc-bPP?FqD?e8V9YC=zN{zBr{gVM$og~Wd`N}TLdNo=$<$Rp!aJ~A>c8)by zZ2xr6nPb92H+TwYFaDoX8A>6p1qthIJ#e1^LsK3#U;nfC*EB=gc4DRaJ8wST!A>pp zLBO{AHgk=`df&)NXcql+ZYt#}YS|m$lp5vzyY{<3Zi|sN(JvKwMS7H}^@!5ghY(H3d}?J-et2!V zE*xH8CbtLa`9DeJZe+r(PR`Y>q> z+FO+_W+ZtI3%F`4MP{gNHoa?LRKG#;oSh$75G8w*F@U3o^ZI?YIQs7J`jb}qh) zFBJ%9TwZUtp6+@cw|Z>ixGeige%jUCi@;(Icx2V&6xCzJ<_=H zOc#l0`VF}vd)TPhS<4uh-~4urxjk144a}%k(VZF%;3U0-1C_g5T> zdCc03B=V4)7Y1A2VEuo@t+l0fYa8p0d9_J2E^LxT%Z?tovSj7wyL$H6J)8^FMqZRI#>?5* zjEZ|y%4Ucnb_f3l00YI7)2|6B5ktmr&stVTVj|-zPG{RbHW!yO4WE!t1&XuSwHvQ9 zRY~pui0A-L(&bPG;#M zQ;Nf@E#6%W;)9=K;>x#x{|WO(6N}6Z^TOmOTrg_M)=%1eM%PAb1y}y$T;2KGujgV3 z*K=sB)p|#F#%^6U{+!>D_5yIEt$A5&`XX9bEgMYgwmU@#Pc|gm`6N-snU>**&Z%4L zxaY+0mA}$DuPV?Jakh}XDI-gh0sZ=m(3Uh$iBdv`^80aaZY zbiXhBSWwq(%6ISUJj}Q>V$>lR+Qk;RUx?Y*_QwJhaP{Uj^n8u6=P6)L-y%KBNz3@s z*$MeZXqV7>`dUqTO(E=HV)Ju9nj|2LdJ(S|R8p44YCTU6>cGBF^8*wB+1ftz9;MMrgAu9!G_2Z^jUJnyEXeAtnNTd62djI{fNh<{ z_Hu<9Px5yASgunr{_1x6hw0ypmnuYGf*ifrr7Qcx{m%bf!>6p(G@iBLV!agCf9745 zLCGqkXNDj}5u3N7-*!^Bm{yqO8&LJ~3#WsO;Wz3E4=cPzn(QiNs zi=X;h;n%2vl2ohNBBePCJ4naJcXrfE6cAvLL%MI|l|5B8$<xTrD2qMLe&xR+;R&cg?^Q{%o% zL$_X+YTYf-j1&lmgrKmKlVIy{{)eb60Xt@@Bzj6ncF_uqgRKi2_rsl?RMu!~j}W2} z!;UeCH(CtU^vRzm5l9yD?l^Wp;)Um;DCN^x?tXZZxN_*L%0Vol2w=veRX=7i`kWI= zwNi%?MfOx+HDW7myh*=Kl3h>$GJZm*p|+72B%(J-qmxz?N)fgItoZ$Fbm45CPnT;A z?X%Ur4jCISSH5_^-uUpD`VAm6k+SY}S{UiW2?!rne@Byi`;9;sTQ;U8rtTp$3R5C; zt;@-dg+|17UAlJ*V0)IlaiIrd(kAa(ZV+~aSQ3bD`IDZpB4m5=rirQcP{x)}7_W2s z4x72fu`uC|JLdHu){=9H4$E$H*%>$x&8xVWSaEttYlx^T&Tq9IdaO&gKZ@X$+8skA zIN?ZLxx_GL?$q0!L>)?QH93_$=`K!U()*B>Cb%@C3+WZ4r|`$s(Y$W0yrZ2kMiYT6 zKGhrlcUsh$UH7649PHxg>hCH$N7Hgary2M7T?&fiC*)_IkKP>&`tcOGrVBaU8o@E9 z$Gat0h9&@;cC9k zv{7$QgDLZetT?P@kG{z15TW4#8rRTmQm@`Ow1pS5etZz%zn4GG$7~?2B2@U~&%Xg7 zTf?6Ok8!H;C--rUjpK67K(0g8?q{r9E&aQRE#r+HVJ*4tgZ8C;));nuH2&aSfq97x zQKvOYvLx=-8}Wt9v?Jo8`FxM$jBzx@*nN6B&oWHqAeCuHd*KFjwf^0bh$UN>CgQ-? z6577{y3^6pS6O4-E2=EO}Q*o{O4R-M?`vI2Irkn0dOfkk%VlEMJL6qv9_`CFW4i;_In!Y~ ztb?SCL=921n(Sewy943p1E!!rM_`aw$rv@TT#su@?@v7*R8BFZXpVZ?_`@nhb^8dp zG5JBA82wPN=q+dl&AN{2P)CQp?MG()>AVyE#_$emL_Id@^vQdhn~=EN!2SnQtpFKK zYin@|;fUT6>7o4UEzWpDv6~+*^l>1(Jv0P1)K5-)OBTA*8`1g65Wbv;7d`-3v;10} z?%fTrUR%K~c8Y5OY?5Pa-Ffgyf1Ucs>SrfUUPbK>&r?@`9gFvNeC=A%v-RW`(5oKx-yxp4KcC_2?8{oFaw43E; zboeG<3a$u2HP*KkDwxr(g9wZ7;&gp2&3AK7s}d4Ppz$g#qJPo=Hl!62^TQ8`wQp7Z z1}X0A`0nF=dJOi1yfqs`(QHTwFa?<2q{w0P1O= z6oxX&5a17HAiZJvnya^K+IQ?-YN^`pge_S&XC4IY`FMRRuOU^g_iAhv z{?p^J9cGeLOWMFIshoV)(uGrf^q{TP<{D7&8nQ~q5bvy}t1}bfW4R<{vAVR<>D_)t zCq(Ku4-u&9kqmyjw8mCxMYDf$6KLu{9AZWB(}vzG$w&GiM|~_3`ND1s>--di-h7%NF81 zdQjT$&WC@=KkijiU@iEqd?#~u*7$P+{w-6zsZv- zWcr>fU4h?l+up}{`_hNXITOf;{N(heR-5gZJBrH}EaM`qbHS^;C;%t93mQqY>y1_5 z9!V8Ne0{={i1v1}<)M{E%a7kvqlt583U}4Dd|ob?V!6BUNs_KY0j$;N5u#o1Dg~KD zHW|YuCYZyy#67<(Q{DM+&%8A_E1sVviGC5Q3uYtG!GMKSxENhzB}u#HZ9HD;hpi{y zUW%xaPMM|uA*T+TnR(T}bEwN9@!)U4%7OS8lkgZM(M@ouSLyD}-}RnQFn(&FY=6+W z%^PN18~y}6!!n_&^U&nq$HjyApry=wwY4v@tX6H{67s?85S}<{!ENsWO2m+Lwh^|{ z{5!6VsPi$XO9g0haU6DD-_8pCjKD4siAzA>1FX!LM{3l0`=7DTrJBP7Ln%9+)avxn z6Pu$nX^Cj}XbTO^Y+|@%j`{`c_@E{KdW)h8LKLCGydTqn&O_ET=d~} zq%vv8KyOPsLCxSyUbA4fDM04&8i4XI+5rm`Rj@XgzWu@qk=HQfq!4zCvb+oxIu%2n zUFv+@lf)8eWUdC%u;OFhQgb8>+leEgpqD0f8dW+7daR$3BS-F6u{?on< z1A&$Rqehg<Dei~xIB+@ZYEGWsDzGt#3l+S@6wpVr5byoJFy)05;Dw+ei{ke61+ zftc7Of3K+fq;FzNAXS}ebfq|S9PX@wI;Y|pwCd0>VOTCaI#mDFa9yl9Gp@DjPFJqG z%Mc}c9p4qnI&rEwgu$Z#*MVjecn7t?0+9(oc_LT^d^dPdww5T+JnDI9S4wEg+qez?naW{&v{SsX7g?Qxods71}xx|LcjLOA!+xqu} zaH$1!jD#43IF-={HG@GancwV;lQO0bW- zUUt1uWu)IKFGix@g{zUeK(;D>Ah9%M3%Jx1lQP50E~t?@eAOcI0<+#wi38<<`~*AZ z@yBN$wFF`~WP&&lYo^68X+n)pHqNER3XzDf^PSlJWGH9V^E3EhS<%|t^QIYej0>Q2 zzUlBE3pPx`owMk_`MboLuiiK82B+JdUcc215u&_Kb3eVyv^1pL?y~DgQxS=+N}_am zO3TS#ds=?=u2AHeRZiZvv2Q*w)$67Zw(t>kaDpcW+x&jVG_(@@WmzY`Nf^xS)Vp(4IJ{zS>c>kP#|0u zP0H))%D%29DhmDPY$Z)~qkrEALsbV$$w^fQk7mk>enEMd59B| zCtzMN`F$rBosFQHVa11qKxB;#Fp4Ml$OyZ|7$Ir^y}9z3Pt&>U`4OTbL&NJLvel}G z_dfVt(tKvO-IA_JJd>`TQqe|={G_u^Ex+_niXa?1e_IgZUq};hXT9FdCw+dgTD6Hf z=weZ&|6DX&c9g`wBRLqv3H>24eBg)GaMqS$FDHZ@k3qoYn?I-&PnYD~+2nDgcK{kLIK0_}2pu^M|pB3^9U3fE0@Kc6|)<@Fa;&}poKzQXq;R$B{CbNyOUe%d8$ zff*lu?uU)ER>4KL_2HufiOXw4ZR5|R0jw=nYgvcJKiqj{ zEh$i-{yrc5|5$tXfF$qse|$OHYTIL*tvOArWoBh+=FmL5)wE^l(#jNtmX#%;DMM34 zv|ooI3BpuO_xE$7yt2=i^28RwnYFn!^61_hklW@$R0yHX>rn{DQwOE>u~6U z^u6zWxqC%&;BYjCmYOz^vwJO$+gMPmE!=%mmp)$WX(Bp0?4brC1~`z28v+@5U1 zvA0|FEQYtwlfg(9$%~TDe#2n-jCn~^HN5YEk5BaGbLD@!!If8cM>yk3>lgB^83O>) z|1WR50qRFe!<9Pi8Fn?0exDv}6gn9qasBr|u=+Ozr#kWdvzvbeN4;e|?YFa(JoYRsiWH7VM|9(bzwHp2c<@J8*JV8QM{x#qk7 zr9KTNmJLJ&E~P2js9=wbX?0pdFeRwpY3F=(<;IiRaFnDMRq_AH3kEw!H-aC_IGD7zmnwxv%;v9Y$?U# z)9D9a{Op0k`;WHYs4X}4QobNw9gv4ahexok73f;0tA#*$J*#_>o?0t3MkUNYz#-gt zVJTcM9#VZZZwot;e(FG4mIA8t*t|(^S`wF6r@vf&V7FLUHc+M@gAz={RTFYH%d@xb zXIjKFLp$poao?46b^M-hOo`q_m26Rn>j(3cAfA+LnOh*bg^)uY+tkFb_rs7XcvaLd znHIIzkg9;oqyfo%mL_TPk#;Ymv@kwnRKPpNF8~a zbp-R2$`Oy+{I>*&RsU_80wU)>mx1fNcjY$F%n-eeG@Alz!Z0kWot{}WWBHmUUuFIl z%|kp`1%luf98=yzb%Z9w`NJ(Q%MP#4p*PV(1|+XIAL01%hQB}QoAJJ1Om+41KnE#{ zc1aCvt8K2Z{ClOR&3tF_zh6gr*{1B(>jWFbKk{Y(>4Ax?4n9FJ?6yDlv*C*UfY8=7 zc7+pIw+4shFZ4}&y{+sD^hW=4zUmADpgvatdc!_1Xv&z|Jr{p*C%An*^Q+Yh8xjGv z;^^zb`K!TwojBQpb)+yR{;}|ykL?Gi=$-U$)4MiE-ePVoj>4PxbYX7J-Ugcwk>l)4 zuwK~*Xn{zVPpO-)EZskb;|xA~nKHcI8wZiYZIBAR&7L<^5edZ$NpbRL+Gl2#@GeX7`s%b z7OkIOO@pO{pI7_Ft1mkbjYnp()ahk`-#w&7@V}l3i}xu3VN7VuDMKJ8`0vJS|2)`V z-dH1aV~xSbzj|xq`X5WYwljW@Ly8*H%T~jYlQV+kU>}u%ApCL z-2F$RvZayq()U^fz1JfC_&>@@td(!IiC=t-MMmAZFQ8QM#l7vX{B6$JEvx#!kNILt zup43o)FR^ze}4d3qO>eC&`0Q0_lVsat3g|lLpdwZG)Vk_d zETeP5Z#u?IZoKj*0HUj3G1kB>wj1t$vkrzo1Dom4QyAZnAo<{${-*2b`yWLA#cpgwJTiW$; zVVhBz92I~Kq0?t4^uWV^7|cz(IDEY$KRAliWj_)|v3d?Lu$d|o9{*=hvV30YEmwJ; z!BOj{3{%!TUq!h1!EDuH3Fg(D_a3e=P%g~ri_l)RYYMx07Np6n+^4QhHG$whn(gi? zZw4_xPQ`Mm7^W+6%CLLmF^iYu4N5Yp`p4^OAK@Nehv3c2tr6a5uR-s_)9%=^H!r0d z;^X!U|1RL>y?e+q$ZFwiZ27fi-TMJP<1V{==iXmA>Ns$Tu_6$6fHbN)e&BL&9Ok*r z)V_a3tPDH6fv9ag%!?VCF-WAP%~fNR}4gWj^9$&6<19)N$^7q=s-^ZH*u?*)sZCCxAiSe zc<`L5B-@CxC`PS^la;`QLSIq%)y-rj#^cYV>hF<+W}dO;$dSt}3$T|2))}k1 zy!LD_)E40R)s}-7ivwvHd7quxL1_B0Z~f~JSGRD!zXQ|^&#EpXey^Bfge^MM4ewa? z^P4Rw`8$yHu6jz06`S7_ld5e; zOBk{{_6CYw{MK{fgq|M{@rHiS3HYGeV@0pqeppD@+Z5BVgDv@hszC4tU=ukA9x5i9 zl`kR35;{NZTUeO;A*5|t$&Ggik`L$Gk@{)a8hAXdjGI3w2t`;3tNQB?bRFam%$JIG zk{QZ2steFkS4n3K#_8S?{C7s0!f!G>Qavmqt-{J8Dln@le zhKqX5hO1`>jpXuKyc@b9qOQ~oo!Z9fQHtoY82MwC6IgXK{3L7&yvm*D63MVf6*ZB= zaquc*CfH^=X`T-0H?@^gCe3VeaHDlD@~j*Ae33QwL}?~zQDyu58c)&6pfrgP>H zBTE?=A$AQM339PSMPtUf{PFQbJ1=}kg(Vtw3&_BcK{j-T*%?3N+B5QR3W5O>ubeNA zh0CFu5((Sc5Ev;AomMs@o?YQw^E;E;TgrJBPUFaWzlBqd@Nqqz2jB$-^-lakHN8s# zslYTJ^qIbz74Hxt40Y%Bhd|b5$RNwIan(nF|?vJQQf&JjkplrE@yDn zo%}c!7ESz|RyY1aPA7Bxngbn2R%2j~h}Sz!p8-+jAz7Gk@OoBk$5w~KlGW0X$DHP8 zKs-Y%#h4H*a=Y#N4P~>&5Evrz_=xEm?sT#N%bSv6Rtphp^-v9@A>JMxydtU#) z4@6F{J}|Q?^I5?B-wl86j@rE0&*JYXm6vwvLgl`<0RjMIO#;7#kRL$Bq{VbOHzg5p z^rG1~jv2`zp9h!c*P!BXm|irFTPcyn5~y z9qNZ+JR)K@b2&!~gjEb*P$>(FJP;j4xm+Tlga=IXs?Qvd(}TUXzfPbGDP zhqf0}bH|fPQ@dON5%BtlG7(9(|fEOU!6l5H5y5_xcGaL>#7zbxy z%W4Q^dnNyMCK`gUG?JHr9pJvdV} zB8rj^In%gLvn9nd-CgwfVg#w0mQjBS6z{S{ocq*0#gZ-3UIlNUN6p&2em)?^RnHUOkRQ=dY@~EcPwnX$oJ$az zl1@VT_imMRQ@ia|K_mN8<@}6qrN)+XsJMMYYJNrlazH5)ac@5)QggPTBNRqhdjEVKd#^TL zo>**_$ILp9oxg7$2OYo1axR>B6M0lY;ogCG{W2+`VzL2^`E}d2rym&18P^~pfl?kW z^JSjxYA`kp@^wquMp+jmq>cC?#n&`pGxOlccBEC6IQxpJKPRCXHH=u(g3}uQRL8e< ziN)-#R}v2U#^hjA@xo3il}gMSz3orNz5rZ9i36S8V4O%UvGB?X&UER-$B;^GdDXRH z7_T*ulyCCMWA1(P8}>X`=&FkAal{&{eQ>%zHBU!JnZg0(;}H*mqXYirx}d6;1^{L1 z0U-P5M6iDVV|JPcd)q327w<_h|86hG1_g?tbWOTV&o~uX_TS`6pN&*wY_uj!MWP23 z?TOjXU;WI6H%PSQQ^#Cl>#?Ui7;Ntt5=7kOR9lV!LNGn1Jz&f#VcUc2O4l4#JtI7# zEs`82nSe|QB9c@U*+<0%51w5f;B(!)b3)~=dvfUf`^?p7;H_4?MMaNJ3oHTJ$y@Gu zlKUDk$|u9<^}w=VUkc84PDs(}4;un}`H@e-~Pk2&(nBLs>qSMxS1H{W#~x zAS}o4x>=B@!TNbLL16ON+$~I$1qL4!;WMDB^azdwo)lQw!PF=VUv4pw)q9|#N-Q2L zd2DpFoZb!5MEOkS@h``A@SI_%>a_RyC8&uplGY+PYLY=@h`V}kNNhCxB#(PaE=gz-T`_o5H)9NJT)i0; zGjX2h?&qiZN&hGxAtlxpN!;QD!6>;)O7}6cJRH@BDt26V%WP<10=MfiTRxHR`>)YA ziQCIE(C{fJPM!QYy5HZ($I7QIWBfAc91hwXo><94F6!vrq?Pznv!zO$^vpwPH^$|0JAmj>Az>ElfTs4U|^(q>Y)2j}|H(d-6 zhkZd-u47L}cZ=gcBPOIOaTo7Q2j4N4BRW@)yGca)l}f1R4uNVg{U(s%fE(*ITg7A} ziDvyN)5ezcI8gID)@kw=CFKU=OHrV{8&Nw}Up@A%XYF~{RVL5p!Zr(z*M(tSBhD~O zb&b>cgF9utLa);9HRNRS^W16&$#56 z1>Q_U|Fdhgg9jaKrVjmVp1WmAp*ZyOjMRhDP$a{34XcZ zTEl=~+H_kijnV(6ybQWznS#~OkO9(KUSjaY>N<~)bKX6awm%n@=1%L$Kx;f!pU?AV z?#1)Mf@acFDm-AiA*sXKGzJ$7BQlhvZYM$(`&3;0VZC+>ku5CX*y1#!Lznk3e(BLP z$|kPo&BWV%C;wiSB06LLcyjA!uWA7Y$;yV-f7?z^8O+^Fw)xuVld~4MvRKRa`cY}M z)gBU;&QN8jukuS{T$l5-OqGwybhUKq2yx{7`c+i!(I8yrV1QmU584`t)_DS^P5*$6 z;xZK85>~Ce{@N37*a6HTkMYC$loFKD*JIwjavLCK92OgJfkcwvw&L2mP6>UNJmwKC z8Z85uZU-CRC;Yqhem>@%jZo1J5HY9w1JbKuAn({K3y(XV{ds@DS!g1v4MN{c)P?Mr z;6Sihf7@)}_v-HnrGEx8bg+vxznE-%Wn{c#%az?u49>h23GpJ1S`^%(@sKyw>@+|D zDa%HOon*|><0r108exN*a)WFG8MFKrIWfz)68DdmawQeVtk|J6C2;(XIIZY{xlQ$yFO&z!C@Hh=a=z{l4snz1vRaaG=)s5F{?((fI| zvyaw}LKv^tMjk}eT}W77ZrcRP!1~+MkiR={4hTqoCe*~KC;ho9^JPT#dZEHP#dp5p z-*{rPFp=$nmnr*i-jCd6PfD%O8&K{8lJ@zpTI3f@o_D*w zu(g4!C$}qDC$l!YFuaY->tfa4#Dops(B1p?AuoDlLa{zPRhp75)I4SJatC2Gqbv^V z6d57wQQ$DZ1;K=1>*W0r}*A_^0fhK)mI+UOHYg0cm6mk_}O!NuKJ$0eCEZz9t5L@J#<=NBXN`TWic{G z%^565hS0-3Nt5{3-9-loO0|4ngzEVOBh$t-IgSKp-qwvK;V?w>Dio{LD@h9%NAABR z!tWW#VLnG{Qg}%UaVGOpPcs$e8l-beetLaZCv#@zU^^e%8-ZcPCl{yjnF!oaj`n?*J)z9uz1A2?2*hw<; zNd3LU4o^uyT_U62N%RprNHR%{nS1JiHI^c9Xtcj3EVDvB(Clunu#TjCzMV58AvvPc z{2)#S=;BAS@JVRZO9A z43V1I)j1QG8s~Go(jO3yXS{Z{yJ3i$F_vPlg}Km9K-bJ&5TPU<>igCQBLTg+1U8 zaToGX1Nxst_f$&$01m|B2tjT=r!vCta)kqSD2_NdC~`INBw}2J8t&)#^;25mtToe1 zp+AtC=2QZG)@!=?l=Mb9x!;qA4^o*vZVQwh(x1k;A&VXBp^y`m%ukZeaLm!Tw%#5k zagL5ipc6yofqG6uJ%dw0>FB_apC%d1-J)j*jC`1TiB$)IBb0M{AROT5y={R-RIQ}~ zhq9SDkxaMe0a|iL1qGv!G$#mYxIUcDLlR(GkGUpFvIm6=oC*ZE$~?%c!WTGMDfw#$ zfWrmwV6zx|T;PTdI!LJ)3?PwSAm_|3#%s?M{O07$w)A8a3d}2LR^m|UEI|9wdIY;- z$S11YHh2NF=Y4i}vG4{RCv2#6?xG2L*sR#W;l`Ht)qOJKGh@66Ry8 zJ4n14S*&6ZiA1gwZr`D1(##D%CxzF$?`-GimnyljC+Bm>a8)CAu-FOCyZdEy1#4)x zJ&VW9s3P*lQ`Ix9Qw&rbD!W9+BbVn1Q3Y^0e?Cj)=1gQ_K6t^rpy%wPRiEs<4%5IZ ziMrPOe5}kSLgGpRRgd=k!Fyy_1i;kQbS5rrygAVP3CNg9MwIj+SCL!$$<#CuUYa%m zEm~yf^_|N55I#Saf@W~YUd{Ww<3RUb*!STEE#h|-g_gzbaNZX{a$GKbBaIz`Vx8fl56kgBr?ITzBW5{WP zNUM7SuEd&}WdV zgJ5NR9tV+KK>T@6+clKTw4}3iB+}rl%lG1 zVie>x2P)56J2X2%+w{~73de`B%htRO%Z(t?)5l!gr(M5Sw0guxm;{*IHz`W1ayikJ zmQbw;pV=<`Mqgu)$WALc^{up3pvb&KSDBTI$GkMXmn!CMrBmOYHO2knfTMUQj4g3% zyVjDZk&K<9gRsmyaBlJ_OyZyZ&;huCNOF=G!gov2Cv=YEqkaR9WK>uFy^F2+4v`&Q zjjMgh){50Qc2<5GL&8;LsHeRo{v3=nG4+HrzDQnJRiycV4PyW3r$O&g=Fc|ojQ@dE z1B4+l9e!G1wI8`Q8^5W$p4_9j{||mnB%oPD32C>?Ue^U*7H}6qKoC6&V$aFA7o6UZ zp-q-)z!(vr5czrOz|L16Y^m5I z%>sgf+9b0%771CDEZ{wY^PuD%7SvMt&xml5bfbbGK!p5p^y|02V$$m7E0y;vsN*fj z?GAvzDt8P*F$qw#JwS?%rfRjw<*q{6g1U{jrf)~G~XcM{?z!4U|FKqIcci{!@!gB>NLxCSjJ}(a2_-fP_Gsl;XsKYzK zO9>x89P)+>OPE=CbkVQq&B!f%5chAuK2+X(MgxV4gyIYTw@JssQ2YWO-R!t4>MHh4 zRbcVrufWbXU-c3VY%v9&as3m1_q{juu7uC-I=}hTLe%mGMhBTC0Yt3M=hNyJBKYvlCpSv$}TdEyiSQszy-q#7yxx)aaB&)|gYoal4ht{uH@Na$H;=Az<2Ghmv z64b<`di883OE+dy6MgL^96!8b8Ej?xiuqI>O)s(m1^w2-zD>mq3Ahws#ZlBM$vO1u zDSnE+M{(})&J=z=3RO2ED&}!>1BS^4Qg%nUD)9v~w4E+0;oZ^!kGq7ah+nJ? z*q`42y}(s@mwPCvVO+U&FE zbEaiiU%TZ1JNj3W3qlUKD9Nx1qXy=I^VClh1T4lUeSQmo4x*G3^6^pJ-)AxtYU8_q zwmmCzTGUYw9)@;RB-)(8(`!=ah#AGlv08J_iiq3ZMM#-%o9$R(Pvn^{HS5D`>_2RH z@|=3TWTtjVHe`t-W>ZmpC2f3{vDN=&I?#fHfC7qYYoyJ^a-Yxg2D6%fHXkz7+1_pc zBRADV({i9mr%cSW8XNXMo*5c&CoAFaOAKW(9~EWAGC@T(UoBw!Kg}^~0}Tcb5Crn# zx^RrMDwL{v-mmIkCq7N|YHDP&1xa;mBJ%e&%|XYcnwS~ATtAi?${6HK{3ZT+?fch$ z^j>>$EqBFexYL1)o~M`ybJvQe3!BTUZ5+G|64;FzdnIA48@BJ4)Tf8Ac3Q3o^WA{_ zCASaN>oOa7oRXhVwVD_okhlsBPb`+$xJa>`*X!G?iz9-buAV7?7QO0|yV*@2aFF+e z*i6dgCALix@Nt?6G71e z2ZQu|ai#^a9#NNA!e)e? zS!<#1ZmzDn+%q>2n}{$gC@ei%IVIBxlJdBJXM{Y6(F{yUF$F9o9e5;CNY?sVgE_x# zB{l8)^2YfQ86K$ZB$_N0D`-4|*GCQQWRgRKc{&d=c1WPjci~S-`|4Tlv_xXE9mKL6o)v6~Mk9(J3ogB&)+i`@OH<&eQJ0b2Ff)9tvr=^}6@-aZ*`kg99p$%tShz8(zvw^vO|?cpZ6y~74n3Kru~||{_M>o#tdeot&5dd87vcdu7`_ti%M}@ zY`Uq*7Er&syd{xtHzue^jb=UbYrZF>Pk|pmnF@itx4B`reU5Kia8iNOh$k>`BeToR zwONH!!-^Y6-N;?Sz=)2mu+`EqhG-OcxdfbEyYQ{sUVm%6YUxt#3-|sCaP`4-GPM80 z7&_Nh5|UTWrzO%J-k{d^aL@cN$ZBRN9Cg-$R##r4L58S+KcNy9iup1os@P+Iwk|rc zeVxFey*L-g39S{u=ph6A`SfqAP4nghe1Ju1oDPQ3zjz#gdgN7HV4q9deq7REi^0b| zobdFW;WN@R)^?#JqD07Vydu0E%BE#(tGnY2az{9SYyo2p)?29RPS8%VQE`qS9Z&!E ztVLeU;_7h+nw-TW9dH@I64NHk_E?;q3ouOi;g8K;rQXatcCoDnGggrnewY)sel7_T zcCp_JC0|l>DOcY$N#7!xCr%wL6!u8~kf||aS_aa9FvN{;B z53j%;km9y^Nu}3I6Z!L;(-GSuE8^i$VG4Hx4p-94yymd`FAv?ztq6^bkxQvg5AaPF zfj5gaJ1DWD-)CB~H&xp_?it}%ZA!a_D+N|BIQrLmPF}~H-*$AJ=G)YPc$(-FVz4s# z2W>UU*;f#5(E$L+GMRjc7BMc4OfDcg#d;D1xJn^fHgH%4jL9)f8G#O$dEeoc?jJ z0np{yvo?Ft^@W&GUAm_!w?YXCbSS6zT+ZHTjqXwIX<&bl#kBTOB5n=o58(=xWjir3=>h6^!^B2At{wggI5bGnkSByjBt2O#}Bb5R)|-bo*x#^+{bLdQ>-| z4%r=(QSFR>3Bm$CY|b6cfT&TPtqKXY_oSCmC^h{9Se4HLmt_DY!M_){Xt1tqJ9+k& z6xD8R-7_v#40bz*I-|DrWZZ~~nUSdn9WQ^|B!s-w-N<dw zE`o}_+-TnOZaSY%^ORG^8RGrY2(m6rcnEkI@W_#!e-!m7DB+!_hpNW9TplWb5ze3E z{g|w%q9ZqxO&Rfox#P)Ox!mLg-Jn3E_Tjkz_)`9X!k4#2-fVy&{y}F3C)5Q?=XIvx zoe0b+rU$B2a5$p-dvXk0%S07>@TwOZQSN%vD6kw-W^gDX#wEC#{lZqkN}!&yyc<4z z-=0pRJlJa>TJyQ~hD*}>Mt0`5?nm^!s^{X_n#0A`k~5kixNbWuRVmJWRa)n`xKzIs9VUSU3r9-w|*YS(>%<&UO`DSpG>L zByv90C|OnLYM8S-2pyJ6i+}zD!4}!?J0^}H6%nO~vn18+SV{xWpPD)(D_)F7W`DZi@^Y&T zfC8tjbJ-8wu-7YT&7jf46n{lC(1u?i7hx#&NM5%Mu_ecFx)x?U?ZYVl zS7&nP6`SfQ+mEe_Hp$Bo{QDwuH+$9?+oTa1{>FZ!pncMrU@5OCj-lU5w+2onu?$|` zqZ_EL#V7PK23H;{(+x>>3Sq!1$q_3=G-V?_00?{U?MnHtXa8efJRcZ;VV4~APm zm(H0XRoLdWu$B)lg`9?OLHYQLzohiZ(su)&1x&h#4x>UA`T&OoZ@6e>Z0WY;;%1*X zVHO4eSrP0=qNV%<1y*+CI3-D3ZE|1!OY8mn%~h>?$%O#v?VM=6AKjVv2m-XtzqrB{ zpEh^U=R}1{c)^}FzAm%)^VcTN4>b#0@2`-f_I$gvd=dQV-BSi0Am2;cw(4x>R}~do z%;(tJ99*zL@TYfJ8x+eY)(CIHR`>aCV0~z8+1vfR>3Gz?`ghy=D6JwH-qpO!&~;C= zc54}qmU0(|ogz-tT2sw0=0VBc8<0NMK4sk|k1Rn~Lr4HdP$u+OvEFrLnnZ%;d;H(# z?j!gKo;!VB-p#o?7hXo=Ez7{zSX@wFyXtaYagD(j(U<$Mo=-~ulXuf&4H{VUPdn1A z#;dptIXy`9!AzyDX_h(!~{(X8QocP8S0@NkIaX9kg1+c zqaKl(2aRN^Kic0_u9X=mUzfZnv%&?OdvEhG~+CUG8g+cQQvNJ{wfDaL>~J737SA>aD9 z+k7m$h~HafkfLX9JDqGZtO~H1=GXQZW*F~MUs9DwRAEUMy^<37pbRFPojap?kw)w+ zR#*&#N^Im)Py&bzOSI=M7FNicj*%8Oi56EdQMid7c1;PtiepzeC4UQcg*x?r^j9hT zTSS{o)!JrGY8#q{QnIWc$5c@ByE!wzwFq@HEYMM+w7AAl`SDTL6?ZwTx?f7C z{Iq@w1*owctGXcc5{|`P5Nn2F^h$n;1nWC2G+0t~10miK@a2LB_@a)u3)_0&H7uXr zppb#h`n?3V|YNjArEa ze`_SJCGw;%WAuls8V=u7F=^Zf4eKSPV-nO0j6=SPA;#&@s+n#W6GJ}O#f^a2a}?d3 zKl7V=279pVv9Z+0BDG>^Wo%e&5D(0v0n7dcpbhvL1z45sbJ+v4D$#B;P?+2c);#(l ziV-9YPP7gPkJN^2e~*#SkFuFVk%O>hpd%ss@&P2s9eP|8u40X#8G;0T>o2GH-}|MO zHCsEqvKj4LyaIyR{J!xR#s|$UbxH8p*I!JN@j#3*3MNnD5)TW5#^jOss zB#*1qYVORXirUKT9gt578H@x+>LY}V!z}-Qf2+^h#iHf8gRk2_>!5NPYin_0_U<6; z{;i|$96nx&bRz_O_=5SV0C!-{fNH`>^qEPD5b?{zW%%eq=1Icm%3IEHUsAw>kVuSc ztTGm)kyhYB|sp$#CLSuC58GBxRs>~&VuLEdcL4l}(Q7#Yaf$KS; z`vCM<&hKn|pa_!e8fpIPHq)O}JGx&%Ib%Y+>)^6-?h$pkYIR>y!#3nQs#~;sJ^f+1-<#b6BDO3q5o zRya7HVylDXcZy2fd6Io_ZF0M2vc`nL$NT4b=~)$+{r4u6s@1^tY=lCzO#&|b=xFV;wHCE1`7b?*wQa5$pXcSL zB^AR|l=N`N%s~urVH<7b_A++HO9}y#_Y@Ho*NNZ)zb3d?q?X0r2-^Q)Iy2M!gB#>W za#K>cPv*m#Tc@^aBv?rU^8NKM*u|(&coo1k;e7SPb%szn(JWPGLf;Wj?h%n9Qq|AO zd$um&rU6)@+dvr)HHWvGz9nEhG%wyZC8KviP-InV2mO>56{q_0hy+Hk6b|I`OXwYb z>5~i4V+rP7M(cz-WT3RZ$oXFG=%#zQab4Pw<0lSSxK;7REOVWQ9)8g!F?@vmqec%GnBb#6F7XsAbwF~R17s^bQH|| zZP)onMcBpn_HI14laLJZyO^{EvsNzJDn>#jQ^%P_l=LD1g(;|AU6>(ZQ-Hq(qcEVp z7uBh)LVbHV_-W3ZB+;*E!A4&Si;!#?kwA*V|3c*$&G8vXj7~$WQ0ir_UHU5C(a(BO zD9wWz4wZaRRvzbv>#*THV*X$|N6#G`%$uN=QtF7$^0CyZ2WoL>sXv7zwPC|43>TnS z%;fqFXsA#=@=6%mS#Oaof?+nL9(dSG)`;^<@fEgOs|3&!z}SlR-;D(> z?}-~YYDRPNQq-q+G-RDdQSj?-L~JWBt{UY)4pu0NDcsi-3E`cY|1_5hdm!neeR+z^ zA_q?=q0z`hL6Wo!K%*&j@o|19_P;jCTF>A{V2H7FZdN_@U?v-HN`&mJYe$%Jp;%zRHU}>Ni~_f&w}7JO zhn8ss+rVXyxQx7w=x7a2y(Wmg9N^b(4a2*^IO10b>K4D@wE$_!6_(U|pFL#1Qodc6E?}4Df^W@?#X%83J`Zlxu5T{1#2Cnyj4bprmiR%u96~U} zsf4vsVBo)&u^;}HHu3*7_qqwH`G+@!y?PMU>bsWz_ZYPJgGZ4XRsb>V|KSzC1U3No z8WsVX<%W-VguGD`6972Bpw}|aylC(|WtpS#`LB+RszN&wzc<_c>TVY1!tmi`3*Ixs zpBSW`Z?!{TT^!pDJH8mc)Ip)FH0y$91@(eZ4{Ss9oQ(LfW#*FmZ8(`QJ+7CuN2CN8fAND~JsME?i{E_Z9dv7%T7Ldj_BR9}C=Y(cakV_eET>Fld7pCGB400zCP0#jJ4O zH#|~+y&@i=v>2>#2W5$~b+JBK@s|@lM_ftI5)J0IXSB`yFgd%;z>@gH7I#KMCiP?x zLEllhPPBYn5ILZl>ka+G!*KGc%piDnsE6#pPDr(1Og?!Z-+ywWr=cyQdSOV4LGlF+ z*f}h;)O7EWUh*ya4z%Q@IbM7Jhriq$0+YU^a6*BahmKeT0fX(y)DNpXe!L(wjXeKh zJL$=!oTkE6*IAU`g18$p`zyO$RKijVsODv8rJXMxwmNF?a+3uDQ80SX$Mo|vY$SH_ ztM7P{A-TgvGeg8;2XRY-xkquE0=gvzC>BRBGE`kOqX@4AOYX3ta@GQq!|;qP63ABz z8$G-rz4NC8$oP4TOSN1e)Mib5)VpW++%hlL#nlC`rqj7Zf~7N97g>$gRpCavr1a{Z z{Eh((f-18d2K{-P{oLl#y;FWkn!3?D>4h?4Zcu9KGH143!#R zCcjw95Z-zMn8ySW@Lc#NO*EM_5=q#f}jp z26FfPFy=PU=EFU(rEI19cgMu<^e(io@X3sfO12Mvnc^+(SpHw!jr{~zuKnbuxoduO zpEKby1qTi=D5}og{#64T9Z#u_(@~7oiSc z+%X8M71tNQM^8xV9XYtFh?;PJ>+13EPU*wTUeyAEHmY##hlT{9NoX9!*JE+F8?H0> zY+(Ra8BbUgim4vIwjNoyCh!Y-@I^&jQRqWJHQgmO+_sFiuq!RhNIPhcwn7ff-@;wY zPeRWeF2h;;lwaR7gCHa?d)&rdlg@j_{yW2-t(~mlLTb(iKfJsR--wT5U^RRghysOciOPzJF&a830wGEUEkMF`y?xJR@^dr10-NsTrQ z7Vi)D6BGvnHu~ejxByK|2t`;bICQqc^Kex(5>8uJpb^a01$<-ALKm0~pkmsi6J@=& zXp|%;c8s54FO^bX+s=Vq(TO0Ww0~78EEv31YF_vN7CTy&K~5dz_j(drI3~7?9CC;B zvap1d{QJ(sD1cxN9zvc8kjAliFxYAecWs5k)fus?avc$7jUc&!mJ_00Y_%y-vB{?m zGGhVqRMV7I92}61Vc|HU4p7yVE->Sukw-w&%1gl$Y>E0TcI)2mPzGmzwM9bt{G^uy ztsH8xoU7jH>5!MFgM8Bc5Vzbxv$DMFo&8lYouX6<9f!Rq-$S9)m3kd4rXhkX9blgL zG)l!!tLlhSJjv?%%zor?bXV=DTpP`|H=0S#Wn@%aN)GHF>jq}?H&6kL*0AnCB=Gs2 z{{KxIJJqAMEVFd+EBG7?O3=8=HX28mq}3304cLh-x&*^CkcfHbhLikt6>ip%4s{-8&oAhoNk zMizUb=5mggjfTW0WYOqBKgOMb3-AuhU(XMA)S?nhRP2_Z2(Nm^FlKjEad>l74 zUsA0_{fj#uDKyQ#uRUGerT<~5XHHl|7{uT6D_vJYNZEYi$6H;3bqx+$N z@7$v>$_q+}D1Wf}3_7K4Q+-C~(W!!#(01zFjja*J^!1mib40S6t3FU5(4s7O<2(ue z2Mo+GJ{CB4fwv%eXec2L&Ngk>?%nc`FQ)IY^M=7~|7(65NuhOsqJcO~z z&v&cEiNJw*C|F25sa51>G!Xfst38|sI;=h-<9bAN3ZD1rX)ovgZ?yd#c)obza)l;O z1~sMDZ_@@DIoS6MbaEP~^phE3xQIMHKQ@sZ5jCF=`p7hVt>Jj)rI)pJN$D1tR&&gZ zyeAJv!}9S|Eit(`6s|l76uSei2_ZN#9QC3teC|?fymYS0%t|Rhxdl^ndj}Reg5a=a zZHhQQxZ7r`-?c(Df1HOOOW9V=AyH252f*iGsyLLSzi4#=ZIv>y>&fnzRVSrme7l8) z+PD<#e3+D>0p3)0WBl%ZFeIai+bH0ppfd?xG4qLP&hJoKy)s;fxnQZ23TE74c6ju| zv2lys)9shtBhMD)ElPr;4`2no@^U5p#Fwz>?vlmFS>j6Qe-m>>+|Y3-1&G@M*@?VJ z;WJL&dPSpeoOoXCiS*pWuU7+B7!W1LFZArlhWobV+!??KLDvpH*`Yev)jU@^w+GnH zliHg{JSE$Dx_RW7Z4`@OFBl7p34;>N#eq|5ni%60?Q;jPQ-oo2S zJ9( zcpz!Erw1KutK(J7Q>9WfM^DUHs4s=&T)*ydQ$SH`pzx4?%pkX3u&k2P*!e}}WT^=W zUA!7C%T>XnZi5|FlrJ&{JoC~m5pihDOj^}?^6f@Jl7?x1xw4KU(A>g8SoIn5BbM*wK*Qk*h}Ql^McSDAASzfd)SrPN|-G z$fGK8pGyypd{oB3zi?;Y}}_@6H-6Xxg1MJ3HFhL<0X zXCs;K!ybFO_=OS2P=Qc#v=9Nkbi*d@2nQXoT)tEM*hyHbXbGxH-WV?L4Iy!PHQ59L1@awkJpFt6qdOfox+^}1X zli4wquRJn$1s;=pRcXn)tvq08UfkGm$$id=Z~tZY{8*>igLtH61ae68sL)TVFa!Sd zu@o|k<05XXD=*b0g@a0TL#^f-wlM{t$nsns`Ppo%2y>>pROg5zhY#d3$XYGyWCm4p zMQGA@oTbz%BU4B))X`rlC2E`vJB$&J2DzEZFKPGqP%@Zea`aw^SdSRfuuyTV%vrVT z!1r0z)(5#FwI@&-E}-(M#BLrhms+jeZtXSIjqk-Au((x;ktOLfR81!{nvz&JBz)3q zu68zh{R}86-L$;9;NGo+4Bl89!jzv(XknH3ZB<_n!vG$4mfe(|Q!)dyElJX&xgeb{G zto&dtu(TN}DK?Xv%yODKn;GX>E#;A4F1U;>%p3w99C`fqgE>AowWvczM`7OUgd6XU zeRw6gLX-QK?f$D&y&33dHi>-a=oZI8hKdO!@r6&8r|imN$JlR>lUid)Y{sR(FbOfD z;7{*I#%}_uGXcv>70PoHx6WD2G@~*m%Uheq-DliucFm~C%zA6RtU=vWt8*X(8-Z|LK3ccaqwimB8YK;W(x>-*)HIeLf1TZO!N7Mg`K#j3J92gp13!mJYaebtJ7uA5`||0K zy@RRci`He4Ywp^Ctq5?$zN)lt9&?u0fN_f{7W`nidAZpBWbzlgI&S~iA~!5cK}puu-bts#H+J3&oE*S$M(QYlJp!sEtFPdV!<=7_oC^bA*a z>WBGHi28*ds7>*6M4)RH)!OV>6b&zy#a1TkfNA#r^$g4RZ?Ds;(Z%l&)_yR16{9Ov z|0hAWMc&k1ga6dI9H%oNQdY)aoYhgQf|%x^wd z&z|n*&J28xKipTSQziCsf`8b`8^BnLO>!lC0{oF{8 zmkB8WBKu-#&gx&Z`?b9l74h$r1kVHaPq~2|;Zx!KhuK2YGoYsR`7%~&M(p9777Ihc zl;-P zX&lmB#lPCLId?u!&HMj2`|`LXv;F^@*|gosnVM;JX~xXT%*-)!uc@@j)XdBh#mdT( z)RdGIk-XiR#>pi!HTNb{Lq#$LLfP&!fJh)`da_{%|pD%o# z=bZC7pR;|=`}2OkY^xWvigJNy?tR_I{XAcRh-`?wnp|+{M)hhrQG|N>{Kz;nJNJ;qksxsTSc=LqOONwLlIfGKE0^J5i;%xXw;vKfsIR zN5;l`dMeI4is~~;e|?EJ#(<3w1+Vi!O%!tKsG-Lcx2&O{#wX_>;OT|1i ze1ECe_|6IhZscsEv{HKO47;H}}#`;&aG_2}T|~zg7%I)KJn2)Cv8F zCC7dJrw%E&>^iG;-okoQklq|T#P?KKh`OW#ZAliEAu}Gv6CiW~<^PZyZTps85i6wn zwlnKSFH+&~z_`BLfDM<7Tx4~lwZs@40Wc~xLK)sTS8tQu3`*m{;BcUrnC2cY=m^BQ zvaYK1#-W+*omG^j*28cvNB%C3rTvRX`qXPdYF4$qIw=xY7ShR0@2rT!_e$VXO=6O8 zbTDY*`zrw=1W(j2WlJ)Umo$(_K^r+VJ{47eFJ@Ktnza}d%qBgDcmz zQ{#l_XEvYZi0{D83hognbVrNu9rYq&5(Uj7PUML0o3Y^j2v$ZI8Ql09*j2J5VZB-0 zU6&g?Sbenf?>Cztxi4KLIFo4j757Q9q0j2%_xq*C6l404Ys=oePAW0TJ9WgXG|rTA z{>@)zRiCPf6slUpC)~ba|%uprCl55h|BZA4rzUMjz zEkI&5ZY!@!jnn;lBx@!yJ4`|#s8XQQN~KDBK1iefJ*1($Z*%g%x`wS`{T0Vi#aPE! zkY9kLvCS&t`t;zLBER1Hta|ZbFt|n!H6}@_Lh!EMd!2}ZnY>3qx_r$S=6)F05PR0$ zs%OVDb0rBSy5{Gz`Zm{%Hk(qSbE|MloY4b-CK_rL=43Lmr z{=Xz-n+nhyVwj-q4IU1{v>=f2UE<1W%DCfR>?*bcS;8k1Eq6(o8BHOZKw5ZKe-Ob} zQ*0uZ)y?In0dc*31?e=7rf0Y*^HnP{DTqpH<{j=?5)~2EWEYqPL`8th7Q3M8S=7NyAgXI(!gn7OZT6|?B>XyF0yt@tDc8*WVjB5gS^m%Wk^&p zGE)#EhwoO6WFRgXu*&q5-V))-j$lm(4e?Uy&tuC*Y61`swo_2wZX)-^4;$BLPi%Al zWi7?$d`z3qS_ZrT@cC%sSkZTQzeoIbN){Ms&gYsX+qe^|X~FMo@v zsvs}}!J}~%R7q&o9anM+DFIk%?~?u!P$1j;__hncg1~4{A0>g z#iOa4N|Z*$N;bH3J}PU0G+Ub3p%?F6)5MJDR&5?GNK!L=YLd0bN;gkkbB18hvTw z2D~*;xLr>P~cp&m>WO#Ay|}xIijB2`(41 zOc4D~|6{`ATq@S71CSA&^?@U|L-gZ31BUb^S-PgH&@4P(OZ*zi%zVUSk1A`~0t*I| zmA+y+E8PoZrFUFAKg?9rY%2+g2=p8R`9El4ZsZ#+G1pWCM`MUilI&~5xcAdL-D<(2 z%h#(PfQjzb0Vwll?y3k}eSV14sSX7B%d2{O-n2N1$hNbI)p1Zhz{N8V3l4a3hN|kr zH^2sMbkXofin41U+U_?-wIjlBPA7rHVEv=YKu1ZrHu-SU(oWaY@wV={HP#=ff*(8W z-939nx;+Zw57?R1Z6{uMbFu0?1)-d?A!ws79b5SU)O%$^)YMq_)C6KvKn3x{l*sCN=4z>UKaOF%d zWU2XCLn3(3X&xJ9GxDLbtHT%QLhJU`DD31@?6_a=TQt0s&fLsE)YL0ZZTu-@GUM0T z6u~RB>+5DZf(F`xSu+bWo@dY5?!894t~DPa)AI$m=w5Ng?QZpn1s{V~po`Dte@OLy z7qP&y3X(lQMIe~7NDP$^pqAa6Bb=HxMQH#MgrSAr6^1I*NtE-N$Jqa7WFj~% znUNLdgR@qH>23vC`_(N?ppbW$XMop`i%vbZO&Qde)OxR)y6r3b4 zSl2fFvJYYiTzX__A79T!27Vnle7*Yab(L0jdCp#d`mSS7{|Z{5GIS3?O_&TU@3FGk z`Fi!QYEvUpthBA>*Hw|H-!oCdiG^VS^nQx8L(&ylx_jr=S2R9%w67;Mj?{R>k6fr_ zEA2GA|9)o_w{p+rT|X|((0lyU%KWP9^A&p7EiSA^g+`|K4&B=*ll3X5%6{~;J3WTb z4}<=knLEf|)P6$&T;d7yxx@#TU5u!#?w))~k8FD{S!B5VKAhjG_&z!S1uIN{_+EcO zfNjFX^83~F%AU0CvlG_4AT`)-&lOK&VjP8s;4e-=*b^}CI94wn8V!gTz>GC6AD5*{ zn`Zhf!{AEIW%JtL8moal_8Ube#=AHd;W*-MdJF*FTn8bGx~R+q;%3w)LSGTYNe(!o zZvronUURN29$|T76$L)5H`r|_KohgmCV8{7pZ@Y9>%p;XrQDWY^&h}AZuP60I(O4M z!9Ds-yIEWSAaUCr2d|r&U`#0ox1L}zUME`EEo+_Vk383Ttnq71GP7u^a_@x2wSF13 zS%Q_xIs#CVS}yAa+jQ8)N06bD99S8#aY$=P~$C&7`qJcb+7o0U-O>1 zz?=lnT*PgdylQQoVO!S=bg$pb*T@_0H(M?W7wz^Jc_vc2^>3rPZ&6R&otG?s!#mpD z&no0Hx87A6dJ{vuX~E`M4!^E7C20#r5y%Y~vnZm7-Vm5=FUdBhu3cAY?_|ED%-+zH zMjP3|xLO-Q-Glsmz{381M32obPFiO|IF!S4ba~lgUpCKzrC^Dsa#CGxPAaU^&==s` zAR~##em?>(X%b$9dw)1!MWh}acV>9iqT%RjhMM{Iwp-aIWa2{!DZ%c`jaN(|h?2x^ z#YyKCW_l~OD9|rjohFq%Ix{OvkQ%nQ(^B(0)XodVB8DEe;_|vt*95cgp5;B;kY}bB zbtX!-U-EjN&fQwx4Y*_hjM~d`Hn&RRFW3YanID%{Gc}mxI8N9^9VlvXR1%^{qohbv zX8d--a!*O$=rq4DyYR?u?_%fjA0`jdb-R==*zD)D=Z9OnETos164Q zKmsxSa?7s3O|K$rvv>z8e=O5uO9~^_b{E&1fO#fs`)zvsDzP?)*K9ToqPceWdc*X# zs2GeYuVl2DlhzfPfZR=6Ne~JLWrSkJw7SW=4z6s5i#hqhY=3ue!{s}rh>%BI%{h;Xaaf0CHJ_GG=Vz|G-;lq0G+@rLF%6`$5 z5V4i%)WSqO2RIT+Lwfj*iGKD#l0?EDp!QO{T(j(137r;p&jqRO3_wT0Pnnced`D`` ztne-f3dIIyIv_4S-`-DF2*xFp25)&M6OqkgCQjKzC7@UXtqj-+c)X~KfbS?wAi*=s zqz?ce{Cc$sM<~tzm;XzezettlPecCqG=K8^H2+j{s(433_XoBC+c8f)qL|IwCf-Fx zDQ+utl;c?X(8YcK2aL`8;tUnS2H}q!wMxmR^|dCDOkLsyU0^(Rf}H1ELM&)#17NnB zaP=3L~hR#0UPkTfv0)`m9M?&?33$>o3UHT0wab4;@*%^FNc3znJgiN%Byk*yq<3t zP{Dr)!{pX`71}QHq_i5Fy*)p{#!+UTrFt4m?%r^uZ2s)0qQhHFk&Z>{x2IOeRAXhL zDXSLCZa15gSqvGsa#JVX~6X?X)6rK@0S8_?+1d~vEWTZI=2Ro1Sz z4+bobp_^`13j?3QF2bOugXuWL>ydcDHO=k`4hD6321D$w<@ z0|8fFO|DVXhWyy-uR+MV;tj0hlB2!O6^ja`(?9C~uIF0+{RL(WzJz zqwrXRHNvnVcTRrb*OdH_Emq18)9PFdqO48i3k?qi!~v&?Che^hzt@ihaHdB!u8` zr5F4mP|{;xd@e=VNq_s~LM9@(6vPPEfeqpgAJG>b-WvoJ9FSJlAh2eE_E6tvH?K}_ zf=C|f%t*kyp8Xiz`V)D1qP_8N3N;em%Ng0wq2Q%eS3X~a~A)Rd`NDnbCm3p zJaB20KY^C|E4hIDl~!qpj*zaeo5W);WmoRN(*+EqmMal(J{B|jM~qKO z0L1j(wv|&yqPVQ1Ks)o|`S3X+d#CPBb_?B9IQEo`M^`nM<1`XS(@(N5vNDwkPvC}#s-VhXS3a{)H%gXqc&<(LQ{mGt*Nnf7HZX+ zRp3gXcBX&;kR%wJgb*>_xG^Qdkg~-tN`cOlr0_tXzrQjqBY}f8!+v8Kt zKa!YJEw2cG^E8EKF)aarleZpjRRGMhv{7DExJKmJGT14oK=-mUMmmAIfSC3_FjasC z`~_2mdpu4M`b8%Inoz2LhR&xl3LEM1&r*mGUjH`=kvEH?%>F6RI{E{L zo%>SjUpPc==!1X_R8d1yVH-e$X=O?q!%7adqA#k{53PCyW+EJOhvpTs+0&9sg( zfM{X*$v*xd1_hFp7Qcd^Ms{YVfFmQYOqmsiV6|xfvmI#&^Ygl-K(L;ir=!-I@OHAu zJZ@teVC*_&zd>;CZ-_gzy>3+bF1f3b!xC=Ri81<}o#xA92r$KgS2H1T0O3*W)!30@ zgPl^-JuK-^oTMO=jqRq-|_ijdN_O$vu900XbI@ z6Bdp|`Qm+*U6~kCf@y0LSU^I!t(Z*jZs&e%I65W|K$r4rVn{ltD!rbjB8fZA3Nd4^f6d|REDe`FU4ZhQN)UxUlw{IF?Irp=uA2LVtg5Bk#MSoS>3(#n z`_FCNKlBW0%#eeu6P+O_&U@zs)zGpm>|+Rz$?miO_&W5D)b6m)!JDVfTzlJUV*78~ zD*~BbS9i4-&s;i_FaNHsqmEl6I2X)Ek%;1*y31$$Lc8hl8n&ajcu1&H$$3M zzTgAzemfzqBw+b8!p?yDs05J9BG1aVb=w9H z-58e=hQkd`%D7i>bZ!%*ov=+OnZ>8D)9Tn+k(imceQAk?h*NT6#^ke9c>!+(g~Gq4 zt=`kir)L>SA?}lWJFSUQ0HPFzW%QB4r0q2r9!9Cp}Y}dHh<{1&%U^pSPl1{Le?`h^#(=;WFx$SXP(?7 z`3T1CO&y|&4_33im+H@CSJG}603C*@0&iRQ?}&MF2>(GxUHDyn$@V38_kT&*@i6kO zt@nM5k@=D<%55aZ_>jzm_Dtetg+BNGR7J7N+6jw79?TUc^j+HOt&fzVaWN4Bp=pYR z^sBWKJ>dk6Tocx@PS^L^g~i>yoeDs3o8-IvC8nVjgT@yUMK8rzk^CVX>S;|95Sla5-T7CLuYh@lV&F;MFMix7k7VpGY{2)o!3 z)AFlb2(m7Ack;k`oQud8mlX*@e0}d4K+5S9Me|^sTWl)8aZ?I>^Uv4 zl}+$8Pg!~G<=GLU#rpV;ve?V3Ygu&zzb#*=z?A>v>h~xvxF_8Pk*73fs*jvOojupk zzh4Ai0wTa*Z}P0x1EYxF^5PqCj-Bi{JV`t+Ys@BG0xDnkRID{Sp!D2D@PFxn$an=1 z+P$fnHuyW=q~O)6pF;?MVb~tu&EgShY9m>zbPLnMQMx|;t!l!hU+mexQ3ued4Ad>2 zrBOK_B@sPwpIY&99PZiCvlL-4po_lLJyE;XT)lYvZH>xRx`>yHxe(_{mHX)kNrXV( z&Td?$;{p^|2x?#)jU(#EGHtzEcB@padyrsnFY5$II(2QMo#98%e);`>0)Xz_-AZbX zH496oiX;bj9^JAVcJ}_5##Vu*?bQ<+0yLqbGxGjkd5DQ@GU_Ndk!cRHBxbONP&H%DQIH^w1Z!ZMKdfqQQsq2P)57I_0qB}k(4 z=v?WZ=qKGtr0FUn92;^otLci~?nwWo!SW@SOBnYs7uAG97tHvnY6IWCI}kOgMdH!IZ(fmP z`7p$h!T73_XCR;>k5`-6IsQDEXLFtqZ6J8($EVzhB@P?hCJ>*|+}w0QawxETEw!9{ zy$!lYs4f9l1X}z;3lN5}ak_8)bF<~4v7jxxs}5JQUT!Pa*XurOM6(HepSJx@HLFRd zO2>;XU51|JYsnfHw+P>AVRxXJ&X*DR>~eebx9^s!0gXg?LGLO_Rhd0K>O6dKZ}vpA zcxCzZ>x8N0Rq76V4)$o#FAYLRcju1uA7pB18NHXE&vjE!{e^rRDZre8Shm|fDBJQ~ zW%Y|09=Fyip{qo7!*mY<{XYpXFK3U|9~U2u80hD z0-GCP}dcigz&syV&W=UPH*ifufve{Im`*=)T(rR1LGTHTNK*DANom;y_ zG@z2wkPIk!q82a72&(NJG>z!MtjucQ&^GC6 zd^JcFx##iQHYh6AHlWXA5YI_+b7ZVAWLpHH}SgxAL2?hH7C~sB@6eIN2W-)66v(`MQEd?b@uC3&!4$@j_`8ghSd5y-ev+|i82odHet?Xti z5IqAT9Ql}HfKUTGoGG$IWa!vrIR6O1sENfNVbp9)2PE0FXFoe;x_3)!^5`s@FH9s7 z0#5&oX=Z=ti{7KC8f|S?Z!-`uK{o!8ibr&@Ql6d9U2wllkNeu(j5oM1y~x_w9pTvR zi3gFU*2GGu(~V|8XXF==Ot$V+x~3Wdx(EA(`{Q$^j8E`(ZQ6kb=q@wU&4LiPu!VVR zY^j?4vcCPpyYmJN!dw+d!THM+N$^y}#rrH``-!1sL}0anm=k_J3rJT;uW^x7bP-R> z^p`+D5@Y{oBr!Nb^s!1Rli1>J3l4=eKo(<7Qb}9bzOJarNvTZP2Ln?*u7%l%yu=9E zkq4dN)`Z~4SPZJX@9sr8V16VivKXt{Weck!{?U1hTW3GIYc~a=t-w7Rt;2}+E1FTv zkcMzH1;*@Pb{z8wc$p>6=ek(hhZVDuNV17&X@`$dI9jWLAM53ZKp6EC-UcFg=Dqc% zQrDm{mNWC{1F!uMRnOEfjPrPLh+n3jZvoa3jdLqT)Q~8-cAx@?tazF11)B{~?65nn zobiU3HNOz>-Ii5IjfvC5IIc&y&M)LJr0Ec?lk8)kg+?60@3!;9zgUOshQU&Gd+RZj zJpXNnoiLe&-n>jqxA2T;LRw^dzP-^Ui%)%sj}&(4=O5sBL!>)8VLN<4vf*V&;{@In zde=En2+T&!3$`Vanne}cAJ*sL>I6Hx2?6>ouZD2RwjcnY7{&I_2Nq85>dyDH z_qVfRGKau_lLxf5OhzK@5$7Ed!HM2)eh$K=Zb24NX}dxNp4rK^ewHKR4t6YaN3Y$$ zNmyws*P=KErMFY>wnoA#SA~NBu=o^Ua+RiX&qSD{{KCt$&SSQ$(&y(J2}V;HD}ly~ z`B%H#dl3>#ycS5*Bk~RMk{kax2!tJ z<{aQ31wy%|k-}4uItfGfxd(im1J{(Lp&UmI_ebkZ)d;FBnu#H zz|W`==p+*S05Q?7{}G z>JI~aIM0r8k59F--W-=7&#b_lv(_~aX^=%;x-45IzDJa<%U-)Kr3$E;xduN0M1zrc z=7^61s$R9rOyXzt8krTz29PaXntQbR=nq;1* z11AlUnZ91{FgmP}SVj$Z#IMXf5w-)c5)A-qtw;jCfl`NLvTF5&vycq zn03n?JB339P-(~Ltl(N!Wb-%|Xy z$HLOH!(lb&IuDf*SvK)6jgwp%Zow*4ATS9&Cx)Ox@ezQoXiXb~;>@|Y3HzNLVn@Gt z0Jh$Q<;^kxt0|-j^MA8J1mSkAEZDIxa%*vGwup83Zb%YjdVreCF+LW!BR@00k15C% zBq0cJf`5aic)T;EghI$EqX##z&V6eN-c%+H;!9YhkT}u_x#tj509cp)pk~9bYGS*F zh2Rt9Bqwm$(M;Q%=XZoifP(zk)j%q>7-Z(|+RSd4)UdV+kcYr68r+rpM(mL=gm zbqi8;OM>r>C8-%Z#r#vHHRDdD4#gCsHwF4TNp7FCbW$3tg{_J9DZpZKL(ht2_N|@h zSW!WWPBRrDv>u?2(j!tdvZYt9dBo=U#}#|i<6pYjW=8~8*e>t0-lUu?m+KK%q1V_v z04z{erEsg2x=0}X$z&ID;URV`>pSG#`shO-`#ovW5-U2oVE|ozper;*USt{67w&3X zBGtsDwpRvti5?M}iY#3iM4lpn$O*|Zcej*kWyO#D(DkhHpYVy&_jT)GWAVY1}*KhG&jH zY)`LFxpADf1i~Km?2N)r$m#N5Nl!nsy>bowfLGi60hTw7j>?+T#{fb$!tkDvx1#<= zIYX@~(YTIKL>%ve~#cCDv4cNCYDw+k;52f)2_6Jks~7hH;7mW3$7! zaDlaM>3{{dbXh5YTJ%H!-k`ZAmEWqiRlc^3AO@unvr8HQ;L!J_ywCjX$>)huzrgt* zvM2_G+A`smdV#l3AKv>RgKQdo^(kx)*i-#8^?=CRey4AK$bFr*W>os}lMw!XzHMjT zua<+*O8AuJW3}0TN98YX*ZK2@p)vrE5k$R0#{Re)>Ym<3FXwj`^uQdHZTfM@K>5of z{YPK%$xyqIF zRZ5m~Re=8Z=wX#HRP;cKiT;X@90)u+zb9sDHUm?Q!h@)Yf09Yu+^4H2{zyaiQBi@A zI+NqOJZSIhyR6-GuBp?1{7FwrAyKOabfQDgx2lNAVb62s$+Jnrs$t=~wEgox{|?Be zoMt3LeOY^^z(V*WfIkDTjQjfNj2_LLKYj$L95w>sKV{ywmDkeuu5hFJ2d`QM*zfda z9phs=%rATgggg=w4(wACeSPKL5LJ0$-sIHdsy_Uw$k24L?=AsTV%QtV-S$gVk|KKA zCEuja)U9#NPN44kXD&N!_>)jt@wOc=0PN}ZLN^vH>FY1|z^niH(F?%dpW>v|mt;VM zIH_!GCLfQYgCi`+U)-KoY!Whc7~}K7*C2yK?1-UQm zmEH*r&$YLo9t%0F;y`FguEl8C7vYLUGi2sq8oRn+)rVZRH>nu9I^9cMd z@Y>nvTWWORC1>N*Kk|z5)a(6!UNJ7DLB;X@&3O5i#rJ|8HBD|6%yo}?jrzI2f$&y$ zL0}U3hKy76g~v_yQ~;ySL(I=EPk$J=Q5p~mUzhd|F8Kw(d5STK*uj@j#Pd}qXBKX+ zdfCRSTKTcB%`SBIKomCQVKH0X>5K9H6mO?{zkfAT>8MreN9Iof(BPOq)vkeNzyBEV zq8&!DX4e{F4S~7af*NBkeDf!ye;>J`%GIF=d$_RDtFp9fRM9OHI9Z&!A|xL(KWh3S z@5Y=ff80u{Nr7qvH2M?wtA_lBiY=9OgEkNx5gxj}PYsJR7HH>&*bsy(h7>07sz@G>Uw?jckvpGEAN zqh5``7|#y!S!es;{na7R94~~#=o8h$ZGH& z_dfy0RF-*1Q45_zD$n!KrU%b?v@Vhc5vXfuWZ#3kxpJa4ZLzjCF-^*+d zpC&AHrh=Gc=9Q$6=zqZn{>riqz_QedMfa59YG}=CGO#D2trQ3)kGhy+AC@PunLY8B zt86tD8t77asVo+p(~qC^iT?FWs?Qb|Kr#aeQM{{{{q^8exrGko+xGOx^!VzIo0(iO z4EJPOFa3i70c~#eANY@Mwy6#r@kFnZpPn9fk1${!09~Q0-a0>#?oa&H$_ZPk9?d#H@j<_n+3{$1wLjLamm3U%c2Ot_M>y(>nd=GC+oCcoGJ*qI#r1^XszUV zixBGnV>9vKd-&RgS?HT7;r<%!L*KyO!E&HX&bdKaO;Nk>m%G{1zR+0xjCz;?sP0+M z+?eOJyuHynt#yHAem9`R78RlRT-Q(kF>l&ec^(T29C(O)SZ#au5)F9xU;0nCrLVah z{@3&H>@o-Tm_0e6gTQa8!cj9hpFmgce5Z&Ka=1Z} ztK1$0RE}UGTU?_J2%|zo>EA3X^P963A~fF`IPySV`x^J`V2U*5e1qadfq~AWG!N-< zx%cj2D5f|wCZk*ygv}eC(04v;*1;KjW1Hxo%AmV@6|jQ1G#^5RdBolJLhh-MCj$pk z33D2}AocPu%`#n9`+hK>tiNg-uM5oFX8e1?em7T)`$hUlVAlHgFBTMldnSDF_T&%s zQdRI13#qz+v8MdD6eGP+R_i*wfFj7=e-{h z70;V=fe(Q-auPMk)RL@lrH1Uwe1X3CNHc3_?&=T554ip7`2{BO#NAoU3cipnhzn?khI5U6D3suZ^23Q?$LR|DuFJ^m< zgS1S{%g;DdFskOEik1Pkc)&a;-}8J6N4G`|2m2UhM`gFhl8-cNI*{2Sfcz z5R6&F?V4~vXawU=MJ;qil=VTjtKO=%`R|uKZAj)|zxS{Ur$EE5-^SRK<=NeOFQ05V zepO+1`NzNX=nu`kMypQNvN%LMDEQ1L_~%R8*!}SX#NN8mwD;MQoJZj|AHgU5kN@61 zuPIUBRC#80+|0CBb*h9~83-M1J|9G7jU?STN{FGBb|fHBU+@okK{<4Ld-g0y`rE}b zY6k8pk$lbDd;ILxZy<9osIrt(|^AM_|@mNuG+{e zZ`)2jxd@W#fHca~C6=y+%kNLzZ3Xj`4WbyUAEW=OO>(f35(zwecZ0=`gg;&B+xHOe zPd6M2@cxFW%J2OG0Pal8aD; zI7(saF@N9Dsv!X~+-2azTectl&AZQ{P~Zgp^n~NQZA^9MqM|>KKLTHR45rnm$5(DI*DQLf|=bz=Uw6EG_ zgT3L-QB5~k7iW3fVBS0;|?D$p&XHqd$QipGM%|FRuZng3U{ z6tJ@!T=Dhnya)XXnSRGNr@#D*5s!j`9n<%EGY>a@wG-q8fAsiAPCI@Y_^i!%KL?;W zvp1infAr-1#c{TDaA&sdO7@N8Fw{lOPdK~=i8KyyWt&_$o170Ik>uUpb`SOlWhr|9w z%JJtQTfbLl>g_9YA-qblHy1;bD~qP~L`{v;mEG=d%GVtSR^02|PRXe$+PJZepC zrDG>Xhw0qYrA8I;(f%TM{>0MZZwEg^%*Fz?--r4x^y_g{_Zx2_R_2C6{1768+tSo6mXAaZ zoKZsPq0_ce5#HGs4J1mf`wbx8qbec-3J6u+z^c|ft{O;nm>GuP8hQWzkPHjTivZnM z@_*z?_tpFFzS{gf^5Ubo#5~i_qtHu=JkKk9FAYVWf6?8-@t~W@o^Mq%A8)SNx~lui z9VSj%bspxQX=nhYuKy%cbjLPgs^@vvxeaq5Srs!U%_-@78ELGUI~ z2EwZk$(Tks@=AY3>dO)Js0ivNJISszcRxJD)gUr>%sX?#Ej(b0C4D`i(L%CKrB<6h(c`e zcM?&w017V)grSuH(^H!AhR`AWOr4w7j84&A&bA16DES&0F8AVu{*LK73CTX-Gg9;v z{M~&+&N7ve+7ANbd94+>Jk$)f@FU{9SpnG)n*;|gT_-dF)Zry-O0syDt4EfSAE`C3dp-f;@F%qc5@vYW*q4GvH&*wrH*-x2u zWEdvq`B638A{(2(2T*?jT~x-vHdG0{l-4^+c*|Ukj6F;s02!}OQI#0+x%dt5rN1GL z>i^IMu_(@FteF{@%_^2In*iFb5)YW4$c;Z}A@JbvtOtx1-)F?ZQ6m!b*<|KOg*b3J!wEYR^p1lil!Nlz4St{hAC`b2zXSjhooJ0R8)TXa*0xWQ==Wl-ccLM!@fq z!&ea+E?hOJrhWZ>^6CPe+g6ItIo+1(;ZyK?A${GSuc8F%3ZlzW5W?Rz)X3Ocmfai4 zh7#bsPHP51`q{6z1C{pxoqU94+QJ@|PeoCX2h<7k{qivWT`{;EEpKU?)SsKit8fx2 zlRSXjyZK?5(Nv~?|Kf83BD}@ZJ2OST+l+B3`&M78aSDfD_*?>%6b9JgKu-lI!NX$) zBtW%Kph?X@5s3&0FxD1VKgul0>FqOI-uJ53b8OotI*W^N5PFW)93c`z!oz^lN@smG z0+3f8p(Y30nqg&!;Q(yxcsIzEWlFqL2^df*se!u+;zF|u_yV$k&E_>NBK3|`g$xgt z>yA7T!p8=N0M}@WWn1zj?%w(q1OahZS%L3Np?NyMFpl!d2XK2KC*&c1jX!q~NjSl_ zdrl5p2YY@D`vP$9Tcxb0^3yDU&WdjVK4u-26aqL4uwenCd07sT6v@b8ZxI{tTxL%E zc8I2td5bH{W3w&%;T-QQPE`|c7mXSh7dVsAWY!qxx$%RwT( zB@Q94N2Z&JJxA(^Dekgx7Cf>G@RTBj@iv-C=K0@_5~4{?mL$Lf;m_5#UULJ7V0=pf z{OI*+6L^c95>LVN7?Loa>g}znRF=$B0xK5SIH1w~qXSu-5+nl|5{~i5CuD>lF~Z{T z+TE4j>up)xmRn3y=&jPHGO%DrPKA40Uf4<(h#F3ji4zVCaXV15Ee1LW_DD3qCsu?C z(dH0r1zMBkOD8Mkh8@4ytJeY5%T>BQk~(uV&7El-e8_iGzSq;*dkGn&08tpO@z_*y z+W8~6OvEM2H?qK~akBm0E>EQJ=9#w+mv=-qS0|Xp^%Z#q_-$s!ZFpg8kxv%lZMTcs z{8+YkTH@YMMn;Y7<0Tlp&~y;n2PgZ*j2UVD!mfzRtn&MkW*07b%2v6W7B^>^Zq8#Sf`_KG1+b|VT|PqGdfo2IxV|H8 zMgm;I7KXqS6HUSh!=Nuv-Xmnk42(@L6bA;pY%U+u&-3%lwMHB{g4f4HL^yHgq(i%UIeDcm+;Pj8`OE&Y`@ zH~4%0-fS^_j5B~j)DOtr?fbW72Hk&K3_x;=u`3Zh_M`Trb)AUO`f^Y2b?NV^?H)*e zId^?==Wf};vZgB3a7Y82*|$S*9)ZW()^aVp19hk#zD0#*ft559W>e$a3E!xQ(`n-r z-wHjQf02wc6;$5_O~B9ZE@kLNndSj4*bH)U5`h4;ER=%)Pga~@olz3!GO9ajw>^2l z8|EXLB#M(I$a7O)BDC=4X=dc9ru8{tsR&15@??y;0aJMXtXH5vSAHY$@`XM$vrmuN zx0xOXiO&qlo6>T^LIje?vYLzVA;OEUJK4s*zq6?s#Nvc7lG3u{n1Hw$0k|Bz*TGmX zFn+`Yi3J-lOf;rf5Jppk`F<~nDQQS^e{b3f_C=(Xx9e%f!Zo-yyGs6ScDJ$_6FA8x zy(|fRsozHkI+ZB@s?rn$9bh~d`+1if`FKc(26s=EOSkNYAUPn^^1i|e0bR*yVk8Doxj_0Q$n(QlO~twh z!>0872Jb}Ip#cDn%Efy*`=t!FAx2q!cPl8x>sa;Hh4`*OCj0^Ur``0F(SMV;(t-)v zleo}qs%szf9%(rZq6XunQhNb6!k$D#Q%1DeMD6}v zri?Fl3q0*#2HkB*4MC&?do#K%n3(L~>>Eq;gim;qFAki-7E`UuCa4+uM4~*_A)0H$ znS?j4Vu#DO0~H%#saak_2S1EXA>kjHVS~1^NWp$Az94e6Qg{bozC&NQ zrn7AFPdo?+1hfMmktN^`0ioY2l|~9Y*U;9gkaY(r!GtEsxfnRuR3JT(x}Z{Ea&0Bk8i)JI4O&1keOq~(Nde5dab ztr?{=j6F<*ZsbazfL&I5g7w1_4;uY}?QnA31n2+jgVe(?<|%?6BN|93>x#_6{J|$x z-BI5i=y{qESof>HD7LFSCSLo*idAJSU6(pfu_mD6wwNUF3G$9A755?ZEe|M z9W)PZc33$xGc?ccuCy|4#LxGt{4`|vtE4{ikxNL!wwkdw>@iZ^=RTf6Jv*hox^ z#Ge`r9K;tAm7^_X$R4kZ=Dr@OcNVj{qes`dv#%nX8RAUCQWw01z3Jj=jcNln4rs8@ zNH4POsHm^tX;bmOqUzgO;%$9m1IX}jI@y6|2`w4V046<99)QbBMWTRaSyH;RTJU2W zQinC58XqBfp-aO)m4{FUz((0#FK19|2A{u%8=s_D@cEzqKXJ?m`&TXCPbmoxRP$`J z%&s%1kC*wIHv)!~OlfZI&{eveQos98q%luZlS!ApE?iyp{f9lPGU31QFZ2gF922Xy zhYfHMy7GNxCR6feM#twDKr~0&08?O-WJ0_?OFLa`XCmV<#}!-3@2V^9tAq!nhUytN z2i6@Etoz{J1y2`KcsEpTv4IuAW1xLR{D|=f4)3xvS&FGq+zsr!KzW>HlbHpZCT);AqnJD80-P z!b(-{#9n*pTtyVGiWsphxExe95EUh-=;03`i!F@kdzxNq+ZK$>Z%9p*j-vEDg^9Q0 z7#-uP^W;RloQw}h9;;tP>k3nD&~ zH|)lVI_0*oQkirJnZ!%=Yg$FOe=m^sv0f52emr3cXQJKo(jk%sK2T7kwFHYQ`BM+N z-H9v`5M1wVw{5ES<^hpO&tUoJ9nhv{d0o0OuOk$$H632Qan?bZi(@-iBQ$l+=ROyk zeoG_kS@5gH6N%Cfp6QqZc3W; z(igUv;V^Z&~zwrSqlj=RgHwv1Sfn zrT|d3o2~xI4fH8+)iHVp_$7kMfVlb1lrj3NN^XR_%5DA!oc!PhoF{4a*W>bYG-VPK z#2~a^SsY#GC;DYzx2A~o=yj3tZj}h-+wisKMP?^di5EOP#>;E&;6rPTTai@NTq?~% z*h2-!I@h++@`M?X_#?z=6eX>Udac7iYz1c#{o*79giljaZJpl^YUyw#WvBt+5RTh| zq*w}l<6n7-BPMM_2$Ku;_+WulR;|UY-l&epv%;?)T@k;bKG;|{CTEx(*~h;!PN3m4 zBUbNK7Vz-Hy|OBxn6Mb=4`@_tTjjocg>TEw;G3Jee$25tnY49}%zss()5*b1W3Y0i z!_M=R-@MmozXrP$wAW?6#mwdHJM^P{Y;X!hwruh&&PHGkV1BJLUfxs4f%hsZg;?qq z=;SNm4}C1c2X1*k|7AaFR7e3<9GsvXnsSe~>tnlvSh~zpd$IVl{aP%j+}4%Dt46Dv znu4FD-wn&Nrb(uvOrrJjPQ(`N1(!5AxbDWe$BN}GP*jjU@wH(pya7oOgW72|Jcd4% zl}Ng^6__3lZ$H{29~9lNjUYk=JxSGE>J0YUPLeTE-xKsK!@quhMN_8kI=tOs`PCc> zPDI=ttaz99S+wGdLse7uM7GZ;UVdel7g7y_ z^z-JT2PU;=-wKk;=V~Vpw?xKu`>LvB1e&$qLPyUAzj?0sj6IAu^)$rlr^E{-`SjV` zuv&D?fdwjWZ1xKj$C~kK6W6}%7x^_0`JogCz9Ka1$`f#)Yg%W5^K23P&N6VB<9vxb@d8)w^=UmLSxNl42_TVe zJZnT3rnMV{R=!M6snQfybH7$CMLn9=K35J6dg;7+@NwIEEbW3h&eb~vsB1K6zl?vt zg7yh`Kj8Kk^d%y-JhZGm) z8A;Z~W>ibZ>(w?DCUkvyq>%SJKTT}-Ojf&3rl>9Qx2af2r+e=#gEVMcDd0WpAqx1w zS(bTJ-mrl`=XMnBRlT0`uwF#@Ks}b7Bi~H6)BZXzO|5?l+1i~xHsT`>Inv^;6pOnm z&7u|R!?PK{v0xMg_@>y;i;m=%0!QcsqttZWu%OPdW( zFcHH%hzTm&0w+#Tlg(C0w|iw-ZQJZ19*;I7cA6MEmO+60K|B&*ql}*qeK>{t?ER)J zlPUHAVON*p3VjzYk{yohK?bWU_i|z+o8p$5O*~DvITe_1KV4tX?3$Ex^Vog z@>mNiG}57dO!fQ#I>v5T(s>-{E6f#`L5=Y-gFYsFMaa)sKuqsV1;$2Qh&E)C{kZKe zLkrW_WTlI$KzGFDq>P3p6+$}UJSl#EW=M>+sX|lK9Be&GJH_9C8Q@O0be=$5a%Gi- z!Z^l7m?quf+NZ#OWcsc>Odc|rx~B(@6GseIWM8Nh@i3=gm$YvI?FW#O0LhD~vsrLl zu-XV?yC+}tK;=r$r){A{9dhSwW0I5$pfr+b?JNS530W=Rzezr(CMQ~hA{OBO>O^E0 zwgZ_$;^p|=L(|?b*ah!%VDqnteZldUuG4oEw~A(-WsW#Mj&X12b5Ki8w{ zF~F}9V7TX;O_8PO0DY`#u9})5pJRrTGB==!8U+WUR8+tkhj5bTJbdpS$5DWIhl7JO zG|j7N-)qaw4F)cyfOie#9E>kUH%rlDpX=T00I3@?XCsO)2_IRAd31K}QT1iO}C3?9v zHwbWTJ>skI;IVYZ0ZzJEs8Y+S=#P7Fx#lCEo=Ds&Sg?b}=PCROtTKDD7j}4rOk-8i z(O6a}Nf(@TAO9s}r=>6M%pAs*NX3|Wu_tSooO<%OXLvNJxWb=C!YLZ| zw8>NCi=5O(d=FbO)d5#zBWaN=shTry=siZ)#x9k{{>Byr+D)4u2-=bVy6Zq5Wug%? z>=sBV#*Xnrr1mE}l|KwW>IUizzAdQ`W-ft>OlZn*bpn;V!^1t_x?FG8=F6I)i~xUAIc9=RW*bvf9}4Kz&Ph z<-<_Mp&*^9<9RtapMmmS;nx=msvsCjgUJ+H$D>v-TM;I7A%=4|v$Ts>HQI*m)` zRg!c%twBE|qsh~p2SnjS$!30ISu~V_H7yN$eF@!nU>`5H7%T*BwaI4auQ&(m*r?ve>6i@knAnOy1?gN6UfZ0uV$+V+3izBOVsu!$6bA5aGSukdVC9 zP-cgjzV!!0#v3FcUMHxVXAEI^Bqt0|Me#TZte|6Z`6F(z0D{>t14_7k*;R`L6*3hy zf=BkntgqAb)_O821AJ>YoB{SY{GGp&C?Yu7I)^&R_q&4%br$OS$;l0p8MjDyi5kK* zvmLz^A0}5Atj^g z)ovCiN1@BvfD(DlF&$}wGel>_@EfQ8_7z;cF`X7y_@!3|G_uMMN_IKiW^eEtdxI?q zo7?CD#3s#wQ@O|7gOu+$&|oLC8P24ZULhJYPNcX~3I0;-7` zV;pv*iL8;{Vayrw;tTO64#%44MLQKcPxNq61rJdHgI?cqcAkJSljUtF9Vk@?sqa7Di_ecZ}>Ny|U1W^rDd$-F^JUwMo4Zd)L;IrK@ zu=O?Byp--i<0Z?XmkNi$GVLwtnzV&jfX=*!3X3ZMSB5c36m7_*c)KXy(_@W!vBrv_ zbOvz#aiZoxQYNi4DwF=I1ss4bI^*$0vHm$NBX(uJjTqB1v@uiD1Vm8%LG*lb^pP@D zbMLvRT5j-lMH`1Y&XjVGt zO@%dk2lYV{j3qAU5mP1#-20PQV-7Q!v834mT+6_T?ZTQ=-YPhYIX_MJeZ$z9H+qsD zoCeI8@Xy@mxbP`Fa92h+i0siuiMq)oilzf|))AtN z@h-f`v1BE4junZS9YNJSMZ25?#)1g*y0dWwa-g#?AeOgzHIVC)l%<@bK;(eg3rB$0 z!pel8b6dIMbmoJ~gKnYlIDxQ^H21^xwfm|zV5Co=;h+N{NiC(sK7J5^_aLS3*VeaeHlW@GzL5t!YQ*CP18!|D81zWY4n%&U!<)PED z_{^HbRblZ(`00Cxa1ta(aThWBBi|S@T${JxtG;>9=ioL+a|XEy`EQ^B>a8>uf`6 z$Iac|-C??0h8&UPcgA{LO2EtPA32P^Ot2vkGa$R=&*6oM5kL(EHs@hk>^GJl7vu5n z4n9BVl9aDeN1#RmH881fQ*f?Vu@>m2SABQ?*8Z3+P4frm@1#q1q~#pxNfEWZJlo*< z^gI>$Dh-oWOd@mIl=f_ebU9RbTeb)oi4NDW0oP(NVJi-T4=%DCmA4uM+NL}xzIC;I z9lJ?yykKBP$HDg(mi_k&UsBMO%{;W-g9yrm?6t^Q+YK~#T^=jm9+w_Y9tfix0FRQo z=RWZ^bs&p8rt(p>%7C8^U@sg>y*`ig*UsyEU8PW|bku#JwR&}ItT`yPkZzt>F|P4w z#0#^MKr#)&)5(`D3IDp#WlLK5cukm1{p5hlNJQyv7(wr?|Jj=ZRUJ<_^Ve9Kyzys8 z>GF8NZIiOD*rTB6)c+r?h1>8gQG1e)^#7{Gx@9MMOS&DT`hZq73DtdXF?wb{NR@K} zh1$89vTNzB-v#TFTf{>-;KoF2udiSB>yb(yho|%VHe|d~^jd@!b`pt_U!VO;b8X%l76G|hM?CuZ zRU^m#TPr7TH5^H(`Q}#|t!u~3^on?tSpRwb53#vdp&h`_GU^?MlgpFGSfJ$I)do1< z8w53b;@)~v_Duka$=-L`{_Gy!8VOG$T5zqxQHoqMs~F3@x`hu8y#X*!z^8__+@8g- z6GdI3=w+XnmWM&zgd&9?4;;R4*F~!p`!tO1orrr!HRGn{*-gXKtu7O3itZdm=dJH( z@j_p1C~bYt1}H+D#of|wLs5*;tA{c2fEEq4K%!;u-5rDkH4)Cn8#3Xq2z|Bf8Jlk% z`%gye$@hc|SGkdl^V)G$L7X(92#EAyUsD!=RM{E|_CrA)OM`*9wPNyR!>d*3h|crA z4=+HT?Wm+~?h5Vy)^`JWxAOV2SUK^nnd=y0R%es%!yC0hV;`Za7b!K##FW<5SA6CJ zk~Rq_@%aA;aP$#n8|~A&L%sx#qNnIOFf>h@*?Z=icMnZ|4EYOg=?ZPjuVz+(8Se zk#}a4&n`xHe}b$&$X@>i_WKj(^(n>AawEt`ub4K6F4iDwAS;SK-u$0O{Wl!GzeH0Y zDN>-z{%^?jr}(Z#Y`2XD)N7RIzF1=U^Tb^qjv6G^VzF&;PJySVq027)x3@+oL0q-Q zcnPWNw(+^)|NZ5qf?b_vMM{PG8!6X3`|~UxPyXNhHccmAgF}th@Z4%M|G_o~HKX$% z0g`_{v%ilAY!^@${JDF_(xw09!Sol1PBRAnzKf*`vjG=|yy|!{o~CgY)>_}J)!1b7i`$O>{@v3BE)F<#$~m%jK| zZtV5kE>s(^78cFcHT>h6x;3ADa{0gqMuQoeTC-n;T-`MUqo& z9IH2X|i0%Ju-&u8(C^dHyas2$%Q4+cI44Q~sMbo*<7k)PY11MJrgenc7G zU*iMyS+sw&Ktb0?7EFI;r#bM${$)L%qQYyI$YJCI(O9h)!Fzy^+Wh=F_A3)hdHzw+ z;XdnyjzI^@b>AVvnSzVVWT5G`>WdC_-vg!gj^}<_m7foC{%{XWE21!Se=(D8oY7!M zQ3n}Cp`~Gyj1GjZxlDS|Wx#1JKR|>NZ!p4c#_aewR{#71Oq`cJnpQ{;6!{h`>u0t* zc(dPC6pfg#jItvPkA~wqGl9#68c&+lR^Vg(5a?qw=g0zEieANJ>_x z^}Y%no-&_=blhWwW%F^J?xGvf4)bq8pXw4V4M%ThKviwl$a%&y#e%Z$*-y6rJ)x?# z&J&J;HGw*FJ`DbF`B|G=d&}-Qu0561mD`_jH*?~p(h@Cs(>{E-eM1WT+3WS&_Zw?K zhgUX2uMhX1joI|_>4rl-+gEv<$h4oW{k(~&7_PW*$?tb#2tubaG%eUoDuE!JJ=SC_ z0t-zfE94svi5(vj**)U8fmLxq43uNeNYIjTD{JyL!m8 zrQVHv-RVUFck9OY`fK-=h_;{JrU~~E;|`L@4uMBmyc>ot6t6k-;kqjPvWB4oEbsoo z6nYFWvW1%>>M?6i?=*O!-}8xIBUl+sR^+WclXTdY<*G4!9=ck|cC5D8pb*CBSM9yV z4bF+gW(Dg8d;RxA)G%8$QX#u14Bdm>mL=3Qa8R=#2Lhc zScmgOc2~>l(7AVa#U**D)ida`yc^o*|7IRv^mbf|yvkF+i4~EE!{nCe0*hjhf<;YE zEe;^p*T(xiAnnzRpxTbMcpC6Du?TL#_~eJHPf!G10zCkMqoINS+RZ{%5N(E+h;9)~ zAxi4T`MRt#OCY-da-D0RTO2F0QadY*a5yVetz<87Xu0pdR2CFK2lAi(_6vjC``n^T zVQWb!qya=68d$mFVEHK;Untgmc$urJ&x6k^qQ&mvg$4Qt(=>=WSiWrnz`!-mg!+tX za0o4S8c1Dlc|kQitAJ6U>mfmBS@WggY;-k_W>?3UL#EVT2^272<&QY!E+eY;~P9KO8qJFHY=6>95P zvsv@d|J+7qz5@f>V6LJ`16XOV?$D7iE)eoq85 zx!BoTtuZ3G^TH5@8Grc2wuxI-MwR*vD$Qb{ zvxg3Atxs>f3f;7pCZSs2;DxCnHHZmG%j{<8lo4X7EXCS?4gb(6{9JW zwi;KS4vCL5Dt6cpn03P@&4-IFRHl@0AqP0G-jWl4EwMtma))^j*}!_{p|T^uNP;Z| zdahZPScJ&5&#f~RWeO3gmo?q{s}>N-ua43$Z5z&1RSnm8c*1HQDeY(g!hnf$=1y)q zpU`pcZ{N`x*vgYjjL3Z&|4cvl&p&7G+#lY*n?3vNRkG}4=ROEQHHLZ{!9YD^%qzfFMQ+_QAWlusFLk5jqJeRc zUlgvT7o8zOYq8iaqwHIu!t)w4AHFE;T1R zt7N4&_5PN-xcDbMQ|yl<6=Q>zypEWV&WOL-yyh#LKMD3~G|^pTV@6et{Zgg8yk_!B z%KgKRG1hxHJKtn0y?IVH`#3R-){bxTENJ*slp}otdmbJ&zBpA-h3EMj3qUkPx;xm> z)LSaQaX^w?*TP$9T?Tf3d3Yg_#69% zwqW%AT{_TEwu0T|p!ljq-*zt^N4+|@uKn04PY+LDDySi~Cx6EQrInt003bYz?gRR& zc`3?xhCtZHVh3w*Pe!<7lp|R^;L1D{9#duX$;{Nk5{4apgRET69EahA+(yh3iaA|v zZ8{KnMl^;;43ouq6oLVhlWHC5JGubeO>jw!q7t~vqUMydAb64wPPurqZY=4nt5vCl zRSXT?dpm0slEm z#LE&Bv8T=OxY!g?$)xsG&hu7=-W199O3Bw0GPYY#Uo(ctX$HFEFP!6;%;8avtfjL^ zISf!coe&@^{k+yYj#=$K)yK0bnpm9!Zwapw+NnIqabcuSAv#MCo`JCmmT>;jOIH{1 zRzO%kqmcU0sFDS-v2aVuRlD(NX}E-M_c6d;cjL)TyQLzDxh7XQ+^t7kUmsn_wk@|h z+rLr!kp35Q`R_a&ywx7S0+ZRU-7TH@fh(#xy91r(=7Yxd)owc1j!r+fNCUhLTb2RH0Pq#~iuOg?G z%U67^1>IE7L%u5%H&wi-hJFjl-Yf|wh8`RB4=!huOjeobS-gh@`46#=O6+~Bgvu&1 znc5Nji?yO<@NqlSoIs*Pxy`8>9Ee|k0Qv`iMV^a)XfhoAr;`xi9&NWjNd*5DuB;>& zCoTVhWqFXhxpITAk-f38L%(Ur>nt|7l;*yB#?~@!2MouLWI_QyohM4_gZseN+RNT` zRsfsEnsYsD8M91Yil!iY3BY3S)|jOdVGNv>Ub3lzKA>rIFnW^~3xI4ky|m1~B7g_( zyD<=L^~ZGlP>M7QgRh$({)7zJe{|WBx=zhK4R(0-)kD#%2k)Puh9@KnpCqx8%asHk z)xn{jmSZWK9Rl5YgWj$(Ib;~WbM0Q@jqW15keMU9PyM0n-;F4V*_bl1-lI?Tp{H-UUqx+Aa3y0H?JMY&-xb8TA#dD&Xya~;H^eZ zi|JNcJu5@O6}W%12u!hsUL1W%i@M3ZM?T(*SLI|w7cPEx8{ksT+%lRBU0ndRWG^e+ z!s>hp z_m9EF_+l%l9D(b~16e1iume~!X+>yiVY~wbs~*^YE@dcZn{;7W7r56pMAVk9sI}WA z#j%~(!sGdCkDc4|u#DDh<9W93zT?7p_lCo-cdjqL?^xYxTB_$_b!@xTsyJ_+KM$eP zvNM*Sg(7m6s-erYwyb~t@5?OF%{4lMPl>_(pe1tH}pYPWiil%nW) zruRfwncf_{U%%-Q_P>ql!3}4dUgH6FIhJRM>?5z#Tkv$fQge8P{m}A)+g1B|wm(17 zf9f{lJbLWbLxt_J(1ST@f|b_=)tWUI_+LcNN$K+}vn|Grt$D-GUG+;EHfF80aIMMg zod=R(nYKA2e~&hhpKMvC(Rkhd;a4y}@bB+AV0ttZyR>#ny7(_VhnH+_2YdTz;^R)^ z5@6bpBZ<_Kta6)moQNdPS3fC|CC$Kx%onWP|8cLo6rn&btgZvj!++-`)q z>RX|x%htd!)OFpqvN1;0tuqZ^l|t!dxe0i@%~R06NTGBZK-AlnuI{kWt$(FYhn#D^ z|73Cmt_OR~y>v4KaI?Me*Lc!ki$JAhDqu2rNeX9|$>p3Tit za#<=+!2WyZ0Nx`-i=tQA8ot<+U_@%u_)T8HjNPwubywlP?6Blnyb(A7R|VsFi^78C zE>=bDPF(LN(@7!$=)}i@hB|2SH}Uzi?G~HRLD@K*o09*&B~90#b8gJ|55j#qQpO0& z&L7POiH8F}TNiyfkRR%^QK!AOW9ETnCrvfABGfTIZqLu)A3~e4gGrT8rFwy;o+1~K zz4HT1Wk~M^f7%Etr=$9Q#E`wXaNrKMQ-%>{ z_%;N{g`9%2Cli^M9=|6dnGIJf*=2z>jhUpGv7ssxmQxlTB$FY-MS$h)7a zoHOy|>(XqI3%~*aR!7yhB%}t2PjM4a#GAw+HT}Bu)~f=2T7zqx-K64KBK_o1`$rk0 zJ-*{~NFMizilBwkww6ue(8%LOS(Pb5lnqM70x%;{jwmc zTNL6to~UdQf})+(gOsfec1Fm{CPr39DE$JEnYTi$cSXd6&F{9Ob*uTkIg`%fU8W&? z<^0W8>&7lP zY$T(SJJ6`|CM*#Ucbp(FLC(ko4Q(>do#ySrn)IgTsv3E6;%`x}>B-tJLQTX?_!u}0 z*eCZwB6gmDYb+5!Cw#+DL=$8{{2gS`CxD5XJn^V%G85%*%q!j5SRzKQ8Qgy==G!xx z{xN8gABo7W+(nCn6EZxqaZEG}G-{`Zs*h;Cy}NM=oS62?Tf(dkYkgn?EXalU7NIfr zvK=50wp(myK>Pal^5@-w0}emgY-e~21aMtKG`0;4d3rJS(FBX}rVRATgP0^h+qMM8 z*I_65j8|u~3gi&X$?ZcR2AvXbW?gistV0&lE{)mhWJgM?dL}WS=2OR zrpwe0QD^;+8AnD3fwO`^;_`oEAEjeqK=&Uw66`!d`1`)a5XcGO8=-k<$*2M_Pf1Ga z6G~%Vj#?!K=ICR67Z!tvYk4=BOB-(Cz4wH_Y5|(9AxfjxMw({0b)l>rvA>_aeKKS) zI?D)U_@6VI>~NCZEl|ldr6k+1IS}z$o;dWfNU|x26#c)WPX4NStAc zM9FPcBxi%3cehBscu`@>Eo+Qbt|@b9VK1*}kJ*dtwyH!gXVGO!Opd6#a^ajhKCK7I z%}j0TCYw&}kQYLE$NP@-4Og44%RjtEi06c$kvVT&T{gEn8na@!S{}9kdaKR;CB48dXg{GdbfzF)DXFI~421T3^nl{r{^O6`cseImnY8 z8uf(bTC+dmO#k)EiEo}~+@$^1_uZx?^~3ND2^F)&-Qa*`Fi zq7kCN9Sx9QqRowd%oM;M7jNDCMiU-g`wzI}-Pwmm!5yV`7Z`ZZ;(c$0csLZRT=i?#i|FvG* z9bn&gT;euc3e<%1$XZO{5@xLQ>N!sQl=-WV!=X}&w?GMsgQZM=>F8#Zu zsQE=bjbQqj7aHNni>#afm$J+!hiky^@j&RP;&9V{%V36mefs|ptL!%iIni9RB8d0r znW8zHo?||Faf^@jAN@-(TyCA+_Q#i?H&$b_viVQS$j1To&%0RsIC^SjtNk(T!rGQk zqKm}|m}zqH(^2xtk44vMv_s3G0f#@{;{UHo>Aa>ll3&3TRvsP>NEjC8KaSxc{4O+8P8GC@k*y7|#UfC$j7^<*+LON3` zO8?Fi=i}1iy%E=W?l#~}eE!IxX{Z9b(=Un|L%|BH_K5+;1!ZRWahOG$Xw_;4^C>W! z`bN;6i^c2AeWwW*@N=(rMa9-Q%ulEZI}J*H-4?Wi7%%oK<6wo2xREtlOWlcA|4t9m z0upPQ7NhY*azpR|f2G1tXH&Pten(kkJl0?s|T1J5ji!aYl2XKrAJNSJSY>Iu<5(_`g(%6dTH=KNRAuU?$NiD<_vl zZ8P1X`k-a&Fu$f>jg$tpn$#7)u5p6B3H@PT$A^f=KcLdlH*0mTe!u)tJNL2Ov$vRE zeeP%P^ileKvoZR!V;>Ax@D!bEA8daf&AKtpN)$Z~y8Z}(^R>2r+LU7yw{Q9CnMlL_ zZ)~6c#N~Zh?qarcnbud)T}SRa=VT0LtfbB@=n!vLym&;OLNLPs?qlX~KSfAfxS*OP z)+*>SQqO$BGk31ED|KeRx{I{ z?^~A<7J13;p#k#q`7*ZZc8PmK$@bIA)6J{g)?DNX=FFAEIYad<2eW&H)5e(|;X>0@ zm&nU@;Zf=$yaTnRa!dc{JdOuZmUn&Gv9ZKvtbn5+IdlXFR|OzA#A$&7X@Wot@ZE7s zYZU2kmw{B^;!@~uFckTXKc+pBgSKM~##Q&c5Q7CKdiP2~w$dc{MShEi1FafQrxR@+ z+AtlN{)JVoN^AD{$MRph>E?~_p!B^o&bqt8Ynwux_E}Z$JRRiq9gUp}L?O-z9Z(UR zc^tQMHl;IO=(_DeJhH<6C6^u~L6G}n_2^aMrAflzMzIa|L$Xx>q7GTaN>(&W9gsz5 z;`3KDFG|gQT#8mKtb3j~s(sr^J&!zB9I@veDJ9>4F|1N4gl<`g17Q91-g6rFP}Mlw zTCbn+L_TbFAWWKBl5nrZW6u>D_R(C_I*Z1KGZRJ@Zn=k0=ZZu2zV@^ln$2?zgddx5 zjYg2Gl}b@3kyBx&@`vL*tFpHII!@amDLdP4U%xBI{!Lrg&-0z%x`8&Zh*g zX7+HR{=UA|QO6tsl&|;Oi$S<_>Gj994<$hJA(thu4(7NxF=G=JSWTZg;LqkLxp>3mT){Mf5>j?1U7 zPn}REXb@Al`WQL_zpOcl0;s zx%?xWGIG8RxECwGQ=SqZvTt?Oxtdjj!T3-va7b_0a>IikE_u~COCkj2v>0xC=7qY8 zTR%bobOJrm`a5x9>+LqR%&GG8!|?Du7u!C$Z?N<)TehuWS5!Uyt5avL1YWs&XNrAE z=!uRm36;VU&uG4S`itqH_)!UTINbFjkga)~u<%n+!e`NER%XvHM9A{)lBW{pPO2~P zuta%K>|Mfo9_7ez{)$TjXYU%JQfHN%^(kA$N+=M*`}=pfE2qJV{p@DkS?86j^bkFN zoJHASMxY`G4A3~aD|GU>XC&iJ4xw=vk(HMShsh6t4!O<_bfp{7ok=E%wMlhe@h{ve zs4_G?*Noze%9Ky6c&C$0u872(ZSKAsYJ#J}m^pa2YKrfrY_HPEjyVS3%ZgE27Md?N zVO|-*)va<-OVuj%{Dpf49IyE75W2k|)r-_|UQY4JuZG3bZ7B?sh#aX~#KK!cwBIBA zr1*vO7;og|Fn^-n8a37aN-(J+w z?(mU{q?}Ip@Lpw-q8-~E+=Ojxv*v~#6?)+Urc}F+kJ;EWM*@X+|6CTbv?~7EbPP6w znf7+owa#gOUk^PaYPz#Pw32Io5K$>C++Ir`&y{D}7X<6&5RYWij!xgZAcj`55AGX3 z+EI)47dN!EBbzeYEJK}M%?j>JtVa#xxZR~!Q@%#p%kn zr_4L^X@X2{CF2>966{9G)=S)-KsPH9xNXBkj*3T=B+$zqKaTYxWkYfs7}Ku4PIdxG zuXvr|Ugz&+3Ci^@_(oit!;?S`ZGdn@z{MF1e49L1r@E7C5AEGHRMs=yA!yIP^7X*C z0g6e+`-k5K8_v#;#(f4A5q}R8qpC%aw)Wkf71)J?*8t8N-F4!`lF+a`)6V&dxB+Lfq4CSF?&JbvoSae z$=hM69SL(q(kv&B2L6~JZSV`!kt#WxP4J(F<=2kYT+~{z8LTp1H6diT$Gy)tZKF)S zZ+gNz6Fqa^;iw5zdRs^*>545WTbojN8NDz+q&5gfgtOp2JV7qM{2 zw2oW*2%k(%h<9VcA}+P~JvAHIs%Vdp7DEuy8>+b#ImXCgEW!_whr? zzV9j^`^F_PUe(-Q+@zsSyBDm;^k^E}B5%y2QeZ<(M*YH=wA}U@Ye3OW2y(hR5m7pP zTvD8OJ=?HJUfyaX%^=nF&dO|B>%52FtZJKG)rvbWY-A;uL8#t`$wJTBrdcl@9s5ex zOC=2qrkHS3o_M>VPj>I7g5MX+Z&gj*!OhAtT4@WSjMi1gf7Jr2sjUuou^e$egUc=V z5>}z5<+gRJMZrZm-k2y={Q3>VMkPi50wJk@ z5C@x;by&@yhiBv@ley=&!CJQsxIa=fPEZI#<+t4Ekh(77_pzazf$ zB6d;+69oIDFyC1}8Dm=#-Lm;nL*?c11o|Bu@(86imDcQoBFCB3G2vS-@NYaCryxh9 zZ6z@U`EKcE6tnmO6a5^MZ+(L8YP-AwTRg;wVadqD+K##Sj%53vT6vH7@3u-twu)d+ z^tSNU`^B>iZ)kq%UD3Q$3!7t4}9^e zq%nu_W}ZNRi+g%DM@&|S=qHxFp5=>6EOy1+D_$SMviz24K)0P$%~x^DxQv5&-o#N@ zQ+t4mZ=)|+tpl_tY@ww?JUfw}$}BG_Kads|H}S6grmzd!d+phmoBvLrHL3E;FS?FF z#&RNfzh8QImU9=UlnuTS)g|y(4LA6Wz(-5Myc>(J2b)Ows*+ICAX`Ob zM*1K)hTCok0zb%Q2>}SDBXj-_CIc*~FpOfbnHP#(h@x_5xscMy-p=aFRoA7>vOWkW z4V5g8il!iJUWbKKmSztQwWot8dpN3ms*3tBDpX4ziDIx48JoMStYwJb$iH zRLZAoMjLklukI`0=9z^|)M7PqFx#w(YcV4KP#TPt| zG^UaA8Epv@PS{t6#8HHuxa@&s9=~%I^BccH-b@lz%|&tM0>JQ`AsCsar^CPr-^*G2lRUa|VZo{x!u<`3I%KxDXabYrUy z2(J88*J+){mBv7p;Iy56FYWc_`&-$$Y9Bo3gC`8toOp>6EGEq4UX@w#3D@JCMGgn- z1^sRzI}(ZqK7S>y_C8m2zKLN8CwV##-rd^$Hb(owr2!9<*08;n-dRa(hWx6HG2527 zy2`Jl#*nNp;-vR{zio4Cp;4^6UPLGeGHqYLed{*g;f22ehfZ}-}8&l zpv&fAC1+vP5Zg`Bqw}fQ@=7iD4XLL=%J8}2Xx~mr_jf}iMWu2Nnq+FRb^4XO*?}+^ zp@=p7@g)4^n^{kko$toOZt+#gCESH%+X*Lv0UcYnjZ2rO^}K_G_~D_VU<%73n8Q0} zEXdw--R3M9IB#t;XwUF}un4c<8&iSX)+WF8%df$~aLX;38j3E1<{3?Bl!zn7m?B z!;%22!1S@!pOeIK&qbqid)}pg7TvVs%_?<@>-LF4$H1>+E=Xn))*^`Tk+}E7(^V5h zZq>J^mDYE7^Nst<9QJ;Yw>SqQ)Xs=7l1Zift&*$#0r_&x!#mj(zwdpLPqSY!zU~e$ z=#@SuZNN5~Z;rwT`_oBfx@iv_(HoQ0L9W&$`@Mg8el1l-Pica#%cnPt6ap~4?*cJR2hWC}=E@T>pg;Qls3$Km0yjx4Ot=)h z>5jHEIP2QL<>H8oZh@J@&Q{K-`S)-N)>+w^v7Fj!2)Tn;`Hrqck(1A?d>3&v&{N1= zfQ1S>d5YVWPg|CjZuqW?%%xzgCLb&qa~%WKd0m?1I{np)Q%0wI9<9sxEN{=XC;xuO zJaY2vo82x2_?FJ?k$ft_&O3`psm&K5U?in-Wq^9Rfg4C~IT6hNX<9A|#={X}qU?4j zRD{66-8euUA#wcnxmTVj>j9<66P1W0)uhpGjYp|x-x)i%g#Wjd;oQo= zr=w+WFyAjDGcWWv$8FtWDy!SL?Hj=$2H@RS2=<*;8XTD9&D5iCll1)q!P+<4^C-JX zs(K7*;@8P~nGcJRF05z!`47@f?8y0SBAgZS?(Te|dBRSF;?(;4gWp8YE4`xJ;CJm@ zGF3{B!NdHzL1E9k`4L&_VrhM`T=rSC+vndU*X#$c@vEut1SR*uf~xv(iBlhPWBrDc zCeImd7bOcFhb%X5Y4z(pq(bIZ;EYb&wo}UK5JsqX7TY2ijmL4%G^x0ZXYANA?qnX8 zN4VF)pF@{>ZH$~-;7o}OPpG3rGo9JJ6TjY&HbX@;N)DsiPW)_$>vS=}5$*c}1?@I& zTsJmbQGi$FLdF})kSEhQ6NF_PF=2|X(-en95~T%0WIBb?j$fRSAAFW+m}HuLxnwoi zmzy3&mB;521;HbNmrWM|E=p$gt{{Yv!E)lNhy7oav)p!@J{i%T4d# z@4BbHN4`JH;3KusW_+@}!g% ze%Xg5P9Utu@yf${`-Bct*yL?1CvnJ3!vL>M9^dEX77SO_ zZY-Y^2U7S(LPKt70zrLT(T29C+rR!tt*VB-25i~Dfun2hX=R){{VNYTgWp8~xdcyI zUi0SmaER$8bh1gtXOWYg!{RKXN#~BxF@IR&CdIe%K|9>Z>iGF83l3k!Pxb2Yj0j-T zRp30jcip<4yTP&v#C+I#PPnu9cj#H*$D(c&69m$^T_`FTuW}OJiK3Rr*Y`|Lm2UxIU<4|@oVU@h^|)B*SXKRpGavCHgM_iA=s{YLHP_1jXt&g{!CLs(J6e1;2UZ5C8Vl=;7- z9>ecdJt!w36q$9Y2fPN{*<96moNh`ygaLm^u@N@G6ms)J>Xcqv zGJ+_XzpLHmd+U^r39o~OWiz@9Iu%9o(!BYu#;m#0acA79hrs|`$B$ILPdUbnxAi-c zef8czdmI1z`}plDqbw1MLLX8LR3+QQH6^r#yMbvM?n=i_$F_VmImPdqCs@;DO+8-X z69Y}Y_7>wqyx9l|yp;Z}VMZ$q_@k;<(@SCS<6>p6)^wWN^y z$&oT^A&I%Pb18+%aV<ilKR3b7=CtzHQQs{XfsQ@{;WSYazxD}!prDtA<-651+sFARj; zuBKK~6Jwkzs!N9Ax<|@**z49$Vuw-Ws!-?gZzts$&ebEQOZ-dHM-#Q2CbBm2q7HdD zksTYQbyeG_ZMi=pJ3(IXa2A_RJ3mgW%*5j4)4ZqQ2q)^r`$N<+IQVEqy>#h4l@nEU z+xta^SK&{vbU&Zqu`jFY8|iqi--pL^s@pP6d9>V>n<#6By_g-r=bu;-t=}Fs<)E+J@)jC(`31a zKa05I%NsO-I8ITg(VC8btD$SfYvV)by(58Dx3*_u0H@Ht8Nnt3s+I)l6=-G%W zX_M)aQPw~TrQK-T#DTXS6k|eO|`FbfK)oIcS;2lqDROo#ds>Uti^j~ROAh?1{nHHLkT75%PLo@4-@t}{51 zZigzbW+wa9zML|~cWxl+y|%)u-p=-LgqI&9w=z&ix|_A4#a+YX=3@cYG~Xi#6h_N5 zCO(6jIEYhZ7x-3D%?7Qi_ueC|_pHXzh^f{H&zW~l@JKExcI4?8e`4@xnuqqWn{Tai*Yk$& zz4?7qTS~>v0@la~^TcnEvnh7-4W$`-5lpCxzLy!soxp^ZH5#W69OYd3LE3B60sOO# z(#(|wlXh=0FVnh~EhCJU?d2uJWN|r8lNZlXHZ@zOVGEi{vOCj4&m5ID@#k_`&jSL| z9pF#e*r{n|p=&}fGoA%{4jPS+6_7DkzO`>%6QqiN7TUw3(0TvSLr|=8!|*D+HZ6^b zOCuLza$bY@#JCC<{vzS(tK~(&RrPK!opYDbIO=V8rYy? zkyT>5nVG>#cAA56i7v`9%IXF}d{DOzGsq zo2$Yy?p})W=U2J0#QP@C8scLd27T?Y)Lr0&`XX=IU%X|#Gf0swIOMHy_?9E~5rrNw z5qykHoPqNwb%nZ=+dPjKo~gIpKy~<>+s!}qJIGvQX8_MTbo77f^W{MwbkJjK`r$fx zN#-u*>S%zuxAjg+L&7LH9LE=6XFP zk|$xpzs`MV(EPw%;bGgFcm+kGF8PwXe1mp6Ft=E7r`r0N;yy3q)Q>tX{d}iyk9tlm$m&XV|Odsj8coW(4f1zWUK?l;e^o$JD?g zuAI`vFUfT;caT~Xf?2a!IKCzcIyW}A*zxcB*KEGEQeQMZ50amyaFs)+x~%5dnsegR z#Sugau&>`;w9iA)-7qm(40Ic~1NP5cA9R6G?#Z}%M~M8~2QmNh^ut*1zrK4Q z$Yk%@BzAgU2{plwdT4dO|a%dK`mqdf$Vp1TOA1$5*O)+7WU$Yhc@?AXn zL?@1?f{eQ1VUZfMi7Hb5#V68d09S&7XD+>$_z5*g>4(P_Y498eMUG`3&O#SHQ=|Ez zCFVYUhYO4jk!zAOGTM#G9YAuzA_WjGD_}W9BEYtnG7n>O4|UhtOAIpJzb!ct+LMqe zTok=sqCq6wwwMkV6M){?KmQ?>2eogEB~vqdJ$P7T8vDgGT%PEY70g~oybNG)R@-dw zWmq5*p#_!Te*v;JbWglShSf(Epw-^od>%GC%~N)Ib5o~MCmR&p48a;ddV7As1PQ0^ zl}pC|EdL-2b>A$kNcVW=3m7a(fpsN#)%X-_)-ETTNzo7J5WsU2r9R3BftD*zm&uGUuK5>DZmU{1M;Cn-D6L+&cr7~7bRvN zX=LQcRyXBFWqTX>y9$y}h4U<-i$F|1WUWBl4{m9pmr}F!G)TiGHi#`s#VDWrO_zN| zs{h@U#1e!GD)_)&nR5%8#dHg>3fGmmEt#gIg1nNM?Ych>r1=k(x~`mt=;wY}Y`)M& z$nW`~bM!^K0{sZi9Btq7A*<6efNMr9kvh!u5VxE^2+p%%@i0DS$!_kq00x`h{?t$v zRRW3!Mit)ZnPeVBV1$c-4=+{SKSxmaAHd?hS1`HyJ06ZYJ+NdPZ*vUHo8BA;`ZfS3 z^QhRVFGGP22hk?ZYKd7R`>vz2`EIU3KBhOHwKFa%!7&HnFDSO{B{8{Q+abV8d#Y%TkqsAuq5_zULbLy_vrvzb8M%mikAnLDlWUxA zNm=?#eX^VRN3Uj1iC z2my3{XwR_>lF&s)k8GKH<$ky9t<(jZC}6!P1g^V)6haEc&<*<-Z zHKzujHm{C=?rncH9qUp-SI zvxwMf$;k?*5~jR3;JQ5p>sH1n#ayvnMV;H>X4YQ(@;>VU`J27|1-YxG;^oVV<1ajJ zU5`tdxFhoV?k5oEv$G~%+zfI5&ZD0Xyxz@MB0WqrEHE-9W`SntJ5X1sMa&nXa2e=8 zaSG{-#gsn^w`1kI0eeg&YlFO1!S3Vj76ETdY;csExt3|kcILkITQVLw+EZ}l_-z4Wm z*hmg`SOhSgGlHGw9@i|jH2<7}&4DmB{Mb^BATF-CJ_2OsxjJ9Vbko>8R|~b^j?N2# z$k_z_So|^azM=Eq5=#;MAijQSlC!{ljM@!s$vfDy2_ag*^W_H}gyOd7q_TWXvNPC^ zpDRCv8t44G{q7u2UxsTd+CcY&#;JEoO9lD*RW;$da~}j-H~KrsKCbC(6=Kr4_W05g z{Y4~Tr~^b$>2p2yE{L&34_^?C=J$<-^+N2r_RBvoos5!Q@;qONy%y(y(FXiE z^jUN5<_{YIbxqkhvI|GCE_*SJ1eT%+u*#RcX-Q$_t2GoSl+rVd=31KU8jQEjlP`TY4GVCDowODY|S=stl% z{L`EO8aJS)#Vth+qKkY*A(58v0v;^!Dm%-m$FZgMfxcxt$njf1oIhx2-NQ4G0E+y1 z&UyHd3RIc$%FVQJ)ybrFDMCSZPr1ri{QE_ILZuymm1bJbT<_X`m(z}{){#5O$csk) za2cw*`TF?>oc!{@wiep=+|3zY_KRAUdb`iP6|ze!dTkm? z)+~xaetH|6GZR&inAl^B3`Gv}IZ$U-p_ubOh{XHuS_8S>y)6y1;{Eh?v6x1B!Ds;{jkPr$1mr#PYt*t z_EVP!h}7+U!S{!_46NX&&YF}YN1McscFkxw;g@yTCnLi*2RDlmVWC?0K0KH8tk)k%SYWrQ$e?p6k3`at-X&kJvoG(fs z%Su>RIX|%0Diy7p@jZz4@?6mm+V>arRe=qf@y+fW*#j%m!r!h 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 literal 0 HcmV?d00001 diff --git a/dev/payload.config.ts b/dev/payload.config.ts index 3abc9ff..2d10622 100644 --- a/dev/payload.config.ts +++ b/dev/payload.config.ts @@ -23,10 +23,13 @@ if (!process.env.ROOT_DIR) { export default buildConfig({ admin: { importMap: { baseDir: path.resolve(dirname) } }, collections: [media, users], - db: mongooseAdapter({ url: process.env.DATABASE_URI || '', connectOptions: { - dbName: 'payload-auditor-db', - appName: 'payload-auditor-app', - } }), + db: mongooseAdapter({ + url: process.env.DATABASE_URI || '', + connectOptions: { + dbName: 'payload-auditor-db', + appName: 'payload-auditor-app', + }, + }), editor: lexicalEditor(), email: testEmailAdapter, // plugins @@ -40,11 +43,15 @@ export default buildConfig({ track: [ { slug: 'media', - +enabled: hooks: { + // enabled: true, // customLogger afterOperation: { - updateByID: true, + // enabled: true, + updateByID: { + enabled: true, + }, }, // afterRead: { // enabled: true, diff --git a/package.json b/package.json index bbb3249..609936e 100644 --- a/package.json +++ b/package.json @@ -71,8 +71,8 @@ "check-types": "npx tsc --noEmit --pretty", "prepublishOnly": "npm run clean && npm run build", "test:plugin": "npm run clean && npm run build && npm run link && npm run --dir ./dev link payload-auditor && npm run dev", - "test:watch": "vitest --reporter=verbose", - "test": "vitest run", + "test:watch": "vitest", + "test:unit": "vitest run", "commit": "cz", "sync-main": "git fetch origin main && git rebase origin/main", "sync-main:fork": "git fetch upstream main && git rebase upstream/main", diff --git a/src/core/log-builders/collections/helpers/isOperationEnabled.ts b/src/core/log-builders/collections/helpers/isOperationEnabled.ts deleted file mode 100644 index b738cfa..0000000 --- a/src/core/log-builders/collections/helpers/isOperationEnabled.ts +++ /dev/null @@ -1,28 +0,0 @@ -import type { CollectionConfig } from 'payload'; - -import type { HookConfigForTracking, LogConfig } from '../../../../types/pluginOptions.js'; - -type CollectionHooksKeys = keyof NonNullable; - -interface Params { - hookOperationLevelConfig?: LogConfig | true; - hookLevelConfig?: HookConfigForTracking[CollectionHooksKeys]; -} - -export const checkIsOperationEnabled = (params: Params): boolean => { - const hookLevelEnabled = params.hookLevelConfig?.enabled; - const operationLevelEnabled = typeof params.hookOperationLevelConfig === 'boolean' - ? params.hookOperationLevelConfig - : params.hookOperationLevelConfig?.enabled; - - if ( - (hookLevelEnabled && operationLevelEnabled) - || (hookLevelEnabled === undefined && operationLevelEnabled) - || (hookLevelEnabled && operationLevelEnabled === undefined) - ) { - return true; - } - else { - return false; - } -}; diff --git a/src/core/log-builders/collections/helpers/isOperationEnabled/isOperationEnabled.test.ts b/src/core/log-builders/collections/helpers/isOperationEnabled/isOperationEnabled.test.ts new file mode 100644 index 0000000..84de2e2 --- /dev/null +++ b/src/core/log-builders/collections/helpers/isOperationEnabled/isOperationEnabled.test.ts @@ -0,0 +1,274 @@ +import type { PartialDeep } from 'type-fest'; +import { describe, expect, it } from 'vitest'; + +import { checkIsOperationEnabled } from './isOperationEnabled.js'; +import type { TrackedCollection } from '../../../../../types/pluginOptions.js'; + +describe('checkIsOperationEnabled', () => { + const createPluginConfig = (collectionConfig: PartialDeep): Parameters[0] => { + return { + allHooksLevelConfig: collectionConfig.hooks, + // @ts-expect-error + hookLevelConfig: collectionConfig.hooks?.afterOperation, + // @ts-expect-error + hookOperationLevelConfig: collectionConfig.hooks?.afterOperation?.updateByID, + // @ts-expect-error + collectionLevelConfig: collectionConfig, + }; + }; + + it('should return true when explicitly true at the operation level', () => { + const configWithEnabled = checkIsOperationEnabled(createPluginConfig({ + hooks: { afterOperation: { updateByID: { enabled: true } } }, + })); + const config = checkIsOperationEnabled(createPluginConfig({ + hooks: { afterOperation: { updateByID: true } }, + })); + + expect(config).toEqual(true); + expect(configWithEnabled).toEqual(true); + }); + + it('should return true when explicitly true at the hook level', () => { + const configWithEnabled = checkIsOperationEnabled(createPluginConfig({ + hooks: { afterOperation: { enabled: true } }, + })); + const config = checkIsOperationEnabled(createPluginConfig({ hooks: { afterOperation: true } })); + + expect(config).toEqual(true); + expect(configWithEnabled).toEqual(true); + }); + + it('should return true when explicitly true at the all hooks level', () => { + const configWithEnabled = checkIsOperationEnabled(createPluginConfig({ + hooks: { enabled: true }, + })); + const config = checkIsOperationEnabled(createPluginConfig({ hooks: true })); + + expect(config).toEqual(true); + expect(configWithEnabled).toEqual(true); + }); + + it('should return true when explicitly true at the collection level', () => { + const config = checkIsOperationEnabled(createPluginConfig({ enabled: true })); + + expect(config).toEqual(true); + }); + + it('should return false when explicitly false at the operation level', () => { + const config = checkIsOperationEnabled(createPluginConfig({ + hooks: { + enabled: true, + afterOperation: { + updateByID: false, + }, + }, + })); + const configWithEnabled = checkIsOperationEnabled(createPluginConfig({ + hooks: { + enabled: true, + afterOperation: { updateByID: { enabled: false } }, + }, + })); + const configStrict = checkIsOperationEnabled(createPluginConfig({ + enabled: true, + hooks: { + enabled: true, + afterOperation: { + enabled: true, + updateByID: false, + }, + }, + })); + const configWithEnabledStrict = checkIsOperationEnabled(createPluginConfig({ + enabled: true, + hooks: { + enabled: true, + afterOperation: { + enabled: true, + updateByID: { enabled: false }, + }, + }, + })); + + expect(config).toEqual(false); + expect(configWithEnabled).toEqual(false); + expect(configStrict).toEqual(false); + expect(configWithEnabledStrict).toEqual(false); + }); + + it('should return false when explicitly false at the hook level', () => { + const config = checkIsOperationEnabled(createPluginConfig({ + hooks: { + enabled: true, + afterOperation: false, + }, + })); + const configWithEnabled = checkIsOperationEnabled(createPluginConfig({ + hooks: { + enabled: true, + afterOperation: { enabled: false }, + }, + })); + + const configStrict = checkIsOperationEnabled(createPluginConfig({ + enabled: true, + hooks: { + enabled: true, + afterOperation: false, + }, + })); + const configWithEnabledStrict = checkIsOperationEnabled(createPluginConfig({ + hooks: { + enabled: true, + afterOperation: { enabled: false, updateByID: true }, + }, + })); + + expect(config).toEqual(false); + expect(configWithEnabled).toEqual(false); + expect(configStrict).toEqual(false); + expect(configWithEnabledStrict).toEqual(false); + }); + + it('should return false when explicitly false at the all hooks level', () => { + const allHooksLevelConfig = checkIsOperationEnabled(createPluginConfig({ hooks: false })); + const allHooksLevelConfigWithEnabled = checkIsOperationEnabled(createPluginConfig({ + hooks: { enabled: false }, + })); + const allHooksLevelConfigStrict = checkIsOperationEnabled(createPluginConfig({ + enabled: true, + hooks: false, + })); + const allHooksLevelConfigWithEnabledStrict = checkIsOperationEnabled(createPluginConfig({ + enabled: true, + hooks: { enabled: false }, + })); + + const hookLevelConfig = checkIsOperationEnabled(createPluginConfig({ + hooks: { + enabled: false, + afterOperation: true, + }, + })); + const hookLevelConfigWithEnabled = checkIsOperationEnabled(createPluginConfig({ + hooks: { + enabled: false, + afterOperation: { enabled: true }, + }, + })); + const hookLevelConfigStrict = checkIsOperationEnabled(createPluginConfig({ + enabled: true, + hooks: { + enabled: false, + afterOperation: true, + }, + })); + const hookLevelConfigWithEnabledStrict = checkIsOperationEnabled(createPluginConfig({ + enabled: true, + hooks: { + enabled: false, + afterOperation: { enabled: true }, + }, + })); + + const operationLevelConfig = checkIsOperationEnabled(createPluginConfig({ + hooks: { + enabled: false, + afterOperation: { updateByID: true }, + }, + })); + const operationLevelConfigWithEnabled = checkIsOperationEnabled(createPluginConfig({ + hooks: { + enabled: false, + afterOperation: { updateByID: { enabled: true } }, + }, + })); + const operationLevelConfigStrict = checkIsOperationEnabled(createPluginConfig({ + enabled: true, + hooks: { + enabled: false, + afterOperation: { enabled: true, updateByID: true }, + }, + })); + const operationLevelConfigWithEnabledStrict = checkIsOperationEnabled(createPluginConfig({ + hooks: { + enabled: false, + afterOperation: { enabled: true, updateByID: { enabled: true } }, + }, + })); + + expect(allHooksLevelConfig).toEqual(false); + expect(allHooksLevelConfigWithEnabled).toEqual(false); + expect(hookLevelConfig).toEqual(false); + expect(hookLevelConfigWithEnabled).toEqual(false); + expect(operationLevelConfig).toEqual(false); + expect(operationLevelConfigWithEnabled).toEqual(false); + expect(hookLevelConfigStrict).toEqual(false); + expect(hookLevelConfigWithEnabledStrict).toEqual(false); + expect(operationLevelConfigStrict).toEqual(false); + expect(operationLevelConfigWithEnabledStrict).toEqual(false); + expect(allHooksLevelConfigStrict).toEqual(false); + expect(allHooksLevelConfigWithEnabledStrict).toEqual(false); + }); + + it('should return false when explicitly false at the collection level', () => { + const collectionLevelConfig = checkIsOperationEnabled(createPluginConfig({ enabled: false })); + const allHooksLevelConfig = checkIsOperationEnabled(createPluginConfig({ + enabled: false, + hooks: true, + })); + const allHooksLevelConfigWithEnabled = checkIsOperationEnabled(createPluginConfig({ + enabled: false, + hooks: { enabled: true }, + })); + + const hookLevelConfig = checkIsOperationEnabled(createPluginConfig({ + enabled: false, + hooks: { afterOperation: true }, + })); + const hookLevelConfigWithEnabled = checkIsOperationEnabled(createPluginConfig({ + enabled: false, + hooks: { afterOperation: { enabled: true } }, + })); + + const hookLevelConfigStrict = checkIsOperationEnabled(createPluginConfig({ + enabled: false, + hooks: { enabled: false, afterOperation: true }, + })); + const hookLevelConfigWithEnabledStrict = checkIsOperationEnabled(createPluginConfig({ + enabled: false, + hooks: { enabled: false, afterOperation: { enabled: true } }, + })); + + const operationLevelConfig = checkIsOperationEnabled(createPluginConfig({ + enabled: false, + hooks: { afterOperation: { updateByID: true } }, + })); + const operationLevelConfigWithEnabled = checkIsOperationEnabled(createPluginConfig({ + enabled: false, + hooks: { afterOperation: { updateByID: { enabled: true } } }, + })); + + const operationLevelConfigStrict = checkIsOperationEnabled(createPluginConfig({ + enabled: false, + hooks: { enabled: false, afterOperation: { enabled: false, updateByID: true } }, + })); + const operationLevelConfigWithEnabledStrict = checkIsOperationEnabled(createPluginConfig({ + enabled: false, + hooks: { enabled: false, afterOperation: { enabled: false, updateByID: { enabled: true } } }, + })); + + expect(collectionLevelConfig).toEqual(false); + expect(allHooksLevelConfigWithEnabled).toEqual(false); + expect(allHooksLevelConfig).toEqual(false); + expect(hookLevelConfigWithEnabled).toEqual(false); + expect(hookLevelConfig).toEqual(false); + expect(operationLevelConfig).toEqual(false); + expect(operationLevelConfigWithEnabled).toEqual(false); + expect(hookLevelConfigStrict).toEqual(false); + expect(hookLevelConfigWithEnabledStrict).toEqual(false); + expect(operationLevelConfigStrict).toEqual(false); + expect(operationLevelConfigWithEnabledStrict).toEqual(false); + }); +}); diff --git a/src/core/log-builders/collections/helpers/isOperationEnabled/isOperationEnabled.ts b/src/core/log-builders/collections/helpers/isOperationEnabled/isOperationEnabled.ts new file mode 100644 index 0000000..6c74c57 --- /dev/null +++ b/src/core/log-builders/collections/helpers/isOperationEnabled/isOperationEnabled.ts @@ -0,0 +1,33 @@ +import type { CollectionConfig } from 'payload'; + +import type { HookConfigForTracking, LogConfig, TrackedCollection } from '../../../../../types/pluginOptions.js'; + +type CollectionHooksKeys = keyof NonNullable; + +interface Params { + hookOperationLevelConfig?: LogConfig | true; + hookLevelConfig?: HookConfigForTracking[CollectionHooksKeys]; + allHooksLevelConfig: TrackedCollection['hooks']; + collectionLevelConfig: TrackedCollection; +} + +export const isBooleanConfig = (v: T): boolean | undefined => typeof v === 'boolean' + ? v + // @ts-expect-error + : v?.enabled; + +export const checkIsOperationEnabled = (params: Params): boolean => { + const hookLevelEnabled = isBooleanConfig(params.hookLevelConfig); + const allHooksLevelConfigEnabled = isBooleanConfig(params.allHooksLevelConfig); + const operationLevelEnabled = isBooleanConfig(params.hookOperationLevelConfig); + + return params.collectionLevelConfig.enabled !== false + && (operationLevelEnabled !== false) + && (hookLevelEnabled !== false) + && (allHooksLevelConfigEnabled !== false) + && !!( + params.collectionLevelConfig.enabled + || operationLevelEnabled + || hookLevelEnabled + || allHooksLevelConfigEnabled); +}; diff --git a/src/core/log-builders/collections/logBuilderManager.ts b/src/core/log-builders/collections/logBuilderManager.ts index 10c0b7c..7c37ef2 100644 --- a/src/core/log-builders/collections/logBuilderManager.ts +++ b/src/core/log-builders/collections/logBuilderManager.ts @@ -1,13 +1,14 @@ import type { AllOperations, CollectionConfig } from 'payload'; import type { AuditorLog } from '../../../collections/auditor.js'; -import { checkIsOperationEnabled } from './helpers/isOperationEnabled.js'; import { extractOperation } from './helpers/extractOperation/extractOperation.js'; +import { checkIsOperationEnabled } from './helpers/isOperationEnabled/isOperationEnabled.js'; import { customLoggingHandler } from './helpers/customLoggingHandler/customLoggingHandler.js'; import type { HookConfigForTracking, LogConfig, PluginConfig, + TrackedCollection, } from '../../../types/pluginOptions.js'; export type CollectionHooksKeys = keyof NonNullable; @@ -26,6 +27,8 @@ type LogBuilderManager = { pluginConfig: PluginConfig; targetHookName: CollectionHooksKeys; targetHookLevelConfig: HookConfigForTracking[CollectionHooksKeys]; + allHooksLevelConfig: TrackedCollection['hooks']; + collectionConfig: TrackedCollection; collectionSlug: string; }; @@ -34,10 +37,11 @@ export const logBuilderManager = async (params: LogBuilderManager) => { // @ts-expect-error const hookOperationLevelConfig = params .targetHookLevelConfig?.[operation] as LogConfig | undefined; - const isOperationEnabled = checkIsOperationEnabled({ hookLevelConfig: params.targetHookLevelConfig, hookOperationLevelConfig, + allHooksLevelConfig: params.allHooksLevelConfig, + collectionLevelConfig: params.collectionConfig, }); const baseLog: AuditorLog = { diff --git a/src/pluginUtils/configHelpers.ts b/src/pluginUtils/configHelpers.ts index 9def125..056e478 100644 --- a/src/pluginUtils/configHelpers.ts +++ b/src/pluginUtils/configHelpers.ts @@ -25,24 +25,32 @@ export const attachCollectionConfig = ( tc => tc.slug === collection.slug, ); - if (tracked && !tracked.disabled) { + if (tracked && tracked.enabled) { collection.hooks = collection.hooks || {}; - if (tracked.hooks) { - for (const hookName in tracked?.hooks) { - const typedHookName = hookName as CollectionHooksKeys; - // @ts-expect-error - collection.hooks[typedHookName] = [ - ...(collection.hooks[typedHookName] || []), - // @ts-ignore - async args => logBuilderManager({ - collectionSlug: collection.slug, - hookArgs: args, - pluginConfig: pluginOpts, - targetHookLevelConfig: tracked.hooks?.[typedHookName], - targetHookName: typedHookName, - }), - ]; + if (tracked?.hooks) { + if (typeof tracked.hooks === 'boolean') { + for (const hook in collection.hooks) { + + } + } + else { + for (const hookName in tracked?.hooks) { + const typedHookName = hookName as CollectionHooksKeys; + // @ts-expect-error + collection.hooks[typedHookName] = [ + ...(collection.hooks[typedHookName] || []), + // @ts-ignore + async args => logBuilderManager({ + collectionSlug: collection.slug, + hookArgs: args, + pluginConfig: pluginOpts, + targetHookLevelConfig: tracked.hooks?.[typedHookName], + targetHookName: typedHookName, + allHooksLevelConfig: tracked.hooks, + }), + ]; + } } } } diff --git a/src/types/pluginOptions.ts b/src/types/pluginOptions.ts index 186ef54..416fe77 100644 --- a/src/types/pluginOptions.ts +++ b/src/types/pluginOptions.ts @@ -14,18 +14,18 @@ export type PayloadCollectionHooksMap = { export type HookConfigForTracking = { [K in keyof NonNullable]: - Partial< - { + Partial< + { // @ts-expect-error - [O in Parameters< - NonNullable< + [O in Parameters< NonNullable< - CollectionConfig['hooks'] - >[K] - >[number] - >[0]['operation']]: LogConfig | boolean - } & LogConfig - > + NonNullable< + CollectionConfig['hooks'] + >[K] + >[number] + >[0]['operation']]: LogConfig | boolean + } & LogConfig + > | boolean }; @@ -186,7 +186,7 @@ export interface TrackedCollection { * @default undefined * */ - disabled?: boolean; + enabled?: boolean; /** * 📝 Define payload cms hooks for each collection being tracked @@ -212,7 +212,7 @@ export interface TrackedCollection { * Read more: * @see {@link https://payloadcms.com/docs/hooks/collections} */ - hooks?: Partial; + hooks?: (LogConfig & Partial) | boolean; /** Optional label or description for UI/doc */ label?: string; From 33dcce9dabf86dc85c325a509727f0124f374750 Mon Sep 17 00:00:00 2001 From: shaadcode Date: Wed, 22 Jul 2026 17:40:30 +0330 Subject: [PATCH 6/8] feat: add global logs --- dev/globals/Nav.ts | 22 + dev/payload-types.ts | 32 +- dev/payload.config.ts | 40 +- src/collections/auditor.ts | 31 +- .../automation/tasks/cleanup/cleanup.test.ts | 19 +- src/core/automation/tasks/cleanup/cleanup.ts | 20 +- src/core/buffer/bufferManager.test.ts | 93 ++-- src/core/buffer/bufferManager.ts | 36 +- .../helpers/handleBufferDebugMode.test.ts | 263 ----------- .../buffer/helpers/handleBufferDebugMode.ts | 21 - src/core/buffer/types.ts | 69 +-- .../customLoggingHandler.ts | 41 -- .../extractOperation/extractOperation.ts | 7 +- .../collections/helpers/handleDebugMode.ts | 46 +- .../isOperationEnabled.test.ts | 174 +------ .../isOperationEnabled/isOperationEnabled.ts | 21 +- .../collections/logBuilderManager.ts | 66 --- .../logBuilderManager.test.ts | 65 +++ .../logBuilderManager/logBuilderManager.ts | 80 ++++ src/index.ts | 46 +- .../attachCollectionConfig.ts | 47 ++ .../attachGlobalConfig/attachGlobalConfig.ts | 53 +++ src/pluginUtils/configHelpers.ts | 86 +--- src/types/collection.ts | 70 +++ src/types/global.ts | 67 +++ src/types/pluginOptions.ts | 436 +----------------- src/utils/prettyDebugLog.ts | 40 +- 27 files changed, 684 insertions(+), 1307 deletions(-) create mode 100644 dev/globals/Nav.ts delete mode 100644 src/core/buffer/helpers/handleBufferDebugMode.test.ts delete mode 100644 src/core/buffer/helpers/handleBufferDebugMode.ts delete mode 100644 src/core/log-builders/collections/helpers/customLoggingHandler/customLoggingHandler.ts delete mode 100644 src/core/log-builders/collections/logBuilderManager.ts create mode 100644 src/core/log-builders/collections/logBuilderManager/logBuilderManager.test.ts create mode 100644 src/core/log-builders/collections/logBuilderManager/logBuilderManager.ts create mode 100644 src/pluginUtils/attachCollectionConfig/attachCollectionConfig.ts create mode 100644 src/pluginUtils/attachGlobalConfig/attachGlobalConfig.ts create mode 100644 src/types/collection.ts create mode 100644 src/types/global.ts diff --git a/dev/globals/Nav.ts b/dev/globals/Nav.ts new file mode 100644 index 0000000..664b6ab --- /dev/null +++ b/dev/globals/Nav.ts @@ -0,0 +1,22 @@ +import type { GlobalConfig } from 'payload'; + +export const navigation: GlobalConfig = { + slug: 'navigation', + access: { + read: () => true, + readVersions: () => true, + update: () => true, + }, + fields: [ + { + name: 'name', + type: 'text', + defaultValue: 'nav item name', + }, + { + name: 'link', + type: 'text', + defaultValue: 'nav item href', + }, + ], +}; diff --git a/dev/payload-types.ts b/dev/payload-types.ts index 4c8272b..03fe5d0 100644 --- a/dev/payload-types.ts +++ b/dev/payload-types.ts @@ -92,9 +92,11 @@ export interface Config { }; fallbackLocale: null; globals: { + navigation: Navigation; 'payload-jobs-stats': PayloadJobsStat; }; globalsSelect: { + navigation: NavigationSelect | NavigationSelect; 'payload-jobs-stats': PayloadJobsStatsSelect | PayloadJobsStatsSelect; }; locale: null; @@ -184,10 +186,12 @@ export interface User { export interface AuditLog { id: string; operation: string; - onCollection: string; + identifier: string; + scope: 'collection' | 'global'; userAgent?: string | null; hook?: string | null; createdAt: string; + 'new-fields'?: string | null; } /** * This interface was referenced by `Config`'s JSON-Schema @@ -416,10 +420,12 @@ export interface UsersSelect { */ export interface AuditLogSelect { operation?: T; - onCollection?: T; + identifier?: T; + scope?: T; userAgent?: T; hook?: T; createdAt?: T; + 'new-fields'?: T; } /** * This interface was referenced by `Config`'s JSON-Schema @@ -493,6 +499,17 @@ export interface PayloadMigrationsSelect { updatedAt?: T; createdAt?: T; } +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "navigation". + */ +export interface Navigation { + id: string; + name?: string | null; + link?: string | null; + updatedAt?: string | null; + createdAt?: string | null; +} /** * This interface was referenced by `Config`'s JSON-Schema * via the `definition` "payload-jobs-stats". @@ -511,6 +528,17 @@ export interface PayloadJobsStat { updatedAt?: string | null; createdAt?: string | null; } +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "navigation_select". + */ +export interface NavigationSelect { + name?: T; + link?: T; + updatedAt?: T; + createdAt?: T; + globalType?: T; +} /** * This interface was referenced by `Config`'s JSON-Schema * via the `definition` "payload-jobs-stats_select". diff --git a/dev/payload.config.ts b/dev/payload.config.ts index 2d10622..5699924 100644 --- a/dev/payload.config.ts +++ b/dev/payload.config.ts @@ -3,10 +3,12 @@ import sharp from 'sharp'; import path from 'node:path'; import { buildConfig } from 'payload'; import { fileURLToPath } from 'node:url'; +import type { CollectionConfig } from 'payload'; // import { auditorPlugin } from 'payload-auditor'; import { mongooseAdapter } from '@payloadcms/db-mongodb'; import { lexicalEditor } from '@payloadcms/richtext-lexical'; +import { navigation } from './globals/Nav.js'; import { media } from './collections/Media.js'; import { users } from './collections/Users.js'; // import { auditorPlugin } from './../dist/index.js'; @@ -23,6 +25,7 @@ if (!process.env.ROOT_DIR) { export default buildConfig({ admin: { importMap: { baseDir: path.resolve(dirname) } }, collections: [media, users], + globals: [navigation], db: mongooseAdapter({ url: process.env.DATABASE_URI || '', connectOptions: { @@ -36,32 +39,49 @@ export default buildConfig({ plugins: [ auditorPlugin({ automation: { - logCleanup: { cronTime: '*/1 * * * *', queueName: 'test', olderThan: 60000 }, + logCleanup: { cronTime: '0/1 * * * *', queueName: 'test', olderThan: 60000 }, }, - // customLogger - collection: { + configureRootCollection: (collection) => { + const newCollection = { + ...collection, + fields: [ + ...collection.fields, + { + name: 'new-fields', + type: 'text', + defaultValue: 'test new fields value', + }, + ], + } as CollectionConfig; + return newCollection; + }, + globals: { + track: [ + { + slug: 'navigation', + hooks: { + beforeRead: true, + }, + }, + ], + }, + collections: { track: [ { slug: 'media', -enabled: hooks: { - // enabled: true, - // customLogger afterOperation: { - // enabled: true, updateByID: { enabled: true, }, }, - // afterRead: { - // enabled: true, - // }, }, }, ], }, }), ], + secret: process.env.PAYLOAD_SECRET || 'test-secret_key', sharp, typescript: { diff --git a/src/collections/auditor.ts b/src/collections/auditor.ts index 871c3c1..1c47ba4 100644 --- a/src/collections/auditor.ts +++ b/src/collections/auditor.ts @@ -1,25 +1,27 @@ import type { CollectionConfig } from 'payload'; -import type { CollectionHooksKeys, CollectionHooksOperation } from '../core/log-builders/collections/logBuilderManager.js'; +import type { GlobalHooksKeys } from '../types/global.js'; +import type { CollectionHooksKeys, CollectionHooksOperation } from '../types/collection.js'; export interface AuditorLog { - onCollection: string; - hook: CollectionHooksKeys; + scope: 'collection' | 'global' | 'field'; + hook: CollectionHooksKeys | GlobalHooksKeys; operation: CollectionHooksOperation; timestamp: Date; userAgent?: string; + identifier: string; } export type TypedRootCollection = typeof auditor; -export const auditor: CollectionConfig = { +export const auditor = { slug: 'Audit-log', labels: { plural: 'Audit-logs', singular: 'Audit-log', }, admin: { - defaultColumns: ['operation', 'hook', 'onCollection', 'timestamp', 'createdAt'], + defaultColumns: ['operation', 'hook', 'identifier', 'scope', 'timestamp', 'createdAt'], useAsTitle: 'operation', }, fields: [ @@ -29,10 +31,25 @@ export const auditor: CollectionConfig = { required: true, }, { - name: 'onCollection', + name: 'identifier', type: 'text', required: true, }, + { + name: 'scope', + type: 'select', + required: true, + options: [ + { + value: 'collection', + label: 'Collection', + }, + { + value: 'global', + label: 'Global', + }, + ], + }, { name: 'userAgent', type: 'text', @@ -52,6 +69,6 @@ export const auditor: CollectionConfig = { }, ], timestamps: false, -}; +} as const satisfies CollectionConfig; export default auditor; diff --git a/src/core/automation/tasks/cleanup/cleanup.test.ts b/src/core/automation/tasks/cleanup/cleanup.test.ts index ea6c338..4e6d1eb 100644 --- a/src/core/automation/tasks/cleanup/cleanup.test.ts +++ b/src/core/automation/tasks/cleanup/cleanup.test.ts @@ -1,6 +1,7 @@ import type { TaskConfig } from 'payload'; import { beforeEach, describe, expect, it, vi } from 'vitest'; +import { auditor } from '../../../../collections/auditor.js'; import type { PluginConfig } from '../../../../types/pluginOptions.js'; import { CLEANUP_TASK_LABEL, CLEANUP_TASK_SLUG, cleanupLogsTask, DEFAULT_CRON_TIME, DEFAULT_OLDER_THAN, DEFAULT_QUEUE_NAME } from './cleanup.js'; @@ -12,7 +13,6 @@ const mockPluginConfig = { queueName: DEFAULT_QUEUE_NAME, }, }, - // @ts-expect-error } as const satisfies PluginConfig; const mockReq = { @@ -31,8 +31,7 @@ describe('cleanupLogsTask', () => { }); it('should return expected task', () => { - // @ts-expect-error - const result = cleanupLogsTask(mockPluginConfig); + const result = cleanupLogsTask({ internalCollectionConfig: auditor, pluginConfig: mockPluginConfig }); const expectedResultInstance = { handler: expect.any(Function), @@ -54,9 +53,7 @@ describe('cleanupLogsTask', () => { describe('handler task', () => { it('should call payload.delete with correct parameters', async () => { - const pluginOptions: Partial = {}; - // @ts-expect-error - const task = cleanupLogsTask(pluginOptions); + const task = cleanupLogsTask({ internalCollectionConfig: auditor, pluginConfig: mockPluginConfig }); typeof task.handler === 'function' && await task .handler({ @@ -77,14 +74,14 @@ describe('cleanupLogsTask', () => { it('should use configureRootCollection result when provided', async () => { const configuredSlug = 'configured-audit-logs'; - const pluginOptions: PluginConfig = { - collection: { - configureRootCollection: vi.fn().mockReturnValue({ slug: configuredSlug }), + const pluginConfig: PluginConfig = { + configureRootCollection: vi.fn().mockReturnValue({ slug: configuredSlug }), + collections: { track: [], }, }; - const task = cleanupLogsTask(pluginOptions); + const task = cleanupLogsTask({ internalCollectionConfig: auditor, pluginConfig }); typeof task.handler === 'function' && await task .handler({ // @ts-expect-error @@ -99,7 +96,6 @@ describe('cleanupLogsTask', () => { it('should use custom olderThan value', async () => { const customOlderThan = 86400000; // 1 day - // @ts-expect-error const pluginOptions: PluginConfig = { automation: { logCleanup: { @@ -108,6 +104,7 @@ describe('cleanupLogsTask', () => { }, }; + // @ts-expect-error const task = cleanupLogsTask(pluginOptions); typeof task.handler === 'function' && await task.handler({ // @ts-expect-error diff --git a/src/core/automation/tasks/cleanup/cleanup.ts b/src/core/automation/tasks/cleanup/cleanup.ts index 7151fac..d848a4c 100644 --- a/src/core/automation/tasks/cleanup/cleanup.ts +++ b/src/core/automation/tasks/cleanup/cleanup.ts @@ -1,6 +1,5 @@ -import type { TaskConfig } from 'payload'; +import type { CollectionConfig, TaskConfig } from 'payload'; -import auditor from '../../../../collections/auditor.js'; import type { PluginConfig } from '../../../../types/pluginOptions.js'; export const DEFAULT_OLDER_THAN = 604800000; // 1 week @@ -9,12 +8,15 @@ export const DEFAULT_QUEUE_NAME = 'payload-auditor-queue'; // default queue name export const CLEANUP_TASK_SLUG = 'cleanup-payload-auditor-log'; export const CLEANUP_TASK_LABEL = 'payload auditor - cleanup logs'; -export const cleanupLogsTask = (pluginOptions: PluginConfig): TaskConfig => { - const cronTime = pluginOptions.automation?.logCleanup?.cronTime ?? DEFAULT_CRON_TIME; - const queueName = pluginOptions.automation?.logCleanup?.queueName ?? DEFAULT_QUEUE_NAME; - const olderThan = pluginOptions.automation?.logCleanup?.olderThan ?? DEFAULT_OLDER_THAN; - const collectionSlug - = pluginOptions.collection?.configureRootCollection?.(auditor).slug ?? 'Audit-log'; +type CleanupLogsTaskParams = { + pluginConfig: PluginConfig; + internalCollectionConfig: CollectionConfig; +}; +export const cleanupLogsTask = (params: CleanupLogsTaskParams): TaskConfig => { + const cronTime = params.pluginConfig.automation?.logCleanup?.cronTime ?? DEFAULT_CRON_TIME; + const queueName = params.pluginConfig.automation?.logCleanup?.queueName ?? DEFAULT_QUEUE_NAME; + const olderThan = params.pluginConfig.automation?.logCleanup?.olderThan ?? DEFAULT_OLDER_THAN; + return { slug: CLEANUP_TASK_SLUG, label: CLEANUP_TASK_LABEL, @@ -23,7 +25,7 @@ export const cleanupLogsTask = (pluginOptions: PluginConfig): TaskConfig { describe('bufferManager', () => { it('should flush when buffer reaches size limit', async () => { const pluginOptions = { - collection: { - buffer: { - flushStrategy: 'size', - size: 2, - }, + buffer: { + flushStrategy: 'size', + size: 2, }, } as PluginConfig; - - bufferManager(mockPayload as any, pluginOptions); + bufferManager({ + payload: mockPayload as any, + bufferConfig: pluginOptions.buffer, + internalCollectionConfig: auditor, + }); // simulate event listener const handler = mockOnEventLog.mock.calls[0][1]; @@ -52,14 +53,17 @@ describe('bufferManager', () => { it('should flush immediately in realtime mode', async () => { const pluginOptions = { - collection: { - buffer: { - flushStrategy: 'realtime', - }, + buffer: { + flushStrategy: 'realtime', }, } as PluginConfig; - bufferManager(mockPayload as any, pluginOptions); + bufferManager({ + payload: mockPayload as any, + bufferConfig: pluginOptions.buffer, + internalCollectionConfig: auditor, + }); + const handler = mockOnEventLog.mock.calls[0][1]; await handler(sampleLog); @@ -71,15 +75,16 @@ describe('bufferManager', () => { it('should flush periodically in time mode', async () => { const pluginOptions = { - collection: { - buffer: { - flushStrategy: 'time', - time: 2000, - }, + buffer: { + flushStrategy: 'time', + time: 2000, }, } as unknown as PluginConfig; - - bufferManager(mockPayload as any, pluginOptions); + bufferManager({ + payload: mockPayload as any, + bufferConfig: pluginOptions.buffer, + internalCollectionConfig: auditor, + }); const handler = mockOnEventLog.mock.calls[0][1]; await handler(sampleLog); expect(mockPayload.create).not.toHaveBeenCalled(); @@ -94,15 +99,16 @@ describe('bufferManager', () => { it('should flushing logs after create log when size value is 1', async () => { const pluginOptions = { - collection: { - buffer: { - flushStrategy: 'size', - size: 1, - }, + buffer: { + flushStrategy: 'size', + size: 1, }, } as PluginConfig; - - bufferManager(mockPayload as any, pluginOptions); + bufferManager({ + payload: mockPayload as any, + bufferConfig: pluginOptions.buffer, + internalCollectionConfig: auditor, + }); const handler = mockOnEventLog.mock.calls[0][1]; await handler(sampleLog); @@ -122,8 +128,11 @@ describe('bufferManager', () => { }, }, } as unknown as PluginConfig; - - bufferManager(mockPayload as any, pluginOptions); + bufferManager({ + payload: mockPayload as any, + bufferConfig: pluginOptions.buffer, + internalCollectionConfig: auditor, + }); const handler = mockOnEventLog.mock.calls[0][1]; @@ -136,15 +145,16 @@ describe('bufferManager', () => { it('should clear buffer store after flushing by time', async () => { const pluginOptions = { - collection: { - buffer: { - flushStrategy: 'time', - time: 2000, - }, + buffer: { + flushStrategy: 'time', + time: 2000, }, } as PluginConfig; - - bufferManager(mockPayload as any, pluginOptions); + bufferManager({ + payload: mockPayload as any, + bufferConfig: pluginOptions.buffer, + internalCollectionConfig: auditor, + }); const handler = mockOnEventLog.mock.calls[0][1]; @@ -159,14 +169,15 @@ describe('bufferManager', () => { it('should clear buffer store after flushing by realtime', async () => { const pluginOptions = { - collection: { - buffer: { - flushStrategy: 'realtime', - }, + buffer: { + flushStrategy: 'realtime', }, } as PluginConfig; - - bufferManager(mockPayload as any, pluginOptions); + bufferManager({ + payload: mockPayload as any, + bufferConfig: pluginOptions.buffer, + internalCollectionConfig: auditor, + }); const handler = mockOnEventLog.mock.calls[0][1]; diff --git a/src/core/buffer/bufferManager.ts b/src/core/buffer/bufferManager.ts index fe4f241..4f51faf 100644 --- a/src/core/buffer/bufferManager.ts +++ b/src/core/buffer/bufferManager.ts @@ -1,11 +1,8 @@ -import type { Payload } from 'payload'; +import type { CollectionConfig, Payload } from 'payload'; import type { BufferConfig } from './types.js'; -import { auditor } from '../../collections/auditor.js'; import { onEventLog } from './../../core/events/emitter.js'; import type { AuditorLog } from '../../collections/auditor.js'; -import type { PluginConfig } from '../../types/pluginOptions.js'; -import { handleBufferDebugMode } from './../../core/buffer/helpers/handleBufferDebugMode.js'; export const DEFAULT_INTERVAL_BUFFER = 10000 as NonNullable; export const DEFAULT_BUFFER_SIZE = 10 as NonNullable; @@ -13,41 +10,46 @@ export const DEFAULT_BUFFER_STRATEGY = 'time' as NonNullable { +const flushBuffer = async (params: FlushBufferParams) => { const logsToInsert = [...bufferStore]; bufferStore.length = 0; - const internalCollection = pluginOptions.collection?.configureRootCollection?.(); await Promise.all( logsToInsert.map(log => - payloadInstance.create({ - collection: internalCollection?.slug ?? auditor.slug, + params.payload.create({ + collection: params.internalCollectionConfig?.slug, data: log, }), ), ); }; -export const bufferManager = (payload: Payload, pluginOptions: PluginConfig) => { - const bufferConfig = pluginOptions.collection?.buffer; +type BufferConfigParams = { + payload: Payload; + bufferConfig?: BufferConfig; + internalCollectionConfig: CollectionConfig; +}; + +export const bufferManager = (params: BufferConfigParams) => { + const bufferConfig = params.bufferConfig; const size = bufferConfig?.size ?? DEFAULT_BUFFER_SIZE; const interval = bufferConfig?.time ?? DEFAULT_INTERVAL_BUFFER; const flushStrategy = bufferConfig?.flushStrategy ?? DEFAULT_BUFFER_STRATEGY; - payloadInstance = payload; - // When the log is generated, add it to the buffer. onEventLog('logGenerated', async (log: AuditorLog) => { - handleBufferDebugMode({ flushStrategy, interval, size }, bufferConfig); bufferStore.push(log); if (flushStrategy === 'size') { if (bufferStore.length >= size) { - await flushBuffer(pluginOptions); + await flushBuffer(params); } } else if (flushStrategy === 'realtime') { - await flushBuffer(pluginOptions); + await flushBuffer(params); } }); @@ -55,7 +57,7 @@ export const bufferManager = (payload: Payload, pluginOptions: PluginConfig) => // Every few seconds, empty the buffer (even if it's not full) setInterval(async () => { if (bufferStore.length > 0) { - await flushBuffer(pluginOptions); + await flushBuffer(params); } }, interval); } diff --git a/src/core/buffer/helpers/handleBufferDebugMode.test.ts b/src/core/buffer/helpers/handleBufferDebugMode.test.ts deleted file mode 100644 index 392c771..0000000 --- a/src/core/buffer/helpers/handleBufferDebugMode.test.ts +++ /dev/null @@ -1,263 +0,0 @@ -import { beforeEach, describe, expect, it, vi } from 'vitest'; - -import { prettyDebugLog } from '../../../utils/prettyDebugLog.js'; -import type { BufferConfig, BufferDebugFields } from '../types.js'; -import { handleBufferDebugMode } from './handleBufferDebugMode.js'; -import { DEFAULT_BUFFER_SIZE, DEFAULT_BUFFER_STRATEGY, DEFAULT_INTERVAL_BUFFER } from '../bufferManager.js'; - -vi.mock('../../../utils/prettyDebugLog.js'); - -const mockFields = { - flushStrategy: DEFAULT_BUFFER_STRATEGY, - size: DEFAULT_BUFFER_SIZE, - interval: DEFAULT_INTERVAL_BUFFER, -} satisfies Record; - -describe('handleBufferDebugMode', () => { - beforeEach(() => { - vi.clearAllMocks(); - }); - - describe('when debug is disabled', () => { - it('should return null and not call prettyDebugLog', () => { - const bufferConfig: BufferConfig = { - modes: { - debug: { - enabled: false, - }, - }, - }; - - const result = handleBufferDebugMode(mockFields, bufferConfig); - - expect(result).toBeNull(); - expect(prettyDebugLog).not.toHaveBeenCalled(); - }); - - it('should return null when bufferConfig is undefined', () => { - const result = handleBufferDebugMode(mockFields, undefined); - - expect(result).toBeNull(); - expect(prettyDebugLog).not.toHaveBeenCalled(); - }); - - it('should return null when bufferConfig.modes is undefined', () => { - const bufferConfig: BufferConfig = {}; - - const result = handleBufferDebugMode(mockFields, bufferConfig); - - expect(result).toBeNull(); - expect(prettyDebugLog).not.toHaveBeenCalled(); - }); - }); - - describe('when debug is enabled', () => { - it('should call prettyDebugLog with all fields when debugFields is not specified', () => { - const bufferConfig: BufferConfig = { - modes: { - debug: { - enabled: true, - }, - }, - }; - - handleBufferDebugMode(mockFields, bufferConfig); - - expect(prettyDebugLog).toHaveBeenCalledTimes(1); - expect(prettyDebugLog).toHaveBeenCalledWith( - 'Buffer', - '', - mockFields, - 'table', - ); - }); - - it('should filter fields based on debugFields configuration', () => { - const bufferConfig: BufferConfig = { - modes: { - debug: { - enabled: true, - fields: { - size: true, - }, - }, - }, - }; - - handleBufferDebugMode(mockFields, bufferConfig); - - const expectedFiltered = { - size: 10, - }; - - expect(prettyDebugLog).toHaveBeenCalledWith( - 'Buffer', - '', - expectedFiltered, - 'table', - ); - }); - - it('should use custom displayType when provided', () => { - const bufferConfig: BufferConfig = { - modes: { - debug: { - enabled: true, - displayType: 'manual', - }, - }, - }; - - handleBufferDebugMode(mockFields, bufferConfig); - - expect(prettyDebugLog).toHaveBeenCalledWith( - 'Buffer', - '', - mockFields, - 'manual', - ); - }); - - it('should use custom fields when provided in debug configuration', () => { - const bufferConfig: BufferConfig = { - modes: { - debug: { - enabled: true, - fields: { - size: true, - interval: true, - }, - }, - }, - }; - - handleBufferDebugMode(mockFields, bufferConfig); - - const expectedFiltered = { - size: 10, - interval: 10000, - }; - - expect(prettyDebugLog).toHaveBeenCalledWith( - 'Buffer', - '', - expectedFiltered, - 'table', - ); - }); - }); - - describe('edge cases', () => { - it('should handle empty fields object', () => { - const emptyFields = {} as Record; - const bufferConfig: BufferConfig = { - modes: { - debug: { - enabled: true, - }, - }, - }; - - handleBufferDebugMode(emptyFields, bufferConfig); - - expect(prettyDebugLog).toHaveBeenCalledWith( - 'Buffer', - '', - emptyFields, - 'table', - ); - }); - - it('should handle debugFields with all false values', () => { - const bufferConfig: BufferConfig = { - modes: { - debug: { - enabled: true, - fields: { - size: false, - flushStrategy: false, - interval: false, - }, - }, - }, - }; - - handleBufferDebugMode(mockFields, bufferConfig); - - expect(prettyDebugLog).toHaveBeenCalledWith( - 'Buffer', - '', - {}, - 'table', - ); - }); - - it('should handle undefined displayType', () => { - const bufferConfig: BufferConfig = { - modes: { - debug: { - enabled: true, - displayType: undefined, - }, - }, - }; - - handleBufferDebugMode(mockFields, bufferConfig); - - expect(prettyDebugLog).toHaveBeenCalledWith( - 'Buffer', - '', - mockFields, - 'table', - ); - }); - }); - - describe('multiple calls', () => { - it('should work correctly with multiple calls', () => { - const bufferConfig: BufferConfig = { - modes: { - debug: { - enabled: true, - fields: { - size: true, - interval: true, - }, - }, - }, - }; - - // فراخوانی اول - handleBufferDebugMode(mockFields, bufferConfig); - - // فراخوانی دوم با داده‌های متفاوت - const otherFields = { - ...mockFields, - size: 2048, - interval: 50000, - }; - handleBufferDebugMode(otherFields, bufferConfig); - - expect(prettyDebugLog).toHaveBeenCalledTimes(2); - - const expectedFirstFilter = { size: 10, interval: 10000 }; - const expectedSecondFilter = { size: 2048, interval: 50000 }; - - expect(prettyDebugLog).toHaveBeenNthCalledWith( - 1, - 'Buffer', - '', - expectedFirstFilter, - 'table', - ); - - expect(prettyDebugLog).toHaveBeenNthCalledWith( - 2, - 'Buffer', - '', - expectedSecondFilter, - 'table', - ); - }); - }); -}); diff --git a/src/core/buffer/helpers/handleBufferDebugMode.ts b/src/core/buffer/helpers/handleBufferDebugMode.ts deleted file mode 100644 index 6699780..0000000 --- a/src/core/buffer/helpers/handleBufferDebugMode.ts +++ /dev/null @@ -1,21 +0,0 @@ -import type { BufferConfig, BufferDebugFields } from '../types.js'; -import { prettyDebugLog } from './../../../utils/prettyDebugLog.js'; - -export const handleBufferDebugMode = ( - fields: Record, - bufferConfig: BufferConfig | undefined, -) => { - const isDebugEnabled = bufferConfig?.modes?.debug?.enabled ?? false; - - if (!isDebugEnabled) { - return null; - } - const debugFields = bufferConfig?.modes?.debug?.fields ?? fields; - const displayType = bufferConfig?.modes?.debug?.displayType ?? 'table'; - - const debugLog = Object.fromEntries( - Object.entries(fields).filter(([key]) => debugFields[key as keyof BufferDebugFields]), - ); - - prettyDebugLog('Buffer', '', debugLog, displayType); -}; diff --git a/src/core/buffer/types.ts b/src/core/buffer/types.ts index 6559e6b..0438250 100644 --- a/src/core/buffer/types.ts +++ b/src/core/buffer/types.ts @@ -4,70 +4,19 @@ export interface BufferDebugFields { size: boolean; } -export interface BufferModesConfig { +export type BufferDebugModeConfig = { /** - * 📝 Debug mode for better inspection of logging performance + * 📝 Enable or disable debug mode * - * @default undefined + * 📖 long. * + * 📌@type {'manual' | 'table'} * - * 📦 Usage Example - * - * @example 🧪 Enable debug mode - * ```ts - * debug: { - * enabled: boolean - * } + * @default false * - * ``` - * ### ⚠️ Critical Notes - * - The generated logs are only displayed in the console and are not stored in the database. */ - debug?: { - /** - * 📝 How to display debug logs - * - * 📖 long. - * - * 📌@type {'manual' | 'table'} - * - * @default "table" - * - */ - displayType?: 'manual' | 'table'; - /** - * 📝 Enable or disable debug mode - * - * 📖 long. - * - * 📌@type {'manual' | 'table'} - * - * @default false - * - */ - enabled?: boolean; - /** - * 📝 Select the required fields - * - * 📖 To reduce confusion, you can log only the fields you need. - * - * 📌@type {BufferDebugFields} - * - * @default undefined - * - * - * 📦 Usage Example - * - * @example 🧪 Only the size field is included in the log - * ```ts - * fields:{ - * size: true - * } - * ``` - */ - fields?: Partial; - }; -} + enabled?: boolean; +} | true; export interface BufferConfig { /** @@ -89,10 +38,6 @@ export interface BufferConfig { * */ flushStrategy?: 'realtime' | 'size' | 'time'; - /** - * 📝 Auxiliary side modes - */ - modes?: BufferModesConfig; /** * 📝 Maximum number of logs before injection * diff --git a/src/core/log-builders/collections/helpers/customLoggingHandler/customLoggingHandler.ts b/src/core/log-builders/collections/helpers/customLoggingHandler/customLoggingHandler.ts deleted file mode 100644 index d0108f7..0000000 --- a/src/core/log-builders/collections/helpers/customLoggingHandler/customLoggingHandler.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { emitEvent } from '../../../../events/emitter.js'; -import type { CollectionHooksKeys } from '../../logBuilderManager.js'; -import type { AuditorLog } from '../../../../../collections/auditor.js'; -import type { - HookConfigForTracking, - LogConfig, - PayloadCollectionHooksMap, - PluginConfig, -} from '../../../../../types/pluginOptions.js'; - -interface Params { - - logData: AuditorLog; - hookConfig: HookConfigForTracking[CollectionHooksKeys]; - hookName: CollectionHooksKeys; - operationConfig: LogConfig | undefined; - pluginConfig: PluginConfig; - hookArgs: Parameters[0]; -} - -export const customLoggingHandler = async (params: Params) => { - const customLogging = async (): Promise => { - const { hook, ...otherLogData } = params.logData; - - const result = { - ...params.logData, - ...(await params.pluginConfig.customLogger?.(params.hookArgs, otherLogData)), - // ...(await params.userActivatedHooks?.customLogger?.(params.hookArgs, otherLogData)), - // @ts-expect-error - ...(await params.hookConfig.customLogger?.(params.hookArgs, otherLogData)), - ...(await params.operationConfig?.customLogger?.(params.hookArgs, otherLogData)), - hook: params.logData.hook, - }; - - return result; - }; - - const log = await customLogging(); - - emitEvent('logGenerated', log); -}; diff --git a/src/core/log-builders/collections/helpers/extractOperation/extractOperation.ts b/src/core/log-builders/collections/helpers/extractOperation/extractOperation.ts index d35eccf..959ff4e 100644 --- a/src/core/log-builders/collections/helpers/extractOperation/extractOperation.ts +++ b/src/core/log-builders/collections/helpers/extractOperation/extractOperation.ts @@ -1,8 +1,9 @@ -import type { CollectionHooksArgsParameterUnion, CollectionHooksKeys, CollectionHooksOperation } from '../../logBuilderManager.js'; +import type { GlobalHooksArgsParameterUnion, GlobalHooksKeys } from '../../../../../types/global.js'; +import type { CollectionHooksArgsParameterUnion, CollectionHooksKeys, CollectionHooksOperation } from '../../../../../types/collection.js'; interface Params { - hookArgs: CollectionHooksArgsParameterUnion; - targetHookName: CollectionHooksKeys; + hookArgs: CollectionHooksArgsParameterUnion | GlobalHooksArgsParameterUnion; + targetHookName: CollectionHooksKeys | GlobalHooksKeys; } const regex = /[A-Z]?[a-z]+/g; diff --git a/src/core/log-builders/collections/helpers/handleDebugMode.ts b/src/core/log-builders/collections/helpers/handleDebugMode.ts index 70dc1f0..6422014 100644 --- a/src/core/log-builders/collections/helpers/handleDebugMode.ts +++ b/src/core/log-builders/collections/helpers/handleDebugMode.ts @@ -1,33 +1,29 @@ import type { AuditorLog } from './../../../../collections/auditor.js'; import { prettyDebugLog } from './../../../../utils/prettyDebugLog.js'; -import type { CollectionHooksKeys, CollectionHooksOperation } from '../logBuilderManager.js'; -import type { - HookConfigForTracking, - LogConfig, -} from './../../../../types/pluginOptions.js'; +import type { GlobalHookConfigForTracking, GlobalHooksKeys, GlobalOperationLogConfig } from '../../../../types/global.js'; +import type { CollectionHooksKeys, CollectionHooksOperation, CollectionsHookConfigForTracking } from '../../../../types/collection.js'; -export const handleDebugMode = ( - hookConfig: HookConfigForTracking[T] | undefined, - operationConfig: LogConfig | undefined, - allFields: AuditorLog, - operation: CollectionHooksOperation, -) => { - const hookDebugConfig = hookConfig?.modes?.debug; - const operationDebugConfig = operationConfig?.modes?.debug; - - const isDebugEnabled - = (operationDebugConfig?.enabled ?? false) || (hookDebugConfig?.enabled ?? false); +type Params = { + hookLevelConfig?: CollectionsHookConfigForTracking[CollectionHooksKeys] | GlobalHookConfigForTracking[GlobalHooksKeys]; + operationLevelConfig?: GlobalOperationLogConfig; + logData: AuditorLog; + operation: CollectionHooksOperation; + hookName: CollectionHooksKeys; +}; - if (isDebugEnabled) { - const debugFields = operationDebugConfig?.fields ?? hookDebugConfig?.fields; - const debugDisplayType = operationDebugConfig?.displayType ?? hookDebugConfig?.displayType; +export const handleDebugMode = (params: Params) => { + const hookDebugConfig = typeof params.hookLevelConfig === 'boolean' + ? undefined + : params.hookLevelConfig?.debug; + const operationDebugConfig = params.operationLevelConfig?.debug; - const debugLog = debugFields - ? Object.fromEntries( - Object.entries(allFields).filter(([key]) => debugFields[key as keyof AuditorLog]), - ) - : allFields; + const isDebugEnabled = operationDebugConfig || hookDebugConfig; - prettyDebugLog('afterChange', operation, debugLog, debugDisplayType); + if (isDebugEnabled) { + prettyDebugLog({ + title: params.hookName, + data: params.logData, + subtitle: params.operation, + }); } }; diff --git a/src/core/log-builders/collections/helpers/isOperationEnabled/isOperationEnabled.test.ts b/src/core/log-builders/collections/helpers/isOperationEnabled/isOperationEnabled.test.ts index 84de2e2..07c568a 100644 --- a/src/core/log-builders/collections/helpers/isOperationEnabled/isOperationEnabled.test.ts +++ b/src/core/log-builders/collections/helpers/isOperationEnabled/isOperationEnabled.test.ts @@ -2,18 +2,14 @@ import type { PartialDeep } from 'type-fest'; import { describe, expect, it } from 'vitest'; import { checkIsOperationEnabled } from './isOperationEnabled.js'; -import type { TrackedCollection } from '../../../../../types/pluginOptions.js'; +import type { TrackedCollection } from '../../../../../types/collection.js'; describe('checkIsOperationEnabled', () => { const createPluginConfig = (collectionConfig: PartialDeep): Parameters[0] => { return { - allHooksLevelConfig: collectionConfig.hooks, - // @ts-expect-error hookLevelConfig: collectionConfig.hooks?.afterOperation, // @ts-expect-error hookOperationLevelConfig: collectionConfig.hooks?.afterOperation?.updateByID, - // @ts-expect-error - collectionLevelConfig: collectionConfig, }; }; @@ -39,26 +35,9 @@ describe('checkIsOperationEnabled', () => { expect(configWithEnabled).toEqual(true); }); - it('should return true when explicitly true at the all hooks level', () => { - const configWithEnabled = checkIsOperationEnabled(createPluginConfig({ - hooks: { enabled: true }, - })); - const config = checkIsOperationEnabled(createPluginConfig({ hooks: true })); - - expect(config).toEqual(true); - expect(configWithEnabled).toEqual(true); - }); - - it('should return true when explicitly true at the collection level', () => { - const config = checkIsOperationEnabled(createPluginConfig({ enabled: true })); - - expect(config).toEqual(true); - }); - it('should return false when explicitly false at the operation level', () => { const config = checkIsOperationEnabled(createPluginConfig({ hooks: { - enabled: true, afterOperation: { updateByID: false, }, @@ -66,14 +45,11 @@ describe('checkIsOperationEnabled', () => { })); const configWithEnabled = checkIsOperationEnabled(createPluginConfig({ hooks: { - enabled: true, afterOperation: { updateByID: { enabled: false } }, }, })); const configStrict = checkIsOperationEnabled(createPluginConfig({ - enabled: true, hooks: { - enabled: true, afterOperation: { enabled: true, updateByID: false, @@ -81,9 +57,7 @@ describe('checkIsOperationEnabled', () => { }, })); const configWithEnabledStrict = checkIsOperationEnabled(createPluginConfig({ - enabled: true, hooks: { - enabled: true, afterOperation: { enabled: true, updateByID: { enabled: false }, @@ -100,27 +74,22 @@ describe('checkIsOperationEnabled', () => { it('should return false when explicitly false at the hook level', () => { const config = checkIsOperationEnabled(createPluginConfig({ hooks: { - enabled: true, afterOperation: false, }, })); const configWithEnabled = checkIsOperationEnabled(createPluginConfig({ hooks: { - enabled: true, afterOperation: { enabled: false }, }, })); const configStrict = checkIsOperationEnabled(createPluginConfig({ - enabled: true, hooks: { - enabled: true, afterOperation: false, }, })); const configWithEnabledStrict = checkIsOperationEnabled(createPluginConfig({ hooks: { - enabled: true, afterOperation: { enabled: false, updateByID: true }, }, })); @@ -130,145 +99,4 @@ describe('checkIsOperationEnabled', () => { expect(configStrict).toEqual(false); expect(configWithEnabledStrict).toEqual(false); }); - - it('should return false when explicitly false at the all hooks level', () => { - const allHooksLevelConfig = checkIsOperationEnabled(createPluginConfig({ hooks: false })); - const allHooksLevelConfigWithEnabled = checkIsOperationEnabled(createPluginConfig({ - hooks: { enabled: false }, - })); - const allHooksLevelConfigStrict = checkIsOperationEnabled(createPluginConfig({ - enabled: true, - hooks: false, - })); - const allHooksLevelConfigWithEnabledStrict = checkIsOperationEnabled(createPluginConfig({ - enabled: true, - hooks: { enabled: false }, - })); - - const hookLevelConfig = checkIsOperationEnabled(createPluginConfig({ - hooks: { - enabled: false, - afterOperation: true, - }, - })); - const hookLevelConfigWithEnabled = checkIsOperationEnabled(createPluginConfig({ - hooks: { - enabled: false, - afterOperation: { enabled: true }, - }, - })); - const hookLevelConfigStrict = checkIsOperationEnabled(createPluginConfig({ - enabled: true, - hooks: { - enabled: false, - afterOperation: true, - }, - })); - const hookLevelConfigWithEnabledStrict = checkIsOperationEnabled(createPluginConfig({ - enabled: true, - hooks: { - enabled: false, - afterOperation: { enabled: true }, - }, - })); - - const operationLevelConfig = checkIsOperationEnabled(createPluginConfig({ - hooks: { - enabled: false, - afterOperation: { updateByID: true }, - }, - })); - const operationLevelConfigWithEnabled = checkIsOperationEnabled(createPluginConfig({ - hooks: { - enabled: false, - afterOperation: { updateByID: { enabled: true } }, - }, - })); - const operationLevelConfigStrict = checkIsOperationEnabled(createPluginConfig({ - enabled: true, - hooks: { - enabled: false, - afterOperation: { enabled: true, updateByID: true }, - }, - })); - const operationLevelConfigWithEnabledStrict = checkIsOperationEnabled(createPluginConfig({ - hooks: { - enabled: false, - afterOperation: { enabled: true, updateByID: { enabled: true } }, - }, - })); - - expect(allHooksLevelConfig).toEqual(false); - expect(allHooksLevelConfigWithEnabled).toEqual(false); - expect(hookLevelConfig).toEqual(false); - expect(hookLevelConfigWithEnabled).toEqual(false); - expect(operationLevelConfig).toEqual(false); - expect(operationLevelConfigWithEnabled).toEqual(false); - expect(hookLevelConfigStrict).toEqual(false); - expect(hookLevelConfigWithEnabledStrict).toEqual(false); - expect(operationLevelConfigStrict).toEqual(false); - expect(operationLevelConfigWithEnabledStrict).toEqual(false); - expect(allHooksLevelConfigStrict).toEqual(false); - expect(allHooksLevelConfigWithEnabledStrict).toEqual(false); - }); - - it('should return false when explicitly false at the collection level', () => { - const collectionLevelConfig = checkIsOperationEnabled(createPluginConfig({ enabled: false })); - const allHooksLevelConfig = checkIsOperationEnabled(createPluginConfig({ - enabled: false, - hooks: true, - })); - const allHooksLevelConfigWithEnabled = checkIsOperationEnabled(createPluginConfig({ - enabled: false, - hooks: { enabled: true }, - })); - - const hookLevelConfig = checkIsOperationEnabled(createPluginConfig({ - enabled: false, - hooks: { afterOperation: true }, - })); - const hookLevelConfigWithEnabled = checkIsOperationEnabled(createPluginConfig({ - enabled: false, - hooks: { afterOperation: { enabled: true } }, - })); - - const hookLevelConfigStrict = checkIsOperationEnabled(createPluginConfig({ - enabled: false, - hooks: { enabled: false, afterOperation: true }, - })); - const hookLevelConfigWithEnabledStrict = checkIsOperationEnabled(createPluginConfig({ - enabled: false, - hooks: { enabled: false, afterOperation: { enabled: true } }, - })); - - const operationLevelConfig = checkIsOperationEnabled(createPluginConfig({ - enabled: false, - hooks: { afterOperation: { updateByID: true } }, - })); - const operationLevelConfigWithEnabled = checkIsOperationEnabled(createPluginConfig({ - enabled: false, - hooks: { afterOperation: { updateByID: { enabled: true } } }, - })); - - const operationLevelConfigStrict = checkIsOperationEnabled(createPluginConfig({ - enabled: false, - hooks: { enabled: false, afterOperation: { enabled: false, updateByID: true } }, - })); - const operationLevelConfigWithEnabledStrict = checkIsOperationEnabled(createPluginConfig({ - enabled: false, - hooks: { enabled: false, afterOperation: { enabled: false, updateByID: { enabled: true } } }, - })); - - expect(collectionLevelConfig).toEqual(false); - expect(allHooksLevelConfigWithEnabled).toEqual(false); - expect(allHooksLevelConfig).toEqual(false); - expect(hookLevelConfigWithEnabled).toEqual(false); - expect(hookLevelConfig).toEqual(false); - expect(operationLevelConfig).toEqual(false); - expect(operationLevelConfigWithEnabled).toEqual(false); - expect(hookLevelConfigStrict).toEqual(false); - expect(hookLevelConfigWithEnabledStrict).toEqual(false); - expect(operationLevelConfigStrict).toEqual(false); - expect(operationLevelConfigWithEnabledStrict).toEqual(false); - }); }); diff --git a/src/core/log-builders/collections/helpers/isOperationEnabled/isOperationEnabled.ts b/src/core/log-builders/collections/helpers/isOperationEnabled/isOperationEnabled.ts index 6c74c57..930efb4 100644 --- a/src/core/log-builders/collections/helpers/isOperationEnabled/isOperationEnabled.ts +++ b/src/core/log-builders/collections/helpers/isOperationEnabled/isOperationEnabled.ts @@ -1,14 +1,13 @@ import type { CollectionConfig } from 'payload'; -import type { HookConfigForTracking, LogConfig, TrackedCollection } from '../../../../../types/pluginOptions.js'; +import type { CollectionOperationLogConfig, CollectionsHookConfigForTracking } from '../../../../../types/collection.js'; +import type { GlobalHookConfigForTracking, GlobalHooksKeys, GlobalOperationLogConfig } from '../../../../../types/global.js'; type CollectionHooksKeys = keyof NonNullable; interface Params { - hookOperationLevelConfig?: LogConfig | true; - hookLevelConfig?: HookConfigForTracking[CollectionHooksKeys]; - allHooksLevelConfig: TrackedCollection['hooks']; - collectionLevelConfig: TrackedCollection; + hookOperationLevelConfig?: CollectionOperationLogConfig | GlobalOperationLogConfig | true; + hookLevelConfig?: CollectionsHookConfigForTracking[CollectionHooksKeys] | GlobalHookConfigForTracking[GlobalHooksKeys]; } export const isBooleanConfig = (v: T): boolean | undefined => typeof v === 'boolean' @@ -18,16 +17,8 @@ export const isBooleanConfig = (v: T): boolean | undefined => typeof v === 'b export const checkIsOperationEnabled = (params: Params): boolean => { const hookLevelEnabled = isBooleanConfig(params.hookLevelConfig); - const allHooksLevelConfigEnabled = isBooleanConfig(params.allHooksLevelConfig); const operationLevelEnabled = isBooleanConfig(params.hookOperationLevelConfig); - return params.collectionLevelConfig.enabled !== false - && (operationLevelEnabled !== false) - && (hookLevelEnabled !== false) - && (allHooksLevelConfigEnabled !== false) - && !!( - params.collectionLevelConfig.enabled - || operationLevelEnabled - || hookLevelEnabled - || allHooksLevelConfigEnabled); + return (operationLevelEnabled !== false) && (hookLevelEnabled !== false) + && !!(operationLevelEnabled || hookLevelEnabled); }; diff --git a/src/core/log-builders/collections/logBuilderManager.ts b/src/core/log-builders/collections/logBuilderManager.ts deleted file mode 100644 index 7c37ef2..0000000 --- a/src/core/log-builders/collections/logBuilderManager.ts +++ /dev/null @@ -1,66 +0,0 @@ -import type { AllOperations, CollectionConfig } from 'payload'; - -import type { AuditorLog } from '../../../collections/auditor.js'; -import { extractOperation } from './helpers/extractOperation/extractOperation.js'; -import { checkIsOperationEnabled } from './helpers/isOperationEnabled/isOperationEnabled.js'; -import { customLoggingHandler } from './helpers/customLoggingHandler/customLoggingHandler.js'; -import type { - HookConfigForTracking, - LogConfig, - PluginConfig, - TrackedCollection, -} from '../../../types/pluginOptions.js'; - -export type CollectionHooksKeys = keyof NonNullable; -export type CollectionHooksOperation = AllOperations | 'read' | 'delete' | 'error' | 'login' | 'logout' | 'me' | 'refresh' | 'forgotPassword' | ''; - -export type CollectionHooksArgsParameterUnion = Parameters< - NonNullable< - NonNullable< - CollectionConfig['hooks'] - >[CollectionHooksKeys] - >[number] ->[0]; - -type LogBuilderManager = { - hookArgs: CollectionHooksArgsParameterUnion; - pluginConfig: PluginConfig; - targetHookName: CollectionHooksKeys; - targetHookLevelConfig: HookConfigForTracking[CollectionHooksKeys]; - allHooksLevelConfig: TrackedCollection['hooks']; - collectionConfig: TrackedCollection; - collectionSlug: string; -}; - -export const logBuilderManager = async (params: LogBuilderManager) => { - const operation = extractOperation(params); - // @ts-expect-error - const hookOperationLevelConfig = params - .targetHookLevelConfig?.[operation] as LogConfig | undefined; - const isOperationEnabled = checkIsOperationEnabled({ - hookLevelConfig: params.targetHookLevelConfig, - hookOperationLevelConfig, - allHooksLevelConfig: params.allHooksLevelConfig, - collectionLevelConfig: params.collectionConfig, - }); - - const baseLog: AuditorLog = { - onCollection: params.collectionSlug, - hook: params.targetHookName, - operation, - timestamp: new Date(), - // @ts-expect-error - userAgent: params.hookArgs.req.headers.get('user-agent') || 'unknown', - }; - - if (isOperationEnabled) { - await customLoggingHandler({ - hookName: params.targetHookName, - pluginConfig: params.pluginConfig, - hookArgs: params.hookArgs, - hookConfig: params.targetHookLevelConfig, - logData: baseLog, - operationConfig: hookOperationLevelConfig, - }); - } -}; diff --git a/src/core/log-builders/collections/logBuilderManager/logBuilderManager.test.ts b/src/core/log-builders/collections/logBuilderManager/logBuilderManager.test.ts new file mode 100644 index 0000000..52cb52a --- /dev/null +++ b/src/core/log-builders/collections/logBuilderManager/logBuilderManager.test.ts @@ -0,0 +1,65 @@ +import { beforeEach, describe, expect, it, vi } from 'vitest'; + +import { emitEvent } from './../../../events/emitter.js'; +import { logBuilderManager } from './logBuilderManager.js'; +import type { LogBuilderManager } from './logBuilderManager.js'; +import type { TrackedCollection } from '../../../../types/collection.js'; +import type { PluginConfig } from './../../../../types/pluginOptions.js'; + +vi.mock('./../../../events/emitter.js', () => ({ + emitEvent: vi.fn(), +})); + +const createPlugin = (hookLevelConfig: TrackedCollection['hooks']): PluginConfig => ({ + collections: { track: [{ slug: 'user-collection', hooks: hookLevelConfig }] }, +}); + +const createCollectionLogBuilderParams = (pluginConfig: PluginConfig): LogBuilderManager => ({ + scopeSlug: 'collection', + identifier: 'user-collection', + // @ts-expect-error + hookArgs: { + operation: 'updateByID', + collection: 'user-collection', + req: { headers: { get: () => 'unknown' } }, + }, + pluginConfig, + targetHookLevelConfig: pluginConfig.collections?.track[0].hooks?.afterOperation, + targetHookName: 'afterOperation', +}); + +describe('logBuilderManager', () => { + beforeEach(() => vi.clearAllMocks()); + it('should correct hook name', async () => { + const pluginConfigDebugMode = createPlugin({ afterOperation: { updateByID: { enabled: true } } }); + const builderParams = createCollectionLogBuilderParams(pluginConfigDebugMode); + await logBuilderManager(builderParams); + + expect(emitEvent).toHaveBeenCalledWith('logGenerated', { + operation: 'updateByID', + onCollection: 'user-collection', + hook: 'afterOperation', + userAgent: 'unknown', + timestamp: expect.any(Date), + }); + expect(emitEvent).toHaveBeenCalledTimes(1); + }); + + it('should skip save to database when debug mode is active with skipDatabaseSave flag', () => { + const pluginConfigDebugModeWithFlag = createPlugin({ afterOperation: { + debug: { skipDatabaseSave: true }, + } }); + const builderParams = createCollectionLogBuilderParams(pluginConfigDebugModeWithFlag); + logBuilderManager(builderParams); + expect(emitEvent).toHaveBeenCalledTimes(0); + }); + + it('should skip save to database when debug mode is active', () => { + const pluginConfigDebugMode = createPlugin({ afterOperation: { debug: true } }); + const builderParams = createCollectionLogBuilderParams(pluginConfigDebugMode); + + logBuilderManager(builderParams); + + expect(emitEvent).toHaveBeenCalledTimes(0); + }); +}); diff --git a/src/core/log-builders/collections/logBuilderManager/logBuilderManager.ts b/src/core/log-builders/collections/logBuilderManager/logBuilderManager.ts new file mode 100644 index 0000000..712cc77 --- /dev/null +++ b/src/core/log-builders/collections/logBuilderManager/logBuilderManager.ts @@ -0,0 +1,80 @@ +import { emitEvent } from '../../../events/emitter.js'; +import { handleDebugMode } from '../helpers/handleDebugMode.js'; +import type { AuditorLog } from '../../../../collections/auditor.js'; +import type { + PluginConfig, +} from '../../../../types/pluginOptions.js'; +import { extractOperation } from '../helpers/extractOperation/extractOperation.js'; +import { checkIsOperationEnabled } from '../helpers/isOperationEnabled/isOperationEnabled.js'; +import type { GlobalHookConfigForTracking, GlobalHooksArgsParameterUnion, GlobalHooksKeys, GlobalOperationLogConfig } from '../../../../types/global.js'; +import type { CollectionHooksArgsParameterUnion, CollectionHooksKeys, CollectionOperationLogConfig, CollectionsHookConfigForTracking } from '../../../../types/collection.js'; + +export type LogBuilderManager = { + hookArgs: CollectionHooksArgsParameterUnion | GlobalHooksArgsParameterUnion; + pluginConfig: PluginConfig; + targetHookName: CollectionHooksKeys; + targetHookLevelConfig: CollectionsHookConfigForTracking[CollectionHooksKeys] | GlobalHookConfigForTracking[GlobalHooksKeys]; + scopeSlug: AuditorLog['scope']; + identifier: string; +}; + +export const logBuilderManager = async (params: LogBuilderManager) => { + const operation = extractOperation(params); + // @ts-expect-error + const hookOperationLevelConfig = params + .targetHookLevelConfig?.[operation] as CollectionOperationLogConfig | GlobalOperationLogConfig | undefined; + const hookLevelConfig = typeof params.targetHookLevelConfig === 'boolean' + ? undefined + : params.targetHookLevelConfig; + const isOperationEnabled = checkIsOperationEnabled({ + hookLevelConfig: params.targetHookLevelConfig, + hookOperationLevelConfig, + }); + + const baseLog: AuditorLog = { + scope: params.scopeSlug, + hook: params.targetHookName, + identifier: params.identifier, + operation, + timestamp: new Date(), + // @ts-expect-error + userAgent: params.hookArgs.req.headers.get('user-agent') || 'unknown', + }; + + if (isOperationEnabled) { + const { hook, operation, ...otherLogData } = baseLog; + const customLogData = { + ...baseLog, + ...(await hookLevelConfig?.customLogger?.( + // @ts-expect-error + params.hookArgs, + otherLogData, + )), + ...(await hookOperationLevelConfig?.customLogger?.( + // @ts-expect-error + params.hookArgs, + otherLogData, + )), + hook, + operation, + } as AuditorLog; + + const skipToDatabase = hookLevelConfig?.debug === true + || hookLevelConfig?.debug?.skipDatabaseSave + || hookOperationLevelConfig?.debug === true + || hookOperationLevelConfig?.debug?.skipDatabaseSave; + + if (!skipToDatabase) { + emitEvent('logGenerated', customLogData); + } + + handleDebugMode({ + logData: customLogData, + hookLevelConfig: params.targetHookLevelConfig, + hookName: params.targetHookName, + operation, + // @ts-expect-error + operationLevelConfig: hookOperationLevelConfig, + }); + } +}; diff --git a/src/index.ts b/src/index.ts index 92ca03a..c8e279d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,36 +1,54 @@ import type { Config, Plugin } from 'payload'; +import { auditor } from './collections/auditor.js'; import type { PluginConfig } from './types/pluginOptions.js'; +import { onInitManager } from './pluginUtils/configHelpers.js'; import { cleanupLogsTask } from './core/automation/tasks/cleanup/cleanup.js'; -import { - attachCollectionConfig, - onInitManager, -} from './pluginUtils/configHelpers.js'; +import { attachGlobalConfig } from './pluginUtils/attachGlobalConfig/attachGlobalConfig.js'; +import { attachCollectionConfig } from './pluginUtils/attachCollectionConfig/attachCollectionConfig.js'; /** * 📝 The main function of plugin packaging * * - * 📌@type {(opts?: PluginOptions) => Plugin} + * 📌@type {(pluginConfig?: PluginConfig) => Plugin} * - * @param opts + * @param pluginConfig * */ export const auditorPlugin - = (opts: PluginConfig): Plugin => - async (incomingConfig: Config): Promise => { - const config = { ...incomingConfig }; - if (opts.enabled === false) { - return config; + = (pluginConfig: PluginConfig): Plugin => + async (payloadConfig: Config): Promise => { + if (pluginConfig.disabled === true) { + return payloadConfig; } + const config = { ...payloadConfig }; - config.collections = attachCollectionConfig(config.collections, opts); + const updatedCollection = pluginConfig.configureRootCollection?.(auditor) ?? auditor; + + config.collections = attachCollectionConfig(config.collections, pluginConfig); + config.globals = attachGlobalConfig(config.globals, pluginConfig); + + config.collections = [ + ...(config?.collections ?? []), + updatedCollection, + ]; config.jobs = { ...config.jobs, - tasks: [...(config.jobs?.tasks ?? []), cleanupLogsTask(opts)], + tasks: [ + ...(config.jobs?.tasks ?? []), + cleanupLogsTask({ + pluginConfig, + internalCollectionConfig: updatedCollection, + }), + ], }; - config.onInit = onInitManager(config, opts); + config.onInit = onInitManager({ + payloadConfig: config, + internalCollectionConfig: updatedCollection, + pluginConfig, + }); return config; }; diff --git a/src/pluginUtils/attachCollectionConfig/attachCollectionConfig.ts b/src/pluginUtils/attachCollectionConfig/attachCollectionConfig.ts new file mode 100644 index 0000000..caf6cf9 --- /dev/null +++ b/src/pluginUtils/attachCollectionConfig/attachCollectionConfig.ts @@ -0,0 +1,47 @@ +import type { Config } from 'payload'; + +import type { PluginConfig } from '../../types/pluginOptions.js'; +import type { CollectionHooksKeys } from '../../types/collection.js'; + +export const attachCollectionConfig = ( + userCollectionsConfig: Config['collections'], + pluginOpts: PluginConfig, +) => { + const pluginCollectionsConfig = pluginOpts.collections; + + const trackedCollections = pluginCollectionsConfig?.track ?? []; + + // Attaching Log Builders + if (trackedCollections.length) { + userCollectionsConfig = (userCollectionsConfig || []).map((collection) => { + const trackedCollectionConfig = pluginCollectionsConfig?.track.find( + tc => tc.slug === collection.slug, + ); + + if (trackedCollectionConfig?.hooks) { + collection.hooks = collection.hooks ?? {}; + + for (const hookName in trackedCollectionConfig?.hooks) { + const typedHookName = hookName as CollectionHooksKeys; + // @ts-expect-error + collection.hooks[typedHookName] = [ + ...(collection.hooks?.[typedHookName] || []), + // @ts-ignore + async args => logBuilderManager({ + scopeSlug: 'collection', + hookArgs: args, + pluginConfig: pluginOpts, + targetHookLevelConfig: trackedCollectionConfig.hooks?.[typedHookName], + targetHookName: typedHookName, + identifier: collection.slug, + }), + ]; + } + } + + return collection; + }); + } + + return userCollectionsConfig ?? []; +}; diff --git a/src/pluginUtils/attachGlobalConfig/attachGlobalConfig.ts b/src/pluginUtils/attachGlobalConfig/attachGlobalConfig.ts new file mode 100644 index 0000000..e9f818a --- /dev/null +++ b/src/pluginUtils/attachGlobalConfig/attachGlobalConfig.ts @@ -0,0 +1,53 @@ +import type { Config } from 'payload'; + +import type { GlobalHooksKeys } from '../../types/global.js'; +import type { PluginConfig } from '../../types/pluginOptions.js'; +import { logBuilderManager } from '../../core/log-builders/collections/logBuilderManager/logBuilderManager.js'; + +export const attachGlobalConfig = ( + userGlobalConfig: Config['globals'], + pluginOpts: PluginConfig, +) => { + const pluginGlobalsConfig = pluginOpts.globals; + if (!pluginGlobalsConfig) { + return userGlobalConfig; + } + + const trackedGlobals = pluginGlobalsConfig.track ?? []; + + // Attaching Log Builders + if (trackedGlobals.length) { + userGlobalConfig = (userGlobalConfig || []).map((global) => { + const tracked = pluginGlobalsConfig.track.find( + tc => tc.slug === global.slug, + ); + + if (tracked) { + global.hooks = global.hooks || {}; + + if (tracked?.hooks) { + for (const hookName in tracked?.hooks) { + const typedHookName = hookName as GlobalHooksKeys; + // @ts-expect-error + global.hooks[typedHookName] = [ + ...(global.hooks[typedHookName] || []), + // @ts-ignore + async args => logBuilderManager({ + scopeSlug: 'collection', + hookArgs: args, + pluginConfig: pluginOpts, + targetHookLevelConfig: tracked.hooks?.[typedHookName], + targetHookName: typedHookName, + identifier: global.slug, + }), + ]; + } + } + } + + return global; + }); + } + + return userGlobalConfig ?? []; +}; diff --git a/src/pluginUtils/configHelpers.ts b/src/pluginUtils/configHelpers.ts index 056e478..261c68d 100644 --- a/src/pluginUtils/configHelpers.ts +++ b/src/pluginUtils/configHelpers.ts @@ -1,93 +1,29 @@ -import type { BasePayload, Config } from 'payload'; +import type { BasePayload, CollectionConfig, Config } from 'payload'; -import auditor from '../collections/auditor.js'; import type { PluginConfig } from './../types/pluginOptions.js'; import { bufferManager } from './../core/buffer/bufferManager.js'; import { DEFAULT_QUEUE_NAME } from '../core/automation/tasks/cleanup/cleanup.js'; -import { logBuilderManager } from '../core/log-builders/collections/logBuilderManager.js'; -import type { CollectionHooksKeys } from '../core/log-builders/collections/logBuilderManager.js'; -export const attachCollectionConfig = ( - userCollectionsConfig: Config['collections'], - pluginOpts: PluginConfig, -) => { - const pluginCollectionsConfig = pluginOpts.collection; - if (!pluginCollectionsConfig) { - return userCollectionsConfig; - } - - const trackedCollections = pluginCollectionsConfig.track ?? []; - - // Attaching Log Builders - if (trackedCollections.length) { - userCollectionsConfig = (userCollectionsConfig || []).map((collection) => { - const tracked = pluginCollectionsConfig.track.find( - tc => tc.slug === collection.slug, - ); - - if (tracked && tracked.enabled) { - collection.hooks = collection.hooks || {}; - - if (tracked?.hooks) { - if (typeof tracked.hooks === 'boolean') { - for (const hook in collection.hooks) { - - } - } - else { - for (const hookName in tracked?.hooks) { - const typedHookName = hookName as CollectionHooksKeys; - // @ts-expect-error - collection.hooks[typedHookName] = [ - ...(collection.hooks[typedHookName] || []), - // @ts-ignore - async args => logBuilderManager({ - collectionSlug: collection.slug, - hookArgs: args, - pluginConfig: pluginOpts, - targetHookLevelConfig: tracked.hooks?.[typedHookName], - targetHookName: typedHookName, - allHooksLevelConfig: tracked.hooks, - }), - ]; - } - } - } - } - - return collection; - }); - } - - // add root collection to payload config - const rootCollection = pluginCollectionsConfig.configureRootCollection - ? { - ...auditor, - ...pluginCollectionsConfig.configureRootCollection(auditor), - } - : auditor; - - userCollectionsConfig = [ - ...(userCollectionsConfig || []), - rootCollection, - ]; - - // Attaching settings to plugin's internal collection hooks - return userCollectionsConfig; +type OnInitManagerParams = { + payloadConfig: Config; + pluginConfig: PluginConfig; + internalCollectionConfig: CollectionConfig; }; -export const onInitManager = (incomingConfig: Config, pluginOptions: PluginConfig) => { - const originalOnInit = incomingConfig.onInit; +export const onInitManager = (params: OnInitManagerParams) => { + const originalOnInit = params.payloadConfig.onInit; + const bufferConfig = params.pluginConfig.buffer; + const internalCollectionConfig = params.internalCollectionConfig; return async (payload: BasePayload) => { if (originalOnInit) { await originalOnInit(payload); } - bufferManager(payload, pluginOptions); + bufferManager({ payload, bufferConfig, internalCollectionConfig }); let autoRun = payload.config.jobs?.autoRun ?? []; - const queueName = pluginOptions.automation?.logCleanup?.queueName ?? DEFAULT_QUEUE_NAME; + const queueName = params.pluginConfig.automation?.logCleanup?.queueName ?? DEFAULT_QUEUE_NAME; if (Array.isArray(autoRun)) { autoRun = [...(autoRun ?? []), { queue: queueName }]; } diff --git a/src/types/collection.ts b/src/types/collection.ts new file mode 100644 index 0000000..0355052 --- /dev/null +++ b/src/types/collection.ts @@ -0,0 +1,70 @@ +import type { AllOperations, CollectionConfig } from 'payload'; + +import type { AuditorLog } from '../collections/auditor.js'; + +export type OperationDebugConfig = { + skipDatabaseSave?: boolean; +} | true; + +export type CollectionHookDebugConfig = { + skipDatabaseSave?: true; +} | true; + +export type CollectionHooksKeys = keyof NonNullable; +export type CollectionHooksOperation = AllOperations | 'read' | 'delete' | 'error' | 'login' | 'logout' | 'me' | 'refresh' | 'forgotPassword' | ''; +export type CollectionHooksArgsParameterUnion = Parameters< + NonNullable< + NonNullable< + CollectionConfig['hooks'] + >[CollectionHooksKeys] + >[number] +>[0]; + +export type PayloadCollectionHooksMap = { + [K in CollectionHooksKeys]: NonNullable[K]>[number] +}; +export type CollectionsHookConfigForTracking = { + [K in keyof NonNullable]: + Partial< + { + // @ts-expect-error + [O in Parameters< + NonNullable< + NonNullable< + CollectionConfig['hooks'] + >[K] + >[number] + >[0]['operation']]: CollectionOperationLogConfig | boolean + } & CollectionHookLevelLogConfig + > | boolean +}; + +export interface CollectionOperationLogConfig< + HookName extends CollectionHooksKeys = CollectionHooksKeys, +> { + customLogger?: ( + args: Parameters[0], + fields: Omit, + ) => Omit | Promise>; + enabled?: boolean; + debug?: OperationDebugConfig; +} + +export interface CollectionHookLevelLogConfig< + HookName extends CollectionHooksKeys = CollectionHooksKeys, +> { + customLogger?: ( + args: Parameters[0], + fields: Omit, + ) => Omit | Promise>; + enabled?: boolean; + debug?: CollectionHookDebugConfig; +} + +export interface TrackedCollection { + hooks?: Partial; + slug: string; +} +export interface CollectionsTrackConfig { + track: TrackedCollection[]; +} diff --git a/src/types/global.ts b/src/types/global.ts new file mode 100644 index 0000000..cb75291 --- /dev/null +++ b/src/types/global.ts @@ -0,0 +1,67 @@ +import type { GlobalConfig } from 'payload'; + +import type { AuditorLog } from '../collections/auditor.js'; +import type { CollectionHookDebugConfig } from './collection.js'; + +export type GlobalHooksKeys = keyof NonNullable; + +export type GlobalOperationDebugConfig = { + skipDatabaseSave?: boolean; +} | true; + +export type GlobalHookConfigForTracking = { + [K in keyof NonNullable]: + Partial< + { + // @ts-expect-error + [O in Parameters< + NonNullable< + NonNullable< + GlobalConfig['hooks'] + >[K] + >[number] + >[0]['operation']]: GlobalOperationLogConfig | boolean + } & GlobalHookLevelLogConfig + > | boolean +}; + +export interface GlobalOperationLogConfig< + HookName extends GlobalHooksKeys = GlobalHooksKeys, +> { + customLogger?: ( + args: Parameters[HookName]>[number]>[0], + fields: Omit, + ) => Omit | Promise>; + enabled?: boolean; + debug?: GlobalOperationDebugConfig; +} + +export interface GlobalHookLevelLogConfig< + HookName extends GlobalHooksKeys = GlobalHooksKeys, +> { + customLogger?: ( + args: Parameters[HookName]>[number]>[0], + fields: Omit, + ) => Omit + | Promise>; + enabled?: boolean; + debug?: GlobalHookDebugConfig; +} + +export type GlobalHookDebugConfig = CollectionHookDebugConfig; +export interface TrackedGlobal { + hooks?: Partial; + slug: string; +} + +export interface GlobalsTrackConfig { + track: TrackedGlobal[]; +} + +export type GlobalHooksArgsParameterUnion = Parameters< + NonNullable< + NonNullable< + GlobalConfig['hooks'] + >[GlobalHooksKeys] + >[number] +>[0]; diff --git a/src/types/pluginOptions.ts b/src/types/pluginOptions.ts index 416fe77..a739cf9 100644 --- a/src/types/pluginOptions.ts +++ b/src/types/pluginOptions.ts @@ -1,356 +1,11 @@ import type { CollectionConfig, - LabelFunction, - StaticLabel, } from 'payload'; +import type { GlobalsTrackConfig } from './global.js'; +import type { auditor } from './../collections/auditor.js'; import type { BufferConfig } from '../core/buffer/types.js'; -import type { AuditorLog } from './../collections/auditor.js'; -import type { CollectionHooksKeys } from '../core/log-builders/collections/logBuilderManager.js'; - -export type PayloadCollectionHooksMap = { - [K in CollectionHooksKeys]: NonNullable[K]>[number] -}; - -export type HookConfigForTracking = { - [K in keyof NonNullable]: - Partial< - { - // @ts-expect-error - [O in Parameters< - NonNullable< - NonNullable< - CollectionConfig['hooks'] - >[K] - >[number] - >[0]['operation']]: LogConfig | boolean - } & LogConfig - > | boolean - -}; - -export interface HookOperationDebugModeConfig { - /** - * 📝 How to display debug logs - * - * 📖 long. - * - * 📌@type {'manual' | 'table'} - * - * @default "table" - * - * ``` - * - * ``` - * - * --- - * - * ### ⚠️ Critical Notes - * - The timeStamp field is not displayed in the table type - * - */ - displayType?: 'manual' | 'table'; - /** - * 📝 Enable or disable debug mode - * - * 📖 long. - * - * 📌@type {'manual' | 'table'} - * - * @default false - * - * ``` - * - * ``` - * - * --- - * - * ### ⚠️ Critical Notes - * - The timeStamp field is not displayed in the table type - * - */ - enabled?: boolean; - /** - * 📝 Select the required fields - * - * 📖 To reduce confusion, you can log only the fields you need. - * - * 📌@type {Partial>} - * - * @default undefined - * - * - * 📦 Usage Example - * - * @example 🧪 Only the true field is included in the log - * ```ts - * fields:{ - * type:true - * } - * ``` - * - */ - fields?: Partial>; -} - -export interface HookModesConfig { - /** - * 📝 Debug mode for better inspection of logging performance - * - * @default undefined - * - * - * 📦 Usage Example - * - * @example 🧪 Enable debug mode - * ```ts - * debug: { - * enabled: boolean - * } - * - * ``` - * ### ⚠️ Critical Notes - * - The generated logs are only displayed in the console and are not stored in the database. - */ - debug?: HookOperationDebugModeConfig; -} - -export interface LogConfig< - HookName extends CollectionHooksKeys = CollectionHooksKeys, -> { - /** - * 📝 Custom log creation at a operation level - * - * @default undefined - * - * - * 📦 Usage Example - * - * @example 🧪 Change the user value for the create operation - * ```ts - * create: { - * customLogger: (args, fields) => { - * return { ...fields, user: null } - * }, - * enabled: true, - * }, - * ``` - * - * --- - * ### ⚠️ Critical Notes - * - Only works for the current operation - * - Has the highest priority in execution - */ - customLogger?: ( - args: Parameters[0], - fields: Omit, - ) => Omit | Promise>; - /** - * 📝 Specifies whether logging is enabled or disabled for this operation within the hook - * - * 📌@type {boolean} - * - * @default undefined - * - * - * 📦 Usage Example - * - * @example 🧪 Activating the create operation - * ```ts - * create: { - * enabled: true, - * }, - * ``` - * - * --- - * ### ⚠️ Critical Notes - * - If the enabled value is not entered, it is considered false. - * - */ - enabled?: boolean; - - /** - * 📝 Auxiliary side modes - * - * - - */ - modes?: HookModesConfig; -} - -export interface TrackedCollection { - /** - * 📝 Globally disable tracking for this collection - * - * 📌@type {boolean} - * - * @default undefined - * - */ - enabled?: boolean; - - /** - * 📝 Define payload cms hooks for each collection being tracked - * - * - * 📌@type {Partial} - * - * @default undefined - * - * - * 📦 Usage Example - * - * @example 🧪 Define an afterChange hook for a collection - * ```ts - * hooks: { afterChange: { create: { enabled: true } } } - * ``` - * - * --- - * ### ⚠️ Critical Notes - * - Each hook performs only its own operations - * - Authentication hooks are only triggered when authentication is enabled for the collection - * - * Read more: - * @see {@link https://payloadcms.com/docs/hooks/collections} - */ - hooks?: (LogConfig & Partial) | boolean; - /** Optional label or description for UI/doc */ - label?: string; - - /** - * 📝 The original name of your collection for tracking - * - * 📌@type {string} - * - * @default undefined - * - * - * 📦 Usage Example - * - * @example 🧪 Collection tracking posts - * ```ts - * { slug: 'posts' }, - * ``` - * - * --- - * ### ⚠️ Critical Notes - * - Make sure the value entered exactly matches the value in your main collection configuration. - * @see {@link https://payloadcms.com/docs/configuration/collections#config-options} - */ - slug: string; -} - -export interface Localization { - collection?: { - fields?: Partial>; - }; -} -export interface PluginCollectionConfig { - /** - * 📝 Buffer management for injecting data into the database - * - * - * - * @default undefined - * - * - * 📦 Usage Example - * - * @example 🧪 Data Injection into Database Based on Time - * ```ts - * buffer: { - * flushStrategy: 'time', - * } - * ``` - * - * --- - * ## ⚠️ Critical Notes - * - These settings are very important, to change these settings, consider all aspects including RAM and server power. - * - */ - buffer?: BufferConfig; - /** - * 📝 Collection main configuration - * - * You can fully customize the entire root collection - * - * 📌@type {TypedRootCollection} - * - * @default undefined - * - * @example 🧪 Rename the slug, add a new field, and change the collection label - * - *```ts - * rootCollectionConfig: (defaults) => { - * const prevConf = defaults - * return { - * ...prevConf, - * slug: 'new slug', - * fields: [ - * ...prevConf.fields, - * { - * name: 'product', - * type: 'text', - * }, - * ], - * labels: { - * plural: 'logs', - * singular: 'log', - * }, - * } - * }, - *``` - * --- - * ### ⚠️ Critical Notes - * - Changing collection values requires a lot of testing to make sure everything works correctly - * - In each property, either change all the values or use the default values of the same property (which is for the plugin itself) in the context, otherwise you will encounter an error - * ```ts - * rootCollectionConfig: (defaults) => { - * const prevConf = defaults - * return { - * ...prevConf, - * slug: 'new slug', - * hooks:{ - * ...prevConf.hooks, - * // your hooks ... - * } - * } - * }, - * ``` - */ - configureRootCollection?: (defaults?: CollectionConfig) => Partial; - /** - * 📝 Collection tracking management - * - * 📖 You should define the collections you want to track in this section. - * You can specify which hook each collection should use and what operations (within each hook) should generate logs. - * - * 📌@type {TrackedCollection[]} - * - * @default [] - * - * - * - * 📦 Usage Example - * - * @example 🧪 Track post collections when a new post is created - * ```ts - * trackCollections: [ - * { slug: 'posts', hooks: { afterChange: { create: { enabled: true } } } }, - * ], - * ``` - * @example 🧪 Temporarily disable tracking for a collection - * ```ts - * trackCollections: [ - * { slug: 'slug', disabled: true, hooks: { afterChange: { create: { enabled: true } } } }, - * ], - * ``` - * --- - * ### ⚠️ Critical Notes - * - To temporarily disable tracking for any collection, you can use the disabled key. - * - */ - track: TrackedCollection[]; -} +import type { CollectionsTrackConfig } from './collection.js'; export interface AutomationConfig { logCleanup?: { @@ -388,85 +43,10 @@ export interface AutomationConfig { } export interface PluginConfig { - /** - * 📝 Automatic plugin process management - * - * - * 📌@type {AutomationConfig} - * - * @default undefined - * - * - * 📦 Usage Example - * - * @example 🧪 Setting a strategy for the log cleaner - * ``` - * - * automation:{ - * logCleanup: { - * strategy: "time" - * } - * } - * - *``` - */ automation?: AutomationConfig; - - /** - * 📝 Settings related to collections and the collection used by the plugin - * - * 📌@type {CollectionConfig} - * - * @default undefined - * - * - * 📦 Usage Example - * - * @example 🧪 Media collection tracking - * ```ts - * trackCollections: [ - * { slug: 'media', hooks: { afterChange: { update: { enabled: true } } } }, - * ], - * ``` - * - * --- - * #### ⚠️ Critical Notes - * - If defined, you must also enter the value of trackCollections. - * - */ - collection: PluginCollectionConfig; - /** - * 📝 Custom log creation at a global level - * - * @default undefined - * - * - * 📦 Usage Example - * - * @example 🧪 Change the userAgent value for all operations - * ```ts - * customLogger: (args, fields) => { - * return { ...fields, userAgent: 'custom user agent' } - * } - * ``` - * - * --- - * ### ⚠️ Critical Notes - * - Only works for active operations - * - This function is only executed for all operations and hooks that do not have a dedicated customLogger - * - It works for both collection hooks and globals hooks - */ - customLogger?: ( - args: Parameters[0], - fields: Omit, - ) => Omit | Promise>; - - /** - * 📝 Enable or disable the plugin - * - * 📌@type {boolean} - * - * @default "true" - */ - enabled?: boolean; + collections?: CollectionsTrackConfig; + buffer?: BufferConfig; + configureRootCollection?: (defaults: typeof auditor) => CollectionConfig; + globals?: GlobalsTrackConfig; + disabled?: boolean; } diff --git a/src/utils/prettyDebugLog.ts b/src/utils/prettyDebugLog.ts index a535468..8b97ca4 100644 --- a/src/utils/prettyDebugLog.ts +++ b/src/utils/prettyDebugLog.ts @@ -2,34 +2,26 @@ import type { LiteralUnion } from 'type-fest'; -import type { CollectionHooksKeys, CollectionHooksOperation } from '../core/log-builders/collections/logBuilderManager.js'; +import type { GlobalHooksKeys } from '../types/global.js'; +import type { CollectionHooksKeys, CollectionHooksOperation } from '../types/collection.js'; -export const prettyDebugLog = ( - title: LiteralUnion, - subtitle: LiteralUnion, - data: Record, - type: 'manual' | 'table' = 'table', -) => { - if (!data || Object.keys(data).length === 0) { +type Params = { + title: LiteralUnion; + subtitle: LiteralUnion; + data: Record; +}; + +export const prettyDebugLog = (params: Params) => { + if (!params.data || Object.keys(params.data).length === 0) { console.log('%cNo data to display', 'color: #888; font-style: italic;'); } else { - if (type === 'table') { - console.groupCollapsed( - `| %c🔍 Debug Log - ${title} [${subtitle}]`, - 'color: #007acc; font-weight: bold; font-size: 14px;', - ); - console.table(data); - console.groupEnd(); - } - else if (type === 'manual') { - console.log('-----------------------------------------'); - console.log(`| %c🔍 Debug Log - ${title} ${subtitle && `[${subtitle}]`} |`); - console.log('-----------------------------------------'); - for (const [key, value] of Object.entries(data)) { - console.log(`|- %c${key}:`, 'color: #666; font-weight: 600;', value); - } - console.log('-------------------------------------------'); + console.log('-----------------------------------------'); + console.log(`| %c🔍 Debug Log - ${params.title} ${params.subtitle && `[${params.subtitle}]`} |`); + console.log('-----------------------------------------'); + for (const [key, value] of Object.entries(params.data)) { + console.log(`|- %c${key}:`, 'color: #666; font-weight: 600;', value); } + console.log('-------------------------------------------'); } }; From ab79f438361f500f7dc29ab3b7a24a173e8977ea Mon Sep 17 00:00:00 2001 From: shaadcode Date: Thu, 23 Jul 2026 17:06:09 +0330 Subject: [PATCH 7/8] chore: final tests --- dev/.env.example | 1 + dev/payload.config.ts | 10 +- package.json | 6 +- .../automation/tasks/cleanup/cleanup.test.ts | 38 ++--- src/core/automation/tasks/cleanup/cleanup.ts | 2 +- src/core/buffer/bufferManager.test.ts | 14 +- .../logBuilderManager.test.ts | 65 ------- .../extractOperation/extractOperation.ts | 4 +- .../helpers/handleDebugMode.ts | 8 +- .../isOperationEnabled.test.ts | 2 +- .../isOperationEnabled/isOperationEnabled.ts | 4 +- .../logBuilderManager.test.ts | 159 ++++++++++++++++++ .../logBuilderManager/logBuilderManager.ts | 12 +- src/index.ts | 2 +- .../attachCollectionConfig.ts | 3 +- .../attachGlobalConfig/attachGlobalConfig.ts | 4 +- src/pluginUtils/configHelpers.ts | 2 +- src/types/collection.ts | 4 +- src/types/{pluginOptions.ts => config.ts} | 2 +- src/types/global.ts | 4 +- 20 files changed, 218 insertions(+), 128 deletions(-) delete mode 100644 src/core/log-builders/collections/logBuilderManager/logBuilderManager.test.ts rename src/core/log-builders/{collections => }/helpers/extractOperation/extractOperation.ts (85%) rename src/core/log-builders/{collections => }/helpers/handleDebugMode.ts (76%) rename src/core/log-builders/{collections => }/helpers/isOperationEnabled/isOperationEnabled.test.ts (97%) rename src/core/log-builders/{collections => }/helpers/isOperationEnabled/isOperationEnabled.ts (89%) create mode 100644 src/core/log-builders/logBuilderManager/logBuilderManager.test.ts rename src/core/log-builders/{collections => }/logBuilderManager/logBuilderManager.ts (90%) rename src/types/{pluginOptions.ts => config.ts} (96%) diff --git a/dev/.env.example b/dev/.env.example index 5319688..036695c 100644 --- a/dev/.env.example +++ b/dev/.env.example @@ -1,2 +1,3 @@ DATABASE_URI= PAYLOAD_SECRET= +USE_HTTPS=true diff --git a/dev/payload.config.ts b/dev/payload.config.ts index 5699924..02dbcb7 100644 --- a/dev/payload.config.ts +++ b/dev/payload.config.ts @@ -11,8 +11,9 @@ import { lexicalEditor } from '@payloadcms/richtext-lexical'; import { navigation } from './globals/Nav.js'; import { media } from './collections/Media.js'; import { users } from './collections/Users.js'; -// import { auditorPlugin } from './../dist/index.js'; -import { auditorPlugin } from '../src/index.js'; +// eslint-disable-next-line antfu/no-import-dist +import { auditorPlugin } from './../dist/index.js'; +// import { auditorPlugin } from '../src/index.js'; import { testEmailAdapter } from './helpers/testEmailAdapter.js'; const filename = fileURLToPath(import.meta.url); @@ -23,9 +24,12 @@ if (!process.env.ROOT_DIR) { } export default buildConfig({ - admin: { importMap: { baseDir: path.resolve(dirname) } }, + admin: { importMap: { baseDir: path.resolve(dirname) }, + + }, collections: [media, users], globals: [navigation], + db: mongooseAdapter({ url: process.env.DATABASE_URI || '', connectOptions: { diff --git a/package.json b/package.json index 609936e..090421f 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "node": ">=24" }, "scripts": { - "build:safe": "npm run test && npm run check-types && npm run lint && npm run copyfiles && npm run build:types && npm run build:swc", + "build:safe": "npm run test:unit && npm run check-types && npm run lint && npm run copyfiles && npm run build:types && npm run build:swc", "build:swc": "swc ./src -d ./dist --config-file .swcrc --strip-leading-paths", "build": "npm run copyfiles && npm run build:types && npm run build:swc", "build:types": "tsc --outDir dist --rootDir ./src", @@ -76,8 +76,8 @@ "commit": "cz", "sync-main": "git fetch origin main && git rebase origin/main", "sync-main:fork": "git fetch upstream main && git rebase upstream/main", - "release": "release-it --config .release-it.ts", - "pre-release": "release-it --config .release-it.prerelease.ts --preRelease=beta" + "release": "release-it --config .release-it.ts --ci", + "pre-release": "release-it --config .release-it.prerelease.ts --preReleaseBase=1 --ci" }, "peerDependencies": { "payload": "^3.76.1" diff --git a/src/core/automation/tasks/cleanup/cleanup.test.ts b/src/core/automation/tasks/cleanup/cleanup.test.ts index 4e6d1eb..5c2915a 100644 --- a/src/core/automation/tasks/cleanup/cleanup.test.ts +++ b/src/core/automation/tasks/cleanup/cleanup.test.ts @@ -2,7 +2,7 @@ import type { TaskConfig } from 'payload'; import { beforeEach, describe, expect, it, vi } from 'vitest'; import { auditor } from '../../../../collections/auditor.js'; -import type { PluginConfig } from '../../../../types/pluginOptions.js'; +import type { PluginConfig } from '../../../../types/config.js'; import { CLEANUP_TASK_LABEL, CLEANUP_TASK_SLUG, cleanupLogsTask, DEFAULT_CRON_TIME, DEFAULT_OLDER_THAN, DEFAULT_QUEUE_NAME } from './cleanup.js'; const mockPluginConfig = { @@ -73,15 +73,15 @@ describe('cleanupLogsTask', () => { }); it('should use configureRootCollection result when provided', async () => { - const configuredSlug = 'configured-audit-logs'; const pluginConfig: PluginConfig = { - configureRootCollection: vi.fn().mockReturnValue({ slug: configuredSlug }), + configureRootCollection: vi.fn().mockReturnValue({ slug: auditor.slug }), collections: { track: [], }, }; const task = cleanupLogsTask({ internalCollectionConfig: auditor, pluginConfig }); + typeof task.handler === 'function' && await task .handler({ // @ts-expect-error @@ -89,14 +89,14 @@ describe('cleanupLogsTask', () => { }); expect(mockReq.payload.delete).toHaveBeenCalledWith({ - collection: configuredSlug, + collection: auditor.slug, where: expect.any(Object), }); }); it('should use custom olderThan value', async () => { const customOlderThan = 86400000; // 1 day - const pluginOptions: PluginConfig = { + const pluginConfig: PluginConfig = { automation: { logCleanup: { olderThan: customOlderThan, @@ -104,15 +104,12 @@ describe('cleanupLogsTask', () => { }, }; - // @ts-expect-error - const task = cleanupLogsTask(pluginOptions); + const task = cleanupLogsTask({ internalCollectionConfig: auditor, pluginConfig }); typeof task.handler === 'function' && await task.handler({ // @ts-expect-error req: mockReq, }); - const expectedDate = new Date(Date.now() - customOlderThan).toISOString(); - expect(mockReq.payload.delete).toHaveBeenCalledWith({ collection: 'Audit-log', where: { @@ -124,13 +121,12 @@ describe('cleanupLogsTask', () => { const callArgs = mockReq.payload.delete.mock.calls[0][0]; const lessThanValue = callArgs.where.createdAt.less_than; - expect(lessThanValue).toBe(expectedDate); + expect(lessThanValue).toEqual(expect.any(String)); }); it('should return empty output object', async () => { - const pluginOptions: Partial = {}; - // @ts-expect-error - const task = cleanupLogsTask(pluginOptions); + const pluginConfig: Partial = {}; + const task = cleanupLogsTask({ internalCollectionConfig: auditor, pluginConfig }); const result = typeof task.handler === 'function' && await task.handler({ // @ts-expect-error @@ -144,9 +140,8 @@ describe('cleanupLogsTask', () => { const mockError = new Error('Database connection failed'); mockReq.payload.delete.mockRejectedValueOnce(mockError); - const pluginOptions: Partial = {}; - // @ts-expect-error - const task = cleanupLogsTask(pluginOptions); + const pluginConfig: Partial = {}; + const task = cleanupLogsTask({ internalCollectionConfig: auditor, pluginConfig }); typeof task.handler === 'function' && await task.handler({ // @ts-expect-error @@ -162,9 +157,8 @@ describe('cleanupLogsTask', () => { it('should not throw error when payload.delete fails', async () => { mockReq.payload.delete.mockRejectedValueOnce(new Error('Database error')); - const pluginOptions: Partial = {}; - // @ts-expect-error - const task = cleanupLogsTask(pluginOptions); + const pluginConfig: Partial = {}; + const task = cleanupLogsTask({ internalCollectionConfig: auditor, pluginConfig }); await expect( typeof task.handler === 'function' && task.handler({ @@ -177,9 +171,9 @@ describe('cleanupLogsTask', () => { it('should log error with correct message', async () => { mockReq.payload.delete.mockRejectedValueOnce(new Error('Any error')); - const pluginOptions: Partial = {}; - // @ts-expect-error - const task = cleanupLogsTask(pluginOptions); + const pluginConfig: Partial = {}; + + const task = cleanupLogsTask({ internalCollectionConfig: auditor, pluginConfig }); typeof task.handler === 'function' && await task.handler({ // @ts-expect-error diff --git a/src/core/automation/tasks/cleanup/cleanup.ts b/src/core/automation/tasks/cleanup/cleanup.ts index d848a4c..fbf42d3 100644 --- a/src/core/automation/tasks/cleanup/cleanup.ts +++ b/src/core/automation/tasks/cleanup/cleanup.ts @@ -1,6 +1,6 @@ import type { CollectionConfig, TaskConfig } from 'payload'; -import type { PluginConfig } from '../../../../types/pluginOptions.js'; +import type { PluginConfig } from '../../../../types/config.js'; export const DEFAULT_OLDER_THAN = 604800000; // 1 week export const DEFAULT_CRON_TIME = '0 3 * * *'; // At 03:00 AM diff --git a/src/core/buffer/bufferManager.test.ts b/src/core/buffer/bufferManager.test.ts index 3381978..0f348d8 100644 --- a/src/core/buffer/bufferManager.test.ts +++ b/src/core/buffer/bufferManager.test.ts @@ -2,8 +2,8 @@ import type { Mock } from 'vitest'; import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; import { auditor } from '../../collections/auditor.js'; +import type { PluginConfig } from '../../types/config.js'; import { onEventLog } from './../../core/events/emitter.js'; -import type { PluginConfig } from '../../types/pluginOptions.js'; import { bufferManager, bufferStore } from './../../core/buffer/bufferManager.js'; vi.mock('../../core/events/emitter.ts', () => ({ @@ -120,14 +120,12 @@ describe('bufferManager', () => { }); it('should clear buffer store after flushing by size', async () => { - const pluginOptions = { - collection: { - buffer: { - flushStrategy: 'size', - size: 2, - }, + const pluginOptions: PluginConfig = { + buffer: { + flushStrategy: 'size', + size: 2, }, - } as unknown as PluginConfig; + }; bufferManager({ payload: mockPayload as any, bufferConfig: pluginOptions.buffer, diff --git a/src/core/log-builders/collections/logBuilderManager/logBuilderManager.test.ts b/src/core/log-builders/collections/logBuilderManager/logBuilderManager.test.ts deleted file mode 100644 index 52cb52a..0000000 --- a/src/core/log-builders/collections/logBuilderManager/logBuilderManager.test.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { beforeEach, describe, expect, it, vi } from 'vitest'; - -import { emitEvent } from './../../../events/emitter.js'; -import { logBuilderManager } from './logBuilderManager.js'; -import type { LogBuilderManager } from './logBuilderManager.js'; -import type { TrackedCollection } from '../../../../types/collection.js'; -import type { PluginConfig } from './../../../../types/pluginOptions.js'; - -vi.mock('./../../../events/emitter.js', () => ({ - emitEvent: vi.fn(), -})); - -const createPlugin = (hookLevelConfig: TrackedCollection['hooks']): PluginConfig => ({ - collections: { track: [{ slug: 'user-collection', hooks: hookLevelConfig }] }, -}); - -const createCollectionLogBuilderParams = (pluginConfig: PluginConfig): LogBuilderManager => ({ - scopeSlug: 'collection', - identifier: 'user-collection', - // @ts-expect-error - hookArgs: { - operation: 'updateByID', - collection: 'user-collection', - req: { headers: { get: () => 'unknown' } }, - }, - pluginConfig, - targetHookLevelConfig: pluginConfig.collections?.track[0].hooks?.afterOperation, - targetHookName: 'afterOperation', -}); - -describe('logBuilderManager', () => { - beforeEach(() => vi.clearAllMocks()); - it('should correct hook name', async () => { - const pluginConfigDebugMode = createPlugin({ afterOperation: { updateByID: { enabled: true } } }); - const builderParams = createCollectionLogBuilderParams(pluginConfigDebugMode); - await logBuilderManager(builderParams); - - expect(emitEvent).toHaveBeenCalledWith('logGenerated', { - operation: 'updateByID', - onCollection: 'user-collection', - hook: 'afterOperation', - userAgent: 'unknown', - timestamp: expect.any(Date), - }); - expect(emitEvent).toHaveBeenCalledTimes(1); - }); - - it('should skip save to database when debug mode is active with skipDatabaseSave flag', () => { - const pluginConfigDebugModeWithFlag = createPlugin({ afterOperation: { - debug: { skipDatabaseSave: true }, - } }); - const builderParams = createCollectionLogBuilderParams(pluginConfigDebugModeWithFlag); - logBuilderManager(builderParams); - expect(emitEvent).toHaveBeenCalledTimes(0); - }); - - it('should skip save to database when debug mode is active', () => { - const pluginConfigDebugMode = createPlugin({ afterOperation: { debug: true } }); - const builderParams = createCollectionLogBuilderParams(pluginConfigDebugMode); - - logBuilderManager(builderParams); - - expect(emitEvent).toHaveBeenCalledTimes(0); - }); -}); diff --git a/src/core/log-builders/collections/helpers/extractOperation/extractOperation.ts b/src/core/log-builders/helpers/extractOperation/extractOperation.ts similarity index 85% rename from src/core/log-builders/collections/helpers/extractOperation/extractOperation.ts rename to src/core/log-builders/helpers/extractOperation/extractOperation.ts index 959ff4e..9e7570c 100644 --- a/src/core/log-builders/collections/helpers/extractOperation/extractOperation.ts +++ b/src/core/log-builders/helpers/extractOperation/extractOperation.ts @@ -1,5 +1,5 @@ -import type { GlobalHooksArgsParameterUnion, GlobalHooksKeys } from '../../../../../types/global.js'; -import type { CollectionHooksArgsParameterUnion, CollectionHooksKeys, CollectionHooksOperation } from '../../../../../types/collection.js'; +import type { GlobalHooksArgsParameterUnion, GlobalHooksKeys } from '../../../../types/global.js'; +import type { CollectionHooksArgsParameterUnion, CollectionHooksKeys, CollectionHooksOperation } from '../../../../types/collection.js'; interface Params { hookArgs: CollectionHooksArgsParameterUnion | GlobalHooksArgsParameterUnion; diff --git a/src/core/log-builders/collections/helpers/handleDebugMode.ts b/src/core/log-builders/helpers/handleDebugMode.ts similarity index 76% rename from src/core/log-builders/collections/helpers/handleDebugMode.ts rename to src/core/log-builders/helpers/handleDebugMode.ts index 6422014..f84907c 100644 --- a/src/core/log-builders/collections/helpers/handleDebugMode.ts +++ b/src/core/log-builders/helpers/handleDebugMode.ts @@ -1,7 +1,7 @@ -import type { AuditorLog } from './../../../../collections/auditor.js'; -import { prettyDebugLog } from './../../../../utils/prettyDebugLog.js'; -import type { GlobalHookConfigForTracking, GlobalHooksKeys, GlobalOperationLogConfig } from '../../../../types/global.js'; -import type { CollectionHooksKeys, CollectionHooksOperation, CollectionsHookConfigForTracking } from '../../../../types/collection.js'; +import type { AuditorLog } from '../../../collections/auditor.js'; +import { prettyDebugLog } from '../../../utils/prettyDebugLog.js'; +import type { GlobalHookConfigForTracking, GlobalHooksKeys, GlobalOperationLogConfig } from '../../../types/global.js'; +import type { CollectionHooksKeys, CollectionHooksOperation, CollectionsHookConfigForTracking } from '../../../types/collection.js'; type Params = { hookLevelConfig?: CollectionsHookConfigForTracking[CollectionHooksKeys] | GlobalHookConfigForTracking[GlobalHooksKeys]; diff --git a/src/core/log-builders/collections/helpers/isOperationEnabled/isOperationEnabled.test.ts b/src/core/log-builders/helpers/isOperationEnabled/isOperationEnabled.test.ts similarity index 97% rename from src/core/log-builders/collections/helpers/isOperationEnabled/isOperationEnabled.test.ts rename to src/core/log-builders/helpers/isOperationEnabled/isOperationEnabled.test.ts index 07c568a..ac51a44 100644 --- a/src/core/log-builders/collections/helpers/isOperationEnabled/isOperationEnabled.test.ts +++ b/src/core/log-builders/helpers/isOperationEnabled/isOperationEnabled.test.ts @@ -2,7 +2,7 @@ import type { PartialDeep } from 'type-fest'; import { describe, expect, it } from 'vitest'; import { checkIsOperationEnabled } from './isOperationEnabled.js'; -import type { TrackedCollection } from '../../../../../types/collection.js'; +import type { TrackedCollection } from '../../../../types/collection.js'; describe('checkIsOperationEnabled', () => { const createPluginConfig = (collectionConfig: PartialDeep): Parameters[0] => { diff --git a/src/core/log-builders/collections/helpers/isOperationEnabled/isOperationEnabled.ts b/src/core/log-builders/helpers/isOperationEnabled/isOperationEnabled.ts similarity index 89% rename from src/core/log-builders/collections/helpers/isOperationEnabled/isOperationEnabled.ts rename to src/core/log-builders/helpers/isOperationEnabled/isOperationEnabled.ts index 930efb4..26d5c7b 100644 --- a/src/core/log-builders/collections/helpers/isOperationEnabled/isOperationEnabled.ts +++ b/src/core/log-builders/helpers/isOperationEnabled/isOperationEnabled.ts @@ -1,7 +1,7 @@ import type { CollectionConfig } from 'payload'; -import type { CollectionOperationLogConfig, CollectionsHookConfigForTracking } from '../../../../../types/collection.js'; -import type { GlobalHookConfigForTracking, GlobalHooksKeys, GlobalOperationLogConfig } from '../../../../../types/global.js'; +import type { CollectionOperationLogConfig, CollectionsHookConfigForTracking } from '../../../../types/collection.js'; +import type { GlobalHookConfigForTracking, GlobalHooksKeys, GlobalOperationLogConfig } from '../../../../types/global.js'; type CollectionHooksKeys = keyof NonNullable; diff --git a/src/core/log-builders/logBuilderManager/logBuilderManager.test.ts b/src/core/log-builders/logBuilderManager/logBuilderManager.test.ts new file mode 100644 index 0000000..1d99cde --- /dev/null +++ b/src/core/log-builders/logBuilderManager/logBuilderManager.test.ts @@ -0,0 +1,159 @@ +import { beforeEach, describe, expect, it, vi } from 'vitest'; + +import { emitEvent } from '../../events/emitter.js'; +import { logBuilderManager } from './logBuilderManager.js'; +import type { PluginConfig } from '../../../types/config.js'; +import type { TrackedGlobal } from '../../../types/global.js'; +import type { LogBuilderManager } from './logBuilderManager.js'; +import type { TrackedCollection } from '../../../types/collection.js'; + +vi.mock('./../../events/emitter.js', () => ({ + emitEvent: vi.fn(), +})); + +const createPluginConfig = (hookLevelConfig: TrackedCollection['hooks'] | TrackedGlobal['hooks']): PluginConfig => ({ + // @ts-expect-error + collections: { track: [{ slug: 'user-collection', hooks: hookLevelConfig }] }, + // @ts-expect-error + globals: { track: [{ slug: 'user-global', hooks: hookLevelConfig }] }, +}); + +const createCollectionLogBuilderParams = (pluginConfig: PluginConfig): LogBuilderManager => ({ + scopeSlug: 'collection', + identifier: 'user-collection', + // @ts-expect-error + hookArgs: { + operation: 'updateByID', + collection: 'user-collection', + req: { headers: { get: () => 'unknown' } }, + }, + pluginConfig, + targetHookLevelConfig: pluginConfig.collections?.track[0].hooks?.afterOperation, + targetHookName: 'afterOperation', +}); + +const createGlobalLogBuilderParams = (pluginConfig: PluginConfig): LogBuilderManager => ({ + scopeSlug: 'global', + identifier: 'user-global', + // @ts-expect-error + hookArgs: { + operation: 'updateByID', + global: 'user-global', + req: { headers: { get: () => 'unknown' } }, + }, + pluginConfig, + targetHookLevelConfig: pluginConfig.collections?.track[0].hooks?.afterOperation, + targetHookName: 'afterOperation', +}); + +describe('logBuilderManager', () => { + beforeEach(() => vi.clearAllMocks()); + + describe('collections', () => { + it('should emit logGenerated event for collection scope with enabled afterOperation hook', async () => { + const pluginConfigDebugMode = createPluginConfig({ afterOperation: { updateByID: { enabled: true } } }); + const builderParams = createCollectionLogBuilderParams(pluginConfigDebugMode); + await logBuilderManager(builderParams); + + expect(emitEvent).toHaveBeenCalledWith('logGenerated', { + operation: 'updateByID', + identifier: 'user-collection', + hook: 'afterOperation', + scope: 'collection', + userAgent: 'unknown', + timestamp: expect.any(Date), + }); + expect(emitEvent).toHaveBeenCalledTimes(1); + }); + + it('should skip save to database when debug mode is active with skipDatabaseSave flag', () => { + const pluginConfigDebugModeWithFlag = createPluginConfig({ afterOperation: { + debug: { skipDatabaseSave: true }, + } }); + const builderParams = createCollectionLogBuilderParams(pluginConfigDebugModeWithFlag); + logBuilderManager(builderParams); + expect(emitEvent).toHaveBeenCalledTimes(0); + }); + + it('should skip save to database when debug mode is active', () => { + const pluginConfigDebugMode = createPluginConfig({ afterOperation: { debug: true } }); + const builderParams = createCollectionLogBuilderParams(pluginConfigDebugMode); + + logBuilderManager(builderParams); + + expect(emitEvent).toHaveBeenCalledTimes(0); + }); + + it('should not emit logGenerated when operation is disabled for collection', () => { + const pluginConfigDebugMode = createPluginConfig({ afterOperation: { updateByID: false } }); + const builderParams = createCollectionLogBuilderParams(pluginConfigDebugMode); + + logBuilderManager(builderParams); + + expect(emitEvent).toHaveBeenCalledTimes(0); + }); + + it('should not emit logGenerated when hook is disabled for global', () => { + const pluginConfig = createPluginConfig({ afterOperation: false }); + const builderParams = createCollectionLogBuilderParams(pluginConfig); + + logBuilderManager(builderParams); + + expect(emitEvent).toHaveBeenCalledTimes(0); + }); + }); + + describe('globals', () => { + it('should emit logGenerated event for global scope with enabled afterOperation hook', async () => { + const pluginConfig = createPluginConfig({ afterOperation: { updateByID: { enabled: true } } }); + const builderParams = createGlobalLogBuilderParams(pluginConfig); + await logBuilderManager(builderParams); + + expect(emitEvent).toHaveBeenCalledWith('logGenerated', { + operation: 'updateByID', + identifier: 'user-global', + hook: 'afterOperation', + scope: 'global', + userAgent: 'unknown', + timestamp: expect.any(Date), + }); + expect(emitEvent).toHaveBeenCalledTimes(1); + }); + + it('should skip save to database when debug mode is active with skipDatabaseSave flag', () => { + const pluginConfigDebugModeWithFlag = createPluginConfig({ afterOperation: { + debug: { skipDatabaseSave: true }, + } }); + const builderParams = createGlobalLogBuilderParams(pluginConfigDebugModeWithFlag); + logBuilderManager(builderParams); + expect(emitEvent).toHaveBeenCalledTimes(0); + }); + + it('should skip save to database when debug mode is active', () => { + const pluginConfigDebugMode = createPluginConfig({ afterOperation: { debug: true } }); + const builderParams = createGlobalLogBuilderParams(pluginConfigDebugMode); + + logBuilderManager(builderParams); + + expect(emitEvent).toHaveBeenCalledTimes(0); + }); + + it('should not emit logGenerated when operation is disabled for global', () => { + const pluginConfig = createPluginConfig({ afterOperation: { updateByID: false } }); + const builderParams = createGlobalLogBuilderParams(pluginConfig); + + logBuilderManager(builderParams); + + expect(emitEvent).toHaveBeenCalledTimes(0); + }); + + it('should not emit logGenerated when hook is disabled for global', () => { + const pluginConfig = createPluginConfig({ afterOperation: false }); + const builderParams = createGlobalLogBuilderParams(pluginConfig); + + logBuilderManager(builderParams); + + expect(emitEvent).toHaveBeenCalledTimes(0); + }); + }); +}); diff --git a/src/core/log-builders/collections/logBuilderManager/logBuilderManager.ts b/src/core/log-builders/logBuilderManager/logBuilderManager.ts similarity index 90% rename from src/core/log-builders/collections/logBuilderManager/logBuilderManager.ts rename to src/core/log-builders/logBuilderManager/logBuilderManager.ts index 712cc77..9b836dc 100644 --- a/src/core/log-builders/collections/logBuilderManager/logBuilderManager.ts +++ b/src/core/log-builders/logBuilderManager/logBuilderManager.ts @@ -1,13 +1,11 @@ -import { emitEvent } from '../../../events/emitter.js'; +import { emitEvent } from '../../events/emitter.js'; +import type { PluginConfig } from '../../../types/config.js'; import { handleDebugMode } from '../helpers/handleDebugMode.js'; -import type { AuditorLog } from '../../../../collections/auditor.js'; -import type { - PluginConfig, -} from '../../../../types/pluginOptions.js'; +import type { AuditorLog } from '../../../collections/auditor.js'; import { extractOperation } from '../helpers/extractOperation/extractOperation.js'; import { checkIsOperationEnabled } from '../helpers/isOperationEnabled/isOperationEnabled.js'; -import type { GlobalHookConfigForTracking, GlobalHooksArgsParameterUnion, GlobalHooksKeys, GlobalOperationLogConfig } from '../../../../types/global.js'; -import type { CollectionHooksArgsParameterUnion, CollectionHooksKeys, CollectionOperationLogConfig, CollectionsHookConfigForTracking } from '../../../../types/collection.js'; +import type { GlobalHookConfigForTracking, GlobalHooksArgsParameterUnion, GlobalHooksKeys, GlobalOperationLogConfig } from '../../../types/global.js'; +import type { CollectionHooksArgsParameterUnion, CollectionHooksKeys, CollectionOperationLogConfig, CollectionsHookConfigForTracking } from '../../../types/collection.js'; export type LogBuilderManager = { hookArgs: CollectionHooksArgsParameterUnion | GlobalHooksArgsParameterUnion; diff --git a/src/index.ts b/src/index.ts index c8e279d..d383847 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,7 +1,7 @@ import type { Config, Plugin } from 'payload'; import { auditor } from './collections/auditor.js'; -import type { PluginConfig } from './types/pluginOptions.js'; +import type { PluginConfig } from './types/config.js'; import { onInitManager } from './pluginUtils/configHelpers.js'; import { cleanupLogsTask } from './core/automation/tasks/cleanup/cleanup.js'; import { attachGlobalConfig } from './pluginUtils/attachGlobalConfig/attachGlobalConfig.js'; diff --git a/src/pluginUtils/attachCollectionConfig/attachCollectionConfig.ts b/src/pluginUtils/attachCollectionConfig/attachCollectionConfig.ts index caf6cf9..9e8a8b4 100644 --- a/src/pluginUtils/attachCollectionConfig/attachCollectionConfig.ts +++ b/src/pluginUtils/attachCollectionConfig/attachCollectionConfig.ts @@ -1,7 +1,8 @@ import type { Config } from 'payload'; -import type { PluginConfig } from '../../types/pluginOptions.js'; +import type { PluginConfig } from '../../types/config.js'; import type { CollectionHooksKeys } from '../../types/collection.js'; +import { logBuilderManager } from '../../core/log-builders/logBuilderManager/logBuilderManager.js'; export const attachCollectionConfig = ( userCollectionsConfig: Config['collections'], diff --git a/src/pluginUtils/attachGlobalConfig/attachGlobalConfig.ts b/src/pluginUtils/attachGlobalConfig/attachGlobalConfig.ts index e9f818a..5979d24 100644 --- a/src/pluginUtils/attachGlobalConfig/attachGlobalConfig.ts +++ b/src/pluginUtils/attachGlobalConfig/attachGlobalConfig.ts @@ -1,8 +1,8 @@ import type { Config } from 'payload'; +import type { PluginConfig } from '../../types/config.js'; import type { GlobalHooksKeys } from '../../types/global.js'; -import type { PluginConfig } from '../../types/pluginOptions.js'; -import { logBuilderManager } from '../../core/log-builders/collections/logBuilderManager/logBuilderManager.js'; +import { logBuilderManager } from '../../core/log-builders/logBuilderManager/logBuilderManager.js'; export const attachGlobalConfig = ( userGlobalConfig: Config['globals'], diff --git a/src/pluginUtils/configHelpers.ts b/src/pluginUtils/configHelpers.ts index 261c68d..382e710 100644 --- a/src/pluginUtils/configHelpers.ts +++ b/src/pluginUtils/configHelpers.ts @@ -1,6 +1,6 @@ import type { BasePayload, CollectionConfig, Config } from 'payload'; -import type { PluginConfig } from './../types/pluginOptions.js'; +import type { PluginConfig } from '../types/config.js'; import { bufferManager } from './../core/buffer/bufferManager.js'; import { DEFAULT_QUEUE_NAME } from '../core/automation/tasks/cleanup/cleanup.js'; diff --git a/src/types/collection.ts b/src/types/collection.ts index 0355052..f46e48b 100644 --- a/src/types/collection.ts +++ b/src/types/collection.ts @@ -1,4 +1,4 @@ -import type { AllOperations, CollectionConfig } from 'payload'; +import type { AllOperations, CollectionConfig, PayloadTypes } from 'payload'; import type { AuditorLog } from '../collections/auditor.js'; @@ -63,7 +63,7 @@ export interface CollectionHookLevelLogConfig< export interface TrackedCollection { hooks?: Partial; - slug: string; + slug: keyof PayloadTypes['collections']; } export interface CollectionsTrackConfig { track: TrackedCollection[]; diff --git a/src/types/pluginOptions.ts b/src/types/config.ts similarity index 96% rename from src/types/pluginOptions.ts rename to src/types/config.ts index a739cf9..0abf942 100644 --- a/src/types/pluginOptions.ts +++ b/src/types/config.ts @@ -3,7 +3,7 @@ import type { } from 'payload'; import type { GlobalsTrackConfig } from './global.js'; -import type { auditor } from './../collections/auditor.js'; +import type { auditor } from '../collections/auditor.js'; import type { BufferConfig } from '../core/buffer/types.js'; import type { CollectionsTrackConfig } from './collection.js'; diff --git a/src/types/global.ts b/src/types/global.ts index cb75291..26ae63b 100644 --- a/src/types/global.ts +++ b/src/types/global.ts @@ -1,4 +1,4 @@ -import type { GlobalConfig } from 'payload'; +import type { GlobalConfig, PayloadTypes } from 'payload'; import type { AuditorLog } from '../collections/auditor.js'; import type { CollectionHookDebugConfig } from './collection.js'; @@ -51,7 +51,7 @@ export interface GlobalHookLevelLogConfig< export type GlobalHookDebugConfig = CollectionHookDebugConfig; export interface TrackedGlobal { hooks?: Partial; - slug: string; + slug: keyof PayloadTypes['globals']; } export interface GlobalsTrackConfig { From 133e38dfac9f047a1f342dca6cbd17d571c6aa7c Mon Sep 17 00:00:00 2001 From: shaadcode Date: Thu, 23 Jul 2026 17:09:12 +0330 Subject: [PATCH 8/8] fix: Release workflow must run on the main branch --- .release-it.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.release-it.ts b/.release-it.ts index b3f3e46..e5dcb86 100644 --- a/.release-it.ts +++ b/.release-it.ts @@ -14,7 +14,7 @@ function getCommitAuthor(commitHash: string): string { } export default { git: { - // requireBranch: "main" + requireBranch: "main" }, hooks: { "before:init": ["git pull"],