diff options
Diffstat (limited to 'frontend')
174 files changed, 23282 insertions, 0 deletions
diff --git a/frontend/.eslintignore b/frontend/.eslintignore new file mode 100644 index 0000000..fb4d584 --- /dev/null +++ b/frontend/.eslintignore @@ -0,0 +1,16 @@ +.DS_Store +node_modules +/build +/.svelte-kit +/package +.env +.env.* +!.env.example +/coverage + +# Ignore files for PNPM, NPM and YARN +pnpm-lock.yaml +package-lock.json +yarn.lock + +/src/gql
\ No newline at end of file diff --git a/frontend/.eslintrc.cjs b/frontend/.eslintrc.cjs new file mode 100644 index 0000000..c204ebe --- /dev/null +++ b/frontend/.eslintrc.cjs @@ -0,0 +1,49 @@ +module.exports = { + root: true, + extends: [ + 'eslint:recommended', + 'plugin:@typescript-eslint/recommended-type-checked', + 'plugin:@typescript-eslint/stylistic-type-checked', + 'plugin:svelte/recommended', + 'prettier' + ], + parser: '@typescript-eslint/parser', + plugins: ['@typescript-eslint'], + ignorePatterns: ['*.cjs'], + parserOptions: { + sourceType: 'module', + ecmaVersion: 2022, + extraFileExtensions: ['.svelte'], + project: true, + tsconfigRootDir: __dirname + }, + env: { + browser: true, + es2022: true, + node: true + }, + overrides: [ + { + files: ['*.svelte'], + parser: 'svelte-eslint-parser', + parserOptions: { + parser: '@typescript-eslint/parser' + }, + rules: { + '@typescript-eslint/no-unsafe-argument': 'off', + '@typescript-eslint/no-unsafe-assignment': 'off', + '@typescript-eslint/no-unsafe-call': 'off', + '@typescript-eslint/no-unsafe-enum-comparison': 'off', + '@typescript-eslint/no-unsafe-member-access': 'off' + } + }, + { + files: ['codegen.ts', 'svelte.config.js'], + extends: ['plugin:@typescript-eslint/disable-type-checked'] + } + ], + rules: { + 'no-console': 'warn', + eqeqeq: 'error' + } +}; diff --git a/frontend/.gitignore b/frontend/.gitignore new file mode 100644 index 0000000..99658b4 --- /dev/null +++ b/frontend/.gitignore @@ -0,0 +1,13 @@ +/objects +/coverage + +.DS_Store +node_modules +/build +/.svelte-kit +/package +.env +.env.* +!.env.example +vite.config.js.timestamp-* +vite.config.ts.timestamp-* diff --git a/frontend/.npmrc b/frontend/.npmrc new file mode 100644 index 0000000..b6f27f1 --- /dev/null +++ b/frontend/.npmrc @@ -0,0 +1 @@ +engine-strict=true diff --git a/frontend/.prettierignore b/frontend/.prettierignore new file mode 100644 index 0000000..b5ba723 --- /dev/null +++ b/frontend/.prettierignore @@ -0,0 +1,15 @@ +.DS_Store +node_modules +/build +/.svelte-kit +/package +.env +.env.* +!.env.example + +# Ignore files for PNPM, NPM and YARN +pnpm-lock.yaml +package-lock.json +yarn.lock + +/src/gql/graphql.ts
\ No newline at end of file diff --git a/frontend/.prettierrc b/frontend/.prettierrc new file mode 100644 index 0000000..ee7cc95 --- /dev/null +++ b/frontend/.prettierrc @@ -0,0 +1,7 @@ +{ + "useTabs": true, + "singleQuote": true, + "trailingComma": "none", + "printWidth": 100, + "plugins": ["prettier-plugin-svelte", "prettier-plugin-tailwindcss"] +} diff --git a/frontend/.vscode/settings.json b/frontend/.vscode/settings.json new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/frontend/.vscode/settings.json @@ -0,0 +1 @@ +{} diff --git a/frontend/codegen.ts b/frontend/codegen.ts new file mode 100644 index 0000000..42bc8be --- /dev/null +++ b/frontend/codegen.ts @@ -0,0 +1,20 @@ +import type { CodegenConfig } from '@graphql-codegen/cli'; + +const config: CodegenConfig = { + schema: 'http://[::]:8000/graphql', + documents: 'operations.graphql', + generates: { + './src/gql/graphql.ts': { + plugins: ['typescript', 'typescript-operations', 'typed-document-node'] + } + }, + config: { + useTypeImports: true, + documentMode: 'documentNode', + scalars: { + Date: 'string', + DateTime: 'string' + } + } +}; +export default config; diff --git a/frontend/operations.graphql b/frontend/operations.graphql new file mode 100644 index 0000000..5c41080 --- /dev/null +++ b/frontend/operations.graphql @@ -0,0 +1,696 @@ +fragment Image on Image { + hash + width + height +} + +fragment Page on Page { + id + path + image { + id + hash + aspectRatio + width + height + } + comicId +} + +fragment Comic on Comic { + id + title + originalTitle + favourite + cover { + ...Image + } + tags { + name + description + } + artists { + name + } + characters { + name + } + worlds { + name + } + circles { + name + } +} + +fragment FullArchive on FullArchive { + id + name + path + size + createdAt + mtime + organized + pageCount + pages { + ...Page + } + comics { + ...Comic + } +} + +fragment Archive on Archive { + id + name + size + pageCount + cover { + ...Image + } +} + +fragment FullComic on FullComic { + id + title + originalTitle + url + language + direction + date + layout + rating + category + censorship + favourite + createdAt + updatedAt + organized + bookmarked + pages { + ...Page + } + archive { + id + } + tags { + id + name + description + } + artists { + id + name + } + characters { + id + name + } + worlds { + id + name + } + circles { + id + name + } +} + +fragment ComicScraper on ComicScraper { + id + name +} + +fragment ScrapeComicResult on ScrapeComicResult { + data { + artists + category + censorship + characters + circles + date + direction + language + layout + originalTitle + url + rating + tags + title + worlds + } + warnings +} + +query comics($pagination: Pagination!, $filter: ComicFilterInput, $sort: ComicSortInput) { + comics(pagination: $pagination, filter: $filter, sort: $sort) { + edges { + ...Comic + } + count + } +} + +query archives($pagination: Pagination!, $filter: ArchiveFilterInput, $sort: ArchiveSortInput) { + archives(pagination: $pagination, filter: $filter, sort: $sort) { + edges { + ...Archive + } + count + } +} + +query archive($id: Int!) { + archive(id: $id) { + ... on FullArchive { + ...FullArchive + } + ... on Error { + message + } + } +} + +query comic($id: Int!) { + comic(id: $id) { + ... on FullComic { + ...FullComic + } + ... on Error { + message + } + } +} + +query tag($id: Int!) { + tag(id: $id) { + ... on FullTag { + id + name + description + namespaces { + id + name + } + } + ... on Error { + message + } + } +} + +query tags($pagination: Pagination!, $filter: TagFilterInput, $sort: TagSortInput) { + tags(pagination: $pagination, filter: $filter, sort: $sort) { + edges { + id + name + description + } + count + } +} + +query namespace($id: Int!) { + namespace(id: $id) { + ... on Namespace { + id + name + sortName + } + ... on Error { + message + } + } +} + +query namespaces( + $pagination: Pagination! + $filter: NamespaceFilterInput + $sort: NamespaceSortInput +) { + namespaces(pagination: $pagination, filter: $filter, sort: $sort) { + count + edges { + id + name + } + } +} + +query comicTagList($forFilter: Boolean = false) { + comicTags(forFilter: $forFilter) { + edges { + id + name + } + } +} + +query artistList { + artists { + edges { + id + name + } + } +} + +query characterList { + characters { + edges { + id + name + } + } +} + +query circleList { + circles { + edges { + id + name + } + } +} + +query worldList { + worlds { + edges { + id + name + } + } +} + +query namespaceList { + namespaces { + edges { + id + name + } + } +} + +query artists($pagination: Pagination!, $filter: ArtistFilterInput, $sort: ArtistSortInput) { + artists(pagination: $pagination, filter: $filter, sort: $sort) { + count + edges { + id + name + } + } +} + +query artist($id: Int!) { + artist(id: $id) { + ... on Artist { + id + name + } + ... on Error { + message + } + } +} + +query characters( + $pagination: Pagination! + $filter: CharacterFilterInput + $sort: CharacterSortInput +) { + characters(pagination: $pagination, filter: $filter, sort: $sort) { + count + edges { + id + name + } + } +} + +query character($id: Int!) { + character(id: $id) { + ... on Character { + id + name + } + ... on Error { + message + } + } +} + +query circles($pagination: Pagination!, $filter: CircleFilterInput, $sort: CircleSortInput) { + circles(pagination: $pagination, filter: $filter, sort: $sort) { + count + edges { + id + name + } + } +} + +query circle($id: Int!) { + circle(id: $id) { + ... on Circle { + id + name + } + ... on Error { + message + } + } +} + +query worlds($pagination: Pagination!, $filter: WorldFilterInput, $sort: WorldSortInput) { + worlds(pagination: $pagination, filter: $filter, sort: $sort) { + count + edges { + id + name + } + } +} + +query world($id: Int!) { + world(id: $id) { + ... on World { + id + name + } + ... on Error { + message + } + } +} + +query comicScrapers($id: Int!) { + comicScrapers(id: $id) { + id + name + } +} + +query scrapeComic($id: Int!, $scraper: String!) { + scrapeComic(id: $id, scraper: $scraper) { + ... on ScrapeComicResult { + ...ScrapeComicResult + } + ... on Error { + message + } + } +} + +query frontpage { + recent: comics(pagination: { items: 6 }, sort: { on: CREATED_AT, direction: DESCENDING }) { + edges { + ...Comic + } + count + } + favourites: comics( + pagination: { items: 6 } + filter: { include: { favourite: true } } + sort: { on: RANDOM } + ) { + edges { + ...Comic + } + count + } + bookmarked: comics( + pagination: { items: 6 } + filter: { include: { bookmarked: true } } + sort: { on: RANDOM } + ) { + edges { + ...Comic + } + count + } +} + +mutation addComic($input: AddComicInput!) { + addComic(input: $input) { + ... on AddComicSuccess { + message + archivePagesRemaining + } + ... on Error { + message + } + } +} + +mutation updateArchives($ids: [Int!]!, $input: UpdateArchiveInput!) { + updateArchives(ids: $ids, input: $input) { + ... on Success { + message + } + ... on Error { + message + } + } +} + +mutation updateComics($ids: [Int!]!, $input: UpdateComicInput!) { + updateComics(ids: $ids, input: $input) { + ... on Success { + message + } + ... on Error { + message + } + } +} + +mutation upsertComics($ids: [Int!]!, $input: UpsertComicInput!) { + upsertComics(ids: $ids, input: $input) { + ... on Success { + message + } + ... on Error { + message + } + } +} + +mutation deleteArchives($ids: [Int!]!) { + deleteArchives(ids: $ids) { + ... on Success { + message + } + ... on Error { + message + } + } +} + +mutation deleteComics($ids: [Int!]!) { + deleteComics(ids: $ids) { + ... on Success { + message + } + ... on Error { + message + } + } +} + +mutation addTag($input: AddTagInput!) { + addTag(input: $input) { + ... on Success { + message + } + ... on Error { + message + } + } +} + +mutation updateTags($ids: [Int!]!, $input: UpdateTagInput!) { + updateTags(ids: $ids, input: $input) { + ... on Success { + message + } + ... on Error { + message + } + } +} + +mutation deleteTags($ids: [Int!]!) { + deleteTags(ids: $ids) { + ... on Success { + message + } + ... on Error { + message + } + } +} + +mutation addNamespace($input: AddNamespaceInput!) { + addNamespace(input: $input) { + ... on Success { + message + } + ... on Error { + message + } + } +} + +mutation updateNamespaces($ids: [Int!]!, $input: UpdateNamespaceInput!) { + updateNamespaces(ids: $ids, input: $input) { + ... on Success { + message + } + ... on Error { + message + } + } +} + +mutation deleteNamespaces($ids: [Int!]!) { + deleteNamespaces(ids: $ids) { + ... on Success { + message + } + ... on Error { + message + } + } +} + +mutation addArtist($input: AddArtistInput!) { + addArtist(input: $input) { + ... on Success { + message + } + ... on Error { + message + } + } +} + +mutation updateArtists($ids: [Int!]!, $input: UpdateArtistInput!) { + updateArtists(ids: $ids, input: $input) { + ... on Success { + message + } + ... on Error { + message + } + } +} + +mutation deleteArtists($ids: [Int!]!) { + deleteArtists(ids: $ids) { + ... on Success { + message + } + ... on Error { + message + } + } +} + +mutation addCharacter($input: AddCharacterInput!) { + addCharacter(input: $input) { + ... on Success { + message + } + ... on Error { + message + } + } +} + +mutation updateCharacters($ids: [Int!]!, $input: UpdateCharacterInput!) { + updateCharacters(ids: $ids, input: $input) { + ... on Success { + message + } + ... on Error { + message + } + } +} + +mutation deleteCharacters($ids: [Int!]!) { + deleteCharacters(ids: $ids) { + ... on Success { + message + } + ... on Error { + message + } + } +} + +mutation addCircle($input: AddCircleInput!) { + addCircle(input: $input) { + ... on Success { + message + } + ... on Error { + message + } + } +} + +mutation updateCircles($ids: [Int!]!, $input: UpdateCircleInput!) { + updateCircles(ids: $ids, input: $input) { + ... on Success { + message + } + ... on Error { + message + } + } +} + +mutation deleteCircles($ids: [Int!]!) { + deleteCircles(ids: $ids) { + ... on Success { + message + } + ... on Error { + message + } + } +} + +mutation addWorld($input: AddWorldInput!) { + addWorld(input: $input) { + ... on Success { + message + } + ... on Error { + message + } + } +} + +mutation updateWorlds($ids: [Int!]!, $input: UpdateWorldInput!) { + updateWorlds(ids: $ids, input: $input) { + ... on Success { + message + } + ... on Error { + message + } + } +} + +mutation deleteWorlds($ids: [Int!]!) { + deleteWorlds(ids: $ids) { + ... on Success { + message + } + ... on Error { + message + } + } +} diff --git a/frontend/package-lock.json b/frontend/package-lock.json new file mode 100644 index 0000000..a092acc --- /dev/null +++ b/frontend/package-lock.json @@ -0,0 +1,12892 @@ +{ + "name": "hircine", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "hircine", + "version": "0.1.0", + "license": "ISC", + "dependencies": { + "@jsonurl/jsonurl": "^1.1.7", + "@urql/svelte": "^4.1.0", + "filesize": "^10.1.0", + "graphql": "npm:graphql-web-lite@^16.6.0", + "svelecte": "^3.17.3", + "svelte-modals": "^1.3.0" + }, + "devDependencies": { + "@graphql-codegen/cli": "^5.0.2", + "@graphql-codegen/typed-document-node": "^5.0.6", + "@graphql-codegen/typescript-operations": "^4.2.0", + "@iconify-json/material-symbols": "^1.1.74", + "@iconify/tailwind": "^0.1.4", + "@sveltejs/adapter-static": "^3.0.1", + "@sveltejs/kit": "^2.5.2", + "@sveltejs/vite-plugin-svelte": "^3.0.2", + "@typescript-eslint/eslint-plugin": "^7.1.0", + "@typescript-eslint/parser": "^7.1.0", + "@zerodevx/svelte-toast": "^0.9.5", + "autoprefixer": "^10.4.18", + "date-fns": "^3.3.1", + "eslint": "^8.57.0", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-svelte": "^2.35.1", + "fast-deep-equal": "^3.1.3", + "npm-check-updates": "^16.14.15", + "postcss": "^8.4.35", + "prettier": "^3.2.5", + "prettier-plugin-svelte": "^3.2.2", + "prettier-plugin-tailwindcss": "^0.5.11", + "svelte": "^4.2.12", + "svelte-check": "^3.6.6", + "tailwindcss": "^3.4.1", + "tslib": "^2.6.2", + "typescript": "^5.3.3", + "vite": "^5.1.4", + "vitest": "^1.3.1" + } + }, + "node_modules/@0no-co/graphql.web": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@0no-co/graphql.web/-/graphql.web-1.0.4.tgz", + "integrity": "sha512-W3ezhHGfO0MS1PtGloaTpg0PbaT8aZSmmaerL7idtU5F7oCI+uu25k+MsMS31BVFlp4aMkHSrNRxiD72IlK8TA==", + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0" + }, + "peerDependenciesMeta": { + "graphql": { + "optional": true + } + } + }, + "node_modules/@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@alloc/quick-lru": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", + "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@ardatan/relay-compiler": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@ardatan/relay-compiler/-/relay-compiler-12.0.0.tgz", + "integrity": "sha512-9anThAaj1dQr6IGmzBMcfzOQKTa5artjuPmw8NYK/fiGEMjADbSguBY2FMDykt+QhilR3wc9VA/3yVju7JHg7Q==", + "dev": true, + "dependencies": { + "@babel/core": "^7.14.0", + "@babel/generator": "^7.14.0", + "@babel/parser": "^7.14.0", + "@babel/runtime": "^7.0.0", + "@babel/traverse": "^7.14.0", + "@babel/types": "^7.0.0", + "babel-preset-fbjs": "^3.4.0", + "chalk": "^4.0.0", + "fb-watchman": "^2.0.0", + "fbjs": "^3.0.0", + "glob": "^7.1.1", + "immutable": "~3.7.6", + "invariant": "^2.2.4", + "nullthrows": "^1.1.1", + "relay-runtime": "12.0.0", + "signedsource": "^1.0.0", + "yargs": "^15.3.1" + }, + "bin": { + "relay-compiler": "bin/relay-compiler" + }, + "peerDependencies": { + "graphql": "*" + } + }, + "node_modules/@ardatan/relay-compiler/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/@ardatan/relay-compiler/node_modules/cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "node_modules/@ardatan/relay-compiler/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@ardatan/relay-compiler/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@ardatan/relay-compiler/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@ardatan/relay-compiler/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@ardatan/relay-compiler/node_modules/y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true + }, + "node_modules/@ardatan/relay-compiler/node_modules/yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "dev": true, + "dependencies": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@ardatan/relay-compiler/node_modules/yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@ardatan/sync-fetch": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/@ardatan/sync-fetch/-/sync-fetch-0.0.1.tgz", + "integrity": "sha512-xhlTqH0m31mnsG0tIP4ETgfSB6gXDaYYsUWTrlUV93fFQPI9dd8hE0Ot6MHLCtqgB32hwJAC3YZMWlXZw7AleA==", + "dev": true, + "dependencies": { + "node-fetch": "^2.6.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", + "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.23.4", + "chalk": "^2.4.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/code-frame/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/code-frame/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/@babel/code-frame/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/code-frame/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.5.tgz", + "integrity": "sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.0.tgz", + "integrity": "sha512-fQfkg0Gjkza3nf0c7/w6Xf34BW4YvzNfACRLmmb7XRLa6XHdR+K9AlJlxneFfWYf6uhOzuzZVTjF/8KfndZANw==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.6", + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helpers": "^7.24.0", + "@babel/parser": "^7.24.0", + "@babel/template": "^7.24.0", + "@babel/traverse": "^7.24.0", + "@babel/types": "^7.24.0", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz", + "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.23.6", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz", + "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz", + "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.23.5", + "@babel/helper-validator-option": "^7.23.5", + "browserslist": "^4.22.2", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.0.tgz", + "integrity": "sha512-QAH+vfvts51BCsNZ2PhY6HAggnlS6omLLFTsIpeqZk/MmJ6cW7tgz5yRv0fMJThcr6FmbMrENh1RgrWPTYA76g==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-member-expression-to-functions": "^7.23.0", + "@babel/helper-optimise-call-expression": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.20", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", + "dev": true, + "dependencies": { + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.23.0.tgz", + "integrity": "sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.23.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", + "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", + "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-simple-access": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/helper-validator-identifier": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz", + "integrity": "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.0.tgz", + "integrity": "sha512-9cUznXMG0+FxRuJfvL82QlTqIzhVW9sL0KjMPHhAOOvpQGL8QtdxnBKILjBqxlHyliz0yCa1G903ZXI/FuHy2w==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.22.20.tgz", + "integrity": "sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-member-expression-to-functions": "^7.22.15", + "@babel/helper-optimise-call-expression": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", + "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz", + "integrity": "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", + "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz", + "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.0.tgz", + "integrity": "sha512-ulDZdc0Aj5uLc5nETsa7EPx2L7rM0YJM8r7ck7U73AXi7qOV44IHHRAYZHY6iU1rr3C5N4NtTmMRUJP6kwCWeA==", + "dev": true, + "dependencies": { + "@babel/template": "^7.24.0", + "@babel/traverse": "^7.24.0", + "@babel/types": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", + "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/@babel/highlight/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/parser": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.0.tgz", + "integrity": "sha512-QuP/FxEAzMSjXygs8v4N9dvdXzEHN4W1oF3PxuWAtPo08UdM17u89RDMgjLn/mlc56iM0HlLmVkO/wgR+rDgHg==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-proposal-class-properties": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz", + "integrity": "sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-class-properties instead.", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-object-rest-spread": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.7.tgz", + "integrity": "sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-object-rest-spread instead.", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.20.5", + "@babel/helper-compilation-targets": "^7.20.7", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.20.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-flow": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.23.3.tgz", + "integrity": "sha512-YZiAIpkJAwQXBJLIQbRFayR5c+gJ35Vcz3bg954k7cd73zqjvhacJuL9RbrzPz8qPmZdgqP6EUKwy0PCNhaaPA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-assertions": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.23.3.tgz", + "integrity": "sha512-lPgDSU+SJLK3xmFDTV2ZRQAiM7UuUjGidwBywFavObCiZc1BeAAcMtHJKUya92hPHO+at63JJPLygilZard8jw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.23.3.tgz", + "integrity": "sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.23.3.tgz", + "integrity": "sha512-NzQcQrzaQPkaEwoTm4Mhyl8jI1huEL/WWIEvudjTCMJ9aBZNpsJbMASx7EQECtQQPS/DcnFpo0FIh3LvEO9cxQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.23.3.tgz", + "integrity": "sha512-vI+0sIaPIO6CNuM9Kk5VmXcMVRiOpDh7w2zZt9GXzmE/9KD70CUEVhvPR/etAeNK/FAEkhxQtXOzVF3EuRL41A==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.23.4.tgz", + "integrity": "sha512-0QqbP6B6HOh7/8iNR4CQU2Th/bbRtBp4KS9vcaZd1fZ0wSh5Fyssg0UCIHwxh+ka+pNDREbVLQnHCMHKZfPwfw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-classes": { + "version": "7.23.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.23.8.tgz", + "integrity": "sha512-yAYslGsY1bX6Knmg46RjiCiNSwJKv2IUC8qOdYKqMMr0491SXFhcHqOdRDeCRohOOIzwN/90C6mQ9qAKgrP7dg==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.20", + "@babel/helper-split-export-declaration": "^7.22.6", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.23.3.tgz", + "integrity": "sha512-dTj83UVTLw/+nbiHqQSFdwO9CbTtwq1DsDqm3CUEtDrZNET5rT5E6bIdTlOftDTDLMYxvxHNEYO4B9SLl8SLZw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/template": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.23.3.tgz", + "integrity": "sha512-n225npDqjDIr967cMScVKHXJs7rout1q+tt50inyBCPkyZ8KxeI6d+GIbSBTT/w/9WdlWDOej3V9HE5Lgk57gw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-flow-strip-types": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.23.3.tgz", + "integrity": "sha512-26/pQTf9nQSNVJCrLB1IkHUKyPxR+lMrH2QDPG89+Znu9rAMbtrybdbWeE9bb7gzjmE5iXHEY+e0HUwM6Co93Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-flow": "^7.23.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.23.6.tgz", + "integrity": "sha512-aYH4ytZ0qSuBbpfhuofbg/e96oQ7U2w1Aw/UQmKT+1l39uEhUPoFS3fHevDc1G0OvewyDudfMKY1OulczHzWIw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.23.3.tgz", + "integrity": "sha512-I1QXp1LxIvt8yLaib49dRW5Okt7Q4oaxao6tFVKS/anCdEOMtYwWVKoiOA1p34GOWIZjUK0E+zCp7+l1pfQyiw==", + "dev": true, + "dependencies": { + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-literals": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.23.3.tgz", + "integrity": "sha512-wZ0PIXRxnwZvl9AYpqNUxpZ5BiTGrYt7kueGQ+N5FiQ7RCOD4cm8iShd6S6ggfVIWaJf2EMk8eRzAh52RfP4rQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.23.3.tgz", + "integrity": "sha512-sC3LdDBDi5x96LA+Ytekz2ZPk8i/Ck+DEuDbRAll5rknJ5XRTSaPKEYwomLcs1AA8wg9b3KjIQRsnApj+q51Ag==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.23.3.tgz", + "integrity": "sha512-aVS0F65LKsdNOtcz6FRCpE4OgsP2OFnW46qNxNIX9h3wuzaNcSQsJysuMwqSibC98HPrf2vCgtxKNwS0DAlgcA==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-simple-access": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.23.3.tgz", + "integrity": "sha512-BwQ8q0x2JG+3lxCVFohg+KbQM7plfpBwThdW9A6TMtWwLsbDA01Ek2Zb/AgDN39BiZsExm4qrXxjk+P1/fzGrA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.23.3.tgz", + "integrity": "sha512-09lMt6UsUb3/34BbECKVbVwrT9bO6lILWln237z7sLaWnMsTi7Yc9fhX5DLpkJzAGfaReXI22wP41SZmnAA3Vw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.23.3.tgz", + "integrity": "sha512-jR3Jn3y7cZp4oEWPFAlRsSWjxKe4PZILGBSd4nis1TsC5qeSpb+nrtihJuDhNI7QHiVbUaiXa0X2RZY3/TI6Nw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-display-name": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.23.3.tgz", + "integrity": "sha512-GnvhtVfA2OAtzdX58FJxU19rhoGeQzyVndw3GgtdECQvQFXPEZIOVULHVZGAYmOgmqjXpVpfocAbSjh99V/Fqw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.23.4.tgz", + "integrity": "sha512-5xOpoPguCZCRbo/JeHlloSkTA8Bld1J/E1/kLfD1nsuiW1m8tduTA1ERCgIZokDflX/IBzKcqR3l7VlRgiIfHA==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-jsx": "^7.23.3", + "@babel/types": "^7.23.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.23.3.tgz", + "integrity": "sha512-ED2fgqZLmexWiN+YNFX26fx4gh5qHDhn1O2gvEhreLW2iI63Sqm4llRLCXALKrCnbN4Jy0VcMQZl/SAzqug/jg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-spread": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.23.3.tgz", + "integrity": "sha512-VvfVYlrlBVu+77xVTOAoxQ6mZbnIq5FM0aGBSFEcIh03qHf+zNqA4DC/3XMUozTg7bZV3e3mZQ0i13VB6v5yUg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.23.3.tgz", + "integrity": "sha512-Flok06AYNp7GV2oJPZZcP9vZdszev6vPBkHLwxwSpaIqx75wn6mUd3UFWsSsA0l8nXAKkyCmL/sR02m8RYGeHg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.0.tgz", + "integrity": "sha512-Chk32uHMg6TnQdvw2e9IlqPpFX/6NLuK0Ys2PqLb7/gL5uFn9mXvK715FGLlOLQrcO4qIkNHkvPGktzzXexsFw==", + "dev": true, + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.0.tgz", + "integrity": "sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.23.5", + "@babel/parser": "^7.24.0", + "@babel/types": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.0.tgz", + "integrity": "sha512-HfuJlI8qq3dEDmNU5ChzzpZRWq+oxCZQyMzIMEqLho+AQnhMnKQUzH6ydo3RBl/YjPCuk68Y6s0Gx0AeyULiWw==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.6", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.24.0", + "@babel/types": "^7.24.0", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.0.tgz", + "integrity": "sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==", + "dev": true, + "dependencies": { + "@babel/helper-string-parser": "^7.23.4", + "@babel/helper-validator-identifier": "^7.22.20", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "dev": true, + "optional": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz", + "integrity": "sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.12.tgz", + "integrity": "sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz", + "integrity": "sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.12.tgz", + "integrity": "sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz", + "integrity": "sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz", + "integrity": "sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz", + "integrity": "sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz", + "integrity": "sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz", + "integrity": "sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz", + "integrity": "sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz", + "integrity": "sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz", + "integrity": "sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz", + "integrity": "sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz", + "integrity": "sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz", + "integrity": "sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz", + "integrity": "sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz", + "integrity": "sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz", + "integrity": "sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz", + "integrity": "sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz", + "integrity": "sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz", + "integrity": "sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz", + "integrity": "sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz", + "integrity": "sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", + "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/eslintrc/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/js": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", + "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@gar/promisify": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz", + "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==", + "dev": true + }, + "node_modules/@graphql-codegen/add": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@graphql-codegen/add/-/add-5.0.2.tgz", + "integrity": "sha512-ouBkSvMFUhda5VoKumo/ZvsZM9P5ZTyDsI8LW18VxSNWOjrTeLXBWHG8Gfaai0HwhflPtCYVABbriEcOmrRShQ==", + "dev": true, + "dependencies": { + "@graphql-codegen/plugin-helpers": "^5.0.3", + "tslib": "~2.6.0" + }, + "peerDependencies": { + "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" + } + }, + "node_modules/@graphql-codegen/cli": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@graphql-codegen/cli/-/cli-5.0.2.tgz", + "integrity": "sha512-MBIaFqDiLKuO4ojN6xxG9/xL9wmfD3ZjZ7RsPjwQnSHBCUXnEkdKvX+JVpx87Pq29Ycn8wTJUguXnTZ7Di0Mlw==", + "dev": true, + "dependencies": { + "@babel/generator": "^7.18.13", + "@babel/template": "^7.18.10", + "@babel/types": "^7.18.13", + "@graphql-codegen/client-preset": "^4.2.2", + "@graphql-codegen/core": "^4.0.2", + "@graphql-codegen/plugin-helpers": "^5.0.3", + "@graphql-tools/apollo-engine-loader": "^8.0.0", + "@graphql-tools/code-file-loader": "^8.0.0", + "@graphql-tools/git-loader": "^8.0.0", + "@graphql-tools/github-loader": "^8.0.0", + "@graphql-tools/graphql-file-loader": "^8.0.0", + "@graphql-tools/json-file-loader": "^8.0.0", + "@graphql-tools/load": "^8.0.0", + "@graphql-tools/prisma-loader": "^8.0.0", + "@graphql-tools/url-loader": "^8.0.0", + "@graphql-tools/utils": "^10.0.0", + "@whatwg-node/fetch": "^0.8.0", + "chalk": "^4.1.0", + "cosmiconfig": "^8.1.3", + "debounce": "^1.2.0", + "detect-indent": "^6.0.0", + "graphql-config": "^5.0.2", + "inquirer": "^8.0.0", + "is-glob": "^4.0.1", + "jiti": "^1.17.1", + "json-to-pretty-yaml": "^1.2.2", + "listr2": "^4.0.5", + "log-symbols": "^4.0.0", + "micromatch": "^4.0.5", + "shell-quote": "^1.7.3", + "string-env-interpolation": "^1.0.1", + "ts-log": "^2.2.3", + "tslib": "^2.4.0", + "yaml": "^2.3.1", + "yargs": "^17.0.0" + }, + "bin": { + "gql-gen": "cjs/bin.js", + "graphql-code-generator": "cjs/bin.js", + "graphql-codegen": "cjs/bin.js", + "graphql-codegen-esm": "esm/bin.js" + }, + "peerDependencies": { + "@parcel/watcher": "^2.1.0", + "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" + }, + "peerDependenciesMeta": { + "@parcel/watcher": { + "optional": true + } + } + }, + "node_modules/@graphql-codegen/client-preset": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/@graphql-codegen/client-preset/-/client-preset-4.2.4.tgz", + "integrity": "sha512-k1c8v2YxJhhITGQGxViG9asLAoop9m7X9duU7Zztqjc98ooxsUzXICfvAWsH3mLAUibXAx4Ax6BPzKsTtQmBPg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/template": "^7.20.7", + "@graphql-codegen/add": "^5.0.2", + "@graphql-codegen/gql-tag-operations": "4.0.6", + "@graphql-codegen/plugin-helpers": "^5.0.3", + "@graphql-codegen/typed-document-node": "^5.0.6", + "@graphql-codegen/typescript": "^4.0.6", + "@graphql-codegen/typescript-operations": "^4.2.0", + "@graphql-codegen/visitor-plugin-common": "^5.1.0", + "@graphql-tools/documents": "^1.0.0", + "@graphql-tools/utils": "^10.0.0", + "@graphql-typed-document-node/core": "3.2.0", + "tslib": "~2.6.0" + }, + "peerDependencies": { + "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" + } + }, + "node_modules/@graphql-codegen/core": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@graphql-codegen/core/-/core-4.0.2.tgz", + "integrity": "sha512-IZbpkhwVqgizcjNiaVzNAzm/xbWT6YnGgeOLwVjm4KbJn3V2jchVtuzHH09G5/WkkLSk2wgbXNdwjM41JxO6Eg==", + "dev": true, + "dependencies": { + "@graphql-codegen/plugin-helpers": "^5.0.3", + "@graphql-tools/schema": "^10.0.0", + "@graphql-tools/utils": "^10.0.0", + "tslib": "~2.6.0" + }, + "peerDependencies": { + "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" + } + }, + "node_modules/@graphql-codegen/gql-tag-operations": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@graphql-codegen/gql-tag-operations/-/gql-tag-operations-4.0.6.tgz", + "integrity": "sha512-y6iXEDpDNjwNxJw3WZqX1/Znj0QHW7+y8O+t2V8qvbTT+3kb2lr9ntc8By7vCr6ctw9tXI4XKaJgpTstJDOwFA==", + "dev": true, + "dependencies": { + "@graphql-codegen/plugin-helpers": "^5.0.3", + "@graphql-codegen/visitor-plugin-common": "5.1.0", + "@graphql-tools/utils": "^10.0.0", + "auto-bind": "~4.0.0", + "tslib": "~2.6.0" + }, + "peerDependencies": { + "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" + } + }, + "node_modules/@graphql-codegen/plugin-helpers": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@graphql-codegen/plugin-helpers/-/plugin-helpers-5.0.3.tgz", + "integrity": "sha512-yZ1rpULIWKBZqCDlvGIJRSyj1B2utkEdGmXZTBT/GVayP4hyRYlkd36AJV/LfEsVD8dnsKL5rLz2VTYmRNlJ5Q==", + "dev": true, + "dependencies": { + "@graphql-tools/utils": "^10.0.0", + "change-case-all": "1.0.15", + "common-tags": "1.8.2", + "import-from": "4.0.0", + "lodash": "~4.17.0", + "tslib": "~2.6.0" + }, + "peerDependencies": { + "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" + } + }, + "node_modules/@graphql-codegen/schema-ast": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@graphql-codegen/schema-ast/-/schema-ast-4.0.2.tgz", + "integrity": "sha512-5mVAOQQK3Oz7EtMl/l3vOQdc2aYClUzVDHHkMvZlunc+KlGgl81j8TLa+X7ANIllqU4fUEsQU3lJmk4hXP6K7Q==", + "dev": true, + "dependencies": { + "@graphql-codegen/plugin-helpers": "^5.0.3", + "@graphql-tools/utils": "^10.0.0", + "tslib": "~2.6.0" + }, + "peerDependencies": { + "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" + } + }, + "node_modules/@graphql-codegen/typed-document-node": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/@graphql-codegen/typed-document-node/-/typed-document-node-5.0.6.tgz", + "integrity": "sha512-US0J95hOE2/W/h42w4oiY+DFKG7IetEN1mQMgXXeat1w6FAR5PlIz4JrRrEkiVfVetZ1g7K78SOwBD8/IJnDiA==", + "dev": true, + "dependencies": { + "@graphql-codegen/plugin-helpers": "^5.0.3", + "@graphql-codegen/visitor-plugin-common": "5.1.0", + "auto-bind": "~4.0.0", + "change-case-all": "1.0.15", + "tslib": "~2.6.0" + }, + "peerDependencies": { + "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" + } + }, + "node_modules/@graphql-codegen/typescript": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@graphql-codegen/typescript/-/typescript-4.0.6.tgz", + "integrity": "sha512-IBG4N+Blv7KAL27bseruIoLTjORFCT3r+QYyMC3g11uY3/9TPpaUyjSdF70yBe5GIQ6dAgDU+ENUC1v7EPi0rw==", + "dev": true, + "dependencies": { + "@graphql-codegen/plugin-helpers": "^5.0.3", + "@graphql-codegen/schema-ast": "^4.0.2", + "@graphql-codegen/visitor-plugin-common": "5.1.0", + "auto-bind": "~4.0.0", + "tslib": "~2.6.0" + }, + "peerDependencies": { + "graphql": "^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" + } + }, + "node_modules/@graphql-codegen/typescript-operations": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@graphql-codegen/typescript-operations/-/typescript-operations-4.2.0.tgz", + "integrity": "sha512-lmuwYb03XC7LNRS8oo9M4/vlOrq/wOKmTLBHlltK2YJ1BO/4K/Q9Jdv/jDmJpNydHVR1fmeF4wAfsIp1f9JibA==", + "dev": true, + "dependencies": { + "@graphql-codegen/plugin-helpers": "^5.0.3", + "@graphql-codegen/typescript": "^4.0.6", + "@graphql-codegen/visitor-plugin-common": "5.1.0", + "auto-bind": "~4.0.0", + "tslib": "~2.6.0" + }, + "peerDependencies": { + "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" + } + }, + "node_modules/@graphql-codegen/visitor-plugin-common": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@graphql-codegen/visitor-plugin-common/-/visitor-plugin-common-5.1.0.tgz", + "integrity": "sha512-eamQxtA9bjJqI2lU5eYoA1GbdMIRT2X8m8vhWYsVQVWD3qM7sx/IqJU0kx0J3Vd4/CSd36BzL6RKwksibytDIg==", + "dev": true, + "dependencies": { + "@graphql-codegen/plugin-helpers": "^5.0.3", + "@graphql-tools/optimize": "^2.0.0", + "@graphql-tools/relay-operation-optimizer": "^7.0.0", + "@graphql-tools/utils": "^10.0.0", + "auto-bind": "~4.0.0", + "change-case-all": "1.0.15", + "dependency-graph": "^0.11.0", + "graphql-tag": "^2.11.0", + "parse-filepath": "^1.0.2", + "tslib": "~2.6.0" + }, + "peerDependencies": { + "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" + } + }, + "node_modules/@graphql-tools/apollo-engine-loader": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/apollo-engine-loader/-/apollo-engine-loader-8.0.1.tgz", + "integrity": "sha512-NaPeVjtrfbPXcl+MLQCJLWtqe2/E4bbAqcauEOQ+3sizw1Fc2CNmhHRF8a6W4D0ekvTRRXAMptXYgA2uConbrA==", + "dev": true, + "dependencies": { + "@ardatan/sync-fetch": "^0.0.1", + "@graphql-tools/utils": "^10.0.13", + "@whatwg-node/fetch": "^0.9.0", + "tslib": "^2.4.0" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + } + }, + "node_modules/@graphql-tools/apollo-engine-loader/node_modules/@whatwg-node/events": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@whatwg-node/events/-/events-0.1.1.tgz", + "integrity": "sha512-AyQEn5hIPV7Ze+xFoXVU3QTHXVbWPrzaOkxtENMPMuNL6VVHrp4hHfDt9nrQpjO7BgvuM95dMtkycX5M/DZR3w==", + "dev": true, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@graphql-tools/apollo-engine-loader/node_modules/@whatwg-node/fetch": { + "version": "0.9.17", + "resolved": "https://registry.npmjs.org/@whatwg-node/fetch/-/fetch-0.9.17.tgz", + "integrity": "sha512-TDYP3CpCrxwxpiNY0UMNf096H5Ihf67BK1iKGegQl5u9SlpEDYrvnV71gWBGJm+Xm31qOy8ATgma9rm8Pe7/5Q==", + "dev": true, + "dependencies": { + "@whatwg-node/node-fetch": "^0.5.7", + "urlpattern-polyfill": "^10.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@graphql-tools/apollo-engine-loader/node_modules/@whatwg-node/node-fetch": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/@whatwg-node/node-fetch/-/node-fetch-0.5.7.tgz", + "integrity": "sha512-YZA+N3JcW1eh2QRi7o/ij+M07M0dqID73ltgsOEMRyEc2UYVDbyomaih+CWCEZqBIDHw4KMDveXvv4SBZ4TLIw==", + "dev": true, + "dependencies": { + "@kamilkisiela/fast-url-parser": "^1.1.4", + "@whatwg-node/events": "^0.1.0", + "busboy": "^1.6.0", + "fast-querystring": "^1.1.1", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@graphql-tools/apollo-engine-loader/node_modules/urlpattern-polyfill": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-10.0.0.tgz", + "integrity": "sha512-H/A06tKD7sS1O1X2SshBVeA5FLycRpjqiBeqGKmBwBDBy28EnRjORxTNe269KSSr5un5qyWi1iL61wLxpd+ZOg==", + "dev": true + }, + "node_modules/@graphql-tools/batch-execute": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/@graphql-tools/batch-execute/-/batch-execute-9.0.4.tgz", + "integrity": "sha512-kkebDLXgDrep5Y0gK1RN3DMUlLqNhg60OAz0lTCqrYeja6DshxLtLkj+zV4mVbBA4mQOEoBmw6g1LZs3dA84/w==", + "dev": true, + "dependencies": { + "@graphql-tools/utils": "^10.0.13", + "dataloader": "^2.2.2", + "tslib": "^2.4.0", + "value-or-promise": "^1.0.12" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + } + }, + "node_modules/@graphql-tools/code-file-loader": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/code-file-loader/-/code-file-loader-8.1.1.tgz", + "integrity": "sha512-q4KN25EPSUztc8rA8YUU3ufh721Yk12xXDbtUA+YstczWS7a1RJlghYMFEfR1HsHSYbF7cUqkbnTKSGM3o52bQ==", + "dev": true, + "dependencies": { + "@graphql-tools/graphql-tag-pluck": "8.3.0", + "@graphql-tools/utils": "^10.0.13", + "globby": "^11.0.3", + "tslib": "^2.4.0", + "unixify": "^1.0.0" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + } + }, + "node_modules/@graphql-tools/delegate": { + "version": "10.0.4", + "resolved": "https://registry.npmjs.org/@graphql-tools/delegate/-/delegate-10.0.4.tgz", + "integrity": "sha512-WswZRbQZMh/ebhc8zSomK9DIh6Pd5KbuiMsyiKkKz37TWTrlCOe+4C/fyrBFez30ksq6oFyCeSKMwfrCbeGo0Q==", + "dev": true, + "dependencies": { + "@graphql-tools/batch-execute": "^9.0.4", + "@graphql-tools/executor": "^1.2.1", + "@graphql-tools/schema": "^10.0.3", + "@graphql-tools/utils": "^10.0.13", + "dataloader": "^2.2.2", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + } + }, + "node_modules/@graphql-tools/documents": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@graphql-tools/documents/-/documents-1.0.0.tgz", + "integrity": "sha512-rHGjX1vg/nZ2DKqRGfDPNC55CWZBMldEVcH+91BThRa6JeT80NqXknffLLEZLRUxyikCfkwMsk6xR3UNMqG0Rg==", + "dev": true, + "dependencies": { + "lodash.sortby": "^4.7.0", + "tslib": "^2.4.0" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + } + }, + "node_modules/@graphql-tools/executor": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/executor/-/executor-1.2.1.tgz", + "integrity": "sha512-BP5UI1etbNOXmTSt7q4NL1+zsURFgh2pG+Hyt9K/xO0LlsfbSx59L5dHLerqZP7Js0xI6GYqrUQ4m29rUwUHJg==", + "dev": true, + "dependencies": { + "@graphql-tools/utils": "^10.0.13", + "@graphql-typed-document-node/core": "3.2.0", + "@repeaterjs/repeater": "^3.0.4", + "tslib": "^2.4.0", + "value-or-promise": "^1.0.12" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + } + }, + "node_modules/@graphql-tools/executor-graphql-ws": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@graphql-tools/executor-graphql-ws/-/executor-graphql-ws-1.1.2.tgz", + "integrity": "sha512-+9ZK0rychTH1LUv4iZqJ4ESbmULJMTsv3XlFooPUngpxZkk00q6LqHKJRrsLErmQrVaC7cwQCaRBJa0teK17Lg==", + "dev": true, + "dependencies": { + "@graphql-tools/utils": "^10.0.13", + "@types/ws": "^8.0.0", + "graphql-ws": "^5.14.0", + "isomorphic-ws": "^5.0.0", + "tslib": "^2.4.0", + "ws": "^8.13.0" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + } + }, + "node_modules/@graphql-tools/executor-http": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@graphql-tools/executor-http/-/executor-http-1.0.9.tgz", + "integrity": "sha512-+NXaZd2MWbbrWHqU4EhXcrDbogeiCDmEbrAN+rMn4Nu2okDjn2MTFDbTIab87oEubQCH4Te1wDkWPKrzXup7+Q==", + "dev": true, + "dependencies": { + "@graphql-tools/utils": "^10.0.13", + "@repeaterjs/repeater": "^3.0.4", + "@whatwg-node/fetch": "^0.9.0", + "extract-files": "^11.0.0", + "meros": "^1.2.1", + "tslib": "^2.4.0", + "value-or-promise": "^1.0.12" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + } + }, + "node_modules/@graphql-tools/executor-http/node_modules/@whatwg-node/events": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@whatwg-node/events/-/events-0.1.1.tgz", + "integrity": "sha512-AyQEn5hIPV7Ze+xFoXVU3QTHXVbWPrzaOkxtENMPMuNL6VVHrp4hHfDt9nrQpjO7BgvuM95dMtkycX5M/DZR3w==", + "dev": true, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@graphql-tools/executor-http/node_modules/@whatwg-node/fetch": { + "version": "0.9.17", + "resolved": "https://registry.npmjs.org/@whatwg-node/fetch/-/fetch-0.9.17.tgz", + "integrity": "sha512-TDYP3CpCrxwxpiNY0UMNf096H5Ihf67BK1iKGegQl5u9SlpEDYrvnV71gWBGJm+Xm31qOy8ATgma9rm8Pe7/5Q==", + "dev": true, + "dependencies": { + "@whatwg-node/node-fetch": "^0.5.7", + "urlpattern-polyfill": "^10.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@graphql-tools/executor-http/node_modules/@whatwg-node/node-fetch": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/@whatwg-node/node-fetch/-/node-fetch-0.5.7.tgz", + "integrity": "sha512-YZA+N3JcW1eh2QRi7o/ij+M07M0dqID73ltgsOEMRyEc2UYVDbyomaih+CWCEZqBIDHw4KMDveXvv4SBZ4TLIw==", + "dev": true, + "dependencies": { + "@kamilkisiela/fast-url-parser": "^1.1.4", + "@whatwg-node/events": "^0.1.0", + "busboy": "^1.6.0", + "fast-querystring": "^1.1.1", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@graphql-tools/executor-http/node_modules/urlpattern-polyfill": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-10.0.0.tgz", + "integrity": "sha512-H/A06tKD7sS1O1X2SshBVeA5FLycRpjqiBeqGKmBwBDBy28EnRjORxTNe269KSSr5un5qyWi1iL61wLxpd+ZOg==", + "dev": true + }, + "node_modules/@graphql-tools/executor-legacy-ws": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@graphql-tools/executor-legacy-ws/-/executor-legacy-ws-1.0.6.tgz", + "integrity": "sha512-lDSxz9VyyquOrvSuCCnld3256Hmd+QI2lkmkEv7d4mdzkxkK4ddAWW1geQiWrQvWmdsmcnGGlZ7gDGbhEExwqg==", + "dev": true, + "dependencies": { + "@graphql-tools/utils": "^10.0.13", + "@types/ws": "^8.0.0", + "isomorphic-ws": "^5.0.0", + "tslib": "^2.4.0", + "ws": "^8.15.0" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + } + }, + "node_modules/@graphql-tools/git-loader": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/@graphql-tools/git-loader/-/git-loader-8.0.5.tgz", + "integrity": "sha512-P97/1mhruDiA6D5WUmx3n/aeGPLWj2+4dpzDOxFGGU+z9NcI/JdygMkeFpGZNHeJfw+kHfxgPcMPnxHcyhAoVA==", + "dev": true, + "dependencies": { + "@graphql-tools/graphql-tag-pluck": "8.3.0", + "@graphql-tools/utils": "^10.0.13", + "is-glob": "4.0.3", + "micromatch": "^4.0.4", + "tslib": "^2.4.0", + "unixify": "^1.0.0" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + } + }, + "node_modules/@graphql-tools/github-loader": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/github-loader/-/github-loader-8.0.1.tgz", + "integrity": "sha512-W4dFLQJ5GtKGltvh/u1apWRFKBQOsDzFxO9cJkOYZj1VzHCpRF43uLST4VbCfWve+AwBqOuKr7YgkHoxpRMkcg==", + "dev": true, + "dependencies": { + "@ardatan/sync-fetch": "^0.0.1", + "@graphql-tools/executor-http": "^1.0.9", + "@graphql-tools/graphql-tag-pluck": "^8.0.0", + "@graphql-tools/utils": "^10.0.13", + "@whatwg-node/fetch": "^0.9.0", + "tslib": "^2.4.0", + "value-or-promise": "^1.0.12" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + } + }, + "node_modules/@graphql-tools/github-loader/node_modules/@whatwg-node/events": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@whatwg-node/events/-/events-0.1.1.tgz", + "integrity": "sha512-AyQEn5hIPV7Ze+xFoXVU3QTHXVbWPrzaOkxtENMPMuNL6VVHrp4hHfDt9nrQpjO7BgvuM95dMtkycX5M/DZR3w==", + "dev": true, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@graphql-tools/github-loader/node_modules/@whatwg-node/fetch": { + "version": "0.9.17", + "resolved": "https://registry.npmjs.org/@whatwg-node/fetch/-/fetch-0.9.17.tgz", + "integrity": "sha512-TDYP3CpCrxwxpiNY0UMNf096H5Ihf67BK1iKGegQl5u9SlpEDYrvnV71gWBGJm+Xm31qOy8ATgma9rm8Pe7/5Q==", + "dev": true, + "dependencies": { + "@whatwg-node/node-fetch": "^0.5.7", + "urlpattern-polyfill": "^10.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@graphql-tools/github-loader/node_modules/@whatwg-node/node-fetch": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/@whatwg-node/node-fetch/-/node-fetch-0.5.7.tgz", + "integrity": "sha512-YZA+N3JcW1eh2QRi7o/ij+M07M0dqID73ltgsOEMRyEc2UYVDbyomaih+CWCEZqBIDHw4KMDveXvv4SBZ4TLIw==", + "dev": true, + "dependencies": { + "@kamilkisiela/fast-url-parser": "^1.1.4", + "@whatwg-node/events": "^0.1.0", + "busboy": "^1.6.0", + "fast-querystring": "^1.1.1", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@graphql-tools/github-loader/node_modules/urlpattern-polyfill": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-10.0.0.tgz", + "integrity": "sha512-H/A06tKD7sS1O1X2SshBVeA5FLycRpjqiBeqGKmBwBDBy28EnRjORxTNe269KSSr5un5qyWi1iL61wLxpd+ZOg==", + "dev": true + }, + "node_modules/@graphql-tools/graphql-file-loader": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/graphql-file-loader/-/graphql-file-loader-8.0.1.tgz", + "integrity": "sha512-7gswMqWBabTSmqbaNyWSmRRpStWlcCkBc73E6NZNlh4YNuiyKOwbvSkOUYFOqFMfEL+cFsXgAvr87Vz4XrYSbA==", + "dev": true, + "dependencies": { + "@graphql-tools/import": "7.0.1", + "@graphql-tools/utils": "^10.0.13", + "globby": "^11.0.3", + "tslib": "^2.4.0", + "unixify": "^1.0.0" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + } + }, + "node_modules/@graphql-tools/graphql-tag-pluck": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/@graphql-tools/graphql-tag-pluck/-/graphql-tag-pluck-8.3.0.tgz", + "integrity": "sha512-gNqukC+s7iHC7vQZmx1SEJQmLnOguBq+aqE2zV2+o1hxkExvKqyFli1SY/9gmukFIKpKutCIj+8yLOM+jARutw==", + "dev": true, + "dependencies": { + "@babel/core": "^7.22.9", + "@babel/parser": "^7.16.8", + "@babel/plugin-syntax-import-assertions": "^7.20.0", + "@babel/traverse": "^7.16.8", + "@babel/types": "^7.16.8", + "@graphql-tools/utils": "^10.0.13", + "tslib": "^2.4.0" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + } + }, + "node_modules/@graphql-tools/import": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/import/-/import-7.0.1.tgz", + "integrity": "sha512-935uAjAS8UAeXThqHfYVr4HEAp6nHJ2sximZKO1RzUTq5WoALMAhhGARl0+ecm6X+cqNUwIChJbjtaa6P/ML0w==", + "dev": true, + "dependencies": { + "@graphql-tools/utils": "^10.0.13", + "resolve-from": "5.0.0", + "tslib": "^2.4.0" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + } + }, + "node_modules/@graphql-tools/json-file-loader": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/json-file-loader/-/json-file-loader-8.0.1.tgz", + "integrity": "sha512-lAy2VqxDAHjVyqeJonCP6TUemrpYdDuKt25a10X6zY2Yn3iFYGnuIDQ64cv3ytyGY6KPyPB+Kp+ZfOkNDG3FQA==", + "dev": true, + "dependencies": { + "@graphql-tools/utils": "^10.0.13", + "globby": "^11.0.3", + "tslib": "^2.4.0", + "unixify": "^1.0.0" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + } + }, + "node_modules/@graphql-tools/load": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@graphql-tools/load/-/load-8.0.2.tgz", + "integrity": "sha512-S+E/cmyVmJ3CuCNfDuNF2EyovTwdWfQScXv/2gmvJOti2rGD8jTt9GYVzXaxhblLivQR9sBUCNZu/w7j7aXUCA==", + "dev": true, + "dependencies": { + "@graphql-tools/schema": "^10.0.3", + "@graphql-tools/utils": "^10.0.13", + "p-limit": "3.1.0", + "tslib": "^2.4.0" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + } + }, + "node_modules/@graphql-tools/merge": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/@graphql-tools/merge/-/merge-9.0.3.tgz", + "integrity": "sha512-FeKv9lKLMwqDu0pQjPpF59GY3HReUkWXKsMIuMuJQOKh9BETu7zPEFUELvcw8w+lwZkl4ileJsHXC9+AnsT2Lw==", + "dev": true, + "dependencies": { + "@graphql-tools/utils": "^10.0.13", + "tslib": "^2.4.0" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + } + }, + "node_modules/@graphql-tools/optimize": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@graphql-tools/optimize/-/optimize-2.0.0.tgz", + "integrity": "sha512-nhdT+CRGDZ+bk68ic+Jw1OZ99YCDIKYA5AlVAnBHJvMawSx9YQqQAIj4refNc1/LRieGiuWvhbG3jvPVYho0Dg==", + "dev": true, + "dependencies": { + "tslib": "^2.4.0" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + } + }, + "node_modules/@graphql-tools/prisma-loader": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/@graphql-tools/prisma-loader/-/prisma-loader-8.0.3.tgz", + "integrity": "sha512-oZhxnMr3Jw2WAW1h9FIhF27xWzIB7bXWM8olz4W12oII4NiZl7VRkFw9IT50zME2Bqi9LGh9pkmMWkjvbOpl+Q==", + "dev": true, + "dependencies": { + "@graphql-tools/url-loader": "^8.0.2", + "@graphql-tools/utils": "^10.0.13", + "@types/js-yaml": "^4.0.0", + "@types/json-stable-stringify": "^1.0.32", + "@whatwg-node/fetch": "^0.9.0", + "chalk": "^4.1.0", + "debug": "^4.3.1", + "dotenv": "^16.0.0", + "graphql-request": "^6.0.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.0", + "jose": "^5.0.0", + "js-yaml": "^4.0.0", + "json-stable-stringify": "^1.0.1", + "lodash": "^4.17.20", + "scuid": "^1.1.0", + "tslib": "^2.4.0", + "yaml-ast-parser": "^0.0.43" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + } + }, + "node_modules/@graphql-tools/prisma-loader/node_modules/@whatwg-node/events": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@whatwg-node/events/-/events-0.1.1.tgz", + "integrity": "sha512-AyQEn5hIPV7Ze+xFoXVU3QTHXVbWPrzaOkxtENMPMuNL6VVHrp4hHfDt9nrQpjO7BgvuM95dMtkycX5M/DZR3w==", + "dev": true, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@graphql-tools/prisma-loader/node_modules/@whatwg-node/fetch": { + "version": "0.9.17", + "resolved": "https://registry.npmjs.org/@whatwg-node/fetch/-/fetch-0.9.17.tgz", + "integrity": "sha512-TDYP3CpCrxwxpiNY0UMNf096H5Ihf67BK1iKGegQl5u9SlpEDYrvnV71gWBGJm+Xm31qOy8ATgma9rm8Pe7/5Q==", + "dev": true, + "dependencies": { + "@whatwg-node/node-fetch": "^0.5.7", + "urlpattern-polyfill": "^10.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@graphql-tools/prisma-loader/node_modules/@whatwg-node/node-fetch": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/@whatwg-node/node-fetch/-/node-fetch-0.5.7.tgz", + "integrity": "sha512-YZA+N3JcW1eh2QRi7o/ij+M07M0dqID73ltgsOEMRyEc2UYVDbyomaih+CWCEZqBIDHw4KMDveXvv4SBZ4TLIw==", + "dev": true, + "dependencies": { + "@kamilkisiela/fast-url-parser": "^1.1.4", + "@whatwg-node/events": "^0.1.0", + "busboy": "^1.6.0", + "fast-querystring": "^1.1.1", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@graphql-tools/prisma-loader/node_modules/urlpattern-polyfill": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-10.0.0.tgz", + "integrity": "sha512-H/A06tKD7sS1O1X2SshBVeA5FLycRpjqiBeqGKmBwBDBy28EnRjORxTNe269KSSr5un5qyWi1iL61wLxpd+ZOg==", + "dev": true + }, + "node_modules/@graphql-tools/relay-operation-optimizer": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/relay-operation-optimizer/-/relay-operation-optimizer-7.0.1.tgz", + "integrity": "sha512-y0ZrQ/iyqWZlsS/xrJfSir3TbVYJTYmMOu4TaSz6F4FRDTQ3ie43BlKkhf04rC28pnUOS4BO9pDcAo1D30l5+A==", + "dev": true, + "dependencies": { + "@ardatan/relay-compiler": "12.0.0", + "@graphql-tools/utils": "^10.0.13", + "tslib": "^2.4.0" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + } + }, + "node_modules/@graphql-tools/schema": { + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/@graphql-tools/schema/-/schema-10.0.3.tgz", + "integrity": "sha512-p28Oh9EcOna6i0yLaCFOnkcBDQECVf3SCexT6ktb86QNj9idnkhI+tCxnwZDh58Qvjd2nURdkbevvoZkvxzCog==", + "dev": true, + "dependencies": { + "@graphql-tools/merge": "^9.0.3", + "@graphql-tools/utils": "^10.0.13", + "tslib": "^2.4.0", + "value-or-promise": "^1.0.12" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + } + }, + "node_modules/@graphql-tools/url-loader": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@graphql-tools/url-loader/-/url-loader-8.0.2.tgz", + "integrity": "sha512-1dKp2K8UuFn7DFo1qX5c1cyazQv2h2ICwA9esHblEqCYrgf69Nk8N7SODmsfWg94OEaI74IqMoM12t7eIGwFzQ==", + "dev": true, + "dependencies": { + "@ardatan/sync-fetch": "^0.0.1", + "@graphql-tools/delegate": "^10.0.4", + "@graphql-tools/executor-graphql-ws": "^1.1.2", + "@graphql-tools/executor-http": "^1.0.9", + "@graphql-tools/executor-legacy-ws": "^1.0.6", + "@graphql-tools/utils": "^10.0.13", + "@graphql-tools/wrap": "^10.0.2", + "@types/ws": "^8.0.0", + "@whatwg-node/fetch": "^0.9.0", + "isomorphic-ws": "^5.0.0", + "tslib": "^2.4.0", + "value-or-promise": "^1.0.11", + "ws": "^8.12.0" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + } + }, + "node_modules/@graphql-tools/url-loader/node_modules/@whatwg-node/events": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@whatwg-node/events/-/events-0.1.1.tgz", + "integrity": "sha512-AyQEn5hIPV7Ze+xFoXVU3QTHXVbWPrzaOkxtENMPMuNL6VVHrp4hHfDt9nrQpjO7BgvuM95dMtkycX5M/DZR3w==", + "dev": true, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@graphql-tools/url-loader/node_modules/@whatwg-node/fetch": { + "version": "0.9.17", + "resolved": "https://registry.npmjs.org/@whatwg-node/fetch/-/fetch-0.9.17.tgz", + "integrity": "sha512-TDYP3CpCrxwxpiNY0UMNf096H5Ihf67BK1iKGegQl5u9SlpEDYrvnV71gWBGJm+Xm31qOy8ATgma9rm8Pe7/5Q==", + "dev": true, + "dependencies": { + "@whatwg-node/node-fetch": "^0.5.7", + "urlpattern-polyfill": "^10.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@graphql-tools/url-loader/node_modules/@whatwg-node/node-fetch": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/@whatwg-node/node-fetch/-/node-fetch-0.5.7.tgz", + "integrity": "sha512-YZA+N3JcW1eh2QRi7o/ij+M07M0dqID73ltgsOEMRyEc2UYVDbyomaih+CWCEZqBIDHw4KMDveXvv4SBZ4TLIw==", + "dev": true, + "dependencies": { + "@kamilkisiela/fast-url-parser": "^1.1.4", + "@whatwg-node/events": "^0.1.0", + "busboy": "^1.6.0", + "fast-querystring": "^1.1.1", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@graphql-tools/url-loader/node_modules/urlpattern-polyfill": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-10.0.0.tgz", + "integrity": "sha512-H/A06tKD7sS1O1X2SshBVeA5FLycRpjqiBeqGKmBwBDBy28EnRjORxTNe269KSSr5un5qyWi1iL61wLxpd+ZOg==", + "dev": true + }, + "node_modules/@graphql-tools/utils": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-10.1.0.tgz", + "integrity": "sha512-wLPqhgeZ9BZJPRoaQbsDN/CtJDPd/L4qmmtPkjI3NuYJ39x+Eqz1Sh34EAGMuDh+xlOHqBwHczkZUpoK9tvzjw==", + "dev": true, + "dependencies": { + "@graphql-typed-document-node/core": "^3.1.1", + "cross-inspect": "1.0.0", + "dset": "^3.1.2", + "tslib": "^2.4.0" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + } + }, + "node_modules/@graphql-tools/wrap": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@graphql-tools/wrap/-/wrap-10.0.2.tgz", + "integrity": "sha512-nb/YjBcyF02KBCy3hiyw0nBKIC+qkiDY/tGMCcIe4pM6BPEcnreaPhXA28Rdge7lKtySF4Mhbc86XafFH5bIkQ==", + "dev": true, + "dependencies": { + "@graphql-tools/delegate": "^10.0.4", + "@graphql-tools/schema": "^10.0.3", + "@graphql-tools/utils": "^10.0.13", + "tslib": "^2.4.0", + "value-or-promise": "^1.0.12" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + } + }, + "node_modules/@graphql-typed-document-node/core": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@graphql-typed-document-node/core/-/core-3.2.0.tgz", + "integrity": "sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ==", + "dev": true, + "peerDependencies": { + "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz", + "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==", + "dev": true + }, + "node_modules/@iconify-json/material-symbols": { + "version": "1.1.74", + "resolved": "https://registry.npmjs.org/@iconify-json/material-symbols/-/material-symbols-1.1.74.tgz", + "integrity": "sha512-cuQKvpGWrMNJq0i3ynO+V6yus0Smiupw92GW8Gq/4MHfYfbl1MrbVmafKQAd8RJVqiEXq4/F084OEcigf77UqQ==", + "dev": true, + "dependencies": { + "@iconify/types": "*" + } + }, + "node_modules/@iconify/tailwind": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/@iconify/tailwind/-/tailwind-0.1.4.tgz", + "integrity": "sha512-U7RzcU2fkwOfMDsGQ3mtpLIaApSnqb+vgcJJknPPbg8/NF5s7tI1o5otEMfcpnLGk4PbYB8bxmKTz7IJVUlU2Q==", + "dev": true, + "dependencies": { + "@iconify/types": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/cyberalien" + } + }, + "node_modules/@iconify/types": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@iconify/types/-/types-2.0.0.tgz", + "integrity": "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==", + "dev": true + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@jsonurl/jsonurl": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@jsonurl/jsonurl/-/jsonurl-1.1.7.tgz", + "integrity": "sha512-H3aKlfSjVoUhhNRO+2HDtVNq8UT0TV8kyAgJ29bETLdjU6Xz3s1PMzbRkfcAdwuwzHjiisabHpJoP8p+hju6bA==" + }, + "node_modules/@kamilkisiela/fast-url-parser": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@kamilkisiela/fast-url-parser/-/fast-url-parser-1.1.4.tgz", + "integrity": "sha512-gbkePEBupNydxCelHCESvFSFM8XPh1Zs/OAVRW/rKpEqPAl5PbOM90Si8mv9bvnR53uPD2s/FiRxdvSejpRJew==", + "dev": true + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@npmcli/fs": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-3.1.0.tgz", + "integrity": "sha512-7kZUAaLscfgbwBQRbvdMYaZOWyMEcPTH/tJjnyAWJ/dvvs9Ef+CERx/qJb9GExJpl1qipaDGn7KqHnFGGixd0w==", + "dev": true, + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/fs/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@npmcli/fs/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@npmcli/fs/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/@npmcli/git": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-4.1.0.tgz", + "integrity": "sha512-9hwoB3gStVfa0N31ymBmrX+GuDGdVA/QWShZVqE0HK2Af+7QGGrCTbZia/SW0ImUTjTne7SP91qxDmtXvDHRPQ==", + "dev": true, + "dependencies": { + "@npmcli/promise-spawn": "^6.0.0", + "lru-cache": "^7.4.4", + "npm-pick-manifest": "^8.0.0", + "proc-log": "^3.0.0", + "promise-inflight": "^1.0.1", + "promise-retry": "^2.0.1", + "semver": "^7.3.5", + "which": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/git/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/@npmcli/git/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@npmcli/git/node_modules/semver/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@npmcli/git/node_modules/which": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/which/-/which-3.0.1.tgz", + "integrity": "sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/git/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/@npmcli/installed-package-contents": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@npmcli/installed-package-contents/-/installed-package-contents-2.0.2.tgz", + "integrity": "sha512-xACzLPhnfD51GKvTOOuNX2/V4G4mz9/1I2MfDoye9kBM3RYe5g2YbscsaGoTlaWqkxeiapBWyseULVKpSVHtKQ==", + "dev": true, + "dependencies": { + "npm-bundled": "^3.0.0", + "npm-normalize-package-bin": "^3.0.0" + }, + "bin": { + "installed-package-contents": "lib/index.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/move-file": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-2.0.1.tgz", + "integrity": "sha512-mJd2Z5TjYWq/ttPLLGqArdtnC74J6bOzg4rMDnN+p1xTacZ2yPRCk2y0oSWQtygLR9YVQXgOcONrwtnk3JupxQ==", + "deprecated": "This functionality has been moved to @npmcli/fs", + "dev": true, + "dependencies": { + "mkdirp": "^1.0.4", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/@npmcli/move-file/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@npmcli/node-gyp": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/node-gyp/-/node-gyp-3.0.0.tgz", + "integrity": "sha512-gp8pRXC2oOxu0DUE1/M3bYtb1b3/DbJ5aM113+XJBgfXdussRAsX0YOrOhdd8WvnAR6auDBvJomGAkLKA5ydxA==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/promise-spawn": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-6.0.2.tgz", + "integrity": "sha512-gGq0NJkIGSwdbUt4yhdF8ZrmkGKVz9vAdVzpOfnom+V8PLSmSOVhZwbNvZZS1EYcJN5hzzKBxmmVVAInM6HQLg==", + "dev": true, + "dependencies": { + "which": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/promise-spawn/node_modules/which": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/which/-/which-3.0.1.tgz", + "integrity": "sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/run-script": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@npmcli/run-script/-/run-script-6.0.2.tgz", + "integrity": "sha512-NCcr1uQo1k5U+SYlnIrbAh3cxy+OQT1VtqiAbxdymSlptbzBb62AjH2xXgjNCoP073hoa1CfCAcwoZ8k96C4nA==", + "dev": true, + "dependencies": { + "@npmcli/node-gyp": "^3.0.0", + "@npmcli/promise-spawn": "^6.0.0", + "node-gyp": "^9.0.0", + "read-package-json-fast": "^3.0.0", + "which": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/run-script/node_modules/which": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/which/-/which-3.0.1.tgz", + "integrity": "sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@peculiar/asn1-schema": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-schema/-/asn1-schema-2.3.8.tgz", + "integrity": "sha512-ULB1XqHKx1WBU/tTFIA+uARuRoBVZ4pNdOA878RDrRbBfBGcSzi5HBkdScC6ZbHn8z7L8gmKCgPC1LHRrP46tA==", + "dev": true, + "dependencies": { + "asn1js": "^3.0.5", + "pvtsutils": "^1.3.5", + "tslib": "^2.6.2" + } + }, + "node_modules/@peculiar/json-schema": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/@peculiar/json-schema/-/json-schema-1.1.12.tgz", + "integrity": "sha512-coUfuoMeIB7B8/NMekxaDzLhaYmp0HZNPEjYRm9goRou8UZIC3z21s0sL9AWoCw4EG876QyO3kYrc61WNF9B/w==", + "dev": true, + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@peculiar/webcrypto": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/@peculiar/webcrypto/-/webcrypto-1.4.5.tgz", + "integrity": "sha512-oDk93QCDGdxFRM8382Zdminzs44dg3M2+E5Np+JWkpqLDyJC9DviMh8F8mEJkYuUcUOGA5jHO5AJJ10MFWdbZw==", + "dev": true, + "dependencies": { + "@peculiar/asn1-schema": "^2.3.8", + "@peculiar/json-schema": "^1.1.12", + "pvtsutils": "^1.3.5", + "tslib": "^2.6.2", + "webcrypto-core": "^1.7.8" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@pnpm/config.env-replace": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@pnpm/config.env-replace/-/config.env-replace-1.1.0.tgz", + "integrity": "sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==", + "dev": true, + "engines": { + "node": ">=12.22.0" + } + }, + "node_modules/@pnpm/network.ca-file": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@pnpm/network.ca-file/-/network.ca-file-1.0.2.tgz", + "integrity": "sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==", + "dev": true, + "dependencies": { + "graceful-fs": "4.2.10" + }, + "engines": { + "node": ">=12.22.0" + } + }, + "node_modules/@pnpm/network.ca-file/node_modules/graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", + "dev": true + }, + "node_modules/@pnpm/npm-conf": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/@pnpm/npm-conf/-/npm-conf-2.2.2.tgz", + "integrity": "sha512-UA91GwWPhFExt3IizW6bOeY/pQ0BkuNwKjk9iQW9KqxluGCrg4VenZ0/L+2Y0+ZOtme72EVvg6v0zo3AMQRCeA==", + "dev": true, + "dependencies": { + "@pnpm/config.env-replace": "^1.1.0", + "@pnpm/network.ca-file": "^1.0.1", + "config-chain": "^1.1.11" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@polka/url": { + "version": "1.0.0-next.24", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.24.tgz", + "integrity": "sha512-2LuNTFBIO0m7kKIQvvPHN6UE63VjpmL9rnEEaOOaiSPbZK+zUOYIzBAWcED+3XYzhYsd/0mD57VdxAEqqV52CQ==", + "dev": true + }, + "node_modules/@repeaterjs/repeater": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@repeaterjs/repeater/-/repeater-3.0.5.tgz", + "integrity": "sha512-l3YHBLAol6d/IKnB9LhpD0cEZWAoe3eFKUyTYWmFmCO2Q/WOckxLQAUyMZWwZV2M/m3+4vgRoaolFqaII82/TA==", + "dev": true + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.12.0.tgz", + "integrity": "sha512-+ac02NL/2TCKRrJu2wffk1kZ+RyqxVUlbjSagNgPm94frxtr+XDL12E5Ll1enWskLrtrZ2r8L3wED1orIibV/w==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.12.0.tgz", + "integrity": "sha512-OBqcX2BMe6nvjQ0Nyp7cC90cnumt8PXmO7Dp3gfAju/6YwG0Tj74z1vKrfRz7qAv23nBcYM8BCbhrsWqO7PzQQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.12.0.tgz", + "integrity": "sha512-X64tZd8dRE/QTrBIEs63kaOBG0b5GVEd3ccoLtyf6IdXtHdh8h+I56C2yC3PtC9Ucnv0CpNFJLqKFVgCYe0lOQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.12.0.tgz", + "integrity": "sha512-cc71KUZoVbUJmGP2cOuiZ9HSOP14AzBAThn3OU+9LcA1+IUqswJyR1cAJj3Mg55HbjZP6OLAIscbQsQLrpgTOg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.12.0.tgz", + "integrity": "sha512-a6w/Y3hyyO6GlpKL2xJ4IOh/7d+APaqLYdMf86xnczU3nurFTaVN9s9jOXQg97BE4nYm/7Ga51rjec5nfRdrvA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.12.0.tgz", + "integrity": "sha512-0fZBq27b+D7Ar5CQMofVN8sggOVhEtzFUwOwPppQt0k+VR+7UHMZZY4y+64WJ06XOhBTKXtQB/Sv0NwQMXyNAA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.12.0.tgz", + "integrity": "sha512-eTvzUS3hhhlgeAv6bfigekzWZjaEX9xP9HhxB0Dvrdbkk5w/b+1Sxct2ZuDxNJKzsRStSq1EaEkVSEe7A7ipgQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.12.0.tgz", + "integrity": "sha512-ix+qAB9qmrCRiaO71VFfY8rkiAZJL8zQRXveS27HS+pKdjwUfEhqo2+YF2oI+H/22Xsiski+qqwIBxVewLK7sw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.12.0.tgz", + "integrity": "sha512-TenQhZVOtw/3qKOPa7d+QgkeM6xY0LtwzR8OplmyL5LrgTWIXpTQg2Q2ycBf8jm+SFW2Wt/DTn1gf7nFp3ssVA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.12.0.tgz", + "integrity": "sha512-LfFdRhNnW0zdMvdCb5FNuWlls2WbbSridJvxOvYWgSBOYZtgBfW9UGNJG//rwMqTX1xQE9BAodvMH9tAusKDUw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.12.0.tgz", + "integrity": "sha512-JPDxovheWNp6d7AHCgsUlkuCKvtu3RB55iNEkaQcf0ttsDU/JZF+iQnYcQJSk/7PtT4mjjVG8N1kpwnI9SLYaw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.12.0.tgz", + "integrity": "sha512-fjtuvMWRGJn1oZacG8IPnzIV6GF2/XG+h71FKn76OYFqySXInJtseAqdprVTDTyqPxQOG9Exak5/E9Z3+EJ8ZA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.12.0.tgz", + "integrity": "sha512-ZYmr5mS2wd4Dew/JjT0Fqi2NPB/ZhZ2VvPp7SmvPZb4Y1CG/LRcS6tcRo2cYU7zLK5A7cdbhWnnWmUjoI4qapg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@sigstore/bundle": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@sigstore/bundle/-/bundle-1.1.0.tgz", + "integrity": "sha512-PFutXEy0SmQxYI4texPw3dd2KewuNqv7OuK1ZFtY2fM754yhvG2KdgwIhRnoEE2uHdtdGNQ8s0lb94dW9sELog==", + "dev": true, + "dependencies": { + "@sigstore/protobuf-specs": "^0.2.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@sigstore/protobuf-specs": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@sigstore/protobuf-specs/-/protobuf-specs-0.2.1.tgz", + "integrity": "sha512-XTWVxnWJu+c1oCshMLwnKvz8ZQJJDVOlciMfgpJBQbThVjKTCG8dwyhgLngBD2KN0ap9F/gOV8rFDEx8uh7R2A==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@sigstore/sign": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@sigstore/sign/-/sign-1.0.0.tgz", + "integrity": "sha512-INxFVNQteLtcfGmcoldzV6Je0sbbfh9I16DM4yJPw3j5+TFP8X6uIiA18mvpEa9yyeycAKgPmOA3X9hVdVTPUA==", + "dev": true, + "dependencies": { + "@sigstore/bundle": "^1.1.0", + "@sigstore/protobuf-specs": "^0.2.0", + "make-fetch-happen": "^11.0.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@sigstore/tuf": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@sigstore/tuf/-/tuf-1.0.3.tgz", + "integrity": "sha512-2bRovzs0nJZFlCN3rXirE4gwxCn97JNjMmwpecqlbgV9WcxX7WRuIrgzx/X7Ib7MYRbyUTpBYE0s2x6AmZXnlg==", + "dev": true, + "dependencies": { + "@sigstore/protobuf-specs": "^0.2.0", + "tuf-js": "^1.1.7" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true + }, + "node_modules/@sindresorhus/is": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.6.0.tgz", + "integrity": "sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==", + "dev": true, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/@sveltejs/adapter-static": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sveltejs/adapter-static/-/adapter-static-3.0.1.tgz", + "integrity": "sha512-6lMvf7xYEJ+oGeR5L8DFJJrowkefTK6ZgA4JiMqoClMkKq0s6yvsd3FZfCFvX1fQ0tpCD7fkuRVHsnUVgsHyNg==", + "dev": true, + "peerDependencies": { + "@sveltejs/kit": "^2.0.0" + } + }, + "node_modules/@sveltejs/kit": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.5.2.tgz", + "integrity": "sha512-1Pm2lsBYURQsjnLyZa+jw75eVD4gYHxGRwPyFe4DAmB3FjTVR8vRNWGeuDLGFcKMh/B1ij6FTUrc9GrerogCng==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "@types/cookie": "^0.6.0", + "cookie": "^0.6.0", + "devalue": "^4.3.2", + "esm-env": "^1.0.0", + "import-meta-resolve": "^4.0.0", + "kleur": "^4.1.5", + "magic-string": "^0.30.5", + "mrmime": "^2.0.0", + "sade": "^1.8.1", + "set-cookie-parser": "^2.6.0", + "sirv": "^2.0.4", + "tiny-glob": "^0.2.9" + }, + "bin": { + "svelte-kit": "svelte-kit.js" + }, + "engines": { + "node": ">=18.13" + }, + "peerDependencies": { + "@sveltejs/vite-plugin-svelte": "^3.0.0", + "svelte": "^4.0.0 || ^5.0.0-next.0", + "vite": "^5.0.3" + } + }, + "node_modules/@sveltejs/vite-plugin-svelte": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-3.0.2.tgz", + "integrity": "sha512-MpmF/cju2HqUls50WyTHQBZUV3ovV/Uk8k66AN2gwHogNAG8wnW8xtZDhzNBsFJJuvmq1qnzA5kE7YfMJNFv2Q==", + "dev": true, + "dependencies": { + "@sveltejs/vite-plugin-svelte-inspector": "^2.0.0", + "debug": "^4.3.4", + "deepmerge": "^4.3.1", + "kleur": "^4.1.5", + "magic-string": "^0.30.5", + "svelte-hmr": "^0.15.3", + "vitefu": "^0.2.5" + }, + "engines": { + "node": "^18.0.0 || >=20" + }, + "peerDependencies": { + "svelte": "^4.0.0 || ^5.0.0-next.0", + "vite": "^5.0.0" + } + }, + "node_modules/@sveltejs/vite-plugin-svelte-inspector": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte-inspector/-/vite-plugin-svelte-inspector-2.0.0.tgz", + "integrity": "sha512-gjr9ZFg1BSlIpfZ4PRewigrvYmHWbDrq2uvvPB1AmTWKuM+dI1JXQSUu2pIrYLb/QncyiIGkFDFKTwJ0XqQZZg==", + "dev": true, + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.0.0 || >=20" + }, + "peerDependencies": { + "@sveltejs/vite-plugin-svelte": "^3.0.0", + "svelte": "^4.0.0 || ^5.0.0-next.0", + "vite": "^5.0.0" + } + }, + "node_modules/@szmarczak/http-timer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", + "integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==", + "dev": true, + "dependencies": { + "defer-to-connect": "^2.0.1" + }, + "engines": { + "node": ">=14.16" + } + }, + "node_modules/@tootallnate/once": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", + "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tufjs/canonical-json": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@tufjs/canonical-json/-/canonical-json-1.0.0.tgz", + "integrity": "sha512-QTnf++uxunWvG2z3UFNzAoQPHxnSXOwtaI3iJ+AohhV+5vONuArPjJE7aPXPVXfXJsqrVbZBu9b81AJoSd09IQ==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@tufjs/models": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tufjs/models/-/models-1.0.4.tgz", + "integrity": "sha512-qaGV9ltJP0EO25YfFUPhxRVK0evXFIAGicsVXuRim4Ed9cjPxYhNnNJ49SFmbeLgtxpslIkX317IgpfcHPVj/A==", + "dev": true, + "dependencies": { + "@tufjs/canonical-json": "1.0.0", + "minimatch": "^9.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@types/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==", + "dev": true + }, + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==" + }, + "node_modules/@types/http-cache-semantics": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", + "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==", + "dev": true + }, + "node_modules/@types/js-yaml": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.9.tgz", + "integrity": "sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==", + "dev": true + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true + }, + "node_modules/@types/json-stable-stringify": { + "version": "1.0.36", + "resolved": "https://registry.npmjs.org/@types/json-stable-stringify/-/json-stable-stringify-1.0.36.tgz", + "integrity": "sha512-b7bq23s4fgBB76n34m2b3RBf6M369B0Z9uRR8aHTMd8kZISRkmDEpPD8hhpYvDFzr3bJCPES96cm3Q6qRNDbQw==", + "dev": true + }, + "node_modules/@types/node": { + "version": "20.11.24", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.24.tgz", + "integrity": "sha512-Kza43ewS3xoLgCEpQrsT+xRo/EJej1y0kVYGiLFE1NEODXGzTfwiC6tXTLMQskn1X4/Rjlh0MQUvx9W+L9long==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/pug": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@types/pug/-/pug-2.0.10.tgz", + "integrity": "sha512-Sk/uYFOBAB7mb74XcpizmH0KOR2Pv3D2Hmrh1Dmy5BmK3MpdSa5kqZcg6EKBdklU0bFXX9gCfzvpnyUehrPIuA==", + "dev": true + }, + "node_modules/@types/semver": { + "version": "7.5.8", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", + "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", + "dev": true + }, + "node_modules/@types/ws": { + "version": "8.5.10", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz", + "integrity": "sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.1.0.tgz", + "integrity": "sha512-j6vT/kCulhG5wBmGtstKeiVr1rdXE4nk+DT1k6trYkwlrvW9eOF5ZbgKnd/YR6PcM4uTEXa0h6Fcvf6X7Dxl0w==", + "dev": true, + "dependencies": { + "@eslint-community/regexpp": "^4.5.1", + "@typescript-eslint/scope-manager": "7.1.0", + "@typescript-eslint/type-utils": "7.1.0", + "@typescript-eslint/utils": "7.1.0", + "@typescript-eslint/visitor-keys": "7.1.0", + "debug": "^4.3.4", + "graphemer": "^1.4.0", + "ignore": "^5.2.4", + "natural-compare": "^1.4.0", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^7.0.0", + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/@typescript-eslint/parser": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.1.0.tgz", + "integrity": "sha512-V1EknKUubZ1gWFjiOZhDSNToOjs63/9O0puCgGS8aDOgpZY326fzFu15QAUjwaXzRZjf/qdsdBrckYdv9YxB8w==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "7.1.0", + "@typescript-eslint/types": "7.1.0", + "@typescript-eslint/typescript-estree": "7.1.0", + "@typescript-eslint/visitor-keys": "7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.1.0.tgz", + "integrity": "sha512-6TmN4OJiohHfoOdGZ3huuLhpiUgOGTpgXNUPJgeZOZR3DnIpdSgtt83RS35OYNNXxM4TScVlpVKC9jyQSETR1A==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.1.0", + "@typescript-eslint/visitor-keys": "7.1.0" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.1.0.tgz", + "integrity": "sha512-UZIhv8G+5b5skkcuhgvxYWHjk7FW7/JP5lPASMEUoliAPwIH/rxoUSQPia2cuOj9AmDZmwUl1usKm85t5VUMew==", + "dev": true, + "dependencies": { + "@typescript-eslint/typescript-estree": "7.1.0", + "@typescript-eslint/utils": "7.1.0", + "debug": "^4.3.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.1.0.tgz", + "integrity": "sha512-qTWjWieJ1tRJkxgZYXx6WUYtWlBc48YRxgY2JN1aGeVpkhmnopq+SUC8UEVGNXIvWH7XyuTjwALfG6bFEgCkQA==", + "dev": true, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.1.0.tgz", + "integrity": "sha512-k7MyrbD6E463CBbSpcOnwa8oXRdHzH1WiVzOipK3L5KSML92ZKgUBrTlehdi7PEIMT8k0bQixHUGXggPAlKnOQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.1.0", + "@typescript-eslint/visitor-keys": "7.1.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "9.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/@typescript-eslint/utils": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.1.0.tgz", + "integrity": "sha512-WUFba6PZC5OCGEmbweGpnNJytJiLG7ZvDBJJoUcX4qZYf1mGZ97mO2Mps6O2efxJcJdRNpqweCistDbZMwIVHw==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@types/json-schema": "^7.0.12", + "@types/semver": "^7.5.0", + "@typescript-eslint/scope-manager": "7.1.0", + "@typescript-eslint/types": "7.1.0", + "@typescript-eslint/typescript-estree": "7.1.0", + "semver": "^7.5.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.1.0.tgz", + "integrity": "sha512-FhUqNWluiGNzlvnDZiXad4mZRhtghdoKW6e98GoEOYSu5cND+E39rG5KwJMUzeENwm1ztYBRqof8wMLP+wNPIA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.1.0", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, + "node_modules/@urql/core": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@urql/core/-/core-4.3.0.tgz", + "integrity": "sha512-wT+FeL8DG4x5o6RfHEnONNFVDM3616ouzATMYUClB6CB+iIu2mwfBKd7xSUxYOZmwtxna5/hDRQdMl3nbQZlnw==", + "dependencies": { + "@0no-co/graphql.web": "^1.0.1", + "wonka": "^6.3.2" + } + }, + "node_modules/@urql/svelte": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@urql/svelte/-/svelte-4.1.0.tgz", + "integrity": "sha512-Ov3EclCjaXPPTjKNTcIDlAG3qY/jhLjl/J9yyz9FeLUQ9S2jEgsvlzNXibrY27f4ihD4gH36CNGuj1XOi5hEEQ==", + "dependencies": { + "@urql/core": "^4.3.0", + "wonka": "^6.3.2" + }, + "peerDependencies": { + "svelte": "^3.0.0 || ^4.0.0" + } + }, + "node_modules/@vitest/expect": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.3.1.tgz", + "integrity": "sha512-xofQFwIzfdmLLlHa6ag0dPV8YsnKOCP1KdAeVVh34vSjN2dcUiXYCD9htu/9eM7t8Xln4v03U9HLxLpPlsXdZw==", + "dev": true, + "dependencies": { + "@vitest/spy": "1.3.1", + "@vitest/utils": "1.3.1", + "chai": "^4.3.10" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-1.3.1.tgz", + "integrity": "sha512-5FzF9c3jG/z5bgCnjr8j9LNq/9OxV2uEBAITOXfoe3rdZJTdO7jzThth7FXv/6b+kdY65tpRQB7WaKhNZwX+Kg==", + "dev": true, + "dependencies": { + "@vitest/utils": "1.3.1", + "p-limit": "^5.0.0", + "pathe": "^1.1.1" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner/node_modules/p-limit": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-5.0.0.tgz", + "integrity": "sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@vitest/runner/node_modules/yocto-queue": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", + "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", + "dev": true, + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@vitest/snapshot": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-1.3.1.tgz", + "integrity": "sha512-EF++BZbt6RZmOlE3SuTPu/NfwBF6q4ABS37HHXzs2LUVPBLx2QoY/K0fKpRChSo8eLiuxcbCVfqKgx/dplCDuQ==", + "dev": true, + "dependencies": { + "magic-string": "^0.30.5", + "pathe": "^1.1.1", + "pretty-format": "^29.7.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/spy": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.3.1.tgz", + "integrity": "sha512-xAcW+S099ylC9VLU7eZfdT9myV67Nor9w9zhf0mGCYJSO+zM2839tOeROTdikOi/8Qeusffvxb/MyBSOja1Uig==", + "dev": true, + "dependencies": { + "tinyspy": "^2.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.3.1.tgz", + "integrity": "sha512-d3Waie/299qqRyHTm2DjADeTaNdNSVsnwHPWrs20JMpjh6eiVq7ggggweO8rc4arhf6rRkWuHKwvxGvejUXZZQ==", + "dev": true, + "dependencies": { + "diff-sequences": "^29.6.3", + "estree-walker": "^3.0.3", + "loupe": "^2.3.7", + "pretty-format": "^29.7.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@whatwg-node/events": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/@whatwg-node/events/-/events-0.0.3.tgz", + "integrity": "sha512-IqnKIDWfXBJkvy/k6tzskWTc2NK3LcqHlb+KHGCrjOCH4jfQckRX0NAiIcC/vIqQkzLYw2r2CTSwAxcrtcD6lA==", + "dev": true + }, + "node_modules/@whatwg-node/fetch": { + "version": "0.8.8", + "resolved": "https://registry.npmjs.org/@whatwg-node/fetch/-/fetch-0.8.8.tgz", + "integrity": "sha512-CdcjGC2vdKhc13KKxgsc6/616BQ7ooDIgPeTuAiE8qfCnS0mGzcfCOoZXypQSz73nxI+GWc7ZReIAVhxoE1KCg==", + "dev": true, + "dependencies": { + "@peculiar/webcrypto": "^1.4.0", + "@whatwg-node/node-fetch": "^0.3.6", + "busboy": "^1.6.0", + "urlpattern-polyfill": "^8.0.0", + "web-streams-polyfill": "^3.2.1" + } + }, + "node_modules/@whatwg-node/node-fetch": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@whatwg-node/node-fetch/-/node-fetch-0.3.6.tgz", + "integrity": "sha512-w9wKgDO4C95qnXZRwZTfCmLWqyRnooGjcIwG0wADWjw9/HN0p7dtvtgSvItZtUyNteEvgTrd8QojNEqV6DAGTA==", + "dev": true, + "dependencies": { + "@whatwg-node/events": "^0.0.3", + "busboy": "^1.6.0", + "fast-querystring": "^1.1.1", + "fast-url-parser": "^1.1.3", + "tslib": "^2.3.1" + } + }, + "node_modules/@zerodevx/svelte-toast": { + "version": "0.9.5", + "resolved": "https://registry.npmjs.org/@zerodevx/svelte-toast/-/svelte-toast-0.9.5.tgz", + "integrity": "sha512-JLeB/oRdJfT+dz9A5bgd3Z7TuQnBQbeUtXrGIrNWMGqWbabpepBF2KxtWVhL2qtxpRqhae2f6NAOzH7xs4jUSw==", + "dev": true, + "peerDependencies": { + "svelte": "^3.57.0 || ^4.0.0" + } + }, + "node_modules/abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true + }, + "node_modules/acorn": { + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", + "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/agent-base": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", + "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", + "dev": true, + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/agentkeepalive": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.5.0.tgz", + "integrity": "sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==", + "dev": true, + "dependencies": { + "humanize-ms": "^1.2.1" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "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" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-align": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", + "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", + "dev": true, + "dependencies": { + "string-width": "^4.1.0" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "dev": true + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/aproba": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", + "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", + "dev": true + }, + "node_modules/are-we-there-yet": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz", + "integrity": "sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==", + "dev": true, + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", + "dev": true + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/aria-query": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", + "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", + "dev": true + }, + "node_modules/asn1js": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/asn1js/-/asn1js-3.0.5.tgz", + "integrity": "sha512-FVnvrKJwpt9LP2lAMl8qZswRNm3T4q9CON+bxldk2iwk3FFpuwhx2FfinyitizWHsVYyaY+y5JzDR0rCMV5yTQ==", + "dev": true, + "dependencies": { + "pvtsutils": "^1.3.2", + "pvutils": "^1.1.3", + "tslib": "^2.4.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/auto-bind": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/auto-bind/-/auto-bind-4.0.0.tgz", + "integrity": "sha512-Hdw8qdNiqdJ8LqT0iK0sVzkFbzg6fhnQqqfWhBDxcHZvU75+B+ayzTy8x+k5Ix0Y92XOhOUlx74ps+bA6BeYMQ==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/autoprefixer": { + "version": "10.4.18", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.18.tgz", + "integrity": "sha512-1DKbDfsr6KUElM6wg+0zRNkB/Q7WcKYAaK+pzXn+Xqmszm/5Xa9coeNdtP88Vi+dPzZnMjhge8GIV49ZQkDa+g==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "browserslist": "^4.23.0", + "caniuse-lite": "^1.0.30001591", + "fraction.js": "^4.3.7", + "normalize-range": "^0.1.2", + "picocolors": "^1.0.0", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/axobject-query": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.0.0.tgz", + "integrity": "sha512-+60uv1hiVFhHZeO+Lz0RYzsVHy5Wr1ayX0mwda9KPDVLNJgZ1T9Ny7VmFbLDzxsH0D87I86vgj3gFrjTJUYznw==", + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/babel-plugin-syntax-trailing-function-commas": { + "version": "7.0.0-beta.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-7.0.0-beta.0.tgz", + "integrity": "sha512-Xj9XuRuz3nTSbaTXWv3itLOcxyF4oPD8douBBmj7U9BBC6nEBYfyOJYQMf/8PJAFotC62UY5dFfIGEPr7WswzQ==", + "dev": true + }, + "node_modules/babel-preset-fbjs": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/babel-preset-fbjs/-/babel-preset-fbjs-3.4.0.tgz", + "integrity": "sha512-9ywCsCvo1ojrw0b+XYk7aFvTH6D9064t0RIL1rtMf3nsa02Xw41MS7sZw216Im35xj/UY0PDBQsa1brUDDF1Ow==", + "dev": true, + "dependencies": { + "@babel/plugin-proposal-class-properties": "^7.0.0", + "@babel/plugin-proposal-object-rest-spread": "^7.0.0", + "@babel/plugin-syntax-class-properties": "^7.0.0", + "@babel/plugin-syntax-flow": "^7.0.0", + "@babel/plugin-syntax-jsx": "^7.0.0", + "@babel/plugin-syntax-object-rest-spread": "^7.0.0", + "@babel/plugin-transform-arrow-functions": "^7.0.0", + "@babel/plugin-transform-block-scoped-functions": "^7.0.0", + "@babel/plugin-transform-block-scoping": "^7.0.0", + "@babel/plugin-transform-classes": "^7.0.0", + "@babel/plugin-transform-computed-properties": "^7.0.0", + "@babel/plugin-transform-destructuring": "^7.0.0", + "@babel/plugin-transform-flow-strip-types": "^7.0.0", + "@babel/plugin-transform-for-of": "^7.0.0", + "@babel/plugin-transform-function-name": "^7.0.0", + "@babel/plugin-transform-literals": "^7.0.0", + "@babel/plugin-transform-member-expression-literals": "^7.0.0", + "@babel/plugin-transform-modules-commonjs": "^7.0.0", + "@babel/plugin-transform-object-super": "^7.0.0", + "@babel/plugin-transform-parameters": "^7.0.0", + "@babel/plugin-transform-property-literals": "^7.0.0", + "@babel/plugin-transform-react-display-name": "^7.0.0", + "@babel/plugin-transform-react-jsx": "^7.0.0", + "@babel/plugin-transform-shorthand-properties": "^7.0.0", + "@babel/plugin-transform-spread": "^7.0.0", + "@babel/plugin-transform-template-literals": "^7.0.0", + "babel-plugin-syntax-trailing-function-commas": "^7.0.0-beta.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/boxen": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-7.1.1.tgz", + "integrity": "sha512-2hCgjEmP8YLWQ130n2FerGv7rYpfBmnmp9Uy2Le1vge6X3gZIfSmEzP5QTDElFxcvVcXlEn8Aq6MU/PZygIOog==", + "dev": true, + "dependencies": { + "ansi-align": "^3.0.1", + "camelcase": "^7.0.1", + "chalk": "^5.2.0", + "cli-boxes": "^3.0.0", + "string-width": "^5.1.2", + "type-fest": "^2.13.0", + "widest-line": "^4.0.1", + "wrap-ansi": "^8.1.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/boxen/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/boxen/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/boxen/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "dev": true, + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/boxen/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "node_modules/boxen/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/boxen/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/boxen/node_modules/type-fest": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", + "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", + "dev": true, + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/boxen/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.23.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", + "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001587", + "electron-to-chromium": "^1.4.668", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.13" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "dev": true, + "dependencies": { + "node-int64": "^0.4.0" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "node_modules/builtins": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.0.1.tgz", + "integrity": "sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==", + "dev": true, + "dependencies": { + "semver": "^7.0.0" + } + }, + "node_modules/builtins/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/builtins/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/builtins/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/busboy": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", + "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", + "dev": true, + "dependencies": { + "streamsearch": "^1.1.0" + }, + "engines": { + "node": ">=10.16.0" + } + }, + "node_modules/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/cacache": { + "version": "17.1.4", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-17.1.4.tgz", + "integrity": "sha512-/aJwG2l3ZMJ1xNAnqbMpA40of9dj/pIH3QfiuQSqjfPJF747VR0J/bHn+/KdNnHKc6XQcWt/AfRSBft82W1d2A==", + "dev": true, + "dependencies": { + "@npmcli/fs": "^3.1.0", + "fs-minipass": "^3.0.0", + "glob": "^10.2.2", + "lru-cache": "^7.7.1", + "minipass": "^7.0.3", + "minipass-collect": "^1.0.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "p-map": "^4.0.0", + "ssri": "^10.0.0", + "tar": "^6.1.11", + "unique-filename": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/cacache/node_modules/glob": { + "version": "10.3.10", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", + "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.3.5", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", + "path-scurry": "^1.10.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/cacache/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/cacache/node_modules/minipass": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/cacheable-lookup": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz", + "integrity": "sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==", + "dev": true, + "engines": { + "node": ">=14.16" + } + }, + "node_modules/cacheable-request": { + "version": "10.2.14", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-10.2.14.tgz", + "integrity": "sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==", + "dev": true, + "dependencies": { + "@types/http-cache-semantics": "^4.0.2", + "get-stream": "^6.0.1", + "http-cache-semantics": "^4.1.1", + "keyv": "^4.5.3", + "mimic-response": "^4.0.0", + "normalize-url": "^8.0.0", + "responselike": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + } + }, + "node_modules/call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/camel-case": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", + "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", + "dev": true, + "dependencies": { + "pascal-case": "^3.1.2", + "tslib": "^2.0.3" + } + }, + "node_modules/camelcase": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-7.0.1.tgz", + "integrity": "sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==", + "dev": true, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/camelcase-css": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001593", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001593.tgz", + "integrity": "sha512-UWM1zlo3cZfkpBysd7AS+z+v007q9G1+fLTUU42rQnY6t2axoogPW/xol6T7juU5EUoOhML4WgBIdG+9yYqAjQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/capital-case": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/capital-case/-/capital-case-1.0.4.tgz", + "integrity": "sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A==", + "dev": true, + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3", + "upper-case-first": "^2.0.2" + } + }, + "node_modules/chai": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.4.1.tgz", + "integrity": "sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==", + "dev": true, + "dependencies": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.3", + "deep-eql": "^4.1.3", + "get-func-name": "^2.0.2", + "loupe": "^2.3.6", + "pathval": "^1.1.1", + "type-detect": "^4.0.8" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/change-case": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/change-case/-/change-case-4.1.2.tgz", + "integrity": "sha512-bSxY2ws9OtviILG1EiY5K7NNxkqg/JnRnFxLtKQ96JaviiIxi7djMrSd0ECT9AC+lttClmYwKw53BWpOMblo7A==", + "dev": true, + "dependencies": { + "camel-case": "^4.1.2", + "capital-case": "^1.0.4", + "constant-case": "^3.0.4", + "dot-case": "^3.0.4", + "header-case": "^2.0.4", + "no-case": "^3.0.4", + "param-case": "^3.0.4", + "pascal-case": "^3.1.2", + "path-case": "^3.0.4", + "sentence-case": "^3.0.4", + "snake-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/change-case-all": { + "version": "1.0.15", + "resolved": "https://registry.npmjs.org/change-case-all/-/change-case-all-1.0.15.tgz", + "integrity": "sha512-3+GIFhk3sNuvFAJKU46o26OdzudQlPNBCu1ZQi3cMeMHhty1bhDxu2WrEilVNYaGvqUtR1VSigFcJOiS13dRhQ==", + "dev": true, + "dependencies": { + "change-case": "^4.1.2", + "is-lower-case": "^2.0.2", + "is-upper-case": "^2.0.2", + "lower-case": "^2.0.2", + "lower-case-first": "^2.0.2", + "sponge-case": "^1.0.1", + "swap-case": "^2.0.2", + "title-case": "^3.0.3", + "upper-case": "^2.0.2", + "upper-case-first": "^2.0.2" + } + }, + "node_modules/chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true + }, + "node_modules/check-error": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", + "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", + "dev": true, + "dependencies": { + "get-func-name": "^2.0.2" + }, + "engines": { + "node": "*" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "engines": { + "node": ">=8" + } + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/cli-boxes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-3.0.0.tgz", + "integrity": "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-spinners": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", + "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", + "dev": true, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-table3": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.3.tgz", + "integrity": "sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0" + }, + "engines": { + "node": "10.* || >= 12.*" + }, + "optionalDependencies": { + "@colors/colors": "1.5.0" + } + }, + "node_modules/cli-truncate": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", + "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", + "dev": true, + "dependencies": { + "slice-ansi": "^3.0.0", + "string-width": "^4.2.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-width": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", + "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/code-red": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/code-red/-/code-red-1.0.4.tgz", + "integrity": "sha512-7qJWqItLA8/VPVlKJlFXU+NBlo/qyfs39aJcuMT/2ere32ZqvF5OSxgdM5xOfJJ7O429gg2HM47y8v9P+9wrNw==", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.15", + "@types/estree": "^1.0.1", + "acorn": "^8.10.0", + "estree-walker": "^3.0.3", + "periscopic": "^3.1.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "dev": true, + "bin": { + "color-support": "bin.js" + } + }, + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true + }, + "node_modules/commander": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "dev": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/common-tags": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz", + "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==", + "dev": true, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/config-chain": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", + "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", + "dev": true, + "dependencies": { + "ini": "^1.3.4", + "proto-list": "~1.2.1" + } + }, + "node_modules/config-chain/node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, + "node_modules/configstore": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-6.0.0.tgz", + "integrity": "sha512-cD31W1v3GqUlQvbBCGcXmd2Nj9SvLDOP1oQ0YFuLETufzSPaKp11rYBsSOm7rCsW3OnIRAFM3OxRhceaXNYHkA==", + "dev": true, + "dependencies": { + "dot-prop": "^6.0.1", + "graceful-fs": "^4.2.6", + "unique-string": "^3.0.0", + "write-file-atomic": "^3.0.3", + "xdg-basedir": "^5.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/yeoman/configstore?sponsor=1" + } + }, + "node_modules/console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", + "dev": true + }, + "node_modules/constant-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/constant-case/-/constant-case-3.0.4.tgz", + "integrity": "sha512-I2hSBi7Vvs7BEuJDr5dDHfzb/Ruj3FyvFyh7KLilAjNQw3Be+xgqUBA2W6scVEcL0hL1dwPRtIqEPVUCKkSsyQ==", + "dev": true, + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3", + "upper-case": "^2.0.2" + } + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, + "node_modules/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cosmiconfig": { + "version": "8.3.6", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", + "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", + "dev": true, + "dependencies": { + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0", + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/cross-fetch": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.8.tgz", + "integrity": "sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==", + "dev": true, + "dependencies": { + "node-fetch": "^2.6.12" + } + }, + "node_modules/cross-inspect": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/cross-inspect/-/cross-inspect-1.0.0.tgz", + "integrity": "sha512-4PFfn4b5ZN6FMNGSZlyb7wUhuN8wvj8t/VQHZdM4JsDcruGJ8L2kf9zao98QIrBPFCpdk27qst/AGTl7pL3ypQ==", + "dev": true, + "dependencies": { + "tslib": "^2.4.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/crypto-random-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-4.0.0.tgz", + "integrity": "sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==", + "dev": true, + "dependencies": { + "type-fest": "^1.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/crypto-random-string/node_modules/type-fest": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", + "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/css-tree": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", + "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", + "dependencies": { + "mdn-data": "2.0.30", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/dataloader": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/dataloader/-/dataloader-2.2.2.tgz", + "integrity": "sha512-8YnDaaf7N3k/q5HnTJVuzSyLETjoZjVmHc4AeKAzOvKHEFQKcn64OKBfzHYtE9zGjctNM7V9I0MfnUVLpi7M5g==", + "dev": true + }, + "node_modules/date-fns": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-3.3.1.tgz", + "integrity": "sha512-y8e109LYGgoQDveiEBD3DYXKba1jWf5BA8YU1FL5Tvm0BTdEfy54WLCwnuYWZNnzzvALy/QQ4Hov+Q9RVRv+Zw==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/kossnocorp" + } + }, + "node_modules/debounce": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz", + "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==", + "dev": true + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dev": true, + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decompress-response/node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/deep-eql": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", + "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", + "dev": true, + "dependencies": { + "type-detect": "^4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "dev": true, + "dependencies": { + "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/defer-to-connect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", + "dev": true + }, + "node_modules/dependency-graph": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.11.0.tgz", + "integrity": "sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg==", + "dev": true, + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/detect-indent": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", + "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/devalue": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/devalue/-/devalue-4.3.2.tgz", + "integrity": "sha512-KqFl6pOgOW+Y6wJgu80rHpo2/3H07vr8ntR9rkkFIRETewbf5GaYYcakYfiKz89K+sLsuPkQIZaXDMjUObZwWg==", + "dev": true + }, + "node_modules/didyoumean": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", + "dev": true + }, + "node_modules/diff-sequences": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", + "dev": true + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/dot-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", + "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", + "dev": true, + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/dot-prop": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz", + "integrity": "sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==", + "dev": true, + "dependencies": { + "is-obj": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/dotenv": { + "version": "16.4.5", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", + "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/dset": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/dset/-/dset-3.1.3.tgz", + "integrity": "sha512-20TuZZHCEZ2O71q9/+8BwKwZ0QtD9D8ObhrihJPr+vLLYlSuAU3/zL4cSlgbfeoGHTjCSJBa7NGcrF9/Bx/WJQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true + }, + "node_modules/electron-to-chromium": { + "version": "1.4.690", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.690.tgz", + "integrity": "sha512-+2OAGjUx68xElQhydpcbqH50hE8Vs2K6TkAeLhICYfndb67CVH0UsZaijmRUE3rHlIxU1u0jxwhgVe6fK3YANA==", + "dev": true + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "dev": true, + "optional": true, + "dependencies": { + "iconv-lite": "^0.6.2" + } + }, + "node_modules/encoding/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/err-code": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", + "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", + "dev": true + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es6-promise": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.3.1.tgz", + "integrity": "sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg==", + "dev": true + }, + "node_modules/esbuild": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.12.tgz", + "integrity": "sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.19.12", + "@esbuild/android-arm": "0.19.12", + "@esbuild/android-arm64": "0.19.12", + "@esbuild/android-x64": "0.19.12", + "@esbuild/darwin-arm64": "0.19.12", + "@esbuild/darwin-x64": "0.19.12", + "@esbuild/freebsd-arm64": "0.19.12", + "@esbuild/freebsd-x64": "0.19.12", + "@esbuild/linux-arm": "0.19.12", + "@esbuild/linux-arm64": "0.19.12", + "@esbuild/linux-ia32": "0.19.12", + "@esbuild/linux-loong64": "0.19.12", + "@esbuild/linux-mips64el": "0.19.12", + "@esbuild/linux-ppc64": "0.19.12", + "@esbuild/linux-riscv64": "0.19.12", + "@esbuild/linux-s390x": "0.19.12", + "@esbuild/linux-x64": "0.19.12", + "@esbuild/netbsd-x64": "0.19.12", + "@esbuild/openbsd-x64": "0.19.12", + "@esbuild/sunos-x64": "0.19.12", + "@esbuild/win32-arm64": "0.19.12", + "@esbuild/win32-ia32": "0.19.12", + "@esbuild/win32-x64": "0.19.12" + } + }, + "node_modules/escalade": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-goat": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-4.0.0.tgz", + "integrity": "sha512-2Sd4ShcWxbx6OY1IHyla/CVNwvg7XwZVoXZHcSu9w9SReNP1EzzD5T8NWKIR38fIqEns9kDWKUQTXXAmlDrdPg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", + "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.0", + "@humanwhocodes/config-array": "^0.11.14", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-compat-utils": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.1.2.tgz", + "integrity": "sha512-Jia4JDldWnFNIru1Ehx1H5s9/yxiRHY/TimCuUc0jNexew3cF1gI6CYZil1ociakfWO3rRqFjl1mskBblB3RYg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "eslint": ">=6.0.0" + } + }, + "node_modules/eslint-config-prettier": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", + "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", + "dev": true, + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-plugin-svelte": { + "version": "2.35.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-svelte/-/eslint-plugin-svelte-2.35.1.tgz", + "integrity": "sha512-IF8TpLnROSGy98Z3NrsKXWDSCbNY2ReHDcrYTuXZMbfX7VmESISR78TWgO9zdg4Dht1X8coub5jKwHzP0ExRug==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@jridgewell/sourcemap-codec": "^1.4.14", + "debug": "^4.3.1", + "eslint-compat-utils": "^0.1.2", + "esutils": "^2.0.3", + "known-css-properties": "^0.29.0", + "postcss": "^8.4.5", + "postcss-load-config": "^3.1.4", + "postcss-safe-parser": "^6.0.0", + "postcss-selector-parser": "^6.0.11", + "semver": "^7.5.3", + "svelte-eslint-parser": ">=0.33.0 <1.0.0" + }, + "engines": { + "node": "^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ota-meshi" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0-0", + "svelte": "^3.37.0 || ^4.0.0" + }, + "peerDependenciesMeta": { + "svelte": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-svelte/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-plugin-svelte/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-plugin-svelte/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint/node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/eslint/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/esm-env": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/esm-env/-/esm-env-1.0.0.tgz", + "integrity": "sha512-Cf6VksWPsTuW01vU9Mk/3vRue91Zevka5SjyNf3nEpokFRuqt/KjUQoGAwq9qMmhpLTHmXzSIrFRw8zxWzmFBA==", + "dev": true + }, + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "dev": true, + "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" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/execa/node_modules/get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "dev": true, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/execa/node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/execa/node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dev": true, + "dependencies": { + "mimic-fn": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/execa/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/exponential-backoff": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.1.tgz", + "integrity": "sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw==", + "dev": true + }, + "node_modules/external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dev": true, + "dependencies": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/extract-files": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/extract-files/-/extract-files-11.0.0.tgz", + "integrity": "sha512-FuoE1qtbJ4bBVvv94CC7s0oTnKUGvQs+Rjf1L2SJFfS+HTVVjhPFtehPdQ0JiGPqVNfSSZvL5yzHHQq2Z4WNhQ==", + "dev": true, + "engines": { + "node": "^12.20 || >= 14.13" + }, + "funding": { + "url": "https://github.com/sponsors/jaydenseric" + } + }, + "node_modules/fast-decode-uri-component": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/fast-decode-uri-component/-/fast-decode-uri-component-1.0.1.tgz", + "integrity": "sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg==", + "dev": true + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "node_modules/fast-memoize": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/fast-memoize/-/fast-memoize-2.5.2.tgz", + "integrity": "sha512-Ue0LwpDYErFbmNnZSF0UH6eImUwDmogUO1jyE+JbN2gsQz/jICm1Ve7t9QT0rNSsfJt+Hs4/S3GnsDVjL4HVrw==", + "dev": true + }, + "node_modules/fast-querystring": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/fast-querystring/-/fast-querystring-1.1.2.tgz", + "integrity": "sha512-g6KuKWmFXc0fID8WWH0jit4g0AGBoJhCkJMb1RmbsSEUNvQ+ZC8D6CUZ+GtF8nMzSPXnhiePyyqqipzNNEnHjg==", + "dev": true, + "dependencies": { + "fast-decode-uri-component": "^1.0.1" + } + }, + "node_modules/fast-url-parser": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/fast-url-parser/-/fast-url-parser-1.1.3.tgz", + "integrity": "sha512-5jOCVXADYNuRkKFzNJ0dCCewsZiYo0dz8QNYljkOpFC6r2U4OBmKtvm/Tsuh4w1YYdDqDb31a8TVhBJ2OJKdqQ==", + "dev": true, + "dependencies": { + "punycode": "^1.3.2" + } + }, + "node_modules/fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fb-watchman": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", + "dev": true, + "dependencies": { + "bser": "2.1.1" + } + }, + "node_modules/fbjs": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-3.0.5.tgz", + "integrity": "sha512-ztsSx77JBtkuMrEypfhgc3cI0+0h+svqeie7xHbh1k/IKdcydnvadp/mUaGgjAOXQmQSxsqgaRhS3q9fy+1kxg==", + "dev": true, + "dependencies": { + "cross-fetch": "^3.1.5", + "fbjs-css-vars": "^1.0.0", + "loose-envify": "^1.0.0", + "object-assign": "^4.1.0", + "promise": "^7.1.1", + "setimmediate": "^1.0.5", + "ua-parser-js": "^1.0.35" + } + }, + "node_modules/fbjs-css-vars": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/fbjs-css-vars/-/fbjs-css-vars-1.0.2.tgz", + "integrity": "sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ==", + "dev": true + }, + "node_modules/figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/figures/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/filesize": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/filesize/-/filesize-10.1.0.tgz", + "integrity": "sha512-GTLKYyBSDz3nPhlLVPjPWZCnhkd9TrrRArNcy8Z+J2cqScB7h2McAzR6NBX6nYOoWafql0roY8hrocxnZBv9CQ==", + "engines": { + "node": ">= 10.4.0" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "dev": true, + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", + "dev": true + }, + "node_modules/foreground-child": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", + "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/foreground-child/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/form-data-encoder": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.1.4.tgz", + "integrity": "sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==", + "dev": true, + "engines": { + "node": ">= 14.17" + } + }, + "node_modules/fp-and-or": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/fp-and-or/-/fp-and-or-0.1.4.tgz", + "integrity": "sha512-+yRYRhpnFPWXSly/6V4Lw9IfOV26uu30kynGJ03PW+MnjOEQe45RZ141QcS0aJehYBYA50GfCDnsRbFJdhssRw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/fraction.js": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", + "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", + "dev": true, + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/fs-minipass": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.3.tgz", + "integrity": "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==", + "dev": true, + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/fs-minipass/node_modules/minipass": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gauge": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz", + "integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==", + "dev": true, + "dependencies": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.3", + "console-control-strings": "^1.1.0", + "has-unicode": "^2.0.1", + "signal-exit": "^3.0.7", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.5" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-func-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-stdin": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz", + "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/global-dirs": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.1.tgz", + "integrity": "sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==", + "dev": true, + "dependencies": { + "ini": "2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/global-dirs/node_modules/ini": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", + "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/globalyzer": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/globalyzer/-/globalyzer-0.1.0.tgz", + "integrity": "sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q==", + "dev": true + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globrex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz", + "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==", + "dev": true + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/got": { + "version": "12.6.1", + "resolved": "https://registry.npmjs.org/got/-/got-12.6.1.tgz", + "integrity": "sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ==", + "dev": true, + "dependencies": { + "@sindresorhus/is": "^5.2.0", + "@szmarczak/http-timer": "^5.0.1", + "cacheable-lookup": "^7.0.0", + "cacheable-request": "^10.2.8", + "decompress-response": "^6.0.0", + "form-data-encoder": "^2.1.2", + "get-stream": "^6.0.1", + "http2-wrapper": "^2.1.10", + "lowercase-keys": "^3.0.0", + "p-cancelable": "^3.0.0", + "responselike": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sindresorhus/got?sponsor=1" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, + "node_modules/graphql": { + "version": "16.8.1", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.8.1.tgz", + "integrity": "sha512-59LZHPdGZVh695Ud9lRzPBVTtlX9ZCV150Er2W43ro37wVof0ctenSaskPPjN7lVTIN8mSZt8PHUNKZuNQUuxw==", + "engines": { + "node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0" + } + }, + "node_modules/graphql-config": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/graphql-config/-/graphql-config-5.0.3.tgz", + "integrity": "sha512-BNGZaoxIBkv9yy6Y7omvsaBUHOzfFcII3UN++tpH8MGOKFPFkCPZuwx09ggANMt8FgyWP1Od8SWPmrUEZca4NQ==", + "dev": true, + "dependencies": { + "@graphql-tools/graphql-file-loader": "^8.0.0", + "@graphql-tools/json-file-loader": "^8.0.0", + "@graphql-tools/load": "^8.0.0", + "@graphql-tools/merge": "^9.0.0", + "@graphql-tools/url-loader": "^8.0.0", + "@graphql-tools/utils": "^10.0.0", + "cosmiconfig": "^8.1.0", + "jiti": "^1.18.2", + "minimatch": "^4.2.3", + "string-env-interpolation": "^1.0.1", + "tslib": "^2.4.0" + }, + "engines": { + "node": ">= 16.0.0" + }, + "peerDependencies": { + "cosmiconfig-toml-loader": "^1.0.0", + "graphql": "^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" + }, + "peerDependenciesMeta": { + "cosmiconfig-toml-loader": { + "optional": true + } + } + }, + "node_modules/graphql-config/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/graphql-config/node_modules/minimatch": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-4.2.3.tgz", + "integrity": "sha512-lIUdtK5hdofgCTu3aT0sOaHsYR37viUuIc0rwnnDXImbwFRcumyLMeZaM0t0I/fgxS6s6JMfu0rLD1Wz9pv1ng==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/graphql-request": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/graphql-request/-/graphql-request-6.1.0.tgz", + "integrity": "sha512-p+XPfS4q7aIpKVcgmnZKhMNqhltk20hfXtkaIkTfjjmiKMJ5xrt5c743cL03y/K7y1rg3WrIC49xGiEQ4mxdNw==", + "dev": true, + "dependencies": { + "@graphql-typed-document-node/core": "^3.2.0", + "cross-fetch": "^3.1.5" + }, + "peerDependencies": { + "graphql": "14 - 16" + } + }, + "node_modules/graphql-tag": { + "version": "2.12.6", + "resolved": "https://registry.npmjs.org/graphql-tag/-/graphql-tag-2.12.6.tgz", + "integrity": "sha512-FdSNcu2QQcWnM2VNvSCCDCVS5PpPqpzgFT8+GXzqJuoDd0CBncxCY278u4mhRO7tMgo2JjgJA5aZ+nWSQ/Z+xg==", + "dev": true, + "dependencies": { + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "graphql": "^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" + } + }, + "node_modules/graphql-ws": { + "version": "5.15.0", + "resolved": "https://registry.npmjs.org/graphql-ws/-/graphql-ws-5.15.0.tgz", + "integrity": "sha512-xWGAtm3fig9TIhSaNsg0FaDZ8Pyn/3re3RFlP4rhQcmjRDIPpk1EhRuNB+YSJtLzttyuToaDiNhwT1OMoGnJnw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "graphql": ">=0.11 <=16" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", + "dev": true + }, + "node_modules/has-yarn": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-3.0.0.tgz", + "integrity": "sha512-IrsVwUHhEULx3R8f/aA8AHuEzAorplsab/v8HBzEiIukwq5i/EC+xmOW+HfP1OaDP+2JkgT1yILHN2O3UFIbcA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/hasown": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.1.tgz", + "integrity": "sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/header-case": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/header-case/-/header-case-2.0.4.tgz", + "integrity": "sha512-H/vuk5TEEVZwrR0lp2zed9OCo1uAILMlx0JEMgC26rzyJJ3N1v6XkwHHXJQdR2doSjcGPM6OKPYoJgf0plJ11Q==", + "dev": true, + "dependencies": { + "capital-case": "^1.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/hosted-git-info": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-5.2.1.tgz", + "integrity": "sha512-xIcQYMnhcx2Nr4JTjsFmwwnr9vldugPy9uVm0o87bjqqWMv9GaqsTeT+i99wTl0mk1uLxJtHxLb8kymqTENQsw==", + "dev": true, + "dependencies": { + "lru-cache": "^7.5.1" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/hosted-git-info/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/http-cache-semantics": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", + "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", + "dev": true + }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "dev": true, + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/http2-wrapper": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.1.tgz", + "integrity": "sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==", + "dev": true, + "dependencies": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.2.0" + }, + "engines": { + "node": ">=10.19.0" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz", + "integrity": "sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==", + "dev": true, + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "dev": true, + "engines": { + "node": ">=16.17.0" + } + }, + "node_modules/humanize-ms": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", + "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", + "dev": true, + "dependencies": { + "ms": "^2.0.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/ignore": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/ignore-walk": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-6.0.4.tgz", + "integrity": "sha512-t7sv42WkwFkyKbivUCglsQW5YWMskWtbEf4MNKX5u/CCWHKSPzN4FtBQGsQZgCLbxOzpVlcbWVK5KB3auIOjSw==", + "dev": true, + "dependencies": { + "minimatch": "^9.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/immutable": { + "version": "3.7.6", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.7.6.tgz", + "integrity": "sha512-AizQPcaofEtO11RZhPPHBOJRdo/20MKQF9mBLnVkBoyHi1/zXK8fzVdnEpSV9gxqtnh6Qomfp3F0xT5qP/vThw==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-fresh/node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/import-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/import-from/-/import-from-4.0.0.tgz", + "integrity": "sha512-P9J71vT5nLlDeV8FHs5nNxaLbrpfAV5cF5srvbZfpwpcJoM/xZR3hiv+q+SAnuSmuGbXMWud063iIMx/V/EWZQ==", + "dev": true, + "engines": { + "node": ">=12.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-lazy": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz", + "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/import-meta-resolve": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.0.0.tgz", + "integrity": "sha512-okYUR7ZQPH+efeuMJGlq4f8ubUgO50kByRPyt/Cy1Io4PSRsPjxME+YlVaCOx+NIToW7hCsZNFJyTPFFKepRSA==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/infer-owner": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", + "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", + "dev": true + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/ini": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.1.tgz", + "integrity": "sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/inquirer": { + "version": "8.2.6", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.6.tgz", + "integrity": "sha512-M1WuAmb7pn9zdFRtQYk26ZBoY043Sse0wVDdk4Bppr+JOXyQYybdtvK+l9wUibhtjdjvtoiNy8tk+EgsYIUqKg==", + "dev": true, + "dependencies": { + "ansi-escapes": "^4.2.1", + "chalk": "^4.1.1", + "cli-cursor": "^3.1.0", + "cli-width": "^3.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.21", + "mute-stream": "0.0.8", + "ora": "^5.4.1", + "run-async": "^2.4.0", + "rxjs": "^7.5.5", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6", + "wrap-ansi": "^6.0.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "dev": true, + "dependencies": { + "loose-envify": "^1.0.0" + } + }, + "node_modules/ip-address": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", + "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", + "dev": true, + "dependencies": { + "jsbn": "1.1.0", + "sprintf-js": "^1.1.3" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/is-absolute": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", + "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", + "dev": true, + "dependencies": { + "is-relative": "^1.0.0", + "is-windows": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-ci": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz", + "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==", + "dev": true, + "dependencies": { + "ci-info": "^3.2.0" + }, + "bin": { + "is-ci": "bin.js" + } + }, + "node_modules/is-core-module": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "dev": true, + "dependencies": { + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-installed-globally": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", + "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", + "dev": true, + "dependencies": { + "global-dirs": "^3.0.0", + "is-path-inside": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-lambda": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", + "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==", + "dev": true + }, + "node_modules/is-lower-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-lower-case/-/is-lower-case-2.0.2.tgz", + "integrity": "sha512-bVcMJy4X5Og6VZfdOZstSexlEy20Sr0k/p/b2IlQJlfdKAQuMpiv5w2Ccxb8sKdRUNAG1PnHVHjFSdRDVS6NlQ==", + "dev": true, + "dependencies": { + "tslib": "^2.0.3" + } + }, + "node_modules/is-npm": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-6.0.0.tgz", + "integrity": "sha512-JEjxbSmtPSt1c8XTkVrlujcXdKV1/tvuQ7GwKcAlyiVLeYFQ2VHat8xfrDJsIkhCdF/tZ7CiIR3sy141c6+gPQ==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-reference": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.2.tgz", + "integrity": "sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg==", + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/is-relative": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", + "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", + "dev": true, + "dependencies": { + "is-unc-path": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", + "dev": true + }, + "node_modules/is-unc-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", + "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", + "dev": true, + "dependencies": { + "unc-path-regex": "^0.1.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-upper-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-upper-case/-/is-upper-case-2.0.2.tgz", + "integrity": "sha512-44pxmxAvnnAOwBg4tHPnkfvgjPwbc5QIsSstNU+YcJ1ovxVzCWpSGosPJOZh/a1tdl81fbgnLc9LLv+x2ywbPQ==", + "dev": true, + "dependencies": { + "tslib": "^2.0.3" + } + }, + "node_modules/is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-yarn-global": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.4.1.tgz", + "integrity": "sha512-/kppl+R+LO5VmhYSEWARUFjodS25D68gvj8W7z0I7OWhUla5xWu8KL6CtB2V0R6yqhnRgbcaREMr4EEM6htLPQ==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/isomorphic-ws": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-5.0.0.tgz", + "integrity": "sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw==", + "dev": true, + "peerDependencies": { + "ws": "*" + } + }, + "node_modules/jackspeak": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", + "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", + "dev": true, + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jiti": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.0.tgz", + "integrity": "sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==", + "dev": true, + "bin": { + "jiti": "bin/jiti.js" + } + }, + "node_modules/jju": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz", + "integrity": "sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==", + "dev": true + }, + "node_modules/jose": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/jose/-/jose-5.2.2.tgz", + "integrity": "sha512-/WByRr4jDcsKlvMd1dRJnPfS1GVO3WuKyaurJ/vvXcOaUQO8rnNObCQMlv/5uCceVQIq5Q4WLF44ohsdiTohdg==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsbn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", + "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==", + "dev": true + }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "node_modules/json-parse-helpfulerror": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/json-parse-helpfulerror/-/json-parse-helpfulerror-1.0.3.tgz", + "integrity": "sha512-XgP0FGR77+QhUxjXkwOMkC94k3WtqEBfcnjWqhRd82qTat4SWKRE+9kUnynz/shm3I4ea2+qISvTIeGTNU7kJg==", + "dev": true, + "dependencies": { + "jju": "^1.1.0" + } + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stable-stringify": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.1.1.tgz", + "integrity": "sha512-SU/971Kt5qVQfJpyDveVhQ/vya+5hvrjClFOcr8c0Fq5aODJjMwutrOfCU+eCnVD5gpx1Q3fEqkyom77zH1iIg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "isarray": "^2.0.5", + "jsonify": "^0.0.1", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, + "node_modules/json-to-pretty-yaml": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/json-to-pretty-yaml/-/json-to-pretty-yaml-1.2.2.tgz", + "integrity": "sha512-rvm6hunfCcqegwYaG5T4yKJWxc9FXFgBVrcTZ4XfSVRwa5HA/Xs+vB/Eo9treYYHCeNM0nrSUr82V/M31Urc7A==", + "dev": true, + "dependencies": { + "remedial": "^1.0.7", + "remove-trailing-spaces": "^1.0.6" + }, + "engines": { + "node": ">= 0.2.0" + } + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonc-parser": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.1.tgz", + "integrity": "sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==", + "dev": true + }, + "node_modules/jsonify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.1.tgz", + "integrity": "sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/jsonlines": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsonlines/-/jsonlines-0.1.1.tgz", + "integrity": "sha512-ekDrAGso79Cvf+dtm+mL8OBI2bmAOt3gssYs833De/C9NmIpWDWyUO4zPgB5x2/OhY366dkhgfPMYfwZF7yOZA==", + "dev": true + }, + "node_modules/jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", + "dev": true, + "engines": [ + "node >= 0.2.0" + ] + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/kleur": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/known-css-properties": { + "version": "0.29.0", + "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.29.0.tgz", + "integrity": "sha512-Ne7wqW7/9Cz54PDt4I3tcV+hAyat8ypyOGzYRJQfdxnnjeWsTxt1cy8pjvvKeI5kfXuyvULyeeAvwvvtAX3ayQ==", + "dev": true + }, + "node_modules/latest-version": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-7.0.0.tgz", + "integrity": "sha512-KvNT4XqAMzdcL6ka6Tl3i2lYeFDgXNCuIX+xNx6ZMVR1dFq+idXd9FLKNMOIx0t9mJ9/HudyX4oZWXZQ0UJHeg==", + "dev": true, + "dependencies": { + "package-json": "^8.1.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lilconfig": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", + "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, + "node_modules/listr2": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-4.0.5.tgz", + "integrity": "sha512-juGHV1doQdpNT3GSTs9IUN43QJb7KHdF9uqg7Vufs/tG9VTzpFphqF4pm/ICdAABGQxsyNn9CiYA3StkI6jpwA==", + "dev": true, + "dependencies": { + "cli-truncate": "^2.1.0", + "colorette": "^2.0.16", + "log-update": "^4.0.0", + "p-map": "^4.0.0", + "rfdc": "^1.3.0", + "rxjs": "^7.5.5", + "through": "^2.3.8", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "enquirer": ">= 2.3.0 < 3" + }, + "peerDependenciesMeta": { + "enquirer": { + "optional": true + } + } + }, + "node_modules/listr2/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/local-pkg": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.5.0.tgz", + "integrity": "sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==", + "dev": true, + "dependencies": { + "mlly": "^1.4.2", + "pkg-types": "^1.0.3" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/locate-character": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz", + "integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==" + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==", + "dev": true + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", + "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", + "dev": true, + "dependencies": { + "ansi-escapes": "^4.3.0", + "cli-cursor": "^3.1.0", + "slice-ansi": "^4.0.0", + "wrap-ansi": "^6.2.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/loupe": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", + "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", + "dev": true, + "dependencies": { + "get-func-name": "^2.0.1" + } + }, + "node_modules/lower-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", + "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", + "dev": true, + "dependencies": { + "tslib": "^2.0.3" + } + }, + "node_modules/lower-case-first": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lower-case-first/-/lower-case-first-2.0.2.tgz", + "integrity": "sha512-EVm/rR94FJTZi3zefZ82fLWab+GX14LJN4HrWBcuo6Evmsl9hEfnqxgcHCKb9q+mNf6EVdsjx/qucYFIIB84pg==", + "dev": true, + "dependencies": { + "tslib": "^2.0.3" + } + }, + "node_modules/lowercase-keys": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz", + "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/magic-string": { + "version": "0.30.8", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.8.tgz", + "integrity": "sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.15" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/make-fetch-happen": { + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-11.1.1.tgz", + "integrity": "sha512-rLWS7GCSTcEujjVBs2YqG7Y4643u8ucvCJeSRqiLYhesrDuzeuFIk37xREzAsfQaqzl8b9rNCE4m6J8tvX4Q8w==", + "dev": true, + "dependencies": { + "agentkeepalive": "^4.2.1", + "cacache": "^17.0.0", + "http-cache-semantics": "^4.1.1", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.0", + "is-lambda": "^1.0.1", + "lru-cache": "^7.7.1", + "minipass": "^5.0.0", + "minipass-fetch": "^3.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.3", + "promise-retry": "^2.0.1", + "socks-proxy-agent": "^7.0.0", + "ssri": "^10.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/make-fetch-happen/node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/make-fetch-happen/node_modules/http-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", + "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", + "dev": true, + "dependencies": { + "@tootallnate/once": "2", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/make-fetch-happen/node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dev": true, + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/make-fetch-happen/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mdn-data": { + "version": "2.0.30", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", + "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==" + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/meros": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/meros/-/meros-1.3.0.tgz", + "integrity": "sha512-2BNGOimxEz5hmjUG2FwoxCt5HN7BXdaWyFqEwxPTrJzVdABtrL4TiHTcsWSFAxPQ/tOnEaQEJh3qWq71QRMY+w==", + "dev": true, + "engines": { + "node": ">=13" + }, + "peerDependencies": { + "@types/node": ">=13" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/mimic-response": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz", + "integrity": "sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-collect": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", + "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minipass-collect/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-collect/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/minipass-fetch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.4.tgz", + "integrity": "sha512-jHAqnA728uUpIaFm7NWsCnqKT6UqZz7GcI/bDpPATuwYyKwJwW0remxSCxUlKiEty+eopHGa3oc8WxgQ1FFJqg==", + "dev": true, + "dependencies": { + "minipass": "^7.0.3", + "minipass-sized": "^1.0.3", + "minizlib": "^2.1.2" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + }, + "optionalDependencies": { + "encoding": "^0.1.13" + } + }, + "node_modules/minipass-fetch/node_modules/minipass": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minipass-flush": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", + "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minipass-flush/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-flush/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/minipass-json-stream": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minipass-json-stream/-/minipass-json-stream-1.0.1.tgz", + "integrity": "sha512-ODqY18UZt/I8k+b7rl2AENgbWE8IDYam+undIJONvigAz8KR5GWblsFTEfQs0WODsjbSXWlm+JHEv8Gr6Tfdbg==", + "dev": true, + "dependencies": { + "jsonparse": "^1.3.1", + "minipass": "^3.0.0" + } + }, + "node_modules/minipass-json-stream/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-json-stream/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/minipass-pipeline": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", + "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-pipeline/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-pipeline/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/minipass-sized": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", + "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-sized/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-sized/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minizlib/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minizlib/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/mlly": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.6.1.tgz", + "integrity": "sha512-vLgaHvaeunuOXHSmEbZ9izxPx3USsk8KCQ8iC+aTlp5sKRSoZvwhHh5L9VbKSaVC6sJDqbyohIS76E2VmHIPAA==", + "dev": true, + "dependencies": { + "acorn": "^8.11.3", + "pathe": "^1.1.2", + "pkg-types": "^1.0.3", + "ufo": "^1.3.2" + } + }, + "node_modules/mri": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", + "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/mrmime": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.0.tgz", + "integrity": "sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "dev": true + }, + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dev": true, + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/no-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", + "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", + "dev": true, + "dependencies": { + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + } + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dev": true, + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-gyp": { + "version": "9.4.1", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-9.4.1.tgz", + "integrity": "sha512-OQkWKbjQKbGkMf/xqI1jjy3oCTgMKJac58G2+bjZb3fza6gW2YrCSdMQYaoTb70crvE//Gngr4f0AgVHmqHvBQ==", + "dev": true, + "dependencies": { + "env-paths": "^2.2.0", + "exponential-backoff": "^3.1.1", + "glob": "^7.1.4", + "graceful-fs": "^4.2.6", + "make-fetch-happen": "^10.0.3", + "nopt": "^6.0.0", + "npmlog": "^6.0.0", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.2", + "which": "^2.0.2" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": "^12.13 || ^14.13 || >=16" + } + }, + "node_modules/node-gyp/node_modules/@npmcli/fs": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-2.1.2.tgz", + "integrity": "sha512-yOJKRvohFOaLqipNtwYB9WugyZKhC/DZC4VYPmpaCzDBrA8YpK3qHZ8/HGscMnE4GqbkLNuVcCnxkeQEdGt6LQ==", + "dev": true, + "dependencies": { + "@gar/promisify": "^1.1.3", + "semver": "^7.3.5" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/node-gyp/node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/node-gyp/node_modules/cacache": { + "version": "16.1.3", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-16.1.3.tgz", + "integrity": "sha512-/+Emcj9DAXxX4cwlLmRI9c166RuL3w30zp4R7Joiv2cQTtTtA+jeuCAjH3ZlGnYS3tKENSrKhAzVVP9GVyzeYQ==", + "dev": true, + "dependencies": { + "@npmcli/fs": "^2.1.0", + "@npmcli/move-file": "^2.0.0", + "chownr": "^2.0.0", + "fs-minipass": "^2.1.0", + "glob": "^8.0.1", + "infer-owner": "^1.0.4", + "lru-cache": "^7.7.1", + "minipass": "^3.1.6", + "minipass-collect": "^1.0.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "mkdirp": "^1.0.4", + "p-map": "^4.0.0", + "promise-inflight": "^1.0.1", + "rimraf": "^3.0.2", + "ssri": "^9.0.0", + "tar": "^6.1.11", + "unique-filename": "^2.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/node-gyp/node_modules/cacache/node_modules/glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/node-gyp/node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/node-gyp/node_modules/http-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", + "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", + "dev": true, + "dependencies": { + "@tootallnate/once": "2", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/node-gyp/node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dev": true, + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/node-gyp/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/node-gyp/node_modules/make-fetch-happen": { + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-10.2.1.tgz", + "integrity": "sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w==", + "dev": true, + "dependencies": { + "agentkeepalive": "^4.2.1", + "cacache": "^16.1.0", + "http-cache-semantics": "^4.1.0", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.0", + "is-lambda": "^1.0.1", + "lru-cache": "^7.7.1", + "minipass": "^3.1.6", + "minipass-collect": "^1.0.2", + "minipass-fetch": "^2.0.3", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.3", + "promise-retry": "^2.0.1", + "socks-proxy-agent": "^7.0.0", + "ssri": "^9.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/node-gyp/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-gyp/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/node-gyp/node_modules/minipass-fetch": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-2.1.2.tgz", + "integrity": "sha512-LT49Zi2/WMROHYoqGgdlQIZh8mLPZmOrN2NdJjMXxYe4nkN6FUyuPuOAOedNJDrx0IRGg9+4guZewtp8hE6TxA==", + "dev": true, + "dependencies": { + "minipass": "^3.1.6", + "minipass-sized": "^1.0.3", + "minizlib": "^2.1.2" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + }, + "optionalDependencies": { + "encoding": "^0.1.13" + } + }, + "node_modules/node-gyp/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-gyp/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-gyp/node_modules/semver/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-gyp/node_modules/ssri": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-9.0.1.tgz", + "integrity": "sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q==", + "dev": true, + "dependencies": { + "minipass": "^3.1.1" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/node-gyp/node_modules/unique-filename": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-2.0.1.tgz", + "integrity": "sha512-ODWHtkkdx3IAR+veKxFV+VBkUMcN+FaqzUUd7IZzt+0zhDZFPFxhlqwPF3YQvMHx1TD0tdgYl+kuPnJ8E6ql7A==", + "dev": true, + "dependencies": { + "unique-slug": "^3.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/node-gyp/node_modules/unique-slug": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-3.0.0.tgz", + "integrity": "sha512-8EyMynh679x/0gqE9fT9oilG+qEt+ibFyqjuVTsZn1+CMxH+XLlpvr2UZx4nVcCwTpx81nICr2JQFkM+HPLq4w==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/node-gyp/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", + "dev": true + }, + "node_modules/node-releases": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", + "dev": true + }, + "node_modules/nopt": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-6.0.0.tgz", + "integrity": "sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==", + "dev": true, + "dependencies": { + "abbrev": "^1.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/normalize-package-data": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-5.0.0.tgz", + "integrity": "sha512-h9iPVIfrVZ9wVYQnxFgtw1ugSvGEMOlyPWWtm8BMJhnwyEL/FLbYbTY3V3PpjI/BUK67n9PEWDu6eHzu1fB15Q==", + "dev": true, + "dependencies": { + "hosted-git-info": "^6.0.0", + "is-core-module": "^2.8.1", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/normalize-package-data/node_modules/hosted-git-info": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-6.1.1.tgz", + "integrity": "sha512-r0EI+HBMcXadMrugk0GCQ+6BQV39PiWAZVfq7oIckeGiN7sjRGyQxPdft3nQekFTCQbYxLBH+/axZMeH8UX6+w==", + "dev": true, + "dependencies": { + "lru-cache": "^7.5.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/normalize-package-data/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/normalize-package-data/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/normalize-package-data/node_modules/semver/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/normalize-package-data/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-url": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.0.tgz", + "integrity": "sha512-uVFpKhj5MheNBJRTiMZ9pE/7hD1QTeEvugSJW/OmLzAp78PB5O6adfMNTvmfKhXBkvCzC+rqifWcVYpGFwTjnw==", + "dev": true, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-bundled": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-3.0.0.tgz", + "integrity": "sha512-Vq0eyEQy+elFpzsKjMss9kxqb9tG3YHg4dsyWuUENuzvSUWe1TCnW/vV9FkhvBk/brEDoDiVd+M1Btosa6ImdQ==", + "dev": true, + "dependencies": { + "npm-normalize-package-bin": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm-check-updates": { + "version": "16.14.15", + "resolved": "https://registry.npmjs.org/npm-check-updates/-/npm-check-updates-16.14.15.tgz", + "integrity": "sha512-WH0wJ9j6CP7Azl+LLCxWAYqroT2IX02kRIzgK/fg0rPpMbETgHITWBdOPtrv521xmA3JMgeNsQ62zvVtS/nCmQ==", + "dev": true, + "dependencies": { + "chalk": "^5.3.0", + "cli-table3": "^0.6.3", + "commander": "^10.0.1", + "fast-memoize": "^2.5.2", + "find-up": "5.0.0", + "fp-and-or": "^0.1.4", + "get-stdin": "^8.0.0", + "globby": "^11.0.4", + "hosted-git-info": "^5.1.0", + "ini": "^4.1.1", + "js-yaml": "^4.1.0", + "json-parse-helpfulerror": "^1.0.3", + "jsonlines": "^0.1.1", + "lodash": "^4.17.21", + "make-fetch-happen": "^11.1.1", + "minimatch": "^9.0.3", + "p-map": "^4.0.0", + "pacote": "15.2.0", + "parse-github-url": "^1.0.2", + "progress": "^2.0.3", + "prompts-ncu": "^3.0.0", + "rc-config-loader": "^4.1.3", + "remote-git-tags": "^3.0.0", + "rimraf": "^5.0.5", + "semver": "^7.5.4", + "semver-utils": "^1.1.4", + "source-map-support": "^0.5.21", + "spawn-please": "^2.0.2", + "strip-ansi": "^7.1.0", + "strip-json-comments": "^5.0.1", + "untildify": "^4.0.0", + "update-notifier": "^6.0.2" + }, + "bin": { + "ncu": "build/src/bin/cli.js", + "npm-check-updates": "build/src/bin/cli.js" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/npm-check-updates/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/npm-check-updates/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "dev": true, + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/npm-check-updates/node_modules/glob": { + "version": "10.3.10", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", + "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.3.5", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", + "path-scurry": "^1.10.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm-check-updates/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm-check-updates/node_modules/rimraf": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.5.tgz", + "integrity": "sha512-CqDakW+hMe/Bz202FPEymy68P+G50RfMQK+Qo5YUqc9SPipvbGjCGKd0RSKEelbsfQuw3g5NZDSrlZZAJurH1A==", + "dev": true, + "dependencies": { + "glob": "^10.3.7" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm-check-updates/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm-check-updates/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/npm-check-updates/node_modules/strip-json-comments": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-5.0.1.tgz", + "integrity": "sha512-0fk9zBqO67Nq5M/m45qHCJxylV/DhBlIOVExqgOMiCCrzrhU6tCibRXNqE3jwJLftzE9SNuZtYbpzcO+i9FiKw==", + "dev": true, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-check-updates/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/npm-install-checks": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-6.3.0.tgz", + "integrity": "sha512-W29RiK/xtpCGqn6f3ixfRYGk+zRyr+Ew9F2E20BfXxT5/euLdA/Nm7fO7OeTGuAmTs30cpgInyJ0cYe708YTZw==", + "dev": true, + "dependencies": { + "semver": "^7.1.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm-install-checks/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm-install-checks/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm-install-checks/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/npm-normalize-package-bin": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-3.0.1.tgz", + "integrity": "sha512-dMxCf+zZ+3zeQZXKxmyuCKlIDPGuv8EF940xbkC4kQVDTtqoh6rJFO+JTKSA6/Rwi0getWmtuy4Itup0AMcaDQ==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm-package-arg": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-10.1.0.tgz", + "integrity": "sha512-uFyyCEmgBfZTtrKk/5xDfHp6+MdrqGotX/VoOyEEl3mBwiEE5FlBaePanazJSVMPT7vKepcjYBY2ztg9A3yPIA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^6.0.0", + "proc-log": "^3.0.0", + "semver": "^7.3.5", + "validate-npm-package-name": "^5.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm-package-arg/node_modules/hosted-git-info": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-6.1.1.tgz", + "integrity": "sha512-r0EI+HBMcXadMrugk0GCQ+6BQV39PiWAZVfq7oIckeGiN7sjRGyQxPdft3nQekFTCQbYxLBH+/axZMeH8UX6+w==", + "dev": true, + "dependencies": { + "lru-cache": "^7.5.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm-package-arg/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/npm-package-arg/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm-package-arg/node_modules/semver/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm-package-arg/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/npm-packlist": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-7.0.4.tgz", + "integrity": "sha512-d6RGEuRrNS5/N84iglPivjaJPxhDbZmlbTwTDX2IbcRHG5bZCdtysYMhwiPvcF4GisXHGn7xsxv+GQ7T/02M5Q==", + "dev": true, + "dependencies": { + "ignore-walk": "^6.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm-pick-manifest": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-8.0.2.tgz", + "integrity": "sha512-1dKY+86/AIiq1tkKVD3l0WI+Gd3vkknVGAggsFeBkTvbhMQ1OND/LKkYv4JtXPKUJ8bOTCyLiqEg2P6QNdK+Gg==", + "dev": true, + "dependencies": { + "npm-install-checks": "^6.0.0", + "npm-normalize-package-bin": "^3.0.0", + "npm-package-arg": "^10.0.0", + "semver": "^7.3.5" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm-pick-manifest/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm-pick-manifest/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm-pick-manifest/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/npm-registry-fetch": { + "version": "14.0.5", + "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-14.0.5.tgz", + "integrity": "sha512-kIDMIo4aBm6xg7jOttupWZamsZRkAqMqwqqbVXnUqstY5+tapvv6bkH/qMR76jdgV+YljEUCyWx3hRYMrJiAgA==", + "dev": true, + "dependencies": { + "make-fetch-happen": "^11.0.0", + "minipass": "^5.0.0", + "minipass-fetch": "^3.0.0", + "minipass-json-stream": "^1.0.1", + "minizlib": "^2.1.2", + "npm-package-arg": "^10.0.0", + "proc-log": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm-run-path": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", + "dev": true, + "dependencies": { + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-path/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npmlog": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz", + "integrity": "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==", + "dev": true, + "dependencies": { + "are-we-there-yet": "^3.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^4.0.3", + "set-blocking": "^2.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/nullthrows": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/nullthrows/-/nullthrows-1.1.1.tgz", + "integrity": "sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==", + "dev": true + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/optionator": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "dev": true, + "dependencies": { + "@aashutoshrathi/word-wrap": "^1.2.3", + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/ora": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "dev": true, + "dependencies": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/p-cancelable": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz", + "integrity": "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==", + "dev": true, + "engines": { + "node": ">=12.20" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/package-json": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-8.1.1.tgz", + "integrity": "sha512-cbH9IAIJHNj9uXi196JVsRlt7cHKak6u/e6AkL/bkRelZ7rlL3X1YKxsZwa36xipOEKAsdtmaG6aAJoM1fx2zA==", + "dev": true, + "dependencies": { + "got": "^12.1.0", + "registry-auth-token": "^5.0.1", + "registry-url": "^6.0.0", + "semver": "^7.3.7" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/package-json/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/package-json/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/package-json/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/pacote": { + "version": "15.2.0", + "resolved": "https://registry.npmjs.org/pacote/-/pacote-15.2.0.tgz", + "integrity": "sha512-rJVZeIwHTUta23sIZgEIM62WYwbmGbThdbnkt81ravBplQv+HjyroqnLRNH2+sLJHcGZmLRmhPwACqhfTcOmnA==", + "dev": true, + "dependencies": { + "@npmcli/git": "^4.0.0", + "@npmcli/installed-package-contents": "^2.0.1", + "@npmcli/promise-spawn": "^6.0.1", + "@npmcli/run-script": "^6.0.0", + "cacache": "^17.0.0", + "fs-minipass": "^3.0.0", + "minipass": "^5.0.0", + "npm-package-arg": "^10.0.0", + "npm-packlist": "^7.0.0", + "npm-pick-manifest": "^8.0.0", + "npm-registry-fetch": "^14.0.0", + "proc-log": "^3.0.0", + "promise-retry": "^2.0.1", + "read-package-json": "^6.0.0", + "read-package-json-fast": "^3.0.0", + "sigstore": "^1.3.0", + "ssri": "^10.0.0", + "tar": "^6.1.11" + }, + "bin": { + "pacote": "lib/bin.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/param-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", + "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", + "dev": true, + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-filepath": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", + "integrity": "sha512-FwdRXKCohSVeXqwtYonZTXtbGJKrn+HNyWDYVcp5yuJlesTwNH4rsmRZ+GrKAPJ5bLpRxESMeS+Rl0VCHRvB2Q==", + "dev": true, + "dependencies": { + "is-absolute": "^1.0.0", + "map-cache": "^0.2.0", + "path-root": "^0.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/parse-github-url": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/parse-github-url/-/parse-github-url-1.0.2.tgz", + "integrity": "sha512-kgBf6avCbO3Cn6+RnzRGLkUsv4ZVqv/VfAYkRsyBcgkshNvVBkRn1FEZcW0Jb+npXQWm2vHPnnOqFteZxRRGNw==", + "dev": true, + "bin": { + "parse-github-url": "cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pascal-case": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", + "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", + "dev": true, + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/path-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/path-case/-/path-case-3.0.4.tgz", + "integrity": "sha512-qO4qCFjXqVTrcbPt/hQfhTQ+VhFsqNKOPtytgNKkKxSoEp3XPUQ8ObFuePylOIok5gjn69ry8XiULxCwot3Wfg==", + "dev": true, + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/path-root": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", + "integrity": "sha512-QLcPegTHF11axjfojBIoDygmS2E3Lf+8+jI6wOVmNVenrKSo3mFdSGiIgdSHenczw3wPtlVMQaFVwGmM7BJdtg==", + "dev": true, + "dependencies": { + "path-root-regex": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-root-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", + "integrity": "sha512-4GlJ6rZDhQZFE0DPVKh0e9jmZ5egZfxTkp7bcRDuPlJXbAwhxcl2dINPUAsjLdejqaLsCeg8axcLjIbvBjN4pQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-scurry": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", + "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", + "dev": true, + "dependencies": { + "lru-cache": "^9.1.1 || ^10.0.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz", + "integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==", + "dev": true, + "engines": { + "node": "14 || >=16.14" + } + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/pathe": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", + "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", + "dev": true + }, + "node_modules/pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/periscopic": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/periscopic/-/periscopic-3.1.0.tgz", + "integrity": "sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^3.0.0", + "is-reference": "^3.0.0" + } + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pirates": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/pkg-types": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.0.3.tgz", + "integrity": "sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A==", + "dev": true, + "dependencies": { + "jsonc-parser": "^3.2.0", + "mlly": "^1.2.0", + "pathe": "^1.1.0" + } + }, + "node_modules/postcss": { + "version": "8.4.35", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.35.tgz", + "integrity": "sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-import": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", + "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.0.0", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/postcss-js": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", + "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", + "dev": true, + "dependencies": { + "camelcase-css": "^2.0.1" + }, + "engines": { + "node": "^12 || ^14 || >= 16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.4.21" + } + }, + "node_modules/postcss-load-config": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-3.1.4.tgz", + "integrity": "sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==", + "dev": true, + "dependencies": { + "lilconfig": "^2.0.5", + "yaml": "^1.10.2" + }, + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": ">=8.0.9", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "postcss": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/postcss-load-config/node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/postcss-nested": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.1.tgz", + "integrity": "sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==", + "dev": true, + "dependencies": { + "postcss-selector-parser": "^6.0.11" + }, + "engines": { + "node": ">=12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.2.14" + } + }, + "node_modules/postcss-safe-parser": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-6.0.0.tgz", + "integrity": "sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==", + "dev": true, + "engines": { + "node": ">=12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.3.3" + } + }, + "node_modules/postcss-scss": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-4.0.9.tgz", + "integrity": "sha512-AjKOeiwAitL/MXxQW2DliT28EKukvvbEWx3LBmJIRN8KfBGZbRTxNYW0kSqi1COiTZ57nZ9NW06S6ux//N1c9A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss-scss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "engines": { + "node": ">=12.0" + }, + "peerDependencies": { + "postcss": "^8.4.29" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.0.15", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.15.tgz", + "integrity": "sha512-rEYkQOMUCEMhsKbK66tbEU9QVIxbhN18YiniAwA7XQYTVBqrBy+P2p5JcdqsHgKM2zWylp8d7J6eszocfds5Sw==", + "dev": true, + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz", + "integrity": "sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==", + "dev": true, + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/prettier-plugin-svelte": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/prettier-plugin-svelte/-/prettier-plugin-svelte-3.2.2.tgz", + "integrity": "sha512-ZzzE/wMuf48/1+Lf2Ffko0uDa6pyCfgHV6+uAhtg2U0AAXGrhCSW88vEJNAkAxW5qyrFY1y1zZ4J8TgHrjW++Q==", + "dev": true, + "peerDependencies": { + "prettier": "^3.0.0", + "svelte": "^3.2.0 || ^4.0.0-next.0 || ^5.0.0-next.0" + } + }, + "node_modules/prettier-plugin-tailwindcss": { + "version": "0.5.11", + "resolved": "https://registry.npmjs.org/prettier-plugin-tailwindcss/-/prettier-plugin-tailwindcss-0.5.11.tgz", + "integrity": "sha512-AvI/DNyMctyyxGOjyePgi/gqj5hJYClZ1avtQvLlqMT3uDZkRbi4HhGUpok3DRzv9z7Lti85Kdj3s3/1CeNI0w==", + "dev": true, + "engines": { + "node": ">=14.21.3" + }, + "peerDependencies": { + "@ianvs/prettier-plugin-sort-imports": "*", + "@prettier/plugin-pug": "*", + "@shopify/prettier-plugin-liquid": "*", + "@trivago/prettier-plugin-sort-imports": "*", + "prettier": "^3.0", + "prettier-plugin-astro": "*", + "prettier-plugin-css-order": "*", + "prettier-plugin-import-sort": "*", + "prettier-plugin-jsdoc": "*", + "prettier-plugin-marko": "*", + "prettier-plugin-organize-attributes": "*", + "prettier-plugin-organize-imports": "*", + "prettier-plugin-style-order": "*", + "prettier-plugin-svelte": "*" + }, + "peerDependenciesMeta": { + "@ianvs/prettier-plugin-sort-imports": { + "optional": true + }, + "@prettier/plugin-pug": { + "optional": true + }, + "@shopify/prettier-plugin-liquid": { + "optional": true + }, + "@trivago/prettier-plugin-sort-imports": { + "optional": true + }, + "prettier-plugin-astro": { + "optional": true + }, + "prettier-plugin-css-order": { + "optional": true + }, + "prettier-plugin-import-sort": { + "optional": true + }, + "prettier-plugin-jsdoc": { + "optional": true + }, + "prettier-plugin-marko": { + "optional": true + }, + "prettier-plugin-organize-attributes": { + "optional": true + }, + "prettier-plugin-organize-imports": { + "optional": true + }, + "prettier-plugin-style-order": { + "optional": true + }, + "prettier-plugin-svelte": { + "optional": true + }, + "prettier-plugin-twig-melody": { + "optional": true + } + } + }, + "node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/proc-log": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-3.0.0.tgz", + "integrity": "sha512-++Vn7NS4Xf9NacaU9Xq3URUuqZETPsf8L4j5/ckhaRYsfPeRyzGw+iDjFhV/Jr3uNmTvvddEJFWh5R1gRgUH8A==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/promise": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", + "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", + "dev": true, + "dependencies": { + "asap": "~2.0.3" + } + }, + "node_modules/promise-inflight": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==", + "dev": true + }, + "node_modules/promise-retry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", + "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", + "dev": true, + "dependencies": { + "err-code": "^2.0.2", + "retry": "^0.12.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/prompts-ncu": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/prompts-ncu/-/prompts-ncu-3.0.0.tgz", + "integrity": "sha512-qyz9UxZ5MlPKWVhWrCmSZ1ahm2GVYdjLb8og2sg0IPth1KRuhcggHGuijz0e41dkx35p1t1q3GRISGH7QGALFA==", + "dev": true, + "dependencies": { + "kleur": "^4.0.1", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/proto-list": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", + "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==", + "dev": true + }, + "node_modules/punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", + "dev": true + }, + "node_modules/pupa": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/pupa/-/pupa-3.1.0.tgz", + "integrity": "sha512-FLpr4flz5xZTSJxSeaheeMKN/EDzMdK7b8PTOC6a5PYFKTucWbdqjgqaEyH0shFiSJrVB1+Qqi4Tk19ccU6Aug==", + "dev": true, + "dependencies": { + "escape-goat": "^4.0.0" + }, + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pvtsutils": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/pvtsutils/-/pvtsutils-1.3.5.tgz", + "integrity": "sha512-ARvb14YB9Nm2Xi6nBq1ZX6dAM0FsJnuk+31aUp4TrcZEdKUlSqOqsxJHUPJDNE3qiIp+iUPEIeR6Je/tgV7zsA==", + "dev": true, + "dependencies": { + "tslib": "^2.6.1" + } + }, + "node_modules/pvutils": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/pvutils/-/pvutils-1.1.3.tgz", + "integrity": "sha512-pMpnA0qRdFp32b1sJl1wOJNxZLQ2cbQx+k6tjNtZ8CpvVhNqEPRgivZ2WOUev2YMajecdH7ctUPDvEe87nariQ==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/rc-config-loader": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/rc-config-loader/-/rc-config-loader-4.1.3.tgz", + "integrity": "sha512-kD7FqML7l800i6pS6pvLyIE2ncbk9Du8Q0gp/4hMPhJU6ZxApkoLcGD8ZeqgiAlfwZ6BlETq6qqe+12DUL207w==", + "dev": true, + "dependencies": { + "debug": "^4.3.4", + "js-yaml": "^4.1.0", + "json5": "^2.2.2", + "require-from-string": "^2.0.2" + } + }, + "node_modules/rc/node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, + "node_modules/rc/node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "node_modules/read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", + "dev": true, + "dependencies": { + "pify": "^2.3.0" + } + }, + "node_modules/read-package-json": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/read-package-json/-/read-package-json-6.0.4.tgz", + "integrity": "sha512-AEtWXYfopBj2z5N5PbkAOeNHRPUg5q+Nen7QLxV8M2zJq1ym6/lCz3fYNTCXe19puu2d06jfHhrP7v/S2PtMMw==", + "dev": true, + "dependencies": { + "glob": "^10.2.2", + "json-parse-even-better-errors": "^3.0.0", + "normalize-package-data": "^5.0.0", + "npm-normalize-package-bin": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/read-package-json-fast": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/read-package-json-fast/-/read-package-json-fast-3.0.2.tgz", + "integrity": "sha512-0J+Msgym3vrLOUB3hzQCuZHII0xkNGCtz/HJH9xZshwv9DbDwkw1KaE3gx/e2J5rpEY5rtOy6cyhKOPrkP7FZw==", + "dev": true, + "dependencies": { + "json-parse-even-better-errors": "^3.0.0", + "npm-normalize-package-bin": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/read-package-json-fast/node_modules/json-parse-even-better-errors": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.1.tgz", + "integrity": "sha512-aatBvbL26wVUCLmbWdCpeu9iF5wOyWpagiKkInA+kfws3sWdBrTnsvN2CKcyCYyUrc7rebNBlK6+kteg7ksecg==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/read-package-json/node_modules/glob": { + "version": "10.3.10", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", + "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.3.5", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", + "path-scurry": "^1.10.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/read-package-json/node_modules/json-parse-even-better-errors": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.1.tgz", + "integrity": "sha512-aatBvbL26wVUCLmbWdCpeu9iF5wOyWpagiKkInA+kfws3sWdBrTnsvN2CKcyCYyUrc7rebNBlK6+kteg7ksecg==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "dev": true + }, + "node_modules/registry-auth-token": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-5.0.2.tgz", + "integrity": "sha512-o/3ikDxtXaA59BmZuZrJZDJv8NMDGSj+6j6XaeBmHw8eY1i1qd9+6H+LjVvQXx3HN6aRCGa1cUdJ9RaJZUugnQ==", + "dev": true, + "dependencies": { + "@pnpm/npm-conf": "^2.1.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/registry-url": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-6.0.1.tgz", + "integrity": "sha512-+crtS5QjFRqFCoQmvGduwYWEBng99ZvmFvF+cUJkGYF1L1BfU8C6Zp9T7f5vPAwyLkUExpvK+ANVZmGU49qi4Q==", + "dev": true, + "dependencies": { + "rc": "1.2.8" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/relay-runtime": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/relay-runtime/-/relay-runtime-12.0.0.tgz", + "integrity": "sha512-QU6JKr1tMsry22DXNy9Whsq5rmvwr3LSZiiWV/9+DFpuTWvp+WFhobWMc8TC4OjKFfNhEZy7mOiqUAn5atQtug==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.0.0", + "fbjs": "^3.0.0", + "invariant": "^2.2.4" + } + }, + "node_modules/remedial": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/remedial/-/remedial-1.0.8.tgz", + "integrity": "sha512-/62tYiOe6DzS5BqVsNpH/nkGlX45C/Sp6V+NtiN6JQNS1Viay7cWkazmRkrQrdFj2eshDe96SIQNIoMxqhzBOg==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/remote-git-tags": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remote-git-tags/-/remote-git-tags-3.0.0.tgz", + "integrity": "sha512-C9hAO4eoEsX+OXA4rla66pXZQ+TLQ8T9dttgQj18yuKlPMTVkIkdYXvlMC55IuUsIkV6DpmQYi10JKFLaU+l7w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==", + "dev": true + }, + "node_modules/remove-trailing-spaces": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/remove-trailing-spaces/-/remove-trailing-spaces-1.0.8.tgz", + "integrity": "sha512-O3vsMYfWighyFbTd8hk8VaSj9UAGENxAtX+//ugIst2RMk5e03h6RoIS+0ylsFxY1gvmPuAY/PO4It+gPEeySA==", + "dev": true + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dev": true, + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-alpn": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", + "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", + "dev": true + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/responselike": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-3.0.0.tgz", + "integrity": "sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==", + "dev": true, + "dependencies": { + "lowercase-keys": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rfdc": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.1.tgz", + "integrity": "sha512-r5a3l5HzYlIC68TpmYKlxWjmOP6wiPJ1vWv2HeLhNsRZMrCkxeqxiHlQ21oXmQ4F3SiryXBHhAD7JZqvOJjFmg==", + "dev": true + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rollup": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.12.0.tgz", + "integrity": "sha512-wz66wn4t1OHIJw3+XU7mJJQV/2NAfw5OAk6G6Hoo3zcvz/XOfQ52Vgi+AN4Uxoxi0KBBwk2g8zPrTDA4btSB/Q==", + "dev": true, + "dependencies": { + "@types/estree": "1.0.5" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.12.0", + "@rollup/rollup-android-arm64": "4.12.0", + "@rollup/rollup-darwin-arm64": "4.12.0", + "@rollup/rollup-darwin-x64": "4.12.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.12.0", + "@rollup/rollup-linux-arm64-gnu": "4.12.0", + "@rollup/rollup-linux-arm64-musl": "4.12.0", + "@rollup/rollup-linux-riscv64-gnu": "4.12.0", + "@rollup/rollup-linux-x64-gnu": "4.12.0", + "@rollup/rollup-linux-x64-musl": "4.12.0", + "@rollup/rollup-win32-arm64-msvc": "4.12.0", + "@rollup/rollup-win32-ia32-msvc": "4.12.0", + "@rollup/rollup-win32-x64-msvc": "4.12.0", + "fsevents": "~2.3.2" + } + }, + "node_modules/run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "dev": true, + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/sade": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", + "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==", + "dev": true, + "dependencies": { + "mri": "^1.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "node_modules/sander": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/sander/-/sander-0.5.1.tgz", + "integrity": "sha512-3lVqBir7WuKDHGrKRDn/1Ye3kwpXaDOMsiRP1wd6wpZW56gJhsbp5RqQpA6JG/P+pkXizygnr1dKR8vzWaVsfA==", + "dev": true, + "dependencies": { + "es6-promise": "^3.1.2", + "graceful-fs": "^4.1.3", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.2" + } + }, + "node_modules/sander/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/scuid": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/scuid/-/scuid-1.1.0.tgz", + "integrity": "sha512-MuCAyrGZcTLfQoH2XoBlQ8C6bzwN88XT/0slOGz0pn8+gIP85BOAfYa44ZXQUTOwRwPU0QvgU+V+OSajl/59Xg==", + "dev": true + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/semver-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-4.0.0.tgz", + "integrity": "sha512-0Ju4+6A8iOnpL/Thra7dZsSlOHYAHIeMxfhWQRI1/VLcT3WDBZKKtQt/QkBOsiIN9ZpuvHE6cGZ0x4glCMmfiA==", + "dev": true, + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/semver-diff/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver-diff/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver-diff/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/semver-utils": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/semver-utils/-/semver-utils-1.1.4.tgz", + "integrity": "sha512-EjnoLE5OGmDAVV/8YDoN5KiajNadjzIp9BAHOhYeQHt7j0UWxjmgsx4YD48wp4Ue1Qogq38F1GNUJNqF1kKKxA==", + "dev": true + }, + "node_modules/sentence-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/sentence-case/-/sentence-case-3.0.4.tgz", + "integrity": "sha512-8LS0JInaQMCRoQ7YUytAo/xUu5W2XnQxV2HI/6uM6U7CITS1RqPElr30V6uIqyMKM9lJGRVFy5/4CuzcixNYSg==", + "dev": true, + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3", + "upper-case-first": "^2.0.2" + } + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "dev": true + }, + "node_modules/set-cookie-parser": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.6.0.tgz", + "integrity": "sha512-RVnVQxTXuerk653XfuliOxBP81Sf0+qfQE73LIYKcyMYHG94AuH0kgrQpRDuTZnSmjpysHmzxJXKNfa6PjFhyQ==", + "dev": true + }, + "node_modules/set-function-length": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.1.tgz", + "integrity": "sha512-j4t6ccc+VsKwYHso+kElc5neZpjtq9EnRICFZtWyBsLojhmeF/ZBd/elqm22WJh/BziDe/SBiOeAt0m2mfLD0g==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.2", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.3", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", + "dev": true + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/shell-quote": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", + "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "dev": true + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/signedsource": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/signedsource/-/signedsource-1.0.0.tgz", + "integrity": "sha512-6+eerH9fEnNmi/hyM1DXcRK3pWdoMQtlkQ+ns0ntzunjKqp5i3sKCc80ym8Fib3iaYhdJUOPdhlJWj1tvge2Ww==", + "dev": true + }, + "node_modules/sigstore": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/sigstore/-/sigstore-1.9.0.tgz", + "integrity": "sha512-0Zjz0oe37d08VeOtBIuB6cRriqXse2e8w+7yIy2XSXjshRKxbc2KkhXjL229jXSxEm7UbcjS76wcJDGQddVI9A==", + "dev": true, + "dependencies": { + "@sigstore/bundle": "^1.1.0", + "@sigstore/protobuf-specs": "^0.2.0", + "@sigstore/sign": "^1.0.0", + "@sigstore/tuf": "^1.0.3", + "make-fetch-happen": "^11.0.1" + }, + "bin": { + "sigstore": "bin/sigstore.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/sirv": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.4.tgz", + "integrity": "sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==", + "dev": true, + "dependencies": { + "@polka/url": "^1.0.0-next.24", + "mrmime": "^2.0.0", + "totalist": "^3.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/slice-ansi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", + "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "dev": true, + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/snake-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz", + "integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==", + "dev": true, + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/socks": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.1.tgz", + "integrity": "sha512-B6w7tkwNid7ToxjZ08rQMT8M9BJAf8DKx8Ft4NivzH0zBUfd6jldGcisJn/RLgxcX3FPNDdNQCUEMMT79b+oCQ==", + "dev": true, + "dependencies": { + "ip-address": "^9.0.5", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks-proxy-agent": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz", + "integrity": "sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==", + "dev": true, + "dependencies": { + "agent-base": "^6.0.2", + "debug": "^4.3.3", + "socks": "^2.6.2" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/socks-proxy-agent/node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/sorcery": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/sorcery/-/sorcery-0.11.0.tgz", + "integrity": "sha512-J69LQ22xrQB1cIFJhPfgtLuI6BpWRiWu1Y3vSsIwK/eAScqJxd/+CJlUuHQRdX2C9NGFamq+KqNywGgaThwfHw==", + "dev": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.14", + "buffer-crc32": "^0.2.5", + "minimist": "^1.2.0", + "sander": "^0.5.0" + }, + "bin": { + "sorcery": "bin/sorcery" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/spawn-please": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/spawn-please/-/spawn-please-2.0.2.tgz", + "integrity": "sha512-KM8coezO6ISQ89c1BzyWNtcn2V2kAVtwIXd3cN/V5a0xPYc1F/vydrRc01wsKFEQ/p+V1a4sw4z2yMITIXrgGw==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "dev": true, + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "dev": true + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.17", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.17.tgz", + "integrity": "sha512-sh8PWc/ftMqAAdFiBu6Fy6JUOYjqDJBJvIhpfDMyHrr0Rbp5liZqd4TjtQ/RgfLjKFZb+LMx5hpml5qOWy0qvg==", + "dev": true + }, + "node_modules/sponge-case": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sponge-case/-/sponge-case-1.0.1.tgz", + "integrity": "sha512-dblb9Et4DAtiZ5YSUZHLl4XhH4uK80GhAZrVXdN4O2P4gQ40Wa5UIOPUHlA/nFd2PLblBZWUioLMMAVrgpoYcA==", + "dev": true, + "dependencies": { + "tslib": "^2.0.3" + } + }, + "node_modules/sprintf-js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", + "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", + "dev": true + }, + "node_modules/ssri": { + "version": "10.0.5", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.5.tgz", + "integrity": "sha512-bSf16tAFkGeRlUNDjXu8FzaMQt6g2HZJrun7mtMbIPOddxt3GLMSz5VWUWcqTJUPfLEaDIepGxv+bYQW49596A==", + "dev": true, + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/ssri/node_modules/minipass": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dev": true + }, + "node_modules/std-env": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.7.0.tgz", + "integrity": "sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==", + "dev": true + }, + "node_modules/streamsearch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", + "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", + "dev": true, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-env-interpolation": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/string-env-interpolation/-/string-env-interpolation-1.0.1.tgz", + "integrity": "sha512-78lwMoCcn0nNu8LszbP1UA7g55OeE4v7rCeWnM5B453rnNr4aq+5it3FEYtZrSEiMvHZOZ9Jlqb0OD0M2VInqg==", + "dev": true + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strip-literal": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-2.0.0.tgz", + "integrity": "sha512-f9vHgsCWBq2ugHAkGMiiYY+AYG0D/cbloKKg0nhaaaSNsujdGIpVXCNsrJpCKr5M0f4aI31mr13UjY6GAuXCKA==", + "dev": true, + "dependencies": { + "js-tokens": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/strip-literal/node_modules/js-tokens": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-8.0.3.tgz", + "integrity": "sha512-UfJMcSJc+SEXEl9lH/VLHSZbThQyLpw1vLO1Lb+j4RWDvG3N2f7yj3PVQA3cmkTBNldJ9eFnM+xEXxHIXrYiJw==", + "dev": true + }, + "node_modules/sucrase": { + "version": "3.35.0", + "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", + "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.2", + "commander": "^4.0.0", + "glob": "^10.3.10", + "lines-and-columns": "^1.1.6", + "mz": "^2.7.0", + "pirates": "^4.0.1", + "ts-interface-checker": "^0.1.9" + }, + "bin": { + "sucrase": "bin/sucrase", + "sucrase-node": "bin/sucrase-node" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/sucrase/node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/sucrase/node_modules/glob": { + "version": "10.3.10", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", + "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.3.5", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", + "path-scurry": "^1.10.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/svelecte": { + "version": "3.17.3", + "resolved": "https://registry.npmjs.org/svelecte/-/svelecte-3.17.3.tgz", + "integrity": "sha512-wnvoRxJIFFkm+CmXgjL4R3i/TcuYUIBkE+jDJSBD7AdSOzk1K6u3+nW4zwxaGT29zyZpiZkWeiy7lO62r5F+tg==", + "dependencies": { + "svelte-tiny-virtual-list": "^2.0.0" + } + }, + "node_modules/svelte": { + "version": "4.2.12", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-4.2.12.tgz", + "integrity": "sha512-d8+wsh5TfPwqVzbm4/HCXC783/KPHV60NvwitJnyTA5lWn1elhXMNWhXGCJ7PwPa8qFUnyJNIyuIRt2mT0WMug==", + "dependencies": { + "@ampproject/remapping": "^2.2.1", + "@jridgewell/sourcemap-codec": "^1.4.15", + "@jridgewell/trace-mapping": "^0.3.18", + "@types/estree": "^1.0.1", + "acorn": "^8.9.0", + "aria-query": "^5.3.0", + "axobject-query": "^4.0.0", + "code-red": "^1.0.3", + "css-tree": "^2.3.1", + "estree-walker": "^3.0.3", + "is-reference": "^3.0.1", + "locate-character": "^3.0.0", + "magic-string": "^0.30.4", + "periscopic": "^3.1.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/svelte-check": { + "version": "3.6.6", + "resolved": "https://registry.npmjs.org/svelte-check/-/svelte-check-3.6.6.tgz", + "integrity": "sha512-b9q9rOHOMYF3U8XllK7LmXTq1LeWQ98waGfEJzrFutViadkNl1tgdEtxIQ8yuPx+VQ4l7YrknYol+0lfZocaZw==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.17", + "chokidar": "^3.4.1", + "fast-glob": "^3.2.7", + "import-fresh": "^3.2.1", + "picocolors": "^1.0.0", + "sade": "^1.7.4", + "svelte-preprocess": "^5.1.3", + "typescript": "^5.0.3" + }, + "bin": { + "svelte-check": "bin/svelte-check" + }, + "peerDependencies": { + "svelte": "^3.55.0 || ^4.0.0-next.0 || ^4.0.0 || ^5.0.0-next.0" + } + }, + "node_modules/svelte-eslint-parser": { + "version": "0.33.1", + "resolved": "https://registry.npmjs.org/svelte-eslint-parser/-/svelte-eslint-parser-0.33.1.tgz", + "integrity": "sha512-vo7xPGTlKBGdLH8T5L64FipvTrqv3OQRx9d2z5X05KKZDlF4rQk8KViZO4flKERY+5BiVdOh7zZ7JGJWo5P0uA==", + "dev": true, + "dependencies": { + "eslint-scope": "^7.0.0", + "eslint-visitor-keys": "^3.0.0", + "espree": "^9.0.0", + "postcss": "^8.4.29", + "postcss-scss": "^4.0.8" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ota-meshi" + }, + "peerDependencies": { + "svelte": "^3.37.0 || ^4.0.0" + }, + "peerDependenciesMeta": { + "svelte": { + "optional": true + } + } + }, + "node_modules/svelte-hmr": { + "version": "0.15.3", + "resolved": "https://registry.npmjs.org/svelte-hmr/-/svelte-hmr-0.15.3.tgz", + "integrity": "sha512-41snaPswvSf8TJUhlkoJBekRrABDXDMdpNpT2tfHIv4JuhgvHqLMhEPGtaQn0BmbNSTkuz2Ed20DF2eHw0SmBQ==", + "dev": true, + "engines": { + "node": "^12.20 || ^14.13.1 || >= 16" + }, + "peerDependencies": { + "svelte": "^3.19.0 || ^4.0.0" + } + }, + "node_modules/svelte-modals": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/svelte-modals/-/svelte-modals-1.3.0.tgz", + "integrity": "sha512-b1Ylnyv9O6b7VYeWGJVToaVU2lw7GtErVwiEdojyfnOuZcrhNlQ5eDqbTrL3xyKz8j2VTy/QiGUl1lm/6SnQ2A==", + "peerDependencies": { + "svelte": "^3.0.0 || ^4.0.0" + } + }, + "node_modules/svelte-preprocess": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/svelte-preprocess/-/svelte-preprocess-5.1.3.tgz", + "integrity": "sha512-xxAkmxGHT+J/GourS5mVJeOXZzne1FR5ljeOUAMXUkfEhkLEllRreXpbl3dIYJlcJRfL1LO1uIAPpBpBfiqGPw==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "@types/pug": "^2.0.6", + "detect-indent": "^6.1.0", + "magic-string": "^0.30.5", + "sorcery": "^0.11.0", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">= 16.0.0", + "pnpm": "^8.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.10.2", + "coffeescript": "^2.5.1", + "less": "^3.11.3 || ^4.0.0", + "postcss": "^7 || ^8", + "postcss-load-config": "^2.1.0 || ^3.0.0 || ^4.0.0 || ^5.0.0", + "pug": "^3.0.0", + "sass": "^1.26.8", + "stylus": "^0.55.0", + "sugarss": "^2.0.0 || ^3.0.0 || ^4.0.0", + "svelte": "^3.23.0 || ^4.0.0-next.0 || ^4.0.0 || ^5.0.0-next.0", + "typescript": ">=3.9.5 || ^4.0.0 || ^5.0.0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "coffeescript": { + "optional": true + }, + "less": { + "optional": true + }, + "postcss": { + "optional": true + }, + "postcss-load-config": { + "optional": true + }, + "pug": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, + "node_modules/svelte-tiny-virtual-list": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/svelte-tiny-virtual-list/-/svelte-tiny-virtual-list-2.0.5.tgz", + "integrity": "sha512-xg9ckb8UeeIme4/5qlwCrl2QNmUZ8SCQYZn3Ji83cUsoASqRNy3KWjpmNmzYvPDqCHSZjruBBsoB7t5hwuzw5g==" + }, + "node_modules/swap-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/swap-case/-/swap-case-2.0.2.tgz", + "integrity": "sha512-kc6S2YS/2yXbtkSMunBtKdah4VFETZ8Oh6ONSmSd9bRxhqTrtARUCBUiWXH3xVPpvR7tz2CSnkuXVE42EcGnMw==", + "dev": true, + "dependencies": { + "tslib": "^2.0.3" + } + }, + "node_modules/tailwindcss": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.1.tgz", + "integrity": "sha512-qAYmXRfk3ENzuPBakNK0SRrUDipP8NQnEY6772uDhflcQz5EhRdD7JNZxyrFHVQNCwULPBn6FNPp9brpO7ctcA==", + "dev": true, + "dependencies": { + "@alloc/quick-lru": "^5.2.0", + "arg": "^5.0.2", + "chokidar": "^3.5.3", + "didyoumean": "^1.2.2", + "dlv": "^1.1.3", + "fast-glob": "^3.3.0", + "glob-parent": "^6.0.2", + "is-glob": "^4.0.3", + "jiti": "^1.19.1", + "lilconfig": "^2.1.0", + "micromatch": "^4.0.5", + "normalize-path": "^3.0.0", + "object-hash": "^3.0.0", + "picocolors": "^1.0.0", + "postcss": "^8.4.23", + "postcss-import": "^15.1.0", + "postcss-js": "^4.0.1", + "postcss-load-config": "^4.0.1", + "postcss-nested": "^6.0.1", + "postcss-selector-parser": "^6.0.11", + "resolve": "^1.22.2", + "sucrase": "^3.32.0" + }, + "bin": { + "tailwind": "lib/cli.js", + "tailwindcss": "lib/cli.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tailwindcss/node_modules/postcss-load-config": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz", + "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "lilconfig": "^3.0.0", + "yaml": "^2.3.4" + }, + "engines": { + "node": ">= 14" + }, + "peerDependencies": { + "postcss": ">=8.0.9", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "postcss": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/tailwindcss/node_modules/postcss-load-config/node_modules/lilconfig": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.1.tgz", + "integrity": "sha512-O18pf7nyvHTckunPWCV1XUNXU1piu01y2b7ATJ0ppkUkk8ocqVWBrYjJBCwHDjD/ZWcfyrA0P4gKhzWGi5EINQ==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, + "node_modules/tar": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.0.tgz", + "integrity": "sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ==", + "dev": true, + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tar/node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/tar/node_modules/fs-minipass/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tar/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tar/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dev": true, + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "dev": true, + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true + }, + "node_modules/tiny-glob": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/tiny-glob/-/tiny-glob-0.2.9.tgz", + "integrity": "sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg==", + "dev": true, + "dependencies": { + "globalyzer": "0.1.0", + "globrex": "^0.1.2" + } + }, + "node_modules/tinybench": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.6.0.tgz", + "integrity": "sha512-N8hW3PG/3aOoZAN5V/NSAEDz0ZixDSSt5b/a05iqtpgfLWMSVuCo7w0k2vVvEjdrIoeGqZzweX2WlyioNIHchA==", + "dev": true + }, + "node_modules/tinypool": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.8.2.tgz", + "integrity": "sha512-SUszKYe5wgsxnNOVlBYO6IC+8VGWdVGZWAqUxp3UErNBtptZvWbwyUOyzNL59zigz2rCA92QiL3wvG+JDSdJdQ==", + "dev": true, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tinyspy": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-2.2.1.tgz", + "integrity": "sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==", + "dev": true, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/title-case": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/title-case/-/title-case-3.0.3.tgz", + "integrity": "sha512-e1zGYRvbffpcHIrnuqT0Dh+gEJtDaxDSoG4JAIpq4oDFyooziLBIiYQv0GBT4FUAnUop5uZ1hiIAj7oAF6sOCA==", + "dev": true, + "dependencies": { + "tslib": "^2.0.3" + } + }, + "node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/totalist": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", + "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "dev": true + }, + "node_modules/ts-api-utils": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.2.1.tgz", + "integrity": "sha512-RIYA36cJn2WiH9Hy77hdF9r7oEwxAtB/TS9/S4Qd90Ap4z5FSiin5zEiTL44OII1Y3IIlEvxwxFUVgrHSZ/UpA==", + "dev": true, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "typescript": ">=4.2.0" + } + }, + "node_modules/ts-interface-checker": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", + "dev": true + }, + "node_modules/ts-log": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/ts-log/-/ts-log-2.2.5.tgz", + "integrity": "sha512-PGcnJoTBnVGy6yYNFxWVNkdcAuAMstvutN9MgDJIV6L0oG8fB+ZNNy1T+wJzah8RPGor1mZuPQkVfXNDpy9eHA==", + "dev": true + }, + "node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", + "dev": true + }, + "node_modules/tuf-js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/tuf-js/-/tuf-js-1.1.7.tgz", + "integrity": "sha512-i3P9Kgw3ytjELUfpuKVDNBJvk4u5bXL6gskv572mcevPbSKCV3zt3djhmlEQ65yERjIbOSncy7U4cQJaB1CBCg==", + "dev": true, + "dependencies": { + "@tufjs/models": "1.0.4", + "debug": "^4.3.4", + "make-fetch-happen": "^11.1.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, + "dependencies": { + "is-typedarray": "^1.0.0" + } + }, + "node_modules/typescript": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", + "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/ua-parser-js": { + "version": "1.0.37", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.37.tgz", + "integrity": "sha512-bhTyI94tZofjo+Dn8SN6Zv8nBDvyXTymAdM3LDI/0IboIUwTu1rEhW7v2TfiVsoYWgkQ4kOVqnI8APUFbIQIFQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/ua-parser-js" + }, + { + "type": "paypal", + "url": "https://paypal.me/faisalman" + }, + { + "type": "github", + "url": "https://github.com/sponsors/faisalman" + } + ], + "engines": { + "node": "*" + } + }, + "node_modules/ufo": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.4.0.tgz", + "integrity": "sha512-Hhy+BhRBleFjpJ2vchUNN40qgkh0366FWJGqVLYBHev0vpHTrXSA0ryT+74UiW6KWsldNurQMKGqCm1M2zBciQ==", + "dev": true + }, + "node_modules/unc-path-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", + "integrity": "sha512-eXL4nmJT7oCpkZsHZUOJo8hcX3GbsiDOa0Qu9F646fi8dT3XuSVopVqAcEiVzSKKH7UoDti23wNX3qGFxcW5Qg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, + "node_modules/unique-filename": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-3.0.0.tgz", + "integrity": "sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==", + "dev": true, + "dependencies": { + "unique-slug": "^4.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/unique-slug": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-4.0.0.tgz", + "integrity": "sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/unique-string": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-3.0.0.tgz", + "integrity": "sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==", + "dev": true, + "dependencies": { + "crypto-random-string": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/unixify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unixify/-/unixify-1.0.0.tgz", + "integrity": "sha512-6bc58dPYhCMHHuwxldQxO3RRNZ4eCogZ/st++0+fcC1nr0jiGUtAdBJ2qzmLQWSxbtz42pWt4QQMiZ9HvZf5cg==", + "dev": true, + "dependencies": { + "normalize-path": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unixify/node_modules/normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==", + "dev": true, + "dependencies": { + "remove-trailing-separator": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/untildify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", + "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", + "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/update-notifier": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-6.0.2.tgz", + "integrity": "sha512-EDxhTEVPZZRLWYcJ4ZXjGFN0oP7qYvbXWzEgRm/Yql4dHX5wDbvh89YHP6PK1lzZJYrMtXUuZZz8XGK+U6U1og==", + "dev": true, + "dependencies": { + "boxen": "^7.0.0", + "chalk": "^5.0.1", + "configstore": "^6.0.0", + "has-yarn": "^3.0.0", + "import-lazy": "^4.0.0", + "is-ci": "^3.0.1", + "is-installed-globally": "^0.4.0", + "is-npm": "^6.0.0", + "is-yarn-global": "^0.4.0", + "latest-version": "^7.0.0", + "pupa": "^3.1.0", + "semver": "^7.3.7", + "semver-diff": "^4.0.0", + "xdg-basedir": "^5.1.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/yeoman/update-notifier?sponsor=1" + } + }, + "node_modules/update-notifier/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "dev": true, + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/update-notifier/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/update-notifier/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/update-notifier/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/upper-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-2.0.2.tgz", + "integrity": "sha512-KgdgDGJt2TpuwBUIjgG6lzw2GWFRCW9Qkfkiv0DxqHHLYJHmtmdUIKcZd8rHgFSjopVTlw6ggzCm1b8MFQwikg==", + "dev": true, + "dependencies": { + "tslib": "^2.0.3" + } + }, + "node_modules/upper-case-first": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/upper-case-first/-/upper-case-first-2.0.2.tgz", + "integrity": "sha512-514ppYHBaKwfJRK/pNC6c/OxfGa0obSnAl106u97Ed0I625Nin96KAjttZF6ZL3e1XLtphxnqrOi9iWgm+u+bg==", + "dev": true, + "dependencies": { + "tslib": "^2.0.3" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/uri-js/node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/urlpattern-polyfill": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-8.0.2.tgz", + "integrity": "sha512-Qp95D4TPJl1kC9SKigDcqgyM2VDVO4RiJc2d4qe5GrYm+zbIQCWWKAFaJNQ4BhdFeDGwBmAxqJBwWSJDb9T3BQ==", + "dev": true + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/validate-npm-package-name": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-5.0.0.tgz", + "integrity": "sha512-YuKoXDAhBYxY7SfOKxHBDoSyENFeW5VvIIQp2TGQuit8gpK6MnWaQelBKxso72DoxTZfZdcP3W90LqpSkgPzLQ==", + "dev": true, + "dependencies": { + "builtins": "^5.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/value-or-promise": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/value-or-promise/-/value-or-promise-1.0.12.tgz", + "integrity": "sha512-Z6Uz+TYwEqE7ZN50gwn+1LCVo9ZVrpxRPOhOLnncYkY1ZzOYtrX8Fwf/rFktZ8R5mJms6EZf5TqNOMeZmnPq9Q==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/vite": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.1.4.tgz", + "integrity": "sha512-n+MPqzq+d9nMVTKyewqw6kSt+R3CkvF9QAKY8obiQn8g1fwTscKxyfaYnC632HtBXAQGc1Yjomphwn1dtwGAHg==", + "dev": true, + "dependencies": { + "esbuild": "^0.19.3", + "postcss": "^8.4.35", + "rollup": "^4.2.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vite-node": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-1.3.1.tgz", + "integrity": "sha512-azbRrqRxlWTJEVbzInZCTchx0X69M/XPTCz4H+TLvlTcR/xH/3hkRqhOakT41fMJCMzXTu4UvegkZiEoJAWvng==", + "dev": true, + "dependencies": { + "cac": "^6.7.14", + "debug": "^4.3.4", + "pathe": "^1.1.1", + "picocolors": "^1.0.0", + "vite": "^5.0.0" + }, + "bin": { + "vite-node": "vite-node.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/vitefu": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-0.2.5.tgz", + "integrity": "sha512-SgHtMLoqaeeGnd2evZ849ZbACbnwQCIwRH57t18FxcXoZop0uQu0uzlIhJBlF/eWVzuce0sHeqPcDo+evVcg8Q==", + "dev": true, + "peerDependencies": { + "vite": "^3.0.0 || ^4.0.0 || ^5.0.0" + }, + "peerDependenciesMeta": { + "vite": { + "optional": true + } + } + }, + "node_modules/vitest": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-1.3.1.tgz", + "integrity": "sha512-/1QJqXs8YbCrfv/GPQ05wAZf2eakUPLPa18vkJAKE7RXOKfVHqMZZ1WlTjiwl6Gcn65M5vpNUB6EFLnEdRdEXQ==", + "dev": true, + "dependencies": { + "@vitest/expect": "1.3.1", + "@vitest/runner": "1.3.1", + "@vitest/snapshot": "1.3.1", + "@vitest/spy": "1.3.1", + "@vitest/utils": "1.3.1", + "acorn-walk": "^8.3.2", + "chai": "^4.3.10", + "debug": "^4.3.4", + "execa": "^8.0.1", + "local-pkg": "^0.5.0", + "magic-string": "^0.30.5", + "pathe": "^1.1.1", + "picocolors": "^1.0.0", + "std-env": "^3.5.0", + "strip-literal": "^2.0.0", + "tinybench": "^2.5.1", + "tinypool": "^0.8.2", + "vite": "^5.0.0", + "vite-node": "1.3.1", + "why-is-node-running": "^2.2.2" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@types/node": "^18.0.0 || >=20.0.0", + "@vitest/browser": "1.3.1", + "@vitest/ui": "1.3.1", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } + } + }, + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "dev": true, + "dependencies": { + "defaults": "^1.0.3" + } + }, + "node_modules/web-streams-polyfill": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", + "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/webcrypto-core": { + "version": "1.7.8", + "resolved": "https://registry.npmjs.org/webcrypto-core/-/webcrypto-core-1.7.8.tgz", + "integrity": "sha512-eBR98r9nQXTqXt/yDRtInszPMjTaSAMJAFDg2AHsgrnczawT1asx9YNBX6k5p+MekbPF4+s/UJJrr88zsTqkSg==", + "dev": true, + "dependencies": { + "@peculiar/asn1-schema": "^2.3.8", + "@peculiar/json-schema": "^1.1.12", + "asn1js": "^3.0.1", + "pvtsutils": "^1.3.5", + "tslib": "^2.6.2" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "dev": true + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dev": true, + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-module": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", + "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", + "dev": true + }, + "node_modules/why-is-node-running": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.2.2.tgz", + "integrity": "sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==", + "dev": true, + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wide-align": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "dev": true, + "dependencies": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, + "node_modules/widest-line": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-4.0.1.tgz", + "integrity": "sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig==", + "dev": true, + "dependencies": { + "string-width": "^5.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/widest-line/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/widest-line/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "node_modules/widest-line/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/widest-line/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/wonka": { + "version": "6.3.4", + "resolved": "https://registry.npmjs.org/wonka/-/wonka-6.3.4.tgz", + "integrity": "sha512-CjpbqNtBGNAeyNS/9W6q3kSkKE52+FjIj7AkFlLr11s/VWGUu6a2CdYSdGxocIhIVjaW/zchesBQUKPVU69Cqg==" + }, + "node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "node_modules/ws": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz", + "integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==", + "dev": true, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xdg-basedir": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-5.1.0.tgz", + "integrity": "sha512-GCPAHLvrIH13+c0SuacwvRYj2SxJXQ4kaVTT5xgL3kPrz56XxkF21IGhjSE1+W0aw7gpBWRGXLCPnPby6lSpmQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "node_modules/yaml": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.0.tgz", + "integrity": "sha512-j9iR8g+/t0lArF4V6NE/QCfT+CO7iLqrXAHZbJdo+LfjqP1vR8Fg5bSiaq6Q2lOD1AUEVrEVIgABvBFYojJVYQ==", + "dev": true, + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/yaml-ast-parser": { + "version": "0.0.43", + "resolved": "https://registry.npmjs.org/yaml-ast-parser/-/yaml-ast-parser-0.0.43.tgz", + "integrity": "sha512-2PTINUwsRqSd+s8XxKaJWQlUuEMHJQyEuh2edBbW8KNJz0SJPwUSD2zRWqezFEdN7IzAgeuYHFUCF7o8zRdZ0A==", + "dev": true + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "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" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/frontend/package.json b/frontend/package.json new file mode 100644 index 0000000..d5854f1 --- /dev/null +++ b/frontend/package.json @@ -0,0 +1,57 @@ +{ + "name": "hircine", + "version": "0.1.0", + "license": "ISC", + "private": true, + "scripts": { + "dev": "vite dev", + "build": "vite build", + "preview": "vite preview", + "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", + "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch", + "lint": "prettier --plugin prettier-plugin-svelte --check . && eslint .", + "format": "prettier --plugin prettier-plugin-svelte --write .", + "generate": "graphql-codegen", + "test": "vitest" + }, + "devDependencies": { + "@graphql-codegen/cli": "^5.0.2", + "@graphql-codegen/typed-document-node": "^5.0.6", + "@graphql-codegen/typescript-operations": "^4.2.0", + "@iconify-json/material-symbols": "^1.1.74", + "@iconify/tailwind": "^0.1.4", + "@sveltejs/adapter-static": "^3.0.1", + "@sveltejs/kit": "^2.5.2", + "@sveltejs/vite-plugin-svelte": "^3.0.2", + "@typescript-eslint/eslint-plugin": "^7.1.0", + "@typescript-eslint/parser": "^7.1.0", + "@zerodevx/svelte-toast": "^0.9.5", + "autoprefixer": "^10.4.18", + "date-fns": "^3.3.1", + "eslint": "^8.57.0", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-svelte": "^2.35.1", + "fast-deep-equal": "^3.1.3", + "npm-check-updates": "^16.14.15", + "postcss": "^8.4.35", + "prettier": "^3.2.5", + "prettier-plugin-svelte": "^3.2.2", + "prettier-plugin-tailwindcss": "^0.5.11", + "svelte": "^4.2.12", + "svelte-check": "^3.6.6", + "tailwindcss": "^3.4.1", + "tslib": "^2.6.2", + "typescript": "^5.3.3", + "vite": "^5.1.4", + "vitest": "^1.3.1" + }, + "type": "module", + "dependencies": { + "@jsonurl/jsonurl": "^1.1.7", + "@urql/svelte": "^4.1.0", + "filesize": "^10.1.0", + "graphql": "npm:graphql-web-lite@^16.6.0", + "svelecte": "^3.17.3", + "svelte-modals": "^1.3.0" + } +} diff --git a/frontend/postcss.config.cjs b/frontend/postcss.config.cjs new file mode 100644 index 0000000..054c147 --- /dev/null +++ b/frontend/postcss.config.cjs @@ -0,0 +1,6 @@ +module.exports = { + plugins: { + tailwindcss: {}, + autoprefixer: {} + } +}; diff --git a/frontend/src/app.css b/frontend/src/app.css new file mode 100644 index 0000000..13a7883 --- /dev/null +++ b/frontend/src/app.css @@ -0,0 +1,180 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +@layer base { + body { + display: grid; + grid-template-columns: 3rem 1fr; + scrollbar-color: theme('colors.gray.500') rgba(0, 0, 0, 0); + font-family: 'Noto Sans', sans-serif; + } + + input, + textarea { + @apply w-full rounded bg-slate-900 p-[.4rem] focus:outline focus:outline-1 focus:outline-slate-500; + } + + label { + @apply mb-0.5 inline-block; + } + + form { + @apply flex flex-col gap-4 p-px text-sm; + } + + .rounded-group > * { + @apply rounded-none first:rounded-l-sm last:rounded-r-sm !important; + } + + .rounded-group-start > * { + @apply rounded-none first:rounded-l-sm !important; + } + + .rounded-group-end > * { + @apply rounded-none last:rounded-r-sm !important; + } + + .grid-labels { + @apply grid grid-cols-[1fr_5fr] gap-2; + } + + header { + grid-area: header; + } + + aside { + overflow: auto; + grid-area: sidebar; + @apply lg:w-[28rem] xl:w-[32rem] min-[1920px]:w-[36rem]; + } + + main { + grid-area: main; + } +} + +@layer components { + .btn { + @apply flex items-center justify-center rounded-sm p-2 text-white transition-colors disabled:opacity-40; + } + + .btn-xs { + @apply btn rounded-sm p-0.5 py-0; + } + + .btn-blue { + @apply btn bg-blue-700 hover:bg-blue-600 disabled:bg-blue-900; + } + + .btn-rose { + @apply btn bg-rose-700 hover:bg-rose-600 disabled:bg-rose-900; + } + + .btn-slate { + @apply btn bg-slate-700 hover:bg-slate-600 disabled:bg-slate-800; + } + + .btn-indigo { + @apply btn bg-indigo-700 hover:bg-indigo-600 disabled:bg-indigo-800; + } + + .icon-xs { + @apply text-[18px]; + } + + .icon-base { + @apply text-[24px]; + } + + .icon-lg { + @apply text-[28px]; + } + + .icon-2xl { + @apply text-[48px]; + } + + .icon-gray.hoverable:hover { + @apply text-gray-200/80; + } + + .icon-gray.dim { + @apply text-gray-100/40; + } + + .icon-yellow { + @apply text-yellow-300; + } + + .icon-yellow.hoverable:hover { + @apply text-yellow-300/80; + } + + .icon-yellow.dim { + @apply text-slate-100/40; + } +} + +@layer utilities { + .toggled { + @apply bg-indigo-700 hover:bg-indigo-600; + } + + .floating { + @apply rounded-full bg-black/50 p-1 text-white/80 backdrop-blur-sm hover:bg-black/50 hover:text-white; + } + + .ellipsis-nowrap { + @apply overflow-hidden text-ellipsis whitespace-nowrap; + } + + .rounded-inherit { + border-radius: inherit; + } + + .grid-card-h { + grid-template-columns: 210px 1fr; + grid-template-rows: 300px; + } + + .grid-card-cover-only { + @apply !grid-card-h; + } + + .grid-card-v { + grid-template-columns: 1fr; + grid-template-rows: 500px 1fr; + } +} + +.svelecte-control { + --sv-item-color: inherit !important; + --sv-bg: theme(colors.slate.900) !important; + --sv-disabled-bg: theme(colors.slate.900) !important; + --sv-border: 1px solid rgba(0, 0, 0, 0) !important; + --sv-disabled-border-color: rgba(0, 0, 0, 0) !important; + --sv-border-color: theme(colors.slate.600) !important; + --sv-active-border: 1px solid theme(colors.slate.500) !important; + --sv-item-selected-bg: theme(colors.indigo.800) !important; + --sv-item-active-bg: theme(colors.indigo.800) !important; + --sv-highlight-bg: none !important; + --sv-item-btn-bg-hover: theme(colors.rose.900) !important; + --sv-placeholder-color: theme(colors.gray.500) !important; +} + +.svelecte-control input { + @apply !h-8; +} + +.exclude .svelecte-control { + --sv-border: 1px solid theme('colors.red.900') !important; + --sv-active-border: 1px solid theme('colors.red.700') !important; + + --sv-item-selected-bg: theme(colors.rose.800) !important; + --sv-item-active-bg: theme(colors.rose.800) !important; +} + +.sv-dropdown { + @apply my-1 !bg-slate-950; +} diff --git a/frontend/src/app.d.ts b/frontend/src/app.d.ts new file mode 100644 index 0000000..41634fe --- /dev/null +++ b/frontend/src/app.d.ts @@ -0,0 +1,12 @@ +/// <reference types="@sveltejs/kit" /> +/// <reference types="unplugin-icons/types/svelte" /> + +// See https://kit.svelte.dev/docs/types#app +// for information about these interfaces +// and what to do when importing types +declare namespace App { + // interface Locals {} + // interface PageData {} + // interface Error {} + // interface Platform {} +} diff --git a/frontend/src/app.html b/frontend/src/app.html new file mode 100644 index 0000000..6303945 --- /dev/null +++ b/frontend/src/app.html @@ -0,0 +1,13 @@ +<!doctype html> +<html lang="en"> + <head> + <meta charset="utf-8" /> + <meta name="viewport" content="width=device-width" /> + <link rel="icon" href="%sveltekit.assets%/favicon.svg" /> + <title>hircine</title> + %sveltekit.head% + </head> + <body data-sveltekit-preload-data="hover" class="h-screen bg-slate-800 text-gray-200"> + <div style="display: contents">%sveltekit.body%</div> + </body> +</html> diff --git a/frontend/src/gql/Mutations.ts b/frontend/src/gql/Mutations.ts new file mode 100644 index 0000000..d669b25 --- /dev/null +++ b/frontend/src/gql/Mutations.ts @@ -0,0 +1,244 @@ +import { toastSuccess } from '$lib/Toasts'; +import { + Client, + type AnyVariables, + type OperationResult, + type OperationResultSource +} from '@urql/svelte'; +import { isError, isSuccess, type RequiredName } from './Utils'; +import * as gql from './graphql'; + +export type DeleteMutation = (client: Client, args: { ids: number | number[] }) => Promise<unknown>; + +const comicTypes = ['Comic']; +const comicUpsertTypes = comicTypes.concat([ + 'Artist', + 'Character', + 'Circle', + 'Namespace', + 'Collection', + 'Tag', + 'World' +]); + +function handleResult<D, I extends AnyVariables>(result: OperationResult<D, I>): Promise<D> { + return new Promise((resolve, reject) => { + if (result.error) { + return reject(`${result.error.name}: ${result.error.message}`); + } + + if (!result.data) { + return reject('Mutation resolved, but result contains no data.'); + } + + const obj = Object.values(result.data)[0]; + + if (isError(obj)) { + reject(obj.message); + } else if (isSuccess(obj)) { + toastSuccess(obj.message); + resolve(result.data); + } + + reject('This should not happen.'); + }); +} + +async function handleMutation<D, V extends AnyVariables>( + mutation: OperationResultSource<OperationResult<D, V>> +) { + return await mutation.toPromise().then(handleResult); +} + +export async function addComic(client: Client, args: gql.AddComicMutationVariables) { + return await handleMutation( + client.mutation(gql.AddComicDocument, args, { + additionalTypenames: comicTypes.concat('Archive', 'Page') + }) + ); +} + +export async function updateComics(client: Client, args: gql.UpdateComicsMutationVariables) { + return await handleMutation( + client.mutation(gql.UpdateComicsDocument, args, { + additionalTypenames: comicTypes + }) + ); +} + +export async function upsertComics(client: Client, args: gql.UpsertComicsMutationVariables) { + return await handleMutation( + client.mutation(gql.UpsertComicsDocument, args, { + additionalTypenames: comicUpsertTypes + }) + ); +} + +export async function updateArchives(client: Client, args: gql.UpdateArchivesMutationVariables) { + return await handleMutation( + client.mutation(gql.UpdateArchivesDocument, args, { + additionalTypenames: ['Archive'] + }) + ); +} + +export async function deleteArchives(client: Client, args: gql.DeleteArchivesMutationVariables) { + return await handleMutation( + client.mutation(gql.DeleteArchivesDocument, args, { + additionalTypenames: comicTypes.concat('Archive') + }) + ); +} + +export async function deleteComics(client: Client, args: gql.DeleteComicsMutationVariables) { + return await handleMutation( + client.mutation(gql.DeleteComicsDocument, args, { additionalTypenames: comicTypes }) + ); +} + +export async function addArtist(client: Client, args: gql.AddArtistMutationVariables) { + return await handleMutation( + client.mutation(gql.AddArtistDocument, args, { additionalTypenames: ['ArtistFilterResult'] }) + ); +} + +export async function updateArtists(client: Client, args: gql.UpdateArtistsMutationVariables) { + return await handleMutation( + client.mutation(gql.UpdateArtistsDocument, args, { additionalTypenames: ['Artist'] }) + ); +} + +export async function deleteArtists(client: Client, args: gql.DeleteArtistsMutationVariables) { + return await handleMutation( + client.mutation(gql.DeleteArtistsDocument, args, { + additionalTypenames: ['Artist'] + }) + ); +} + +export async function addCharacter(client: Client, args: gql.AddCharacterMutationVariables) { + return await handleMutation( + client.mutation(gql.AddCharacterDocument, args, { + additionalTypenames: ['CharacterFilterResult'] + }) + ); +} + +export async function updateCharacters( + client: Client, + args: gql.UpdateCharactersMutationVariables +) { + return await handleMutation( + client.mutation(gql.UpdateCharactersDocument, args, { additionalTypenames: ['Character'] }) + ); +} + +export async function deleteCharacters( + client: Client, + args: gql.DeleteCharactersMutationVariables +) { + return await handleMutation( + client.mutation(gql.DeleteCharactersDocument, args, { + additionalTypenames: ['Character'] + }) + ); +} + +export async function addCircle(client: Client, args: gql.AddCircleMutationVariables) { + return await handleMutation( + client.mutation(gql.AddCircleDocument, args, { additionalTypenames: ['CircleFilterResult'] }) + ); +} + +export async function updateCircles(client: Client, args: gql.UpdateCirclesMutationVariables) { + return await handleMutation( + client.mutation(gql.UpdateCirclesDocument, args, { additionalTypenames: ['Circle'] }) + ); +} + +export async function deleteCircles(client: Client, args: gql.DeleteCirclesMutationVariables) { + return await handleMutation( + client.mutation(gql.DeleteCirclesDocument, args, { + additionalTypenames: ['Circle'] + }) + ); +} + +export async function addNamespace(client: Client, args: gql.AddNamespaceMutationVariables) { + return await handleMutation( + client.mutation(gql.AddNamespaceDocument, args, { + additionalTypenames: ['NamespaceFilterResult', 'ComicTagFilterResult'] + }) + ); +} + +export async function updateNamespaces( + client: Client, + args: gql.UpdateNamespacesMutationVariables +) { + return await handleMutation( + client.mutation(gql.UpdateNamespacesDocument, args, { + additionalTypenames: ['Namespace', 'ComicTag'] + }) + ); +} + +export async function deleteNamespaces( + client: Client, + args: gql.DeleteNamespacesMutationVariables +) { + return await handleMutation( + client.mutation(gql.DeleteNamespacesDocument, args, { + additionalTypenames: ['NamespaceFilterResult', 'ComicTag'] + }) + ); +} + +export async function addTag(client: Client, args: gql.AddTagMutationVariables) { + return await handleMutation( + client.mutation(gql.AddTagDocument, args, { + additionalTypenames: ['TagFilterResult', 'ComicTagFilterResult'] + }) + ); +} + +export async function updateTags(client: Client, args: gql.UpdateTagsMutationVariables) { + return await handleMutation( + client.mutation(gql.UpdateTagsDocument, args, { + additionalTypenames: ['Tag', 'ComicTag'] + }) + ); +} + +export async function deleteTags(client: Client, args: gql.DeleteTagsMutationVariables) { + return await handleMutation( + client.mutation(gql.DeleteTagsDocument, args, { + additionalTypenames: ['TagFilterResult', 'ComicTag'] + }) + ); +} + +export async function addWorld(client: Client, args: gql.AddWorldMutationVariables) { + return await handleMutation( + client.mutation(gql.AddWorldDocument, args, { additionalTypenames: ['WorldFilterResult'] }) + ); +} + +export async function updateWorlds(client: Client, args: gql.UpdateWorldsMutationVariables) { + return await handleMutation( + client.mutation(gql.UpdateWorldsDocument, args, { additionalTypenames: ['World'] }) + ); +} + +export async function deleteWorlds(client: Client, args: gql.DeleteWorldsMutationVariables) { + return await handleMutation( + client.mutation(gql.DeleteWorldsDocument, args, { additionalTypenames: ['World'] }) + ); +} + +export type ArtistInput = RequiredName<gql.UpdateArtistInput>; +export type CharacterInput = RequiredName<gql.UpdateCharacterInput>; +export type CircleInput = RequiredName<gql.UpdateCircleInput>; +export type NamespaceInput = RequiredName<gql.UpdateNamespaceInput>; +export type TagInput = RequiredName<gql.UpdateTagInput>; +export type WorldInput = RequiredName<gql.UpdateWorldInput>; diff --git a/frontend/src/gql/Queries.ts b/frontend/src/gql/Queries.ts new file mode 100644 index 0000000..cc9dd4c --- /dev/null +++ b/frontend/src/gql/Queries.ts @@ -0,0 +1,243 @@ +import { Client, queryStore, type OperationResult } from '@urql/svelte'; +import { isError } from './Utils'; +import * as gql from './graphql'; + +function handleResult<D, T>(result: OperationResult<D>): Promise<T> { + return new Promise((resolve, reject) => { + if (result.error) { + return reject(`${result.error.name}: ${result.error.message}`); + } + + if (!result.data) { + return reject('Query resolved, but result contains no data.'); + } + + const data = Object.values<T>(result.data)[0]; + + if (isError(data)) { + reject(data.message); + } else { + resolve(data); + } + + reject('This should not happen.'); + }); +} + +export function comicTagList(client: Client, args?: gql.ComicTagListQueryVariables) { + return queryStore({ + client: client, + query: gql.ComicTagListDocument, + context: { + additionalTypenames: ['Namespace', 'Tag'] + }, + variables: args + }); +} + +export function artistList(client: Client) { + return queryStore({ + client: client, + query: gql.ArtistListDocument, + context: { + additionalTypenames: ['Artist'] + } + }); +} + +export function characterList(client: Client) { + return queryStore({ + client: client, + query: gql.CharacterListDocument, + context: { + additionalTypenames: ['Character'] + } + }); +} + +export function circleList(client: Client) { + return queryStore({ + client: client, + query: gql.CircleListDocument, + context: { + additionalTypenames: ['Circle'] + } + }); +} + +export function worldList(client: Client) { + return queryStore({ + client: client, + query: gql.WorldListDocument, + context: { + additionalTypenames: ['World'] + } + }); +} + +export function namespaceList(client: Client) { + return queryStore({ + client: client, + query: gql.NamespaceListDocument, + context: { + additionalTypenames: ['Namespace'] + } + }); +} + +export function comicScrapersQuery(client: Client, args: gql.ComicScrapersQueryVariables) { + return queryStore({ + client: client, + query: gql.ComicScrapersDocument, + variables: args, + context: { + additionalTypenames: ['Comic'] + } + }); +} + +export async function scrapeComic(client: Client, args: gql.ScrapeComicQueryVariables) { + return await client + .query(gql.ScrapeComicDocument, args, { additionalTypenames: ['Comic'] }) + .toPromise(); +} + +export function archiveQuery(client: Client, args: gql.ArchiveQueryVariables) { + return queryStore({ + client: client, + query: gql.ArchiveDocument, + variables: args, + context: { additionalTypenames: ['Archive'] } + }); +} + +export function archivesQuery(client: Client, args: gql.ArchivesQueryVariables) { + return queryStore({ + client: client, + query: gql.ArchivesDocument, + variables: args, + context: { additionalTypenames: ['Archive'] } + }); +} + +export function artistsQuery(client: Client, args?: gql.ArtistsQueryVariables) { + return queryStore({ + client: client, + query: gql.ArtistsDocument, + variables: args, + context: { additionalTypenames: ['Artist'] } + }); +} + +export function charactersQuery(client: Client, args?: gql.CharactersQueryVariables) { + return queryStore({ + client: client, + query: gql.CharactersDocument, + variables: args, + context: { additionalTypenames: ['Character'] } + }); +} + +export function circlesQuery(client: Client, args?: gql.CirclesQueryVariables) { + return queryStore({ + client: client, + query: gql.CirclesDocument, + variables: args, + context: { additionalTypenames: ['Circle'] } + }); +} + +export function comicQuery(client: Client, args: gql.ComicQueryVariables) { + return queryStore({ + client: client, + query: gql.ComicDocument, + variables: args, + context: { additionalTypenames: ['Comic'] } + }); +} + +export function comicsQuery(client: Client, args?: gql.ComicsQueryVariables) { + return queryStore({ + client: client, + query: gql.ComicsDocument, + variables: args, + context: { additionalTypenames: ['Comic'] } + }); +} + +export function namespacesQuery(client: Client, args?: gql.NamespacesQueryVariables) { + return queryStore({ + client: client, + query: gql.NamespacesDocument, + variables: args, + context: { additionalTypenames: ['Namespace'] } + }); +} + +export function tagsQuery(client: Client, args?: gql.TagsQueryVariables) { + return queryStore({ + client: client, + query: gql.TagsDocument, + variables: args, + context: { additionalTypenames: ['Tag'] } + }); +} + +export function worldsQuery(client: Client, args?: gql.WorldsQueryVariables) { + return queryStore({ + client: client, + query: gql.WorldsDocument, + variables: args, + context: { additionalTypenames: ['World'] } + }); +} + +export function frontpageQuery(client: Client) { + return queryStore({ + client: client, + query: gql.FrontpageDocument, + requestPolicy: 'network-only' + }); +} + +export function fetchArtist(client: Client, id: number) { + return client + .query(gql.ArtistDocument, { id }, { requestPolicy: 'cache-and-network' }) + .toPromise() + .then(handleResult<gql.ArtistQuery, gql.Artist>); +} + +export function fetchCharacter(client: Client, id: number) { + return client + .query(gql.CharacterDocument, { id }, { requestPolicy: 'cache-and-network' }) + .toPromise() + .then(handleResult<gql.CharacterQuery, gql.Character>); +} + +export function fetchCircle(client: Client, id: number) { + return client + .query(gql.CircleDocument, { id }, { requestPolicy: 'cache-and-network' }) + .toPromise() + .then(handleResult<gql.CircleQuery, gql.Circle>); +} + +export function fetchNamespace(client: Client, id: number) { + return client + .query(gql.NamespaceDocument, { id }, { requestPolicy: 'cache-and-network' }) + .toPromise() + .then(handleResult<gql.NamespaceQuery, gql.Namespace>); +} + +export function fetchTag(client: Client, id: number) { + return client + .query(gql.TagDocument, { id }, { requestPolicy: 'cache-and-network' }) + .toPromise() + .then(handleResult<gql.TagQuery, gql.FullTag>); +} + +export function fetchWorld(client: Client, id: number) { + return client + .query(gql.WorldDocument, { id }, { requestPolicy: 'cache-and-network' }) + .toPromise() + .then(handleResult<gql.WorldQuery, gql.World>); +} diff --git a/frontend/src/gql/Utils.ts b/frontend/src/gql/Utils.ts new file mode 100644 index 0000000..dd21bbe --- /dev/null +++ b/frontend/src/gql/Utils.ts @@ -0,0 +1,74 @@ +import equal from 'fast-deep-equal'; +import * as gql from './graphql'; + +export type OmitIdentifiers<T> = Omit<T, 'id' | '__typename'>; +export type RequiredName<T> = T & { name: string }; + +export function isSuccess(object: any): object is gql.Success { + if (object.__typename === undefined) { + return false; + } + + return object.__typename.endsWith('Success') && (object as gql.Success).message !== undefined; +} + +export function isError(object: any): object is gql.Error { + if (object.__typename === undefined) { + return false; + } + return object.__typename.endsWith('Error') && (object as gql.Error).message !== undefined; +} + +type Item = { + id: number | string; + name: string; +}; + +export function itemEquals(a: Item, b: Item) { + return a.name == b.name; +} + +function assocEquals(as: Item[], bs: Item[]) { + return equal( + as.map((a) => a.id), + bs.map((b) => b.id) + ); +} + +function stringEquals(a: string | null | undefined, b: string | null | undefined) { + return (a ? a : null) == (b ? b : null); +} + +export function tagEquals(a: gql.FullTag, b: gql.FullTag) { + return ( + itemEquals(a, b) && + stringEquals(a.description, b.description) && + assocEquals(a.namespaces, b.namespaces) + ); +} + +export function comicEquals( + a: gql.FullComicFragment | undefined, + b: gql.FullComicFragment | undefined +) { + if (a === undefined) return b === undefined; + if (b === undefined) return a === undefined; + + return ( + stringEquals(a.title, b.title) && + stringEquals(a.originalTitle, b.originalTitle) && + stringEquals(a.url, b.url) && + stringEquals(a.date, b.date) && + a.category == b.category && + a.rating == b.rating && + a.censorship == b.censorship && + a.language == b.language && + a.direction == b.direction && + a.layout == b.layout && + assocEquals(a.artists, b.artists) && + assocEquals(a.circles, b.circles) && + assocEquals(a.characters, b.characters) && + assocEquals(a.tags, b.tags) && + assocEquals(a.worlds, b.worlds) + ); +} diff --git a/frontend/src/gql/graphql.ts b/frontend/src/gql/graphql.ts new file mode 100644 index 0000000..139068c --- /dev/null +++ b/frontend/src/gql/graphql.ts @@ -0,0 +1,1764 @@ +import type { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'; +export type Maybe<T> = T | null; +export type InputMaybe<T> = Maybe<T>; +export type Exact<T extends { [key: string]: unknown }> = { [K in keyof T]: T[K] }; +export type MakeOptional<T, K extends keyof T> = Omit<T, K> & { [SubKey in K]?: Maybe<T[SubKey]> }; +export type MakeMaybe<T, K extends keyof T> = Omit<T, K> & { [SubKey in K]: Maybe<T[SubKey]> }; +export type MakeEmpty<T extends { [key: string]: unknown }, K extends keyof T> = { [_ in K]?: never }; +export type Incremental<T> = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; +/** All built-in and custom scalars, mapped to their actual values */ +export type Scalars = { + ID: { input: string; output: string; } + String: { input: string; output: string; } + Boolean: { input: boolean; output: boolean; } + Int: { input: number; output: number; } + Float: { input: number; output: number; } + Date: { input: string; output: string; } + DateTime: { input: string; output: string; } +}; + +export type AddArtistInput = { + name: Scalars['String']['input']; +}; + +export type AddCharacterInput = { + name: Scalars['String']['input']; +}; + +export type AddCircleInput = { + name: Scalars['String']['input']; +}; + +export type AddComicInput = { + archive: ArchiveInput; + cover: CoverInput; + pages: UniquePagesInput; + title: Scalars['String']['input']; +}; + +export type AddComicResponse = AddComicSuccess | IdNotFoundError | InvalidParameterError | PageClaimedError | PageRemoteError; + +export type AddComicSuccess = Success & { + __typename?: 'AddComicSuccess'; + archivePagesRemaining: Scalars['Boolean']['output']; + id: Scalars['Int']['output']; + message: Scalars['String']['output']; +}; + +export type AddNamespaceInput = { + name: Scalars['String']['input']; + sortName?: InputMaybe<Scalars['String']['input']>; +}; + +export type AddResponse = AddSuccess | IdNotFoundError | InvalidParameterError | NameExistsError; + +export type AddSuccess = Success & { + __typename?: 'AddSuccess'; + id: Scalars['Int']['output']; + message: Scalars['String']['output']; +}; + +export type AddTagInput = { + description?: InputMaybe<Scalars['String']['input']>; + name: Scalars['String']['input']; + namespaces?: InputMaybe<NamespacesInput>; +}; + +export type AddWorldInput = { + name: Scalars['String']['input']; +}; + +export type Archive = { + __typename?: 'Archive'; + cover: Image; + id: Scalars['Int']['output']; + name: Scalars['String']['output']; + organized: Scalars['Boolean']['output']; + pageCount: Scalars['Int']['output']; + path: Scalars['String']['output']; + size: Scalars['Int']['output']; +}; + +export type ArchiveFilter = { + organized?: InputMaybe<Scalars['Boolean']['input']>; + path?: InputMaybe<StringFilter>; +}; + +export type ArchiveFilterInput = { + exclude?: InputMaybe<ArchiveFilter>; + include?: InputMaybe<ArchiveFilter>; +}; + +export type ArchiveFilterResult = { + __typename?: 'ArchiveFilterResult'; + count: Scalars['Int']['output']; + edges: Array<Archive>; +}; + +export type ArchiveInput = { + id: Scalars['Int']['input']; +}; + +export type ArchiveResponse = FullArchive | IdNotFoundError; + +export enum ArchiveSort { + CreatedAt = 'CREATED_AT', + PageCount = 'PAGE_COUNT', + Path = 'PATH', + Random = 'RANDOM', + Size = 'SIZE' +} + +export type ArchiveSortInput = { + direction?: InputMaybe<SortDirection>; + on: ArchiveSort; + seed?: InputMaybe<Scalars['Int']['input']>; +}; + +export type Artist = { + __typename?: 'Artist'; + id: Scalars['Int']['output']; + name: Scalars['String']['output']; +}; + +export type ArtistFilter = { + name?: InputMaybe<StringFilter>; +}; + +export type ArtistFilterInput = { + exclude?: InputMaybe<ArtistFilter>; + include?: InputMaybe<ArtistFilter>; +}; + +export type ArtistFilterResult = { + __typename?: 'ArtistFilterResult'; + count: Scalars['Int']['output']; + edges: Array<Artist>; +}; + +export type ArtistResponse = Artist | IdNotFoundError; + +export enum ArtistSort { + CreatedAt = 'CREATED_AT', + Name = 'NAME', + Random = 'RANDOM', + UpdatedAt = 'UPDATED_AT' +} + +export type ArtistSortInput = { + direction?: InputMaybe<SortDirection>; + on: ArtistSort; + seed?: InputMaybe<Scalars['Int']['input']>; +}; + +export type ArtistsUpdateInput = { + ids: Array<Scalars['Int']['input']>; + options?: InputMaybe<UpdateOptions>; +}; + +export type ArtistsUpsertInput = { + names?: Array<Scalars['String']['input']>; + options?: InputMaybe<UpsertOptions>; +}; + +export type AssociationFilter = { + all?: InputMaybe<Array<Scalars['Int']['input']>>; + any?: InputMaybe<Array<Scalars['Int']['input']>>; + empty?: InputMaybe<Scalars['Boolean']['input']>; + exact?: InputMaybe<Array<Scalars['Int']['input']>>; +}; + +export enum Category { + Artbook = 'ARTBOOK', + Comic = 'COMIC', + Doujinshi = 'DOUJINSHI', + GameCg = 'GAME_CG', + ImageSet = 'IMAGE_SET', + Manga = 'MANGA', + VariantSet = 'VARIANT_SET', + Webtoon = 'WEBTOON' +} + +export type CategoryFilter = { + any?: InputMaybe<Array<Category>>; + empty?: InputMaybe<Scalars['Boolean']['input']>; +}; + +export enum Censorship { + Bar = 'BAR', + Full = 'FULL', + Mosaic = 'MOSAIC', + None = 'NONE' +} + +export type CensorshipFilter = { + any?: InputMaybe<Array<Censorship>>; + empty?: InputMaybe<Scalars['Boolean']['input']>; +}; + +export type Character = { + __typename?: 'Character'; + id: Scalars['Int']['output']; + name: Scalars['String']['output']; +}; + +export type CharacterFilter = { + name?: InputMaybe<StringFilter>; +}; + +export type CharacterFilterInput = { + exclude?: InputMaybe<CharacterFilter>; + include?: InputMaybe<CharacterFilter>; +}; + +export type CharacterFilterResult = { + __typename?: 'CharacterFilterResult'; + count: Scalars['Int']['output']; + edges: Array<Character>; +}; + +export type CharacterResponse = Character | IdNotFoundError; + +export enum CharacterSort { + CreatedAt = 'CREATED_AT', + Name = 'NAME', + Random = 'RANDOM', + UpdatedAt = 'UPDATED_AT' +} + +export type CharacterSortInput = { + direction?: InputMaybe<SortDirection>; + on: CharacterSort; + seed?: InputMaybe<Scalars['Int']['input']>; +}; + +export type CharactersUpdateInput = { + ids: Array<Scalars['Int']['input']>; + options?: InputMaybe<UpdateOptions>; +}; + +export type CharactersUpsertInput = { + names?: Array<Scalars['String']['input']>; + options?: InputMaybe<UpsertOptions>; +}; + +export type Circle = { + __typename?: 'Circle'; + id: Scalars['Int']['output']; + name: Scalars['String']['output']; +}; + +export type CircleFilter = { + name?: InputMaybe<StringFilter>; +}; + +export type CircleFilterInput = { + exclude?: InputMaybe<CircleFilter>; + include?: InputMaybe<CircleFilter>; +}; + +export type CircleFilterResult = { + __typename?: 'CircleFilterResult'; + count: Scalars['Int']['output']; + edges: Array<Circle>; +}; + +export type CircleResponse = Circle | IdNotFoundError; + +export enum CircleSort { + CreatedAt = 'CREATED_AT', + Name = 'NAME', + Random = 'RANDOM', + UpdatedAt = 'UPDATED_AT' +} + +export type CircleSortInput = { + direction?: InputMaybe<SortDirection>; + on: CircleSort; + seed?: InputMaybe<Scalars['Int']['input']>; +}; + +export type CirclesUpdateInput = { + ids: Array<Scalars['Int']['input']>; + options?: InputMaybe<UpdateOptions>; +}; + +export type CirclesUpsertInput = { + names?: Array<Scalars['String']['input']>; + options?: InputMaybe<UpsertOptions>; +}; + +export type Comic = { + __typename?: 'Comic'; + artists: Array<Artist>; + bookmarked: Scalars['Boolean']['output']; + category?: Maybe<Category>; + censorship?: Maybe<Censorship>; + characters: Array<Character>; + circles: Array<Circle>; + cover: Image; + date?: Maybe<Scalars['Date']['output']>; + favourite: Scalars['Boolean']['output']; + id: Scalars['Int']['output']; + language?: Maybe<Language>; + organized: Scalars['Boolean']['output']; + originalTitle?: Maybe<Scalars['String']['output']>; + pageCount: Scalars['Int']['output']; + rating?: Maybe<Rating>; + tags: Array<ComicTag>; + title: Scalars['String']['output']; + worlds: Array<World>; +}; + +export type ComicFilter = { + artists?: InputMaybe<AssociationFilter>; + bookmarked?: InputMaybe<Scalars['Boolean']['input']>; + category?: InputMaybe<CategoryFilter>; + censorship?: InputMaybe<CensorshipFilter>; + characters?: InputMaybe<AssociationFilter>; + circles?: InputMaybe<AssociationFilter>; + favourite?: InputMaybe<Scalars['Boolean']['input']>; + language?: InputMaybe<LanguageFilter>; + organized?: InputMaybe<Scalars['Boolean']['input']>; + originalTitle?: InputMaybe<StringFilter>; + rating?: InputMaybe<RatingFilter>; + tags?: InputMaybe<TagAssociationFilter>; + title?: InputMaybe<StringFilter>; + url?: InputMaybe<StringFilter>; + worlds?: InputMaybe<AssociationFilter>; +}; + +export type ComicFilterInput = { + exclude?: InputMaybe<ComicFilter>; + include?: InputMaybe<ComicFilter>; +}; + +export type ComicFilterResult = { + __typename?: 'ComicFilterResult'; + count: Scalars['Int']['output']; + edges: Array<Comic>; +}; + +export type ComicResponse = FullComic | IdNotFoundError; + +export type ComicScraper = { + __typename?: 'ComicScraper'; + id: Scalars['String']['output']; + name: Scalars['String']['output']; +}; + +export enum ComicSort { + CreatedAt = 'CREATED_AT', + Date = 'DATE', + OriginalTitle = 'ORIGINAL_TITLE', + PageCount = 'PAGE_COUNT', + Random = 'RANDOM', + TagCount = 'TAG_COUNT', + Title = 'TITLE', + UpdatedAt = 'UPDATED_AT' +} + +export type ComicSortInput = { + direction?: InputMaybe<SortDirection>; + on: ComicSort; + seed?: InputMaybe<Scalars['Int']['input']>; +}; + +export type ComicTag = { + __typename?: 'ComicTag'; + description?: Maybe<Scalars['String']['output']>; + id: Scalars['String']['output']; + name: Scalars['String']['output']; +}; + +export type ComicTagFilterResult = { + __typename?: 'ComicTagFilterResult'; + count: Scalars['Int']['output']; + edges: Array<ComicTag>; +}; + +export type ComicTagsUpdateInput = { + ids?: Array<Scalars['String']['input']>; + options?: InputMaybe<UpdateOptions>; +}; + +export type ComicTagsUpsertInput = { + names?: Array<Scalars['String']['input']>; + options?: InputMaybe<UpsertOptions>; +}; + +export type CoverInput = { + id: Scalars['Int']['input']; +}; + +export type CoverUpdateInput = { + id: Scalars['Int']['input']; +}; + +export type DeleteResponse = DeleteSuccess | IdNotFoundError; + +export type DeleteSuccess = Success & { + __typename?: 'DeleteSuccess'; + message: Scalars['String']['output']; +}; + +export enum Direction { + LeftToRight = 'LEFT_TO_RIGHT', + RightToLeft = 'RIGHT_TO_LEFT' +} + +export type Error = { + message: Scalars['String']['output']; +}; + +export type FullArchive = { + __typename?: 'FullArchive'; + comics: Array<Comic>; + cover: Image; + createdAt: Scalars['DateTime']['output']; + id: Scalars['Int']['output']; + mtime: Scalars['DateTime']['output']; + name: Scalars['String']['output']; + organized: Scalars['Boolean']['output']; + pageCount: Scalars['Int']['output']; + pages: Array<Page>; + path: Scalars['String']['output']; + size: Scalars['Int']['output']; +}; + +export type FullComic = { + __typename?: 'FullComic'; + archive: Archive; + artists: Array<Artist>; + bookmarked: Scalars['Boolean']['output']; + category?: Maybe<Category>; + censorship?: Maybe<Censorship>; + characters: Array<Character>; + circles: Array<Circle>; + cover: Image; + createdAt: Scalars['DateTime']['output']; + date?: Maybe<Scalars['Date']['output']>; + direction: Direction; + favourite: Scalars['Boolean']['output']; + id: Scalars['Int']['output']; + language?: Maybe<Language>; + layout: Layout; + organized: Scalars['Boolean']['output']; + originalTitle?: Maybe<Scalars['String']['output']>; + pageCount: Scalars['Int']['output']; + pages: Array<Page>; + rating?: Maybe<Rating>; + tags: Array<ComicTag>; + title: Scalars['String']['output']; + updatedAt: Scalars['DateTime']['output']; + url?: Maybe<Scalars['String']['output']>; + worlds: Array<World>; +}; + +export type FullTag = { + __typename?: 'FullTag'; + description?: Maybe<Scalars['String']['output']>; + id: Scalars['Int']['output']; + name: Scalars['String']['output']; + namespaces: Array<Namespace>; +}; + +export type IdNotFoundError = Error & { + __typename?: 'IDNotFoundError'; + id: Scalars['Int']['output']; + message: Scalars['String']['output']; +}; + +export type Image = { + __typename?: 'Image'; + aspectRatio: Scalars['Float']['output']; + hash: Scalars['String']['output']; + height: Scalars['Int']['output']; + id: Scalars['Int']['output']; + width: Scalars['Int']['output']; +}; + +export type InvalidParameterError = Error & { + __typename?: 'InvalidParameterError'; + message: Scalars['String']['output']; + parameter: Scalars['String']['output']; +}; + +export enum Language { + Aa = 'AA', + Ab = 'AB', + Ae = 'AE', + Af = 'AF', + Ak = 'AK', + Am = 'AM', + An = 'AN', + Ar = 'AR', + As = 'AS', + Av = 'AV', + Ay = 'AY', + Az = 'AZ', + Ba = 'BA', + Be = 'BE', + Bg = 'BG', + Bh = 'BH', + Bi = 'BI', + Bm = 'BM', + Bn = 'BN', + Bo = 'BO', + Br = 'BR', + Bs = 'BS', + Ca = 'CA', + Ce = 'CE', + Ch = 'CH', + Co = 'CO', + Cr = 'CR', + Cs = 'CS', + Cu = 'CU', + Cv = 'CV', + Cy = 'CY', + Da = 'DA', + De = 'DE', + Dv = 'DV', + Dz = 'DZ', + Ee = 'EE', + El = 'EL', + En = 'EN', + Eo = 'EO', + Es = 'ES', + Et = 'ET', + Eu = 'EU', + Fa = 'FA', + Ff = 'FF', + Fi = 'FI', + Fj = 'FJ', + Fo = 'FO', + Fr = 'FR', + Fy = 'FY', + Ga = 'GA', + Gd = 'GD', + Gl = 'GL', + Gn = 'GN', + Gu = 'GU', + Gv = 'GV', + Ha = 'HA', + He = 'HE', + Hi = 'HI', + Ho = 'HO', + Hr = 'HR', + Ht = 'HT', + Hu = 'HU', + Hy = 'HY', + Hz = 'HZ', + Ia = 'IA', + Id = 'ID', + Ie = 'IE', + Ig = 'IG', + Ii = 'II', + Ik = 'IK', + Io = 'IO', + Is = 'IS', + It = 'IT', + Iu = 'IU', + Ja = 'JA', + Jv = 'JV', + Ka = 'KA', + Kg = 'KG', + Ki = 'KI', + Kj = 'KJ', + Kk = 'KK', + Kl = 'KL', + Km = 'KM', + Kn = 'KN', + Ko = 'KO', + Kr = 'KR', + Ks = 'KS', + Ku = 'KU', + Kv = 'KV', + Kw = 'KW', + Ky = 'KY', + La = 'LA', + Lb = 'LB', + Lg = 'LG', + Li = 'LI', + Ln = 'LN', + Lo = 'LO', + Lt = 'LT', + Lu = 'LU', + Lv = 'LV', + Mg = 'MG', + Mh = 'MH', + Mi = 'MI', + Mk = 'MK', + Ml = 'ML', + Mn = 'MN', + Mr = 'MR', + Ms = 'MS', + Mt = 'MT', + My = 'MY', + Na = 'NA', + Nb = 'NB', + Nd = 'ND', + Ne = 'NE', + Ng = 'NG', + Nl = 'NL', + Nn = 'NN', + No = 'NO', + Nr = 'NR', + Nv = 'NV', + Ny = 'NY', + Oc = 'OC', + Oj = 'OJ', + Om = 'OM', + Or = 'OR', + Os = 'OS', + Pa = 'PA', + Pi = 'PI', + Pl = 'PL', + Ps = 'PS', + Pt = 'PT', + Qu = 'QU', + Rm = 'RM', + Rn = 'RN', + Ro = 'RO', + Ru = 'RU', + Rw = 'RW', + Sa = 'SA', + Sc = 'SC', + Sd = 'SD', + Se = 'SE', + Sg = 'SG', + Si = 'SI', + Sk = 'SK', + Sl = 'SL', + Sm = 'SM', + Sn = 'SN', + So = 'SO', + Sq = 'SQ', + Sr = 'SR', + Ss = 'SS', + St = 'ST', + Su = 'SU', + Sv = 'SV', + Sw = 'SW', + Ta = 'TA', + Te = 'TE', + Tg = 'TG', + Th = 'TH', + Ti = 'TI', + Tk = 'TK', + Tl = 'TL', + Tn = 'TN', + To = 'TO', + Tr = 'TR', + Ts = 'TS', + Tt = 'TT', + Tw = 'TW', + Ty = 'TY', + Ug = 'UG', + Uk = 'UK', + Ur = 'UR', + Uz = 'UZ', + Ve = 'VE', + Vi = 'VI', + Vo = 'VO', + Wa = 'WA', + Wo = 'WO', + Xh = 'XH', + Yi = 'YI', + Yo = 'YO', + Za = 'ZA', + Zh = 'ZH', + Zu = 'ZU' +} + +export type LanguageFilter = { + any?: InputMaybe<Array<Language>>; + empty?: InputMaybe<Scalars['Boolean']['input']>; +}; + +export enum Layout { + Double = 'DOUBLE', + DoubleOffset = 'DOUBLE_OFFSET', + Single = 'SINGLE' +} + +export type Mutation = { + __typename?: 'Mutation'; + addArtist: AddResponse; + addCharacter: AddResponse; + addCircle: AddResponse; + addComic: AddComicResponse; + addNamespace: AddResponse; + addTag: AddResponse; + addWorld: AddResponse; + deleteArchives: DeleteResponse; + deleteArtists: DeleteResponse; + deleteCharacters: DeleteResponse; + deleteCircles: DeleteResponse; + deleteComics: DeleteResponse; + deleteNamespaces: DeleteResponse; + deleteTags: DeleteResponse; + deleteWorlds: DeleteResponse; + updateArchives: UpdateResponse; + updateArtists: UpdateResponse; + updateCharacters: UpdateResponse; + updateCircles: UpdateResponse; + updateComics: UpdateResponse; + updateNamespaces: UpdateResponse; + updateTags: UpdateResponse; + updateWorlds: UpdateResponse; + upsertComics: UpsertResponse; +}; + + +export type MutationAddArtistArgs = { + input: AddArtistInput; +}; + + +export type MutationAddCharacterArgs = { + input: AddCharacterInput; +}; + + +export type MutationAddCircleArgs = { + input: AddCircleInput; +}; + + +export type MutationAddComicArgs = { + input: AddComicInput; +}; + + +export type MutationAddNamespaceArgs = { + input: AddNamespaceInput; +}; + + +export type MutationAddTagArgs = { + input: AddTagInput; +}; + + +export type MutationAddWorldArgs = { + input: AddWorldInput; +}; + + +export type MutationDeleteArchivesArgs = { + ids: Array<Scalars['Int']['input']>; +}; + + +export type MutationDeleteArtistsArgs = { + ids: Array<Scalars['Int']['input']>; +}; + + +export type MutationDeleteCharactersArgs = { + ids: Array<Scalars['Int']['input']>; +}; + + +export type MutationDeleteCirclesArgs = { + ids: Array<Scalars['Int']['input']>; +}; + + +export type MutationDeleteComicsArgs = { + ids: Array<Scalars['Int']['input']>; +}; + + +export type MutationDeleteNamespacesArgs = { + ids: Array<Scalars['Int']['input']>; +}; + + +export type MutationDeleteTagsArgs = { + ids: Array<Scalars['Int']['input']>; +}; + + +export type MutationDeleteWorldsArgs = { + ids: Array<Scalars['Int']['input']>; +}; + + +export type MutationUpdateArchivesArgs = { + ids: Array<Scalars['Int']['input']>; + input: UpdateArchiveInput; +}; + + +export type MutationUpdateArtistsArgs = { + ids: Array<Scalars['Int']['input']>; + input: UpdateArtistInput; +}; + + +export type MutationUpdateCharactersArgs = { + ids: Array<Scalars['Int']['input']>; + input: UpdateCharacterInput; +}; + + +export type MutationUpdateCirclesArgs = { + ids: Array<Scalars['Int']['input']>; + input: UpdateCircleInput; +}; + + +export type MutationUpdateComicsArgs = { + ids: Array<Scalars['Int']['input']>; + input: UpdateComicInput; +}; + + +export type MutationUpdateNamespacesArgs = { + ids: Array<Scalars['Int']['input']>; + input: UpdateNamespaceInput; +}; + + +export type MutationUpdateTagsArgs = { + ids: Array<Scalars['Int']['input']>; + input: UpdateTagInput; +}; + + +export type MutationUpdateWorldsArgs = { + ids: Array<Scalars['Int']['input']>; + input: UpdateWorldInput; +}; + + +export type MutationUpsertComicsArgs = { + ids: Array<Scalars['Int']['input']>; + input: UpsertComicInput; +}; + +export type NameExistsError = Error & { + __typename?: 'NameExistsError'; + message: Scalars['String']['output']; +}; + +export type Namespace = { + __typename?: 'Namespace'; + id: Scalars['Int']['output']; + name: Scalars['String']['output']; + sortName?: Maybe<Scalars['String']['output']>; +}; + +export type NamespaceFilter = { + name?: InputMaybe<StringFilter>; +}; + +export type NamespaceFilterInput = { + exclude?: InputMaybe<NamespaceFilter>; + include?: InputMaybe<NamespaceFilter>; +}; + +export type NamespaceFilterResult = { + __typename?: 'NamespaceFilterResult'; + count: Scalars['Int']['output']; + edges: Array<Namespace>; +}; + +export type NamespaceResponse = IdNotFoundError | Namespace; + +export enum NamespaceSort { + CreatedAt = 'CREATED_AT', + Name = 'NAME', + Random = 'RANDOM', + SortName = 'SORT_NAME', + UpdatedAt = 'UPDATED_AT' +} + +export type NamespaceSortInput = { + direction?: InputMaybe<SortDirection>; + on: NamespaceSort; + seed?: InputMaybe<Scalars['Int']['input']>; +}; + +export type NamespacesInput = { + ids: Array<Scalars['Int']['input']>; +}; + +export type NamespacesUpdateInput = { + ids: Array<Scalars['Int']['input']>; + options?: InputMaybe<UpdateOptions>; +}; + +export enum OnMissing { + Create = 'CREATE', + Ignore = 'IGNORE' +} + +export type Page = { + __typename?: 'Page'; + comicId?: Maybe<Scalars['Int']['output']>; + id: Scalars['Int']['output']; + image: Image; + path: Scalars['String']['output']; +}; + +export type PageClaimedError = Error & { + __typename?: 'PageClaimedError'; + comicId: Scalars['Int']['output']; + id: Scalars['Int']['output']; + message: Scalars['String']['output']; +}; + +export type PageRemoteError = Error & { + __typename?: 'PageRemoteError'; + archiveId: Scalars['Int']['output']; + id: Scalars['Int']['output']; + message: Scalars['String']['output']; +}; + +export type Pagination = { + items?: Scalars['Int']['input']; + page?: Scalars['Int']['input']; +}; + +export type Query = { + __typename?: 'Query'; + archive: ArchiveResponse; + archives: ArchiveFilterResult; + artist: ArtistResponse; + artists: ArtistFilterResult; + character: CharacterResponse; + characters: CharacterFilterResult; + circle: CircleResponse; + circles: CircleFilterResult; + comic: ComicResponse; + comicScrapers: Array<ComicScraper>; + comicTags: ComicTagFilterResult; + comics: ComicFilterResult; + namespace: NamespaceResponse; + namespaces: NamespaceFilterResult; + scrapeComic: ScrapeComicResponse; + tag: TagResponse; + tags: TagFilterResult; + world: WorldResponse; + worlds: WorldFilterResult; +}; + + +export type QueryArchiveArgs = { + id: Scalars['Int']['input']; +}; + + +export type QueryArchivesArgs = { + filter?: InputMaybe<ArchiveFilterInput>; + pagination?: InputMaybe<Pagination>; + sort?: InputMaybe<ArchiveSortInput>; +}; + + +export type QueryArtistArgs = { + id: Scalars['Int']['input']; +}; + + +export type QueryArtistsArgs = { + filter?: InputMaybe<ArtistFilterInput>; + pagination?: InputMaybe<Pagination>; + sort?: InputMaybe<ArtistSortInput>; +}; + + +export type QueryCharacterArgs = { + id: Scalars['Int']['input']; +}; + + +export type QueryCharactersArgs = { + filter?: InputMaybe<CharacterFilterInput>; + pagination?: InputMaybe<Pagination>; + sort?: InputMaybe<CharacterSortInput>; +}; + + +export type QueryCircleArgs = { + id: Scalars['Int']['input']; +}; + + +export type QueryCirclesArgs = { + filter?: InputMaybe<CircleFilterInput>; + pagination?: InputMaybe<Pagination>; + sort?: InputMaybe<CircleSortInput>; +}; + + +export type QueryComicArgs = { + id: Scalars['Int']['input']; +}; + + +export type QueryComicScrapersArgs = { + id: Scalars['Int']['input']; +}; + + +export type QueryComicTagsArgs = { + forFilter?: Scalars['Boolean']['input']; +}; + + +export type QueryComicsArgs = { + filter?: InputMaybe<ComicFilterInput>; + pagination?: InputMaybe<Pagination>; + sort?: InputMaybe<ComicSortInput>; +}; + + +export type QueryNamespaceArgs = { + id: Scalars['Int']['input']; +}; + + +export type QueryNamespacesArgs = { + filter?: InputMaybe<NamespaceFilterInput>; + pagination?: InputMaybe<Pagination>; + sort?: InputMaybe<NamespaceSortInput>; +}; + + +export type QueryScrapeComicArgs = { + id: Scalars['Int']['input']; + scraper: Scalars['String']['input']; +}; + + +export type QueryTagArgs = { + id: Scalars['Int']['input']; +}; + + +export type QueryTagsArgs = { + filter?: InputMaybe<TagFilterInput>; + pagination?: InputMaybe<Pagination>; + sort?: InputMaybe<TagSortInput>; +}; + + +export type QueryWorldArgs = { + id: Scalars['Int']['input']; +}; + + +export type QueryWorldsArgs = { + filter?: InputMaybe<WorldFilterInput>; + pagination?: InputMaybe<Pagination>; + sort?: InputMaybe<WorldSortInput>; +}; + +export enum Rating { + Explicit = 'EXPLICIT', + Questionable = 'QUESTIONABLE', + Safe = 'SAFE' +} + +export type RatingFilter = { + any?: InputMaybe<Array<Rating>>; + empty?: InputMaybe<Scalars['Boolean']['input']>; +}; + +export type ScrapeComicResponse = IdNotFoundError | ScrapeComicResult | ScraperError | ScraperNotAvailableError | ScraperNotFoundError; + +export type ScrapeComicResult = { + __typename?: 'ScrapeComicResult'; + data: ScrapedComic; + warnings: Array<Scalars['String']['output']>; +}; + +export type ScrapedComic = { + __typename?: 'ScrapedComic'; + artists: Array<Scalars['String']['output']>; + category?: Maybe<Category>; + censorship?: Maybe<Censorship>; + characters: Array<Scalars['String']['output']>; + circles: Array<Scalars['String']['output']>; + date?: Maybe<Scalars['Date']['output']>; + direction?: Maybe<Direction>; + language?: Maybe<Language>; + layout?: Maybe<Layout>; + originalTitle?: Maybe<Scalars['String']['output']>; + rating?: Maybe<Rating>; + tags: Array<Scalars['String']['output']>; + title?: Maybe<Scalars['String']['output']>; + url?: Maybe<Scalars['String']['output']>; + worlds: Array<Scalars['String']['output']>; +}; + +export type ScraperError = Error & { + __typename?: 'ScraperError'; + error: Scalars['String']['output']; + message: Scalars['String']['output']; +}; + +export type ScraperNotAvailableError = Error & { + __typename?: 'ScraperNotAvailableError'; + comicId: Scalars['Int']['output']; + message: Scalars['String']['output']; + scraper: Scalars['String']['output']; +}; + +export type ScraperNotFoundError = Error & { + __typename?: 'ScraperNotFoundError'; + message: Scalars['String']['output']; + name: Scalars['String']['output']; +}; + +export enum SortDirection { + Ascending = 'ASCENDING', + Descending = 'DESCENDING' +} + +export type StringFilter = { + contains?: InputMaybe<Scalars['String']['input']>; +}; + +export type Success = { + message: Scalars['String']['output']; +}; + +export type Tag = { + __typename?: 'Tag'; + description?: Maybe<Scalars['String']['output']>; + id: Scalars['Int']['output']; + name: Scalars['String']['output']; +}; + +export type TagAssociationFilter = { + all?: InputMaybe<Array<Scalars['String']['input']>>; + any?: InputMaybe<Array<Scalars['String']['input']>>; + empty?: InputMaybe<Scalars['Boolean']['input']>; + exact?: InputMaybe<Array<Scalars['String']['input']>>; +}; + +export type TagFilter = { + name?: InputMaybe<StringFilter>; + namespaces?: InputMaybe<AssociationFilter>; +}; + +export type TagFilterInput = { + exclude?: InputMaybe<TagFilter>; + include?: InputMaybe<TagFilter>; +}; + +export type TagFilterResult = { + __typename?: 'TagFilterResult'; + count: Scalars['Int']['output']; + edges: Array<Tag>; +}; + +export type TagResponse = FullTag | IdNotFoundError; + +export enum TagSort { + CreatedAt = 'CREATED_AT', + Name = 'NAME', + Random = 'RANDOM', + UpdatedAt = 'UPDATED_AT' +} + +export type TagSortInput = { + direction?: InputMaybe<SortDirection>; + on: TagSort; + seed?: InputMaybe<Scalars['Int']['input']>; +}; + +export type UniquePagesInput = { + ids: Array<Scalars['Int']['input']>; +}; + +export type UniquePagesUpdateInput = { + ids: Array<Scalars['Int']['input']>; + options?: InputMaybe<UpdateOptions>; +}; + +export type UpdateArchiveInput = { + cover?: InputMaybe<CoverUpdateInput>; + organized?: InputMaybe<Scalars['Boolean']['input']>; +}; + +export type UpdateArtistInput = { + name?: InputMaybe<Scalars['String']['input']>; +}; + +export type UpdateCharacterInput = { + name?: InputMaybe<Scalars['String']['input']>; +}; + +export type UpdateCircleInput = { + name?: InputMaybe<Scalars['String']['input']>; +}; + +export type UpdateComicInput = { + artists?: InputMaybe<ArtistsUpdateInput>; + bookmarked?: InputMaybe<Scalars['Boolean']['input']>; + category?: InputMaybe<Category>; + censorship?: InputMaybe<Censorship>; + characters?: InputMaybe<CharactersUpdateInput>; + circles?: InputMaybe<CirclesUpdateInput>; + cover?: InputMaybe<CoverUpdateInput>; + date?: InputMaybe<Scalars['Date']['input']>; + direction?: InputMaybe<Direction>; + favourite?: InputMaybe<Scalars['Boolean']['input']>; + language?: InputMaybe<Language>; + layout?: InputMaybe<Layout>; + organized?: InputMaybe<Scalars['Boolean']['input']>; + originalTitle?: InputMaybe<Scalars['String']['input']>; + pages?: InputMaybe<UniquePagesUpdateInput>; + rating?: InputMaybe<Rating>; + tags?: InputMaybe<ComicTagsUpdateInput>; + title?: InputMaybe<Scalars['String']['input']>; + url?: InputMaybe<Scalars['String']['input']>; + worlds?: InputMaybe<WorldsUpdateInput>; +}; + +export enum UpdateMode { + Add = 'ADD', + Remove = 'REMOVE', + Replace = 'REPLACE' +} + +export type UpdateNamespaceInput = { + name?: InputMaybe<Scalars['String']['input']>; + sortName?: InputMaybe<Scalars['String']['input']>; +}; + +export type UpdateOptions = { + mode?: UpdateMode; +}; + +export type UpdateResponse = IdNotFoundError | InvalidParameterError | NameExistsError | PageClaimedError | PageRemoteError | UpdateSuccess; + +export type UpdateSuccess = Success & { + __typename?: 'UpdateSuccess'; + message: Scalars['String']['output']; +}; + +export type UpdateTagInput = { + description?: InputMaybe<Scalars['String']['input']>; + name?: InputMaybe<Scalars['String']['input']>; + namespaces?: InputMaybe<NamespacesUpdateInput>; +}; + +export type UpdateWorldInput = { + name?: InputMaybe<Scalars['String']['input']>; +}; + +export type UpsertComicInput = { + artists?: InputMaybe<ArtistsUpsertInput>; + bookmarked?: InputMaybe<Scalars['Boolean']['input']>; + category?: InputMaybe<Category>; + censorship?: InputMaybe<Censorship>; + characters?: InputMaybe<CharactersUpsertInput>; + circles?: InputMaybe<CirclesUpsertInput>; + date?: InputMaybe<Scalars['Date']['input']>; + direction?: InputMaybe<Direction>; + favourite?: InputMaybe<Scalars['Boolean']['input']>; + language?: InputMaybe<Language>; + layout?: InputMaybe<Layout>; + organized?: InputMaybe<Scalars['Boolean']['input']>; + originalTitle?: InputMaybe<Scalars['String']['input']>; + rating?: InputMaybe<Rating>; + tags?: InputMaybe<ComicTagsUpsertInput>; + title?: InputMaybe<Scalars['String']['input']>; + url?: InputMaybe<Scalars['String']['input']>; + worlds?: InputMaybe<WorldsUpsertInput>; +}; + +export type UpsertOptions = { + onMissing?: OnMissing; +}; + +export type UpsertResponse = InvalidParameterError | NameExistsError | UpsertSuccess; + +export type UpsertSuccess = Success & { + __typename?: 'UpsertSuccess'; + message: Scalars['String']['output']; +}; + +export type World = { + __typename?: 'World'; + id: Scalars['Int']['output']; + name: Scalars['String']['output']; +}; + +export type WorldFilter = { + name?: InputMaybe<StringFilter>; +}; + +export type WorldFilterInput = { + exclude?: InputMaybe<WorldFilter>; + include?: InputMaybe<WorldFilter>; +}; + +export type WorldFilterResult = { + __typename?: 'WorldFilterResult'; + count: Scalars['Int']['output']; + edges: Array<World>; +}; + +export type WorldResponse = IdNotFoundError | World; + +export enum WorldSort { + CreatedAt = 'CREATED_AT', + Name = 'NAME', + Random = 'RANDOM', + UpdatedAt = 'UPDATED_AT' +} + +export type WorldSortInput = { + direction?: InputMaybe<SortDirection>; + on: WorldSort; + seed?: InputMaybe<Scalars['Int']['input']>; +}; + +export type WorldsUpdateInput = { + ids: Array<Scalars['Int']['input']>; + options?: InputMaybe<UpdateOptions>; +}; + +export type WorldsUpsertInput = { + names?: Array<Scalars['String']['input']>; + options?: InputMaybe<UpsertOptions>; +}; + +export type ImageFragment = { __typename?: 'Image', hash: string, width: number, height: number }; + +export type PageFragment = { __typename?: 'Page', id: number, path: string, comicId?: number | null, image: { __typename?: 'Image', id: number, hash: string, aspectRatio: number, width: number, height: number } }; + +export type ComicFragment = { __typename?: 'Comic', id: number, title: string, originalTitle?: string | null, favourite: boolean, cover: { __typename?: 'Image', hash: string, width: number, height: number }, tags: Array<{ __typename?: 'ComicTag', name: string, description?: string | null }>, artists: Array<{ __typename?: 'Artist', name: string }>, characters: Array<{ __typename?: 'Character', name: string }>, worlds: Array<{ __typename?: 'World', name: string }>, circles: Array<{ __typename?: 'Circle', name: string }> }; + +export type FullArchiveFragment = { __typename?: 'FullArchive', id: number, name: string, path: string, size: number, createdAt: string, mtime: string, organized: boolean, pageCount: number, pages: Array<{ __typename?: 'Page', id: number, path: string, comicId?: number | null, image: { __typename?: 'Image', id: number, hash: string, aspectRatio: number, width: number, height: number } }>, comics: Array<{ __typename?: 'Comic', id: number, title: string, originalTitle?: string | null, favourite: boolean, cover: { __typename?: 'Image', hash: string, width: number, height: number }, tags: Array<{ __typename?: 'ComicTag', name: string, description?: string | null }>, artists: Array<{ __typename?: 'Artist', name: string }>, characters: Array<{ __typename?: 'Character', name: string }>, worlds: Array<{ __typename?: 'World', name: string }>, circles: Array<{ __typename?: 'Circle', name: string }> }> }; + +export type ArchiveFragment = { __typename?: 'Archive', id: number, name: string, size: number, pageCount: number, cover: { __typename?: 'Image', hash: string, width: number, height: number } }; + +export type FullComicFragment = { __typename?: 'FullComic', id: number, title: string, originalTitle?: string | null, url?: string | null, language?: Language | null, direction: Direction, date?: string | null, layout: Layout, rating?: Rating | null, category?: Category | null, censorship?: Censorship | null, favourite: boolean, createdAt: string, updatedAt: string, organized: boolean, bookmarked: boolean, pages: Array<{ __typename?: 'Page', id: number, path: string, comicId?: number | null, image: { __typename?: 'Image', id: number, hash: string, aspectRatio: number, width: number, height: number } }>, archive: { __typename?: 'Archive', id: number }, tags: Array<{ __typename?: 'ComicTag', id: string, name: string, description?: string | null }>, artists: Array<{ __typename?: 'Artist', id: number, name: string }>, characters: Array<{ __typename?: 'Character', id: number, name: string }>, worlds: Array<{ __typename?: 'World', id: number, name: string }>, circles: Array<{ __typename?: 'Circle', id: number, name: string }> }; + +export type ComicScraperFragment = { __typename?: 'ComicScraper', id: string, name: string }; + +export type ScrapeComicResultFragment = { __typename?: 'ScrapeComicResult', warnings: Array<string>, data: { __typename?: 'ScrapedComic', artists: Array<string>, category?: Category | null, censorship?: Censorship | null, characters: Array<string>, circles: Array<string>, date?: string | null, direction?: Direction | null, language?: Language | null, layout?: Layout | null, originalTitle?: string | null, url?: string | null, rating?: Rating | null, tags: Array<string>, title?: string | null, worlds: Array<string> } }; + +export type ComicsQueryVariables = Exact<{ + pagination: Pagination; + filter?: InputMaybe<ComicFilterInput>; + sort?: InputMaybe<ComicSortInput>; +}>; + + +export type ComicsQuery = { __typename?: 'Query', comics: { __typename?: 'ComicFilterResult', count: number, edges: Array<{ __typename?: 'Comic', id: number, title: string, originalTitle?: string | null, favourite: boolean, cover: { __typename?: 'Image', hash: string, width: number, height: number }, tags: Array<{ __typename?: 'ComicTag', name: string, description?: string | null }>, artists: Array<{ __typename?: 'Artist', name: string }>, characters: Array<{ __typename?: 'Character', name: string }>, worlds: Array<{ __typename?: 'World', name: string }>, circles: Array<{ __typename?: 'Circle', name: string }> }> } }; + +export type ArchivesQueryVariables = Exact<{ + pagination: Pagination; + filter?: InputMaybe<ArchiveFilterInput>; + sort?: InputMaybe<ArchiveSortInput>; +}>; + + +export type ArchivesQuery = { __typename?: 'Query', archives: { __typename?: 'ArchiveFilterResult', count: number, edges: Array<{ __typename?: 'Archive', id: number, name: string, size: number, pageCount: number, cover: { __typename?: 'Image', hash: string, width: number, height: number } }> } }; + +export type ArchiveQueryVariables = Exact<{ + id: Scalars['Int']['input']; +}>; + + +export type ArchiveQuery = { __typename?: 'Query', archive: { __typename?: 'FullArchive', id: number, name: string, path: string, size: number, createdAt: string, mtime: string, organized: boolean, pageCount: number, pages: Array<{ __typename?: 'Page', id: number, path: string, comicId?: number | null, image: { __typename?: 'Image', id: number, hash: string, aspectRatio: number, width: number, height: number } }>, comics: Array<{ __typename?: 'Comic', id: number, title: string, originalTitle?: string | null, favourite: boolean, cover: { __typename?: 'Image', hash: string, width: number, height: number }, tags: Array<{ __typename?: 'ComicTag', name: string, description?: string | null }>, artists: Array<{ __typename?: 'Artist', name: string }>, characters: Array<{ __typename?: 'Character', name: string }>, worlds: Array<{ __typename?: 'World', name: string }>, circles: Array<{ __typename?: 'Circle', name: string }> }> } | { __typename?: 'IDNotFoundError', message: string } }; + +export type ComicQueryVariables = Exact<{ + id: Scalars['Int']['input']; +}>; + + +export type ComicQuery = { __typename?: 'Query', comic: { __typename?: 'FullComic', id: number, title: string, originalTitle?: string | null, url?: string | null, language?: Language | null, direction: Direction, date?: string | null, layout: Layout, rating?: Rating | null, category?: Category | null, censorship?: Censorship | null, favourite: boolean, createdAt: string, updatedAt: string, organized: boolean, bookmarked: boolean, pages: Array<{ __typename?: 'Page', id: number, path: string, comicId?: number | null, image: { __typename?: 'Image', id: number, hash: string, aspectRatio: number, width: number, height: number } }>, archive: { __typename?: 'Archive', id: number }, tags: Array<{ __typename?: 'ComicTag', id: string, name: string, description?: string | null }>, artists: Array<{ __typename?: 'Artist', id: number, name: string }>, characters: Array<{ __typename?: 'Character', id: number, name: string }>, worlds: Array<{ __typename?: 'World', id: number, name: string }>, circles: Array<{ __typename?: 'Circle', id: number, name: string }> } | { __typename?: 'IDNotFoundError', message: string } }; + +export type TagQueryVariables = Exact<{ + id: Scalars['Int']['input']; +}>; + + +export type TagQuery = { __typename?: 'Query', tag: { __typename?: 'FullTag', id: number, name: string, description?: string | null, namespaces: Array<{ __typename?: 'Namespace', id: number, name: string }> } | { __typename?: 'IDNotFoundError', message: string } }; + +export type TagsQueryVariables = Exact<{ + pagination: Pagination; + filter?: InputMaybe<TagFilterInput>; + sort?: InputMaybe<TagSortInput>; +}>; + + +export type TagsQuery = { __typename?: 'Query', tags: { __typename?: 'TagFilterResult', count: number, edges: Array<{ __typename?: 'Tag', id: number, name: string, description?: string | null }> } }; + +export type NamespaceQueryVariables = Exact<{ + id: Scalars['Int']['input']; +}>; + + +export type NamespaceQuery = { __typename?: 'Query', namespace: { __typename?: 'IDNotFoundError', message: string } | { __typename?: 'Namespace', id: number, name: string, sortName?: string | null } }; + +export type NamespacesQueryVariables = Exact<{ + pagination: Pagination; + filter?: InputMaybe<NamespaceFilterInput>; + sort?: InputMaybe<NamespaceSortInput>; +}>; + + +export type NamespacesQuery = { __typename?: 'Query', namespaces: { __typename?: 'NamespaceFilterResult', count: number, edges: Array<{ __typename?: 'Namespace', id: number, name: string }> } }; + +export type ComicTagListQueryVariables = Exact<{ + forFilter?: InputMaybe<Scalars['Boolean']['input']>; +}>; + + +export type ComicTagListQuery = { __typename?: 'Query', comicTags: { __typename?: 'ComicTagFilterResult', edges: Array<{ __typename?: 'ComicTag', id: string, name: string }> } }; + +export type ArtistListQueryVariables = Exact<{ [key: string]: never; }>; + + +export type ArtistListQuery = { __typename?: 'Query', artists: { __typename?: 'ArtistFilterResult', edges: Array<{ __typename?: 'Artist', id: number, name: string }> } }; + +export type CharacterListQueryVariables = Exact<{ [key: string]: never; }>; + + +export type CharacterListQuery = { __typename?: 'Query', characters: { __typename?: 'CharacterFilterResult', edges: Array<{ __typename?: 'Character', id: number, name: string }> } }; + +export type CircleListQueryVariables = Exact<{ [key: string]: never; }>; + + +export type CircleListQuery = { __typename?: 'Query', circles: { __typename?: 'CircleFilterResult', edges: Array<{ __typename?: 'Circle', id: number, name: string }> } }; + +export type WorldListQueryVariables = Exact<{ [key: string]: never; }>; + + +export type WorldListQuery = { __typename?: 'Query', worlds: { __typename?: 'WorldFilterResult', edges: Array<{ __typename?: 'World', id: number, name: string }> } }; + +export type NamespaceListQueryVariables = Exact<{ [key: string]: never; }>; + + +export type NamespaceListQuery = { __typename?: 'Query', namespaces: { __typename?: 'NamespaceFilterResult', edges: Array<{ __typename?: 'Namespace', id: number, name: string }> } }; + +export type ArtistsQueryVariables = Exact<{ + pagination: Pagination; + filter?: InputMaybe<ArtistFilterInput>; + sort?: InputMaybe<ArtistSortInput>; +}>; + + +export type ArtistsQuery = { __typename?: 'Query', artists: { __typename?: 'ArtistFilterResult', count: number, edges: Array<{ __typename?: 'Artist', id: number, name: string }> } }; + +export type ArtistQueryVariables = Exact<{ + id: Scalars['Int']['input']; +}>; + + +export type ArtistQuery = { __typename?: 'Query', artist: { __typename?: 'Artist', id: number, name: string } | { __typename?: 'IDNotFoundError', message: string } }; + +export type CharactersQueryVariables = Exact<{ + pagination: Pagination; + filter?: InputMaybe<CharacterFilterInput>; + sort?: InputMaybe<CharacterSortInput>; +}>; + + +export type CharactersQuery = { __typename?: 'Query', characters: { __typename?: 'CharacterFilterResult', count: number, edges: Array<{ __typename?: 'Character', id: number, name: string }> } }; + +export type CharacterQueryVariables = Exact<{ + id: Scalars['Int']['input']; +}>; + + +export type CharacterQuery = { __typename?: 'Query', character: { __typename?: 'Character', id: number, name: string } | { __typename?: 'IDNotFoundError', message: string } }; + +export type CirclesQueryVariables = Exact<{ + pagination: Pagination; + filter?: InputMaybe<CircleFilterInput>; + sort?: InputMaybe<CircleSortInput>; +}>; + + +export type CirclesQuery = { __typename?: 'Query', circles: { __typename?: 'CircleFilterResult', count: number, edges: Array<{ __typename?: 'Circle', id: number, name: string }> } }; + +export type CircleQueryVariables = Exact<{ + id: Scalars['Int']['input']; +}>; + + +export type CircleQuery = { __typename?: 'Query', circle: { __typename?: 'Circle', id: number, name: string } | { __typename?: 'IDNotFoundError', message: string } }; + +export type WorldsQueryVariables = Exact<{ + pagination: Pagination; + filter?: InputMaybe<WorldFilterInput>; + sort?: InputMaybe<WorldSortInput>; +}>; + + +export type WorldsQuery = { __typename?: 'Query', worlds: { __typename?: 'WorldFilterResult', count: number, edges: Array<{ __typename?: 'World', id: number, name: string }> } }; + +export type WorldQueryVariables = Exact<{ + id: Scalars['Int']['input']; +}>; + + +export type WorldQuery = { __typename?: 'Query', world: { __typename?: 'IDNotFoundError', message: string } | { __typename?: 'World', id: number, name: string } }; + +export type ComicScrapersQueryVariables = Exact<{ + id: Scalars['Int']['input']; +}>; + + +export type ComicScrapersQuery = { __typename?: 'Query', comicScrapers: Array<{ __typename?: 'ComicScraper', id: string, name: string }> }; + +export type ScrapeComicQueryVariables = Exact<{ + id: Scalars['Int']['input']; + scraper: Scalars['String']['input']; +}>; + + +export type ScrapeComicQuery = { __typename?: 'Query', scrapeComic: { __typename?: 'IDNotFoundError', message: string } | { __typename?: 'ScrapeComicResult', warnings: Array<string>, data: { __typename?: 'ScrapedComic', artists: Array<string>, category?: Category | null, censorship?: Censorship | null, characters: Array<string>, circles: Array<string>, date?: string | null, direction?: Direction | null, language?: Language | null, layout?: Layout | null, originalTitle?: string | null, url?: string | null, rating?: Rating | null, tags: Array<string>, title?: string | null, worlds: Array<string> } } | { __typename?: 'ScraperError', message: string } | { __typename?: 'ScraperNotAvailableError', message: string } | { __typename?: 'ScraperNotFoundError', message: string } }; + +export type FrontpageQueryVariables = Exact<{ [key: string]: never; }>; + + +export type FrontpageQuery = { __typename?: 'Query', recent: { __typename?: 'ComicFilterResult', count: number, edges: Array<{ __typename?: 'Comic', id: number, title: string, originalTitle?: string | null, favourite: boolean, cover: { __typename?: 'Image', hash: string, width: number, height: number }, tags: Array<{ __typename?: 'ComicTag', name: string, description?: string | null }>, artists: Array<{ __typename?: 'Artist', name: string }>, characters: Array<{ __typename?: 'Character', name: string }>, worlds: Array<{ __typename?: 'World', name: string }>, circles: Array<{ __typename?: 'Circle', name: string }> }> }, favourites: { __typename?: 'ComicFilterResult', count: number, edges: Array<{ __typename?: 'Comic', id: number, title: string, originalTitle?: string | null, favourite: boolean, cover: { __typename?: 'Image', hash: string, width: number, height: number }, tags: Array<{ __typename?: 'ComicTag', name: string, description?: string | null }>, artists: Array<{ __typename?: 'Artist', name: string }>, characters: Array<{ __typename?: 'Character', name: string }>, worlds: Array<{ __typename?: 'World', name: string }>, circles: Array<{ __typename?: 'Circle', name: string }> }> }, bookmarked: { __typename?: 'ComicFilterResult', count: number, edges: Array<{ __typename?: 'Comic', id: number, title: string, originalTitle?: string | null, favourite: boolean, cover: { __typename?: 'Image', hash: string, width: number, height: number }, tags: Array<{ __typename?: 'ComicTag', name: string, description?: string | null }>, artists: Array<{ __typename?: 'Artist', name: string }>, characters: Array<{ __typename?: 'Character', name: string }>, worlds: Array<{ __typename?: 'World', name: string }>, circles: Array<{ __typename?: 'Circle', name: string }> }> } }; + +export type AddComicMutationVariables = Exact<{ + input: AddComicInput; +}>; + + +export type AddComicMutation = { __typename?: 'Mutation', addComic: { __typename?: 'AddComicSuccess', message: string, archivePagesRemaining: boolean } | { __typename?: 'IDNotFoundError', message: string } | { __typename?: 'InvalidParameterError', message: string } | { __typename?: 'PageClaimedError', message: string } | { __typename?: 'PageRemoteError', message: string } }; + +export type UpdateArchivesMutationVariables = Exact<{ + ids: Array<Scalars['Int']['input']> | Scalars['Int']['input']; + input: UpdateArchiveInput; +}>; + + +export type UpdateArchivesMutation = { __typename?: 'Mutation', updateArchives: { __typename?: 'IDNotFoundError', message: string } | { __typename?: 'InvalidParameterError', message: string } | { __typename?: 'NameExistsError', message: string } | { __typename?: 'PageClaimedError', message: string } | { __typename?: 'PageRemoteError', message: string } | { __typename?: 'UpdateSuccess', message: string } }; + +export type UpdateComicsMutationVariables = Exact<{ + ids: Array<Scalars['Int']['input']> | Scalars['Int']['input']; + input: UpdateComicInput; +}>; + + +export type UpdateComicsMutation = { __typename?: 'Mutation', updateComics: { __typename?: 'IDNotFoundError', message: string } | { __typename?: 'InvalidParameterError', message: string } | { __typename?: 'NameExistsError', message: string } | { __typename?: 'PageClaimedError', message: string } | { __typename?: 'PageRemoteError', message: string } | { __typename?: 'UpdateSuccess', message: string } }; + +export type UpsertComicsMutationVariables = Exact<{ + ids: Array<Scalars['Int']['input']> | Scalars['Int']['input']; + input: UpsertComicInput; +}>; + + +export type UpsertComicsMutation = { __typename?: 'Mutation', upsertComics: { __typename?: 'InvalidParameterError', message: string } | { __typename?: 'NameExistsError', message: string } | { __typename?: 'UpsertSuccess', message: string } }; + +export type DeleteArchivesMutationVariables = Exact<{ + ids: Array<Scalars['Int']['input']> | Scalars['Int']['input']; +}>; + + +export type DeleteArchivesMutation = { __typename?: 'Mutation', deleteArchives: { __typename?: 'DeleteSuccess', message: string } | { __typename?: 'IDNotFoundError', message: string } }; + +export type DeleteComicsMutationVariables = Exact<{ + ids: Array<Scalars['Int']['input']> | Scalars['Int']['input']; +}>; + + +export type DeleteComicsMutation = { __typename?: 'Mutation', deleteComics: { __typename?: 'DeleteSuccess', message: string } | { __typename?: 'IDNotFoundError', message: string } }; + +export type AddTagMutationVariables = Exact<{ + input: AddTagInput; +}>; + + +export type AddTagMutation = { __typename?: 'Mutation', addTag: { __typename?: 'AddSuccess', message: string } | { __typename?: 'IDNotFoundError', message: string } | { __typename?: 'InvalidParameterError', message: string } | { __typename?: 'NameExistsError', message: string } }; + +export type UpdateTagsMutationVariables = Exact<{ + ids: Array<Scalars['Int']['input']> | Scalars['Int']['input']; + input: UpdateTagInput; +}>; + + +export type UpdateTagsMutation = { __typename?: 'Mutation', updateTags: { __typename?: 'IDNotFoundError', message: string } | { __typename?: 'InvalidParameterError', message: string } | { __typename?: 'NameExistsError', message: string } | { __typename?: 'PageClaimedError', message: string } | { __typename?: 'PageRemoteError', message: string } | { __typename?: 'UpdateSuccess', message: string } }; + +export type DeleteTagsMutationVariables = Exact<{ + ids: Array<Scalars['Int']['input']> | Scalars['Int']['input']; +}>; + + +export type DeleteTagsMutation = { __typename?: 'Mutation', deleteTags: { __typename?: 'DeleteSuccess', message: string } | { __typename?: 'IDNotFoundError', message: string } }; + +export type AddNamespaceMutationVariables = Exact<{ + input: AddNamespaceInput; +}>; + + +export type AddNamespaceMutation = { __typename?: 'Mutation', addNamespace: { __typename?: 'AddSuccess', message: string } | { __typename?: 'IDNotFoundError', message: string } | { __typename?: 'InvalidParameterError', message: string } | { __typename?: 'NameExistsError', message: string } }; + +export type UpdateNamespacesMutationVariables = Exact<{ + ids: Array<Scalars['Int']['input']> | Scalars['Int']['input']; + input: UpdateNamespaceInput; +}>; + + +export type UpdateNamespacesMutation = { __typename?: 'Mutation', updateNamespaces: { __typename?: 'IDNotFoundError', message: string } | { __typename?: 'InvalidParameterError', message: string } | { __typename?: 'NameExistsError', message: string } | { __typename?: 'PageClaimedError', message: string } | { __typename?: 'PageRemoteError', message: string } | { __typename?: 'UpdateSuccess', message: string } }; + +export type DeleteNamespacesMutationVariables = Exact<{ + ids: Array<Scalars['Int']['input']> | Scalars['Int']['input']; +}>; + + +export type DeleteNamespacesMutation = { __typename?: 'Mutation', deleteNamespaces: { __typename?: 'DeleteSuccess', message: string } | { __typename?: 'IDNotFoundError', message: string } }; + +export type AddArtistMutationVariables = Exact<{ + input: AddArtistInput; +}>; + + +export type AddArtistMutation = { __typename?: 'Mutation', addArtist: { __typename?: 'AddSuccess', message: string } | { __typename?: 'IDNotFoundError', message: string } | { __typename?: 'InvalidParameterError', message: string } | { __typename?: 'NameExistsError', message: string } }; + +export type UpdateArtistsMutationVariables = Exact<{ + ids: Array<Scalars['Int']['input']> | Scalars['Int']['input']; + input: UpdateArtistInput; +}>; + + +export type UpdateArtistsMutation = { __typename?: 'Mutation', updateArtists: { __typename?: 'IDNotFoundError', message: string } | { __typename?: 'InvalidParameterError', message: string } | { __typename?: 'NameExistsError', message: string } | { __typename?: 'PageClaimedError', message: string } | { __typename?: 'PageRemoteError', message: string } | { __typename?: 'UpdateSuccess', message: string } }; + +export type DeleteArtistsMutationVariables = Exact<{ + ids: Array<Scalars['Int']['input']> | Scalars['Int']['input']; +}>; + + +export type DeleteArtistsMutation = { __typename?: 'Mutation', deleteArtists: { __typename?: 'DeleteSuccess', message: string } | { __typename?: 'IDNotFoundError', message: string } }; + +export type AddCharacterMutationVariables = Exact<{ + input: AddCharacterInput; +}>; + + +export type AddCharacterMutation = { __typename?: 'Mutation', addCharacter: { __typename?: 'AddSuccess', message: string } | { __typename?: 'IDNotFoundError', message: string } | { __typename?: 'InvalidParameterError', message: string } | { __typename?: 'NameExistsError', message: string } }; + +export type UpdateCharactersMutationVariables = Exact<{ + ids: Array<Scalars['Int']['input']> | Scalars['Int']['input']; + input: UpdateCharacterInput; +}>; + + +export type UpdateCharactersMutation = { __typename?: 'Mutation', updateCharacters: { __typename?: 'IDNotFoundError', message: string } | { __typename?: 'InvalidParameterError', message: string } | { __typename?: 'NameExistsError', message: string } | { __typename?: 'PageClaimedError', message: string } | { __typename?: 'PageRemoteError', message: string } | { __typename?: 'UpdateSuccess', message: string } }; + +export type DeleteCharactersMutationVariables = Exact<{ + ids: Array<Scalars['Int']['input']> | Scalars['Int']['input']; +}>; + + +export type DeleteCharactersMutation = { __typename?: 'Mutation', deleteCharacters: { __typename?: 'DeleteSuccess', message: string } | { __typename?: 'IDNotFoundError', message: string } }; + +export type AddCircleMutationVariables = Exact<{ + input: AddCircleInput; +}>; + + +export type AddCircleMutation = { __typename?: 'Mutation', addCircle: { __typename?: 'AddSuccess', message: string } | { __typename?: 'IDNotFoundError', message: string } | { __typename?: 'InvalidParameterError', message: string } | { __typename?: 'NameExistsError', message: string } }; + +export type UpdateCirclesMutationVariables = Exact<{ + ids: Array<Scalars['Int']['input']> | Scalars['Int']['input']; + input: UpdateCircleInput; +}>; + + +export type UpdateCirclesMutation = { __typename?: 'Mutation', updateCircles: { __typename?: 'IDNotFoundError', message: string } | { __typename?: 'InvalidParameterError', message: string } | { __typename?: 'NameExistsError', message: string } | { __typename?: 'PageClaimedError', message: string } | { __typename?: 'PageRemoteError', message: string } | { __typename?: 'UpdateSuccess', message: string } }; + +export type DeleteCirclesMutationVariables = Exact<{ + ids: Array<Scalars['Int']['input']> | Scalars['Int']['input']; +}>; + + +export type DeleteCirclesMutation = { __typename?: 'Mutation', deleteCircles: { __typename?: 'DeleteSuccess', message: string } | { __typename?: 'IDNotFoundError', message: string } }; + +export type AddWorldMutationVariables = Exact<{ + input: AddWorldInput; +}>; + + +export type AddWorldMutation = { __typename?: 'Mutation', addWorld: { __typename?: 'AddSuccess', message: string } | { __typename?: 'IDNotFoundError', message: string } | { __typename?: 'InvalidParameterError', message: string } | { __typename?: 'NameExistsError', message: string } }; + +export type UpdateWorldsMutationVariables = Exact<{ + ids: Array<Scalars['Int']['input']> | Scalars['Int']['input']; + input: UpdateWorldInput; +}>; + + +export type UpdateWorldsMutation = { __typename?: 'Mutation', updateWorlds: { __typename?: 'IDNotFoundError', message: string } | { __typename?: 'InvalidParameterError', message: string } | { __typename?: 'NameExistsError', message: string } | { __typename?: 'PageClaimedError', message: string } | { __typename?: 'PageRemoteError', message: string } | { __typename?: 'UpdateSuccess', message: string } }; + +export type DeleteWorldsMutationVariables = Exact<{ + ids: Array<Scalars['Int']['input']> | Scalars['Int']['input']; +}>; + + +export type DeleteWorldsMutation = { __typename?: 'Mutation', deleteWorlds: { __typename?: 'DeleteSuccess', message: string } | { __typename?: 'IDNotFoundError', message: string } }; + +export const PageFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Page"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Page"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"path"}},{"kind":"Field","name":{"kind":"Name","value":"image"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"hash"}},{"kind":"Field","name":{"kind":"Name","value":"aspectRatio"}},{"kind":"Field","name":{"kind":"Name","value":"width"}},{"kind":"Field","name":{"kind":"Name","value":"height"}}]}},{"kind":"Field","name":{"kind":"Name","value":"comicId"}}]}}]} as unknown as DocumentNode<PageFragment, unknown>; +export const ImageFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Image"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Image"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"hash"}},{"kind":"Field","name":{"kind":"Name","value":"width"}},{"kind":"Field","name":{"kind":"Name","value":"height"}}]}}]} as unknown as DocumentNode<ImageFragment, unknown>; +export const ComicFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Comic"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Comic"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"originalTitle"}},{"kind":"Field","name":{"kind":"Name","value":"favourite"}},{"kind":"Field","name":{"kind":"Name","value":"cover"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"Image"}}]}},{"kind":"Field","name":{"kind":"Name","value":"tags"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"description"}}]}},{"kind":"Field","name":{"kind":"Name","value":"artists"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"characters"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"worlds"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"circles"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Image"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Image"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"hash"}},{"kind":"Field","name":{"kind":"Name","value":"width"}},{"kind":"Field","name":{"kind":"Name","value":"height"}}]}}]} as unknown as DocumentNode<ComicFragment, unknown>; +export const FullArchiveFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"FullArchive"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"FullArchive"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"path"}},{"kind":"Field","name":{"kind":"Name","value":"size"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"mtime"}},{"kind":"Field","name":{"kind":"Name","value":"organized"}},{"kind":"Field","name":{"kind":"Name","value":"pageCount"}},{"kind":"Field","name":{"kind":"Name","value":"pages"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"Page"}}]}},{"kind":"Field","name":{"kind":"Name","value":"comics"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"Comic"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Image"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Image"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"hash"}},{"kind":"Field","name":{"kind":"Name","value":"width"}},{"kind":"Field","name":{"kind":"Name","value":"height"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Page"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Page"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"path"}},{"kind":"Field","name":{"kind":"Name","value":"image"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"hash"}},{"kind":"Field","name":{"kind":"Name","value":"aspectRatio"}},{"kind":"Field","name":{"kind":"Name","value":"width"}},{"kind":"Field","name":{"kind":"Name","value":"height"}}]}},{"kind":"Field","name":{"kind":"Name","value":"comicId"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Comic"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Comic"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"originalTitle"}},{"kind":"Field","name":{"kind":"Name","value":"favourite"}},{"kind":"Field","name":{"kind":"Name","value":"cover"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"Image"}}]}},{"kind":"Field","name":{"kind":"Name","value":"tags"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"description"}}]}},{"kind":"Field","name":{"kind":"Name","value":"artists"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"characters"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"worlds"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"circles"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]} as unknown as DocumentNode<FullArchiveFragment, unknown>; +export const ArchiveFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Archive"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Archive"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"size"}},{"kind":"Field","name":{"kind":"Name","value":"pageCount"}},{"kind":"Field","name":{"kind":"Name","value":"cover"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"Image"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Image"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Image"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"hash"}},{"kind":"Field","name":{"kind":"Name","value":"width"}},{"kind":"Field","name":{"kind":"Name","value":"height"}}]}}]} as unknown as DocumentNode<ArchiveFragment, unknown>; +export const FullComicFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"FullComic"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"FullComic"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"originalTitle"}},{"kind":"Field","name":{"kind":"Name","value":"url"}},{"kind":"Field","name":{"kind":"Name","value":"language"}},{"kind":"Field","name":{"kind":"Name","value":"direction"}},{"kind":"Field","name":{"kind":"Name","value":"date"}},{"kind":"Field","name":{"kind":"Name","value":"layout"}},{"kind":"Field","name":{"kind":"Name","value":"rating"}},{"kind":"Field","name":{"kind":"Name","value":"category"}},{"kind":"Field","name":{"kind":"Name","value":"censorship"}},{"kind":"Field","name":{"kind":"Name","value":"favourite"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}},{"kind":"Field","name":{"kind":"Name","value":"organized"}},{"kind":"Field","name":{"kind":"Name","value":"bookmarked"}},{"kind":"Field","name":{"kind":"Name","value":"pages"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"Page"}}]}},{"kind":"Field","name":{"kind":"Name","value":"archive"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}},{"kind":"Field","name":{"kind":"Name","value":"tags"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"description"}}]}},{"kind":"Field","name":{"kind":"Name","value":"artists"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"characters"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"worlds"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"circles"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Page"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Page"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"path"}},{"kind":"Field","name":{"kind":"Name","value":"image"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"hash"}},{"kind":"Field","name":{"kind":"Name","value":"aspectRatio"}},{"kind":"Field","name":{"kind":"Name","value":"width"}},{"kind":"Field","name":{"kind":"Name","value":"height"}}]}},{"kind":"Field","name":{"kind":"Name","value":"comicId"}}]}}]} as unknown as DocumentNode<FullComicFragment, unknown>; +export const ComicScraperFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ComicScraper"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"ComicScraper"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]} as unknown as DocumentNode<ComicScraperFragment, unknown>; +export const ScrapeComicResultFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ScrapeComicResult"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"ScrapeComicResult"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"data"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"artists"}},{"kind":"Field","name":{"kind":"Name","value":"category"}},{"kind":"Field","name":{"kind":"Name","value":"censorship"}},{"kind":"Field","name":{"kind":"Name","value":"characters"}},{"kind":"Field","name":{"kind":"Name","value":"circles"}},{"kind":"Field","name":{"kind":"Name","value":"date"}},{"kind":"Field","name":{"kind":"Name","value":"direction"}},{"kind":"Field","name":{"kind":"Name","value":"language"}},{"kind":"Field","name":{"kind":"Name","value":"layout"}},{"kind":"Field","name":{"kind":"Name","value":"originalTitle"}},{"kind":"Field","name":{"kind":"Name","value":"url"}},{"kind":"Field","name":{"kind":"Name","value":"rating"}},{"kind":"Field","name":{"kind":"Name","value":"tags"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"worlds"}}]}},{"kind":"Field","name":{"kind":"Name","value":"warnings"}}]}}]} as unknown as DocumentNode<ScrapeComicResultFragment, unknown>; +export const ComicsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"comics"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"pagination"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Pagination"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"filter"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"ComicFilterInput"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"sort"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"ComicSortInput"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"comics"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"pagination"},"value":{"kind":"Variable","name":{"kind":"Name","value":"pagination"}}},{"kind":"Argument","name":{"kind":"Name","value":"filter"},"value":{"kind":"Variable","name":{"kind":"Name","value":"filter"}}},{"kind":"Argument","name":{"kind":"Name","value":"sort"},"value":{"kind":"Variable","name":{"kind":"Name","value":"sort"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"Comic"}}]}},{"kind":"Field","name":{"kind":"Name","value":"count"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Image"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Image"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"hash"}},{"kind":"Field","name":{"kind":"Name","value":"width"}},{"kind":"Field","name":{"kind":"Name","value":"height"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Comic"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Comic"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"originalTitle"}},{"kind":"Field","name":{"kind":"Name","value":"favourite"}},{"kind":"Field","name":{"kind":"Name","value":"cover"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"Image"}}]}},{"kind":"Field","name":{"kind":"Name","value":"tags"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"description"}}]}},{"kind":"Field","name":{"kind":"Name","value":"artists"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"characters"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"worlds"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"circles"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]} as unknown as DocumentNode<ComicsQuery, ComicsQueryVariables>; +export const ArchivesDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"archives"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"pagination"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Pagination"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"filter"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"ArchiveFilterInput"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"sort"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"ArchiveSortInput"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"archives"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"pagination"},"value":{"kind":"Variable","name":{"kind":"Name","value":"pagination"}}},{"kind":"Argument","name":{"kind":"Name","value":"filter"},"value":{"kind":"Variable","name":{"kind":"Name","value":"filter"}}},{"kind":"Argument","name":{"kind":"Name","value":"sort"},"value":{"kind":"Variable","name":{"kind":"Name","value":"sort"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"Archive"}}]}},{"kind":"Field","name":{"kind":"Name","value":"count"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Image"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Image"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"hash"}},{"kind":"Field","name":{"kind":"Name","value":"width"}},{"kind":"Field","name":{"kind":"Name","value":"height"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Archive"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Archive"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"size"}},{"kind":"Field","name":{"kind":"Name","value":"pageCount"}},{"kind":"Field","name":{"kind":"Name","value":"cover"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"Image"}}]}}]}}]} as unknown as DocumentNode<ArchivesQuery, ArchivesQueryVariables>; +export const ArchiveDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"archive"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"id"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"archive"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"FullArchive"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"FullArchive"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Error"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Image"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Image"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"hash"}},{"kind":"Field","name":{"kind":"Name","value":"width"}},{"kind":"Field","name":{"kind":"Name","value":"height"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Page"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Page"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"path"}},{"kind":"Field","name":{"kind":"Name","value":"image"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"hash"}},{"kind":"Field","name":{"kind":"Name","value":"aspectRatio"}},{"kind":"Field","name":{"kind":"Name","value":"width"}},{"kind":"Field","name":{"kind":"Name","value":"height"}}]}},{"kind":"Field","name":{"kind":"Name","value":"comicId"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Comic"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Comic"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"originalTitle"}},{"kind":"Field","name":{"kind":"Name","value":"favourite"}},{"kind":"Field","name":{"kind":"Name","value":"cover"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"Image"}}]}},{"kind":"Field","name":{"kind":"Name","value":"tags"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"description"}}]}},{"kind":"Field","name":{"kind":"Name","value":"artists"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"characters"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"worlds"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"circles"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"FullArchive"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"FullArchive"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"path"}},{"kind":"Field","name":{"kind":"Name","value":"size"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"mtime"}},{"kind":"Field","name":{"kind":"Name","value":"organized"}},{"kind":"Field","name":{"kind":"Name","value":"pageCount"}},{"kind":"Field","name":{"kind":"Name","value":"pages"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"Page"}}]}},{"kind":"Field","name":{"kind":"Name","value":"comics"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"Comic"}}]}}]}}]} as unknown as DocumentNode<ArchiveQuery, ArchiveQueryVariables>; +export const ComicDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"comic"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"id"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"comic"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"FullComic"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"FullComic"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Error"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Page"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Page"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"path"}},{"kind":"Field","name":{"kind":"Name","value":"image"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"hash"}},{"kind":"Field","name":{"kind":"Name","value":"aspectRatio"}},{"kind":"Field","name":{"kind":"Name","value":"width"}},{"kind":"Field","name":{"kind":"Name","value":"height"}}]}},{"kind":"Field","name":{"kind":"Name","value":"comicId"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"FullComic"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"FullComic"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"originalTitle"}},{"kind":"Field","name":{"kind":"Name","value":"url"}},{"kind":"Field","name":{"kind":"Name","value":"language"}},{"kind":"Field","name":{"kind":"Name","value":"direction"}},{"kind":"Field","name":{"kind":"Name","value":"date"}},{"kind":"Field","name":{"kind":"Name","value":"layout"}},{"kind":"Field","name":{"kind":"Name","value":"rating"}},{"kind":"Field","name":{"kind":"Name","value":"category"}},{"kind":"Field","name":{"kind":"Name","value":"censorship"}},{"kind":"Field","name":{"kind":"Name","value":"favourite"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}},{"kind":"Field","name":{"kind":"Name","value":"organized"}},{"kind":"Field","name":{"kind":"Name","value":"bookmarked"}},{"kind":"Field","name":{"kind":"Name","value":"pages"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"Page"}}]}},{"kind":"Field","name":{"kind":"Name","value":"archive"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}},{"kind":"Field","name":{"kind":"Name","value":"tags"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"description"}}]}},{"kind":"Field","name":{"kind":"Name","value":"artists"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"characters"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"worlds"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"circles"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]} as unknown as DocumentNode<ComicQuery, ComicQueryVariables>; +export const TagDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"tag"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"id"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"tag"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"FullTag"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"namespaces"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Error"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}}]} as unknown as DocumentNode<TagQuery, TagQueryVariables>; +export const TagsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"tags"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"pagination"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Pagination"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"filter"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"TagFilterInput"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"sort"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"TagSortInput"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"tags"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"pagination"},"value":{"kind":"Variable","name":{"kind":"Name","value":"pagination"}}},{"kind":"Argument","name":{"kind":"Name","value":"filter"},"value":{"kind":"Variable","name":{"kind":"Name","value":"filter"}}},{"kind":"Argument","name":{"kind":"Name","value":"sort"},"value":{"kind":"Variable","name":{"kind":"Name","value":"sort"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"description"}}]}},{"kind":"Field","name":{"kind":"Name","value":"count"}}]}}]}}]} as unknown as DocumentNode<TagsQuery, TagsQueryVariables>; +export const NamespaceDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"namespace"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"id"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"namespace"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Namespace"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"sortName"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Error"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}}]} as unknown as DocumentNode<NamespaceQuery, NamespaceQueryVariables>; +export const NamespacesDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"namespaces"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"pagination"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Pagination"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"filter"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"NamespaceFilterInput"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"sort"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"NamespaceSortInput"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"namespaces"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"pagination"},"value":{"kind":"Variable","name":{"kind":"Name","value":"pagination"}}},{"kind":"Argument","name":{"kind":"Name","value":"filter"},"value":{"kind":"Variable","name":{"kind":"Name","value":"filter"}}},{"kind":"Argument","name":{"kind":"Name","value":"sort"},"value":{"kind":"Variable","name":{"kind":"Name","value":"sort"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"count"}},{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]}}]} as unknown as DocumentNode<NamespacesQuery, NamespacesQueryVariables>; +export const ComicTagListDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"comicTagList"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"forFilter"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Boolean"}},"defaultValue":{"kind":"BooleanValue","value":false}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"comicTags"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"forFilter"},"value":{"kind":"Variable","name":{"kind":"Name","value":"forFilter"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]}}]} as unknown as DocumentNode<ComicTagListQuery, ComicTagListQueryVariables>; +export const ArtistListDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"artistList"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"artists"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]}}]} as unknown as DocumentNode<ArtistListQuery, ArtistListQueryVariables>; +export const CharacterListDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"characterList"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"characters"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]}}]} as unknown as DocumentNode<CharacterListQuery, CharacterListQueryVariables>; +export const CircleListDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"circleList"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"circles"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]}}]} as unknown as DocumentNode<CircleListQuery, CircleListQueryVariables>; +export const WorldListDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"worldList"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"worlds"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]}}]} as unknown as DocumentNode<WorldListQuery, WorldListQueryVariables>; +export const NamespaceListDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"namespaceList"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"namespaces"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]}}]} as unknown as DocumentNode<NamespaceListQuery, NamespaceListQueryVariables>; +export const ArtistsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"artists"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"pagination"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Pagination"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"filter"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"ArtistFilterInput"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"sort"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"ArtistSortInput"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"artists"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"pagination"},"value":{"kind":"Variable","name":{"kind":"Name","value":"pagination"}}},{"kind":"Argument","name":{"kind":"Name","value":"filter"},"value":{"kind":"Variable","name":{"kind":"Name","value":"filter"}}},{"kind":"Argument","name":{"kind":"Name","value":"sort"},"value":{"kind":"Variable","name":{"kind":"Name","value":"sort"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"count"}},{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]}}]} as unknown as DocumentNode<ArtistsQuery, ArtistsQueryVariables>; +export const ArtistDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"artist"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"id"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"artist"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Artist"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Error"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}}]} as unknown as DocumentNode<ArtistQuery, ArtistQueryVariables>; +export const CharactersDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"characters"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"pagination"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Pagination"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"filter"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"CharacterFilterInput"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"sort"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"CharacterSortInput"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"characters"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"pagination"},"value":{"kind":"Variable","name":{"kind":"Name","value":"pagination"}}},{"kind":"Argument","name":{"kind":"Name","value":"filter"},"value":{"kind":"Variable","name":{"kind":"Name","value":"filter"}}},{"kind":"Argument","name":{"kind":"Name","value":"sort"},"value":{"kind":"Variable","name":{"kind":"Name","value":"sort"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"count"}},{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]}}]} as unknown as DocumentNode<CharactersQuery, CharactersQueryVariables>; +export const CharacterDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"character"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"id"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"character"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Character"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Error"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}}]} as unknown as DocumentNode<CharacterQuery, CharacterQueryVariables>; +export const CirclesDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"circles"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"pagination"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Pagination"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"filter"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"CircleFilterInput"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"sort"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"CircleSortInput"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"circles"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"pagination"},"value":{"kind":"Variable","name":{"kind":"Name","value":"pagination"}}},{"kind":"Argument","name":{"kind":"Name","value":"filter"},"value":{"kind":"Variable","name":{"kind":"Name","value":"filter"}}},{"kind":"Argument","name":{"kind":"Name","value":"sort"},"value":{"kind":"Variable","name":{"kind":"Name","value":"sort"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"count"}},{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]}}]} as unknown as DocumentNode<CirclesQuery, CirclesQueryVariables>; +export const CircleDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"circle"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"id"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"circle"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Circle"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Error"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}}]} as unknown as DocumentNode<CircleQuery, CircleQueryVariables>; +export const WorldsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"worlds"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"pagination"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Pagination"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"filter"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"WorldFilterInput"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"sort"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"WorldSortInput"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"worlds"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"pagination"},"value":{"kind":"Variable","name":{"kind":"Name","value":"pagination"}}},{"kind":"Argument","name":{"kind":"Name","value":"filter"},"value":{"kind":"Variable","name":{"kind":"Name","value":"filter"}}},{"kind":"Argument","name":{"kind":"Name","value":"sort"},"value":{"kind":"Variable","name":{"kind":"Name","value":"sort"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"count"}},{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]}}]} as unknown as DocumentNode<WorldsQuery, WorldsQueryVariables>; +export const WorldDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"world"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"id"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"world"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"World"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Error"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}}]} as unknown as DocumentNode<WorldQuery, WorldQueryVariables>; +export const ComicScrapersDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"comicScrapers"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"id"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"comicScrapers"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]} as unknown as DocumentNode<ComicScrapersQuery, ComicScrapersQueryVariables>; +export const ScrapeComicDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"scrapeComic"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"id"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"scraper"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"scrapeComic"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}},{"kind":"Argument","name":{"kind":"Name","value":"scraper"},"value":{"kind":"Variable","name":{"kind":"Name","value":"scraper"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"ScrapeComicResult"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"ScrapeComicResult"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Error"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ScrapeComicResult"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"ScrapeComicResult"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"data"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"artists"}},{"kind":"Field","name":{"kind":"Name","value":"category"}},{"kind":"Field","name":{"kind":"Name","value":"censorship"}},{"kind":"Field","name":{"kind":"Name","value":"characters"}},{"kind":"Field","name":{"kind":"Name","value":"circles"}},{"kind":"Field","name":{"kind":"Name","value":"date"}},{"kind":"Field","name":{"kind":"Name","value":"direction"}},{"kind":"Field","name":{"kind":"Name","value":"language"}},{"kind":"Field","name":{"kind":"Name","value":"layout"}},{"kind":"Field","name":{"kind":"Name","value":"originalTitle"}},{"kind":"Field","name":{"kind":"Name","value":"url"}},{"kind":"Field","name":{"kind":"Name","value":"rating"}},{"kind":"Field","name":{"kind":"Name","value":"tags"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"worlds"}}]}},{"kind":"Field","name":{"kind":"Name","value":"warnings"}}]}}]} as unknown as DocumentNode<ScrapeComicQuery, ScrapeComicQueryVariables>; +export const FrontpageDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"frontpage"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","alias":{"kind":"Name","value":"recent"},"name":{"kind":"Name","value":"comics"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"pagination"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"items"},"value":{"kind":"IntValue","value":"6"}}]}},{"kind":"Argument","name":{"kind":"Name","value":"sort"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"on"},"value":{"kind":"EnumValue","value":"CREATED_AT"}},{"kind":"ObjectField","name":{"kind":"Name","value":"direction"},"value":{"kind":"EnumValue","value":"DESCENDING"}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"Comic"}}]}},{"kind":"Field","name":{"kind":"Name","value":"count"}}]}},{"kind":"Field","alias":{"kind":"Name","value":"favourites"},"name":{"kind":"Name","value":"comics"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"pagination"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"items"},"value":{"kind":"IntValue","value":"6"}}]}},{"kind":"Argument","name":{"kind":"Name","value":"filter"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"include"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"favourite"},"value":{"kind":"BooleanValue","value":true}}]}}]}},{"kind":"Argument","name":{"kind":"Name","value":"sort"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"on"},"value":{"kind":"EnumValue","value":"RANDOM"}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"Comic"}}]}},{"kind":"Field","name":{"kind":"Name","value":"count"}}]}},{"kind":"Field","alias":{"kind":"Name","value":"bookmarked"},"name":{"kind":"Name","value":"comics"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"pagination"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"items"},"value":{"kind":"IntValue","value":"6"}}]}},{"kind":"Argument","name":{"kind":"Name","value":"filter"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"include"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"bookmarked"},"value":{"kind":"BooleanValue","value":true}}]}}]}},{"kind":"Argument","name":{"kind":"Name","value":"sort"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"on"},"value":{"kind":"EnumValue","value":"RANDOM"}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"Comic"}}]}},{"kind":"Field","name":{"kind":"Name","value":"count"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Image"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Image"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"hash"}},{"kind":"Field","name":{"kind":"Name","value":"width"}},{"kind":"Field","name":{"kind":"Name","value":"height"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Comic"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Comic"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"originalTitle"}},{"kind":"Field","name":{"kind":"Name","value":"favourite"}},{"kind":"Field","name":{"kind":"Name","value":"cover"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"Image"}}]}},{"kind":"Field","name":{"kind":"Name","value":"tags"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"description"}}]}},{"kind":"Field","name":{"kind":"Name","value":"artists"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"characters"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"worlds"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"circles"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]} as unknown as DocumentNode<FrontpageQuery, FrontpageQueryVariables>; +export const AddComicDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"addComic"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"AddComicInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"addComic"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"AddComicSuccess"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}},{"kind":"Field","name":{"kind":"Name","value":"archivePagesRemaining"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Error"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}}]} as unknown as DocumentNode<AddComicMutation, AddComicMutationVariables>; +export const UpdateArchivesDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"updateArchives"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"ids"}},"type":{"kind":"NonNullType","type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UpdateArchiveInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"updateArchives"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"ids"},"value":{"kind":"Variable","name":{"kind":"Name","value":"ids"}}},{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Success"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Error"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}}]} as unknown as DocumentNode<UpdateArchivesMutation, UpdateArchivesMutationVariables>; +export const UpdateComicsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"updateComics"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"ids"}},"type":{"kind":"NonNullType","type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UpdateComicInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"updateComics"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"ids"},"value":{"kind":"Variable","name":{"kind":"Name","value":"ids"}}},{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Success"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Error"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}}]} as unknown as DocumentNode<UpdateComicsMutation, UpdateComicsMutationVariables>; +export const UpsertComicsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"upsertComics"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"ids"}},"type":{"kind":"NonNullType","type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UpsertComicInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"upsertComics"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"ids"},"value":{"kind":"Variable","name":{"kind":"Name","value":"ids"}}},{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Success"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Error"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}}]} as unknown as DocumentNode<UpsertComicsMutation, UpsertComicsMutationVariables>; +export const DeleteArchivesDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"deleteArchives"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"ids"}},"type":{"kind":"NonNullType","type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"deleteArchives"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"ids"},"value":{"kind":"Variable","name":{"kind":"Name","value":"ids"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Success"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Error"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}}]} as unknown as DocumentNode<DeleteArchivesMutation, DeleteArchivesMutationVariables>; +export const DeleteComicsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"deleteComics"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"ids"}},"type":{"kind":"NonNullType","type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"deleteComics"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"ids"},"value":{"kind":"Variable","name":{"kind":"Name","value":"ids"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Success"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Error"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}}]} as unknown as DocumentNode<DeleteComicsMutation, DeleteComicsMutationVariables>; +export const AddTagDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"addTag"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"AddTagInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"addTag"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Success"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Error"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}}]} as unknown as DocumentNode<AddTagMutation, AddTagMutationVariables>; +export const UpdateTagsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"updateTags"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"ids"}},"type":{"kind":"NonNullType","type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UpdateTagInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"updateTags"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"ids"},"value":{"kind":"Variable","name":{"kind":"Name","value":"ids"}}},{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Success"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Error"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}}]} as unknown as DocumentNode<UpdateTagsMutation, UpdateTagsMutationVariables>; +export const DeleteTagsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"deleteTags"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"ids"}},"type":{"kind":"NonNullType","type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"deleteTags"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"ids"},"value":{"kind":"Variable","name":{"kind":"Name","value":"ids"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Success"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Error"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}}]} as unknown as DocumentNode<DeleteTagsMutation, DeleteTagsMutationVariables>; +export const AddNamespaceDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"addNamespace"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"AddNamespaceInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"addNamespace"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Success"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Error"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}}]} as unknown as DocumentNode<AddNamespaceMutation, AddNamespaceMutationVariables>; +export const UpdateNamespacesDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"updateNamespaces"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"ids"}},"type":{"kind":"NonNullType","type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UpdateNamespaceInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"updateNamespaces"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"ids"},"value":{"kind":"Variable","name":{"kind":"Name","value":"ids"}}},{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Success"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Error"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}}]} as unknown as DocumentNode<UpdateNamespacesMutation, UpdateNamespacesMutationVariables>; +export const DeleteNamespacesDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"deleteNamespaces"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"ids"}},"type":{"kind":"NonNullType","type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"deleteNamespaces"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"ids"},"value":{"kind":"Variable","name":{"kind":"Name","value":"ids"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Success"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Error"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}}]} as unknown as DocumentNode<DeleteNamespacesMutation, DeleteNamespacesMutationVariables>; +export const AddArtistDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"addArtist"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"AddArtistInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"addArtist"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Success"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Error"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}}]} as unknown as DocumentNode<AddArtistMutation, AddArtistMutationVariables>; +export const UpdateArtistsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"updateArtists"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"ids"}},"type":{"kind":"NonNullType","type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UpdateArtistInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"updateArtists"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"ids"},"value":{"kind":"Variable","name":{"kind":"Name","value":"ids"}}},{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Success"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Error"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}}]} as unknown as DocumentNode<UpdateArtistsMutation, UpdateArtistsMutationVariables>; +export const DeleteArtistsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"deleteArtists"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"ids"}},"type":{"kind":"NonNullType","type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"deleteArtists"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"ids"},"value":{"kind":"Variable","name":{"kind":"Name","value":"ids"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Success"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Error"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}}]} as unknown as DocumentNode<DeleteArtistsMutation, DeleteArtistsMutationVariables>; +export const AddCharacterDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"addCharacter"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"AddCharacterInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"addCharacter"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Success"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Error"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}}]} as unknown as DocumentNode<AddCharacterMutation, AddCharacterMutationVariables>; +export const UpdateCharactersDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"updateCharacters"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"ids"}},"type":{"kind":"NonNullType","type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UpdateCharacterInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"updateCharacters"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"ids"},"value":{"kind":"Variable","name":{"kind":"Name","value":"ids"}}},{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Success"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Error"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}}]} as unknown as DocumentNode<UpdateCharactersMutation, UpdateCharactersMutationVariables>; +export const DeleteCharactersDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"deleteCharacters"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"ids"}},"type":{"kind":"NonNullType","type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"deleteCharacters"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"ids"},"value":{"kind":"Variable","name":{"kind":"Name","value":"ids"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Success"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Error"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}}]} as unknown as DocumentNode<DeleteCharactersMutation, DeleteCharactersMutationVariables>; +export const AddCircleDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"addCircle"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"AddCircleInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"addCircle"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Success"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Error"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}}]} as unknown as DocumentNode<AddCircleMutation, AddCircleMutationVariables>; +export const UpdateCirclesDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"updateCircles"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"ids"}},"type":{"kind":"NonNullType","type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UpdateCircleInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"updateCircles"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"ids"},"value":{"kind":"Variable","name":{"kind":"Name","value":"ids"}}},{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Success"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Error"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}}]} as unknown as DocumentNode<UpdateCirclesMutation, UpdateCirclesMutationVariables>; +export const DeleteCirclesDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"deleteCircles"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"ids"}},"type":{"kind":"NonNullType","type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"deleteCircles"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"ids"},"value":{"kind":"Variable","name":{"kind":"Name","value":"ids"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Success"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Error"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}}]} as unknown as DocumentNode<DeleteCirclesMutation, DeleteCirclesMutationVariables>; +export const AddWorldDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"addWorld"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"AddWorldInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"addWorld"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Success"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Error"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}}]} as unknown as DocumentNode<AddWorldMutation, AddWorldMutationVariables>; +export const UpdateWorldsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"updateWorlds"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"ids"}},"type":{"kind":"NonNullType","type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UpdateWorldInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"updateWorlds"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"ids"},"value":{"kind":"Variable","name":{"kind":"Name","value":"ids"}}},{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Success"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Error"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}}]} as unknown as DocumentNode<UpdateWorldsMutation, UpdateWorldsMutationVariables>; +export const DeleteWorldsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"deleteWorlds"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"ids"}},"type":{"kind":"NonNullType","type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"deleteWorlds"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"ids"},"value":{"kind":"Variable","name":{"kind":"Name","value":"ids"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Success"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Error"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}}]} as unknown as DocumentNode<DeleteWorldsMutation, DeleteWorldsMutationVariables>;
\ No newline at end of file diff --git a/frontend/src/lib/Actions.ts b/frontend/src/lib/Actions.ts new file mode 100644 index 0000000..7231c2f --- /dev/null +++ b/frontend/src/lib/Actions.ts @@ -0,0 +1,109 @@ +export function debounce( + node: HTMLInputElement, + { callback, timeout = 500 }: { callback: () => void; timeout?: number } +) { + let timer: NodeJS.Timeout; + + function trigger(event: KeyboardEvent) { + clearTimeout(timer); + if (event.key !== 'Enter') { + timer = setTimeout(callback, timeout); + } else { + callback(); + } + } + + node.addEventListener('keyup', trigger); + + return { + destroy() { + clearTimeout(timer); + node.removeEventListener('keyup', trigger); + } + }; +} + +export function clickOutside( + node: HTMLElement, + { handler, ignore }: { handler: () => void; ignore?: HTMLElement } +) { + const handle = (event: Event) => { + const target = event.target as HTMLElement; + if (!target || target === ignore) return; + + if (node && !node.contains(target) && !event.defaultPrevented) { + handler(); + } + }; + + document.addEventListener('click', handle, true); + + return { + destroy() { + document.removeEventListener('click', handle, true); + } + }; +} + +export const focusableElements = [ + 'a[href]', + 'area[href]', + 'input:not([disabled]):not([type="hidden"]):not([aria-hidden])', + 'select:not([disabled]):not([aria-hidden])', + 'textarea:not([disabled]):not([aria-hidden])', + 'button:not([disabled]):not([aria-hidden])', + 'iframe', + 'object', + 'embed', + '[contenteditable]', + '[tabindex]:not([tabindex^="-"])' +]; + +let trapped: HTMLElement[] = []; + +export function trapFocus(node: HTMLElement) { + function handler(event: KeyboardEvent) { + if (event.target === window) return; + + // return if we're not the topmost node to handle + if (trapped.at(0) !== node) return; + + const focusable = node.querySelectorAll<HTMLElement>(focusableElements.join()); + + const first = focusable[0]; + const last = focusable[focusable.length - 1]; + + if (event.key === 'Tab') { + if (!node.contains(document.activeElement)) { + first.focus(); + event.preventDefault(); + } + + if (event.shiftKey && event.target === first) { + last.focus(); + event.preventDefault(); + } else if (!event.shiftKey && event.target === last) { + first.focus(); + event.preventDefault(); + } + } + } + + if (document.activeElement instanceof HTMLElement) { + // if we trap focus, make sure to blur any previously selected external + // item such that focus does not remain outside of the node + if (!node.contains(document.activeElement)) { + document.activeElement.blur(); + } + } + + document.addEventListener('keydown', handler); + trapped.unshift(node); + + return { + destroy() { + document.removeEventListener('keydown', handler); + trapped = trapped.filter((i) => i !== node); + } + }; +} diff --git a/frontend/src/lib/Enums.ts b/frontend/src/lib/Enums.ts new file mode 100644 index 0000000..876aec8 --- /dev/null +++ b/frontend/src/lib/Enums.ts @@ -0,0 +1,325 @@ +import { + ArchiveSort, + ArtistSort, + Category, + Censorship, + CharacterSort, + CircleSort, + ComicSort, + Direction, + Language, + Layout, + NamespaceSort, + Rating, + TagSort, + UpdateMode, + WorldSort +} from '$gql/graphql'; + +export interface EnumOption<T> { + id: T; + name: string; +} + +export const DirectionLabel: Record<Direction, string> = { + [Direction.LeftToRight]: 'Left to Right', + [Direction.RightToLeft]: 'Right to Left' +}; + +export const LayoutLabel: Record<Layout, string> = { + [Layout.Single]: 'Single Page', + [Layout.Double]: 'Double Page', + [Layout.DoubleOffset]: 'Double Page, offset' +}; + +export const RatingLabel: Record<Rating, string> = { + [Rating.Safe]: 'Safe', + [Rating.Questionable]: 'Questionable', + [Rating.Explicit]: 'Explicit' +}; + +export const CensorshipLabel: Record<Censorship, string> = { + [Censorship.None]: 'None', + [Censorship.Bar]: 'Bars', + [Censorship.Mosaic]: 'Mosaic', + [Censorship.Full]: 'Full' +}; + +export const CategoryLabel: Record<Category, string> = { + [Category.Manga]: 'Manga', + [Category.Doujinshi]: 'Doujinshi', + [Category.Comic]: 'Comic', + [Category.Artbook]: 'Artbook', + [Category.GameCg]: 'Game CG', + [Category.ImageSet]: 'Image Set', + [Category.VariantSet]: 'Variant Set', + [Category.Webtoon]: 'Webtoon' +}; + +export const ArchiveSortLabel: Record<ArchiveSort, string> = { + [ArchiveSort.Path]: 'Path', + [ArchiveSort.Size]: 'File Size', + [ArchiveSort.CreatedAt]: 'Created At', + [ArchiveSort.PageCount]: 'Page Count', + [ArchiveSort.Random]: 'Random' +}; + +export const ComicSortLabel: Record<ComicSort, string> = { + [ComicSort.Title]: 'Title', + [ComicSort.OriginalTitle]: 'Original Title', + [ComicSort.Date]: 'Date', + [ComicSort.CreatedAt]: 'Created At', + [ComicSort.UpdatedAt]: 'Updated At', + [ComicSort.TagCount]: 'Tag Count', + [ComicSort.PageCount]: 'Page Count', + [ComicSort.Random]: 'Random' +}; + +export const ArtistSortLabel: Record<ArtistSort, string> = { + [ArtistSort.Name]: 'Name', + [ArtistSort.CreatedAt]: 'Created At', + [ArtistSort.UpdatedAt]: 'Updated At', + [ArchiveSort.Random]: 'Random' +}; + +export const CharacterSortLabel: Record<CharacterSort, string> = { + [CharacterSort.Name]: 'Name', + [CharacterSort.CreatedAt]: 'Created At', + [CharacterSort.UpdatedAt]: 'Updated At', + [ArchiveSort.Random]: 'Random' +}; + +export const CircleSortLabel: Record<CircleSort, string> = { + [CircleSort.Name]: 'Name', + [CircleSort.CreatedAt]: 'Created At', + [CircleSort.UpdatedAt]: 'Updated At', + [ArchiveSort.Random]: 'Random' +}; + +export const NamespaceSortLabel: Record<NamespaceSort, string> = { + [NamespaceSort.Name]: 'Name', + [NamespaceSort.SortName]: 'Sort Name', + [NamespaceSort.CreatedAt]: 'Created At', + [NamespaceSort.UpdatedAt]: 'Updated At', + [ArchiveSort.Random]: 'Random' +}; + +export const TagSortLabel: Record<TagSort, string> = { + [TagSort.Name]: 'Name', + [TagSort.CreatedAt]: 'Created At', + [TagSort.UpdatedAt]: 'Updated At', + [ArchiveSort.Random]: 'Random' +}; + +export const WorldSortLabel: Record<WorldSort, string> = { + [WorldSort.Name]: 'Name', + [WorldSort.CreatedAt]: 'Created At', + [WorldSort.UpdatedAt]: 'Updated At', + [ArchiveSort.Random]: 'Random' +}; + +export const UpdateModeLabel: Record<UpdateMode, string> = { + [UpdateMode.Add]: 'Add', + [UpdateMode.Remove]: 'Remove', + [UpdateMode.Replace]: 'Replace' +}; + +export const LanguageLabel: Record<Language, string> = { + [Language.Ab]: 'Abkhazian', + [Language.Aa]: 'Afar', + [Language.Af]: 'Afrikaans', + [Language.Ak]: 'Akan', + [Language.Sq]: 'Albanian', + [Language.Am]: 'Amharic', + [Language.Ar]: 'Arabic', + [Language.An]: 'Aragonese', + [Language.Hy]: 'Armenian', + [Language.As]: 'Assamese', + [Language.Av]: 'Avaric', + [Language.Ae]: 'Avestan', + [Language.Ay]: 'Aymara', + [Language.Az]: 'Azerbaijani', + [Language.Bm]: 'Bambara', + [Language.Ba]: 'Bashkir', + [Language.Eu]: 'Basque', + [Language.Be]: 'Belarusian', + [Language.Bn]: 'Bengali', + [Language.Bh]: 'Bihari languages', + [Language.Bi]: 'Bislama', + [Language.Bs]: 'Bosnian', + [Language.Br]: 'Breton', + [Language.Bg]: 'Bulgarian', + [Language.My]: 'Burmese', + [Language.Ca]: 'Catalan', + [Language.Km]: 'Central Khmer', + [Language.Ch]: 'Chamorro', + [Language.Ce]: 'Chechen', + [Language.Ny]: 'Chichewa', + [Language.Zh]: 'Chinese', + [Language.Cu]: 'Church Slavic', + [Language.Cv]: 'Chuvash', + [Language.Kw]: 'Cornish', + [Language.Co]: 'Corsican', + [Language.Cr]: 'Cree', + [Language.Hr]: 'Croatian', + [Language.Cs]: 'Czech', + [Language.Da]: 'Danish', + [Language.Dv]: 'Divehi', + [Language.Nl]: 'Dutch', + [Language.Dz]: 'Dzongkha', + [Language.En]: 'English', + [Language.Eo]: 'Esperanto', + [Language.Et]: 'Estonian', + [Language.Ee]: 'Ewe', + [Language.Fo]: 'Faroese', + [Language.Fj]: 'Fijian', + [Language.Fi]: 'Finnish', + [Language.Fr]: 'French', + [Language.Ff]: 'Fulah', + [Language.Gd]: 'Gaelic', + [Language.Gl]: 'Galician', + [Language.Lg]: 'Ganda', + [Language.Ka]: 'Georgian', + [Language.De]: 'German', + [Language.Gn]: 'Guarani', + [Language.Gu]: 'Gujarati', + [Language.Ht]: 'Haitian', + [Language.Ha]: 'Hausa', + [Language.He]: 'Hebrew', + [Language.Hz]: 'Herero', + [Language.Hi]: 'Hindi', + [Language.Ho]: 'Hiri Motu', + [Language.Hu]: 'Hungarian', + [Language.Is]: 'Icelandic', + [Language.Io]: 'Ido', + [Language.Ig]: 'Igbo', + [Language.Id]: 'Indonesian', + [Language.Ia]: 'Interlingua', + [Language.Ie]: 'Interlingue', + [Language.Iu]: 'Inuktitut', + [Language.Ik]: 'Inupiaq', + [Language.Ga]: 'Irish', + [Language.It]: 'Italian', + [Language.Ja]: 'Japanese', + [Language.Jv]: 'Javanese', + [Language.Kl]: 'Kalaallisut', + [Language.Kn]: 'Kannada', + [Language.Kr]: 'Kanuri', + [Language.Ks]: 'Kashmiri', + [Language.Kk]: 'Kazakh', + [Language.Ki]: 'Kikuyu', + [Language.Rw]: 'Kinyarwanda', + [Language.Ky]: 'Kirghiz', + [Language.Kv]: 'Komi', + [Language.Kg]: 'Kongo', + [Language.Ko]: 'Korean', + [Language.Kj]: 'Kuanyama', + [Language.Ku]: 'Kurdish', + [Language.Lo]: 'Lao', + [Language.La]: 'Latin', + [Language.Lv]: 'Latvian', + [Language.Li]: 'Limburgan', + [Language.Ln]: 'Lingala', + [Language.Lt]: 'Lithuanian', + [Language.Lu]: 'Luba-Katanga', + [Language.Lb]: 'Luxembourgish', + [Language.Mk]: 'Macedonian', + [Language.Mg]: 'Malagasy', + [Language.Ms]: 'Malay', + [Language.Ml]: 'Malayalam', + [Language.Mt]: 'Maltese', + [Language.Gv]: 'Manx', + [Language.Mi]: 'Maori', + [Language.Mr]: 'Marathi', + [Language.Mh]: 'Marshallese', + [Language.El]: 'Modern Greek', + [Language.Mn]: 'Mongolian', + [Language.Na]: 'Nauru', + [Language.Nv]: 'Navajo', + [Language.Ng]: 'Ndonga', + [Language.Ne]: 'Nepali', + [Language.Se]: 'Northern Sami', + [Language.Nd]: 'North Ndebele', + [Language.No]: 'Norwegian', + [Language.Nb]: 'Norwegian BokmÃ¥l', + [Language.Nn]: 'Norwegian Nynorsk', + [Language.Oc]: 'Occitan', + [Language.Oj]: 'Ojibwa', + [Language.Or]: 'Oriya', + [Language.Om]: 'Oromo', + [Language.Os]: 'Ossetian', + [Language.Pi]: 'Pali', + [Language.Pa]: 'Panjabi', + [Language.Fa]: 'Persian', + [Language.Pl]: 'Polish', + [Language.Pt]: 'Portuguese', + [Language.Ps]: 'Pushto', + [Language.Qu]: 'Quechua', + [Language.Ro]: 'Romanian', + [Language.Rm]: 'Romansh', + [Language.Rn]: 'Rundi', + [Language.Ru]: 'Russian', + [Language.Sm]: 'Samoan', + [Language.Sg]: 'Sango', + [Language.Sa]: 'Sanskrit', + [Language.Sc]: 'Sardinian', + [Language.Sr]: 'Serbian', + [Language.Sn]: 'Shona', + [Language.Ii]: 'Sichuan Yi', + [Language.Sd]: 'Sindhi', + [Language.Si]: 'Sinhala', + [Language.Sk]: 'Slovak', + [Language.Sl]: 'Slovenian', + [Language.So]: 'Somali', + [Language.St]: 'Southern Sotho', + [Language.Nr]: 'South Ndebele', + [Language.Es]: 'Spanish', + [Language.Su]: 'Sundanese', + [Language.Sw]: 'Swahili', + [Language.Ss]: 'Swati', + [Language.Sv]: 'Swedish', + [Language.Tl]: 'Tagalog', + [Language.Ty]: 'Tahitian', + [Language.Tg]: 'Tajik', + [Language.Ta]: 'Tamil', + [Language.Tt]: 'Tatar', + [Language.Te]: 'Telugu', + [Language.Th]: 'Thai', + [Language.Bo]: 'Tibetan', + [Language.Ti]: 'Tigrinya', + [Language.To]: 'Tonga', + [Language.Ts]: 'Tsonga', + [Language.Tn]: 'Tswana', + [Language.Tr]: 'Turkish', + [Language.Tk]: 'Turkmen', + [Language.Tw]: 'Twi', + [Language.Ug]: 'Uighur', + [Language.Uk]: 'Ukrainian', + [Language.Ur]: 'Urdu', + [Language.Uz]: 'Uzbek', + [Language.Ve]: 'Venda', + [Language.Vi]: 'Vietnamese', + [Language.Vo]: 'Volapük', + [Language.Wa]: 'Walloon', + [Language.Cy]: 'Welsh', + [Language.Fy]: 'Western Frisian', + [Language.Wo]: 'Wolof', + [Language.Xh]: 'Xhosa', + [Language.Yi]: 'Yiddish', + [Language.Yo]: 'Yoruba', + [Language.Za]: 'Zhuang', + [Language.Zu]: 'Zulu' +}; + +export const directions: EnumOption<Direction>[] = optionsFromLabel(DirectionLabel); +export const layouts: EnumOption<Layout>[] = optionsFromLabel(LayoutLabel); +export const ratings: EnumOption<Rating>[] = optionsFromLabel(RatingLabel); +export const censorships: EnumOption<Censorship>[] = optionsFromLabel(CensorshipLabel); +export const categories: EnumOption<Category>[] = optionsFromLabel(CategoryLabel); +export const languages: EnumOption<Language>[] = optionsFromLabel(LanguageLabel); + +function optionsFromLabel<T extends string | number | symbol>( + labels: Record<T, string> +): EnumOption<T>[] { + return Object.entries(labels).map(([k, v]) => ({ id: k as T, name: v as string })); +} diff --git a/frontend/src/lib/Filter.ts b/frontend/src/lib/Filter.ts new file mode 100644 index 0000000..8e419f3 --- /dev/null +++ b/frontend/src/lib/Filter.ts @@ -0,0 +1,365 @@ +import { + type ArchiveFilter, + type ArchiveFilterInput, + type ComicFilter, + type ComicFilterInput, + type StringFilter, + type TagFilter, + type TagFilterInput +} from '$gql/graphql'; +import { getContext, setContext } from 'svelte'; +import { writable, type Writable } from 'svelte/store'; +import { navigate } from './Navigation'; +import { numKeys } from './Utils'; + +interface FilterInput<T> { + include?: T | null; + exclude?: T | null; +} + +interface BasicFilter { + name?: { contains?: string | null } | null; +} + +type FilterMode = 'any' | 'all' | 'exact'; + +type Key = string | number | symbol; + +type Filter<T, K extends Key> = { + [Property in K]?: T | null; +}; + +type AssocFilter<T, K extends Key> = Filter< + { + any?: T[] | null; + all?: T[] | null; + exact?: T[] | null; + empty?: boolean | null; + }, + K +>; + +type EnumFilter<K extends Key> = Filter< + { + any?: string[] | null; + empty?: boolean | null; + }, + K +>; + +interface Integrateable<F> { + integrate(filter: F): void; +} + +class ComplexMember<K extends Key> { + values: unknown[] = []; + key: K; + mode: FilterMode; + empty?: boolean | null; + + constructor(key: K, mode: FilterMode) { + this.key = key; + this.mode = mode; + } + + integrate(filter: AssocFilter<unknown, K>) { + if (this.values.length > 0) { + filter[this.key] = { [this.mode]: this.values }; + } + + if (this.empty) { + filter[this.key] = { ...filter[this.key], empty: this.empty }; + } + } +} + +export class Association<K extends Key> extends ComplexMember<K> { + values: (string | number)[] = []; + + constructor(key: K, mode: FilterMode, filter?: AssocFilter<string | number, K> | null) { + super(key, mode); + + if (!filter) { + return; + } + + const prop = filter[key]; + this.empty = prop?.empty; + + if (prop?.all && prop.all.length > 0) { + this.mode = 'all'; + this.values = prop.all; + } else if (prop?.any && prop.any.length > 0) { + this.mode = 'any'; + this.values = prop.any; + } else if (prop?.exact && prop.exact.length > 0) { + this.mode = 'exact'; + this.values = prop.exact; + } + } +} + +export class Enum<K extends Key> extends ComplexMember<K> { + values: string[] = []; + + constructor(key: K, filter?: EnumFilter<K> | null) { + super(key, 'any'); + + if (!filter) { + return; + } + + this.empty = filter[key]?.empty; + + const prop = filter[key]; + if (prop?.any) { + this.values = prop.any; + } + } +} + +class Bool<K extends Key> { + key: K; + value?: boolean = undefined; + + constructor(key: K, filter?: Filter<boolean, K> | null) { + this.key = key; + + if (filter) { + this.value = filter[key] ?? undefined; + } + } + + integrate(filter: Filter<boolean, K>) { + if (this.value !== undefined) { + filter[this.key] = this.value; + } + } +} + +class Str<K extends Key> { + key: K; + contains = ''; + + constructor(key: K, filter?: Filter<StringFilter, K> | null) { + this.key = key; + + if (filter) { + this.contains = filter[key]?.contains ?? ''; + } + } + + integrate(filter: Filter<StringFilter, K>) { + if (this.contains) { + filter[this.key] = { contains: this.contains }; + } + } +} + +abstract class Controls<F> { + buildFilter() { + const filter = {} as F; + Object.values(this).forEach((v: Integrateable<F>) => v.integrate(filter)); + return filter; + } +} + +export class ArchiveFilterControls extends Controls<ArchiveFilter> { + path: Str<'path'>; + organized: Bool<'organized'>; + + constructor(filter: ArchiveFilter | null | undefined) { + super(); + + this.path = new Str('path', filter); + this.organized = new Bool('organized', filter); + } +} + +export class ComicFilterControls extends Controls<ComicFilter> { + title: Str<'title'>; + categories: Enum<'category'>; + censorships: Enum<'censorship'>; + ratings: Enum<'rating'>; + tags: Association<'tags'>; + languages: Enum<'language'>; + artists: Association<'artists'>; + circles: Association<'circles'>; + characters: Association<'characters'>; + worlds: Association<'worlds'>; + favourite: Bool<'favourite'>; + organized: Bool<'organized'>; + bookmarked: Bool<'bookmarked'>; + + constructor(filter: ComicFilter | null | undefined, mode: FilterMode); + constructor(filter: ComicFilter | null | undefined, mode: FilterMode); + constructor(filter: ComicFilter | null | undefined, mode: FilterMode) { + super(); + + this.title = new Str('title', filter); + this.favourite = new Bool('favourite', filter); + this.organized = new Bool('organized', filter); + this.bookmarked = new Bool('bookmarked', filter); + this.tags = new Association('tags', mode, filter); + this.languages = new Enum('language', filter); + this.categories = new Enum('category', filter); + this.censorships = new Enum('censorship', filter); + this.ratings = new Enum('rating', filter); + this.artists = new Association('artists', mode, filter); + this.circles = new Association('circles', mode, filter); + this.characters = new Association('characters', mode, filter); + this.worlds = new Association('worlds', mode, filter); + } +} + +export class BasicFilterControls extends Controls<BasicFilter> { + name: Str<'name'>; + + constructor(filter?: BasicFilter | null) { + super(); + + this.name = new Str('name', filter); + } +} + +export class TagFilterControls extends BasicFilterControls { + namespaces: Association<'namespaces'>; + + constructor(filter: TagFilter | null | undefined, mode: FilterMode) { + super(filter); + + this.namespaces = new Association('namespaces', mode, filter); + } +} + +function buildFilterInput<F>(include?: F, exclude?: F) { + const input: FilterInput<F> = {}; + + if (include && Object.keys(include).length > 0) { + input.include = include; + } + + if (exclude && Object.keys(exclude).length > 0) { + input.exclude = exclude; + } + + return input; +} + +abstract class FilterContext<F> { + include!: { controls: Controls<F>; size: number }; + exclude!: { controls: Controls<F>; size: number }; + + apply(params: URLSearchParams) { + navigate( + { + filter: buildFilterInput( + this.include.controls.buildFilter(), + this.exclude.controls.buildFilter() + ) + }, + params + ); + } +} + +export class ArchiveFilterContext extends FilterContext<ArchiveFilter> { + include: { controls: ArchiveFilterControls; size: number }; + exclude: { controls: ArchiveFilterControls; size: number }; + private static ignore = ['organized']; + + constructor(filter: ArchiveFilterInput) { + super(); + + this.include = { + controls: new ArchiveFilterControls(filter.include), + size: numKeys(filter.include, ArchiveFilterContext.ignore) + }; + this.exclude = { + controls: new ArchiveFilterControls(filter.exclude), + size: numKeys(filter.exclude, ArchiveFilterContext.ignore) + }; + } +} + +export class ComicFilterContext extends FilterContext<ComicFilter> { + include: { controls: ComicFilterControls; size: number }; + exclude: { controls: ComicFilterControls; size: number }; + private static ignore = ['title', 'favourite', 'organized', 'bookmarked']; + + constructor(filter: ComicFilterInput) { + super(); + + this.include = { + controls: new ComicFilterControls(filter.include, 'all'), + size: numKeys(filter.include, ComicFilterContext.ignore) + }; + this.exclude = { + controls: new ComicFilterControls(filter.exclude, 'any'), + size: numKeys(filter.exclude, ComicFilterContext.ignore) + }; + } +} + +export class BasicFilterContext extends FilterContext<BasicFilter> { + include: { controls: BasicFilterControls; size: number }; + exclude: { controls: BasicFilterControls; size: number }; + + constructor(filter: FilterInput<BasicFilter>) { + super(); + + this.include = { + controls: new BasicFilterControls(filter.include), + size: numKeys(filter.include) + }; + this.exclude = { + controls: new BasicFilterControls(), + size: 0 + }; + } +} + +export class TagFilterContext extends FilterContext<TagFilter> { + include: { controls: TagFilterControls; size: number }; + exclude: { controls: TagFilterControls; size: number }; + private static ignore = ['name']; + + constructor(filter: TagFilterInput) { + super(); + + this.include = { + controls: new TagFilterControls(filter.include, 'all'), + size: numKeys(filter.include, TagFilterContext.ignore) + }; + this.exclude = { + controls: new TagFilterControls(filter.exclude, 'any'), + size: numKeys(filter.exclude, TagFilterContext.ignore) + }; + } +} + +export function initFilterContext<F extends FilterContext<unknown>>() { + return setContext<Writable<F>>('filter', writable()); +} + +export function getFilterContext<F extends FilterContext<unknown>>() { + return getContext<Writable<F>>('filter'); +} + +export function cycleBooleanFilter(value: boolean | undefined, tristate = true) { + if (tristate) { + if (value === undefined) { + return true; + } else if (value) { + return false; + } else { + return undefined; + } + } else { + if (value) { + return undefined; + } else { + return true; + } + } +} diff --git a/frontend/src/lib/Meta.ts b/frontend/src/lib/Meta.ts new file mode 100644 index 0000000..8cfad6b --- /dev/null +++ b/frontend/src/lib/Meta.ts @@ -0,0 +1 @@ +export const codename = 'Satanic Satyr'; diff --git a/frontend/src/lib/Navigation.ts b/frontend/src/lib/Navigation.ts new file mode 100644 index 0000000..e6b17cd --- /dev/null +++ b/frontend/src/lib/Navigation.ts @@ -0,0 +1,114 @@ +import { goto as svelteGoto } from '$app/navigation'; +import { SortDirection } from '$gql/graphql'; +import JsonURL from '@jsonurl/jsonurl'; +import { type PaginationData } from './Pagination'; +import { type SortData } from './Sort'; +import { toastError } from './Toasts'; + +function paramToNum<T>(value: string | null, fallback: T) { + if (value) { + const number = +value; + + if (Number.isNaN(number) || number < 0) { + return fallback; + } + + return number; + } + + return fallback; +} + +export function parseSortData<T>(params: URLSearchParams, fallback: T): SortData<T> { + return { + on: (params.get('s') as T) || fallback, + direction: (params.get('d') as SortDirection) || SortDirection.Ascending, + seed: paramToNum(params.get('r'), undefined) + }; +} + +export function parsePaginationData(params: URLSearchParams, defaultItems = 120): PaginationData { + return { + page: paramToNum(params.get('p'), 1), + items: paramToNum(params.get('i'), defaultItems) + }; +} + +export function parseFilter<T>(params: URLSearchParams): T { + const param = params.get('f'); + + if (!param) return {} as T; + + try { + return JsonURL.parse(param, { AQF: true, impliedObject: {} }) as T; + } catch (e) { + return {} as T; + } +} + +interface NavigationOptions { + to?: string; + params: URLSearchParams; + options?: Parameters<typeof svelteGoto>[1]; +} + +export function goto({ to = '', params, options }: NavigationOptions) { + svelteGoto(`${to}?${params.toString()}`, options).catch(() => toastError('Navigation failed')); +} + +interface NavigationParameters<T> { + filter?: T; + sort?: Partial<SortData<string>>; + pagination?: Partial<PaginationData>; +} + +function paramsFrom<T>( + { pagination, filter, sort }: NavigationParameters<T>, + current?: URLSearchParams +) { + const params = new URLSearchParams(current); + + if (filter !== undefined) { + const json = JsonURL.stringify(filter, { AQF: true, impliedObject: true }); + if (json) { + params.set('f', json); + } else { + params.delete('f'); + } + } + + if (sort !== undefined) { + if (sort.on !== undefined) { + params.set('s', sort.on); + } + if (sort.direction !== undefined) { + params.set('d', sort.direction); + } + if (sort.seed !== undefined) { + params.set('r', sort.seed.toString()); + } + } + + params.delete('p'); + + if (pagination?.items) { + params.set('i', pagination.items.toString()); + } + + if (pagination?.page) { + params.set('p', pagination.page.toString()); + } + + return params; +} + +export function navigate(parameters: NavigationParameters<object>, current?: URLSearchParams) { + goto({ + params: paramsFrom(parameters, current), + options: { noScroll: false, keepFocus: true, replaceState: true } + }); +} + +export function href<T>(base: string, params: NavigationParameters<T>) { + return `/${base}/?${paramsFrom(params).toString()}`; +} diff --git a/frontend/src/lib/Pagination.ts b/frontend/src/lib/Pagination.ts new file mode 100644 index 0000000..f05492b --- /dev/null +++ b/frontend/src/lib/Pagination.ts @@ -0,0 +1,31 @@ +import { navigate } from '$lib/Navigation'; +import { getContext, setContext } from 'svelte'; +import { writable, type Writable } from 'svelte/store'; + +export interface PaginationData { + page: number; + items: number; +} + +export class PaginationContext { + page = 0; + items = 0; + total = 0; + + set update({ page, items }: PaginationData) { + this.page = page; + this.items = items; + } + + apply(params: URLSearchParams) { + navigate({ pagination: { items: this.items } }, params); + } +} + +export function initPaginationContext() { + return setContext<Writable<PaginationContext>>('pagination', writable(new PaginationContext())); +} + +export function getPaginationContext() { + return getContext<Writable<PaginationContext>>('pagination'); +} diff --git a/frontend/src/lib/Reader.ts b/frontend/src/lib/Reader.ts new file mode 100644 index 0000000..8777b9b --- /dev/null +++ b/frontend/src/lib/Reader.ts @@ -0,0 +1,62 @@ +import { Layout, type PageFragment } from '$gql/graphql'; +import { getContext, setContext } from 'svelte'; +import { writable, type Writable } from 'svelte/store'; + +export interface Chunk { + main: PageFragment; + secondary?: PageFragment; + index: number; +} + +class ReaderContext { + visible = false; + sidebar = false; + pages: PageFragment[] = []; + page = 0; + + open(page: number) { + this.page = page; + this.visible = true; + + return this; + } +} + +export function initReaderContext() { + return setContext<Writable<ReaderContext>>('reader', writable(new ReaderContext())); +} + +export function getReaderContext() { + return getContext<Writable<ReaderContext>>('reader'); +} + +export function partition(pages: PageFragment[], layout: Layout): [Chunk[], number[]] { + const single = layout === Layout.Single; + const offset = layout === Layout.DoubleOffset; + + const chunks: Chunk[] = []; + const lookup: number[] = Array<number>(pages.length); + + for (let chunkIndex = 0, pageIndex = 0; pageIndex < pages.length; chunkIndex++) { + const wide = () => pages[pageIndex].image.aspectRatio > 1; + + const nextPage = () => { + lookup[pageIndex] = chunkIndex; + return pages[pageIndex++]; + }; + + const offsetFirst = pageIndex === 0 && offset; + const full = single || wide() || offsetFirst; + + const chunk: Chunk = { index: pageIndex, main: nextPage() }; + + if (!full && pageIndex < pages.length) { + if (!wide()) { + chunk.secondary = nextPage(); + } + } + + chunks.push(chunk); + } + return [chunks, lookup]; +} diff --git a/frontend/src/lib/Scraper.ts b/frontend/src/lib/Scraper.ts new file mode 100644 index 0000000..4baf370 --- /dev/null +++ b/frontend/src/lib/Scraper.ts @@ -0,0 +1,156 @@ +import { + Category, + Censorship, + Direction, + Language, + Layout, + OnMissing, + Rating, + type FullComicFragment, + type ScrapedComic, + type UpsertComicInput, + type UpsertOptions +} from '$gql/graphql'; +import { + CategoryLabel, + CensorshipLabel, + DirectionLabel, + LanguageLabel, + LayoutLabel, + RatingLabel +} from '$lib/Enums'; +import { getContext, setContext } from 'svelte'; +import { writable, type Writable } from 'svelte/store'; + +interface ScraperContext { + scraper: string; + warnings: string[]; + selector?: ScrapedComicSelector; +} + +export function initScraperContext() { + return setContext<Writable<ScraperContext>>('scraper', writable({ scraper: '', warnings: [] })); +} + +export function getScraperContext() { + return getContext<Writable<ScraperContext>>('scraper'); +} + +export class Selector<T extends string> { + keep = true; + value: T; + display: string | undefined; + + constructor(value: T, display?: string) { + this.value = value; + this.display = display; + } + + toString() { + return this.display ?? this.value; + } + + static from<T extends string>( + scraped: T | undefined | null, + have: string | undefined | null, + label?: Record<string, string> + ) { + if (scraped && have !== scraped) { + return new Selector(scraped, label ? label[scraped] : undefined); + } + return undefined; + } + + static fromList(scraped: string[], have: { name: string }[]) { + const haves = new Set(have.map((i) => i.name)); + + return scraped.filter((i) => !haves.has(i)).map((i) => new Selector(i)); + } +} + +function keepItem<T extends string>(selector?: Selector<T>): T | undefined | null { + if (selector?.keep) { + return selector.value; + } + return undefined; +} + +function keepList<T extends string>( + selectorList: Selector<T>[], + onMissing: OnMissing +): { names: T[]; options: UpsertOptions } { + return { + names: selectorList.filter((v) => v.keep).map((v) => v.value), + options: { onMissing } + }; +} + +export class ScrapedComicSelector { + title?: Selector<string>; + originalTitle?: Selector<string>; + url?: Selector<string>; + date?: Selector<string>; + category?: Selector<Category>; + censorship?: Selector<Censorship>; + rating?: Selector<Rating>; + language?: Selector<Language>; + direction?: Selector<Direction>; + layout?: Selector<Layout>; + artists: Selector<string>[]; + circles: Selector<string>[]; + characters: Selector<string>[]; + worlds: Selector<string>[]; + tags: Selector<string>[]; + + constructor(scraped: ScrapedComic, comic: FullComicFragment) { + this.title = Selector.from(scraped.title, comic.title); + this.originalTitle = Selector.from(scraped.originalTitle, comic.originalTitle); + this.url = Selector.from(scraped.url, comic.url); + this.date = Selector.from(scraped.date, comic.date); + this.category = Selector.from(scraped.category, comic.category, CategoryLabel); + this.censorship = Selector.from(scraped.censorship, comic.censorship, CensorshipLabel); + this.rating = Selector.from(scraped.rating, comic.rating, RatingLabel); + this.language = Selector.from(scraped.language, comic.language, LanguageLabel); + this.direction = Selector.from(scraped.direction, comic.direction, DirectionLabel); + this.layout = Selector.from(scraped.layout, comic.layout, LayoutLabel); + + this.artists = Selector.fromList(scraped.artists, comic.artists); + this.circles = Selector.fromList(scraped.circles, comic.circles); + this.characters = Selector.fromList(scraped.characters, comic.characters); + this.tags = Selector.fromList(scraped.tags, comic.tags); + this.worlds = Selector.fromList(scraped.worlds, comic.worlds); + } + + hasData() { + return ( + Object.values(this).filter((i) => { + if (i === undefined) { + return false; + } else if (Array.isArray(i) && i.length === 0) { + return false; + } + return true; + }).length > 0 + ); + } + + toInput(onMissing: OnMissing): UpsertComicInput { + return { + title: keepItem(this.title), + originalTitle: keepItem(this.originalTitle), + url: keepItem(this.url), + date: keepItem(this.date), + category: keepItem(this.category), + censorship: keepItem(this.censorship), + rating: keepItem(this.rating), + language: keepItem(this.language), + direction: keepItem(this.direction), + layout: keepItem(this.layout), + artists: keepList(this.artists, onMissing), + circles: keepList(this.circles, onMissing), + characters: keepList(this.characters, onMissing), + worlds: keepList(this.worlds, onMissing), + tags: keepList(this.tags, onMissing) + }; + } +} diff --git a/frontend/src/lib/Selection.ts b/frontend/src/lib/Selection.ts new file mode 100644 index 0000000..0ea85cc --- /dev/null +++ b/frontend/src/lib/Selection.ts @@ -0,0 +1,141 @@ +import { getContext, hasContext, setContext } from 'svelte'; +import { writable, type Writable } from 'svelte/store'; +import { range } from './Utils'; + +interface Item { + id: number; +} + +export const hasSelectionContext = () => hasContext('selection'); + +export function getSelectionContext<T extends Item>() { + return getContext<Writable<ItemSelection<T>>>('selection'); +} + +export function initSelectionContext<T extends Item>( + typename?: string, + toName?: (item: T) => string +) { + return setContext<Writable<ItemSelection<T>>>( + 'selection', + writable(new ItemSelection(typename, toName)) + ); +} + +export class ItemSelection<T extends Item> { + active = false; + typename: string; + #toName: (item: T) => string; + + #view: T[] = []; + selectable: (item: T) => boolean = () => true; + + #ids = new Set<number>(); + #masked = new Set<number>(); + + constructor(typename?: string, toName?: (item: T) => string) { + this.typename = typename ?? 'unknown'; + this.#toName = toName ?? (() => 'unknown'); + } + + set view(view: T[]) { + this.#view = view; + this.#updateMasked(); + } + + #indexOf = (id: number) => this.#view.findIndex((v) => v.id === id); + + update(index: number, shift: boolean) { + const id = this.#view[index].id; + + const selectableRange = (first: number, last: number) => + range(first, last) + .filter((i) => this.selectable(this.#view[i])) + .map((i) => this.#view[i].id); + + if (shift) { + const indices = this.indices; + + const first = indices.at(0); + const last = indices.at(-1); + + if (first === undefined || last === undefined) { + this.#ids.add(id); + } else if (index === first || index === last) { + this.#ids.clear(); + } else if (index > last) { + this.#ids = new Set([...this.#ids, ...selectableRange(last, index)]); + } else if (index < last) { + this.#ids = new Set([...this.#ids, ...selectableRange(index, last)]); + } + } else { + if (this.#ids.has(id)) { + this.#ids.delete(id); + } else { + this.#ids.add(id); + } + } + + this.#updateMasked(); + + return this; + } + + toggle() { + this.active = !this.active; + + if (!this.active) { + return this.none(); + } + + return this; + } + + all() { + this.#ids = new Set(this.#view.filter(this.selectable).map((i) => i.id)); + this.#updateMasked(); + + return this; + } + + none() { + this.#ids.clear(); + this.#masked.clear(); + + return this; + } + + clear() { + this.active = false; + + return this.none(); + } + + contains(id: number) { + return this.#masked.has(id); + } + + #updateMasked() { + this.#masked = new Set([...this.#ids].filter((i) => this.#indexOf(i) >= 0)); + } + + get ids() { + return [...this.#masked]; + } + + get size() { + return this.#masked.size; + } + + get indices() { + return [...this.#ids].map(this.#indexOf).filter((i) => i >= 0); + } + + get items() { + return this.indices.map((i) => this.#view[i]); + } + + get names() { + return this.items.map(this.#toName); + } +} diff --git a/frontend/src/lib/Shortcuts.ts b/frontend/src/lib/Shortcuts.ts new file mode 100644 index 0000000..063bd40 --- /dev/null +++ b/frontend/src/lib/Shortcuts.ts @@ -0,0 +1,153 @@ +import { closeModal, modals } from 'svelte-modals'; +import { get } from 'svelte/store'; + +type LowercaseLetter = + | 'a' + | 'b' + | 'c' + | 'd' + | 'e' + | 'f' + | 'g' + | 'h' + | 'i' + | 'j' + | 'l' + | 'm' + | 'n' + | 'o' + | 'p' + | 'q' + | 'r' + | 's' + | 't' + | 'u' + | 'v' + | 'w' + | 'x' + | 'y' + | 'z'; + +type UppercaseLetter = Uppercase<LowercaseLetter>; +type Letter = LowercaseLetter | UppercaseLetter; +type Special = '?' | 'Enter' | 'Escape' | 'Delete'; + +const modeSwitches = ['n', 'g', 'i'] as const; +type ModeSwitch = (typeof modeSwitches)[number]; + +function isModeSwitch(s: string): s is ModeSwitch { + // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument + return modeSwitches.indexOf(s as any) !== -1; +} + +type Key = Letter | Special; +type KeyCombo = `${ModeSwitch}${Letter}`; +export type Shortcut = Key | KeyCombo; + +type EventAction = (event: KeyboardEvent) => void; +type FocusAction = HTMLInputElement; +type ClickAction = HTMLElement; + +type Action = EventAction | FocusAction | ClickAction; + +const handlers = new Map<string, Action>(); +let mode: ModeSwitch | undefined; + +export function handleShortcuts(event: KeyboardEvent) { + if (isInputElement(event.target)) { + if (event.key === 'Escape') { + event.target.blur(); + event.preventDefault(); + event.stopImmediatePropagation(); + } + return; + } + + if (event.ctrlKey) { + return; + } + + if (event.key === 'Escape') { + if (get(modals).length > 0) { + closeModal(); + event.preventDefault(); + event.stopImmediatePropagation(); + return; + } + } + + if (isModeSwitch(event.key) && mode === undefined) { + mode = event.key; + event.preventDefault(); + return; + } + + const handler = handlers.get(mode === undefined ? event.key : `${mode}${event.key}`); + + if (!handler || get(modals).length > 0) { + mode = undefined; + return; + } + + if (handler instanceof HTMLInputElement) { + handler.focus(); + } else if (handler instanceof HTMLElement) { + handler.click(); + } else { + handler(event); + } + + mode = undefined; + event.preventDefault(); +} + +export function accelerator(node: HTMLElement | HTMLInputElement, sc: Shortcut) { + handlers.set(sc, node); + + return { + destroy() { + handlers.delete(sc); + } + }; +} + +export function binds(node: Document, scs: [string, EventAction][]) { + const handlers = new Map<string, EventAction>(); + + for (const [k, a] of scs) { + handlers.set(k, a); + } + + function keydown(event: KeyboardEvent) { + if (isInputElement(event.target)) return; + + const handler = handlers.get(event.key); + + if (!handler) return; + + handler(event); + event.preventDefault(); + } + + node.addEventListener('keydown', keydown); + + return { + destroy() { + node.removeEventListener('keydown', keydown); + } + }; +} + +export function addShortcut(sc: Shortcut, action: EventAction) { + handlers.set(sc, action); +} + +function isInputElement(target: EventTarget | null): target is HTMLElement { + return ( + target instanceof HTMLElement && + (target instanceof HTMLInputElement || + target instanceof HTMLSelectElement || + target instanceof HTMLTextAreaElement || + target.isContentEditable) + ); +} diff --git a/frontend/src/lib/Sort.ts b/frontend/src/lib/Sort.ts new file mode 100644 index 0000000..4c9a353 --- /dev/null +++ b/frontend/src/lib/Sort.ts @@ -0,0 +1,42 @@ +import { SortDirection } from '$gql/graphql'; +import { getContext, setContext } from 'svelte'; +import { writable, type Writable } from 'svelte/store'; +import { navigate } from './Navigation'; + +export interface SortData<T> { + on: T; + direction: SortDirection; + seed: number | undefined; +} + +export class SortContext<T extends string> { + on: T; + direction: SortDirection; + seed: number | undefined; + labels: Record<T, string>; + + constructor({ on, direction, seed }: SortData<T>, labels: Record<T, string>) { + this.on = on; + this.direction = direction; + this.seed = seed; + this.labels = labels; + } + + set update({ on, direction, seed }: SortData<T>) { + this.on = on; + this.direction = direction; + this.seed = seed; + } + + apply(params: URLSearchParams) { + navigate({ sort: { on: this.on, direction: this.direction, seed: this.seed } }, params); + } +} + +export function initSortContext<T extends string>(sort: SortData<T>, labels: Record<T, string>) { + return setContext<Writable<SortContext<T>>>('sort', writable(new SortContext(sort, labels))); +} + +export function getSortContext<T extends string>() { + return getContext<Writable<SortContext<T>>>('sort'); +} diff --git a/frontend/src/lib/Tabs.ts b/frontend/src/lib/Tabs.ts new file mode 100644 index 0000000..1c43068 --- /dev/null +++ b/frontend/src/lib/Tabs.ts @@ -0,0 +1,18 @@ +import { getContext, setContext } from 'svelte'; +import { writable, type Writable } from 'svelte/store'; + +type Tab = string; +type Tabs = Record<Tab, { title: string; badge?: boolean }>; + +interface TabContext { + tabs: Tabs; + current: Tab; +} + +export function setTabContext(context: TabContext) { + return setContext<Writable<TabContext>>('tabs', writable(context)); +} + +export function getTabContext() { + return getContext<Writable<TabContext>>('tabs'); +} diff --git a/frontend/src/lib/Toasts.ts b/frontend/src/lib/Toasts.ts new file mode 100644 index 0000000..abc9a7d --- /dev/null +++ b/frontend/src/lib/Toasts.ts @@ -0,0 +1,19 @@ +import { toast } from '@zerodevx/svelte-toast'; + +export function toastSuccess(message: string) { + toast.push(message, { + theme: { '--toastBackground': 'rgba(72, 187, 120, 0.9)', '--toastColor': 'mintcream' }, + duration: 1000 + }); +} + +export function toastError(message: string) { + toast.push(message, { + theme: { '--toastBackground': 'rgba(187, 72, 72, 0.9)', '--toastColor': 'lavenderblush' }, + duration: 5000, + pausable: true + }); +} + +// eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-explicit-any +export const toastFinally = (reason: any) => toastError(reason); diff --git a/frontend/src/lib/Transitions.ts b/frontend/src/lib/Transitions.ts new file mode 100644 index 0000000..59ebaf2 --- /dev/null +++ b/frontend/src/lib/Transitions.ts @@ -0,0 +1,10 @@ +import { quartInOut } from 'svelte/easing'; +import type { FadeParams, SlideParams } from 'svelte/transition'; + +export const fadeFast: FadeParams = { duration: 60 }; +export const fadeDefault: FadeParams = { duration: 100 }; + +export const slideYDefault: SlideParams = { axis: 'y', duration: 300, easing: quartInOut }; + +export const slideXDefault: SlideParams = { axis: 'x', duration: 300, easing: quartInOut }; +export const slideXFast: SlideParams = { axis: 'x', duration: 200 }; diff --git a/frontend/src/lib/Update.ts b/frontend/src/lib/Update.ts new file mode 100644 index 0000000..507dd52 --- /dev/null +++ b/frontend/src/lib/Update.ts @@ -0,0 +1,97 @@ +import { + UpdateMode, + type UpdateComicInput, + type UpdateOptions, + type UpdateTagInput +} from '$gql/graphql'; + +type Key = string | number | symbol; + +interface AssociationUpdate { + ids?: number[] | string[] | null; + options?: UpdateOptions | null; +} + +type Input<T, K extends Key> = { + [Property in K]?: T | null; +}; + +abstract class Entry<K extends Key> { + key: K; + + constructor(key: K) { + this.key = key; + } + + abstract integrate(input: Input<unknown, K>): void; + abstract hasInput(): boolean; +} + +class Association<K extends Key> extends Entry<K> { + ids = []; + options = { + mode: UpdateMode.Add + }; + + constructor(key: K) { + super(key); + } + + integrate(input: Input<AssociationUpdate, K>) { + if (this.hasInput()) { + input[this.key] = { ids: this.ids, options: this.options }; + } + } + + hasInput() { + return this.ids.length > 0; + } +} + +class Enum<K extends Key> extends Entry<K> { + value?: string = undefined; + + constructor(key: K) { + super(key); + } + + integrate(input: Input<string, K>): void { + if (this.hasInput()) { + input[this.key] = this.value; + } + } + + hasInput() { + return this.value !== undefined && this.value !== null; + } +} + +abstract class Controls<I> { + toInput() { + const input = {} as I; + Object.values(this).forEach((v: Entry<keyof I>) => v.integrate(input)); + return input; + } + + hasInput() { + return Object.values(this).some((i: Entry<keyof I>) => i.hasInput()); + } +} + +export class UpdateTagsControls extends Controls<UpdateTagInput> { + namespaces = new Association('namespaces'); +} + +export class UpdateComicsControls extends Controls<UpdateComicInput> { + artists = new Association('artists'); + category = new Enum('category'); + censorship = new Enum('censorship'); + direction = new Enum('direction'); + layout = new Enum('layout'); + characters = new Association('characters'); + circles = new Association('circles'); + language = new Enum('language'); + rating = new Enum('rating'); + tags = new Association('tags'); + worlds = new Association('worlds'); +} diff --git a/frontend/src/lib/Utils.ts b/frontend/src/lib/Utils.ts new file mode 100644 index 0000000..1a07be1 --- /dev/null +++ b/frontend/src/lib/Utils.ts @@ -0,0 +1,108 @@ +import { isError } from '$gql/Utils'; +import type { ImageFragment } from '$gql/graphql'; +import type { BeforeNavigate } from '@sveltejs/kit'; +import type { OperationResultState } from '@urql/svelte'; +import { openModal } from 'svelte-modals'; +import ConfirmDeletion from './dialogs/ConfirmDeletion.svelte'; + +export function range(from: number, to: number) { + return Array.from({ length: to - from + 1 }, (_, k) => k + from); +} + +export function getRandomInt(min: number, max: number) { + const minCeiled = Math.ceil(min); + const maxFloored = Math.floor(max); + + return Math.floor(Math.random() * (maxFloored - minCeiled) + minCeiled); +} + +export interface ListItem { + id: number | string; + name: string; +} + +export interface ResultState { + fetching: boolean; + message?: string; +} + +export function getResultState(state: OperationResultState): ResultState { + let message: string | undefined; + + if (state.error) { + message = `${state.error.name}: ${state.error.message}`; + } else if (state.data) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument + const obj = Object.values(state.data)[0]; + if (isError(obj)) { + message = obj.message; + } + } + + return { fetching: state.fetching, message: message }; +} + +export function src(image: ImageFragment, type: 'full' | 'thumb' = 'thumb') { + const dir = image.hash.slice(0, 2); + const file = image.hash.slice(2); + + return `/objects/${dir}/${file}_${type}.webp`; +} + +export function numKeys(obj?: object | null, ignore: string[] = []) { + if (!obj) return 0; + + const len = Object.keys(obj).length; + let ignored = 0; + + for (const i of ignore) { + if (Object.hasOwn(obj, i)) ignored++; + } + + return len - ignored; +} + +export function confirmDeletion( + typename: string, + names: string | string[], + callback: () => void, + warning?: string +) { + openModal( + ConfirmDeletion, + { names: Array.isArray(names) ? names : [names], typename, callback: callback, warning }, + { replace: true } + ); +} + +export function idFromLabel(label: string) { + return label.toLowerCase().replaceAll(' ', '-'); +} + +export function pluralize(singular: string, size: number) { + return `${singular}${size > 1 ? 's' : ''}`; +} + +export function formatListSize(word: string, size: number) { + return `${size} ${pluralize(word, size)}`; +} + +export function joinText(items: string[], separator = ', ') { + return items.filter((i) => i).join(separator); +} + +export function confirmPending() { + return confirm('There are pending changes. Click Cancel to keep editing or OK to dismiss them.'); +} + +export function preventOnPending({ to, cancel }: BeforeNavigate, pending: boolean) { + if (!pending) return; + + if (to) { + if (confirmPending()) { + return; + } + } + + cancel(); +} diff --git a/frontend/src/lib/assets/logo.webp b/frontend/src/lib/assets/logo.webp Binary files differnew file mode 100644 index 0000000..e41cbb0 --- /dev/null +++ b/frontend/src/lib/assets/logo.webp diff --git a/frontend/src/lib/components/AddButton.svelte b/frontend/src/lib/components/AddButton.svelte new file mode 100644 index 0000000..9c0ab29 --- /dev/null +++ b/frontend/src/lib/components/AddButton.svelte @@ -0,0 +1,7 @@ +<script lang="ts"> + export let title: string; +</script> + +<button class="btn-blue" {title} on:click> + <span class="icon-base icon-[material-symbols--add]" /> +</button> diff --git a/frontend/src/lib/components/Badge.svelte b/frontend/src/lib/components/Badge.svelte new file mode 100644 index 0000000..7ad3173 --- /dev/null +++ b/frontend/src/lib/components/Badge.svelte @@ -0,0 +1,15 @@ +<script lang="ts"> + import { fadeDefault } from '$lib/Transitions'; + import { fade } from 'svelte/transition'; + + export let number: number; +</script> + +{#if number > 0} + <span + class="absolute -right-[3px] -top-[6px] z-[1] rounded-lg bg-teal-600 px-1 text-xs" + transition:fade={fadeDefault} + > + {number} + </span> +{/if} diff --git a/frontend/src/lib/components/BookmarkButton.svelte b/frontend/src/lib/components/BookmarkButton.svelte new file mode 100644 index 0000000..89570e6 --- /dev/null +++ b/frontend/src/lib/components/BookmarkButton.svelte @@ -0,0 +1,9 @@ +<script lang="ts"> + import Bookmark from '$lib/icons/Bookmark.svelte'; + + export let bookmarked: boolean; +</script> + +<button type="button" title="Toggle bookmark" class="flex text-base" on:click> + <Bookmark hoverable {bookmarked} /> +</button> diff --git a/frontend/src/lib/components/Card.svelte b/frontend/src/lib/components/Card.svelte new file mode 100644 index 0000000..2384799 --- /dev/null +++ b/frontend/src/lib/components/Card.svelte @@ -0,0 +1,106 @@ +<script lang="ts" context="module"> + import type { ComicFragment, ImageFragment } from '$gql/graphql'; + + interface CardDetails { + title: string; + favourite?: boolean; + subtitle?: string | null; + cover?: ImageFragment; + } + + export function comicCard(comic: ComicFragment) { + return { + href: `/comics/${comic.id.toString()}`, + details: { + title: comic.title, + subtitle: comic.originalTitle, + favourite: comic.favourite, + cover: comic.cover + } + }; + } +</script> + +<script lang="ts"> + import { src } from '$lib/Utils'; + import Star from '$lib/icons/Star.svelte'; + + export let href: string; + export let details: CardDetails; + export let compact = false; + export let coverOnly = false; + export let ellipsis = true; +</script> + +<a + {href} + class="grid-card-v sm:grid-card-h relative grid overflow-hidden rounded bg-slate-900 shadow-md shadow-slate-950/30" + class:compact + class:grid-card-cover-only={coverOnly} + on:click +> + <slot name="overlay" /> + {#if details.cover} + <img + class="h-full w-full object-cover object-[center_top]" + width={details.cover.width} + height={details.cover.height} + src={src(details.cover)} + alt="" + title={details.title} + /> + {/if} + {#if !coverOnly} + <article class="flex h-full flex-col gap-2 p-2"> + <header> + <h2 + class:ellipsis-nowrap={ellipsis} + class="self-center text-sm font-medium [grid-area:title]" + title={details.title} + > + {details.title} + </h2> + {#if details.subtitle} + <h3 + class="ellipsis-nowrap text-xs opacity-60 [grid-area:subtitle]" + title={details.subtitle} + > + {details.subtitle} + </h3> + {/if} + {#if details.favourite} + <div class="flex items-center text-lg [grid-area:fav]"> + <Star favourite /> + </div> + {/if} + </header> + + <section class="max-h-full grow overflow-auto border-t border-slate-800/80 pt-2 text-xs"> + <slot /> + </section> + </article> + {/if} +</a> + +<style> + a.compact { + grid-template-columns: 175px 1fr; + grid-template-rows: 250px; + } + + img { + border-start-start-radius: inherit; + border-end-start-radius: inherit; + } + + article > header { + display: grid; + + grid-template-columns: 1fr auto; + grid-template-rows: auto; + + grid-template-areas: + 'title fav' + 'subtitle fav'; + } +</style> diff --git a/frontend/src/lib/components/Cardlet.svelte b/frontend/src/lib/components/Cardlet.svelte new file mode 100644 index 0000000..04d8599 --- /dev/null +++ b/frontend/src/lib/components/Cardlet.svelte @@ -0,0 +1,37 @@ +<script lang="ts"> + import type { ComicFilter } from '$gql/graphql'; + import { href } from '$lib/Navigation'; + + export let name: string; + export let title: string | null | undefined = undefined; + + export let filter: keyof ComicFilter | undefined = undefined; + export let id: number | string | undefined = undefined; + + const handleAux = (e: MouseEvent) => { + if (filter === undefined || id === undefined || e.button !== 1) return; + window.open(href('comics', { filter: { include: { [filter]: { all: [id] } } } })); + }; +</script> + +<button + type="button" + class="relative flex overflow-hidden rounded bg-slate-900 text-left shadow-md shadow-slate-950/20" + {title} + on:click + on:auxclick={handleAux} +> + <slot name="overlay" /> + <article class="group h-full grow items-center gap-2 p-2 text-xs"> + <h2 class="ellipsis-nowrap text-sm font-medium">{name}</h2> + </article> +</button> + +<style> + article { + display: grid; + + grid-template-columns: 1fr auto; + grid-template-rows: 2em; + } +</style> diff --git a/frontend/src/lib/components/DeleteButton.svelte b/frontend/src/lib/components/DeleteButton.svelte new file mode 100644 index 0000000..8f5f116 --- /dev/null +++ b/frontend/src/lib/components/DeleteButton.svelte @@ -0,0 +1,15 @@ +<script> + import { accelerator } from '$lib/Shortcuts'; + + export let prominent = false; +</script> + +<button + type="button" + class={prominent ? 'btn-rose' : 'btn-slate hover:bg-rose-700'} + title="Delete forever" + on:click + use:accelerator={'Delete'} +> + <span class="icon-base icon-[material-symbols--delete-forever]" /> +</button> diff --git a/frontend/src/lib/components/Dialog.svelte b/frontend/src/lib/components/Dialog.svelte new file mode 100644 index 0000000..a0bbe5e --- /dev/null +++ b/frontend/src/lib/components/Dialog.svelte @@ -0,0 +1,36 @@ +<script lang="ts"> + import { trapFocus } from '$lib/Actions'; + import { fadeDefault } from '$lib/Transitions'; + import { closeModal } from 'svelte-modals'; + import { fade } from 'svelte/transition'; + + export let isOpen: boolean; +</script> + +{#if isOpen} + <div + role="dialog" + class="pointer-events-none fixed bottom-0 left-0 right-0 top-0 z-30 flex items-center justify-center" + transition:fade|global={fadeDefault} + use:trapFocus + > + <div + class="pointer-events-auto flex flex-col rounded-md bg-slate-800 shadow-md shadow-slate-900" + > + <header class="flex items-center gap-1 border-b-2 border-slate-700/50 p-2"> + <slot name="header" /> + <button + type="button" + class="ml-auto flex items-center text-white/30 hover:text-white" + title="Cancel" + on:click={closeModal} + > + <span class="icon-base icon-[material-symbols--close]" /> + </button> + </header> + <main class="m-3 w-80 sm:w-[34rem]"> + <slot /> + </main> + </div> + </div> +{/if} diff --git a/frontend/src/lib/components/Dropdown.svelte b/frontend/src/lib/components/Dropdown.svelte new file mode 100644 index 0000000..9e935e4 --- /dev/null +++ b/frontend/src/lib/components/Dropdown.svelte @@ -0,0 +1,18 @@ +<script lang="ts"> + import { clickOutside } from '$lib/Actions'; + import { fadeFast } from '$lib/Transitions'; + import { fade } from 'svelte/transition'; + + export let visible: boolean; + export let parent: HTMLElement; +</script> + +{#if visible} + <div + class="absolute z-[1] mt-1 w-max rounded bg-slate-700 p-1 shadow-sm shadow-slate-900" + transition:fade={fadeFast} + use:clickOutside={{ handler: () => (visible = false), ignore: parent }} + > + <slot /> + </div> +{/if} diff --git a/frontend/src/lib/components/Empty.svelte b/frontend/src/lib/components/Empty.svelte new file mode 100644 index 0000000..7f9557c --- /dev/null +++ b/frontend/src/lib/components/Empty.svelte @@ -0,0 +1,10 @@ +<script lang="ts"> + import logo from '$lib/assets/logo.webp'; +</script> + +<div class="col-span-full flex flex-col items-center text-4xl font-medium text-gray-600"> + <img src={logo} class="w-1/5 opacity-60 grayscale" alt="" /> + <div class="flex items-center gap-2"> + <h2>There is nothing here...</h2> + </div> +</div> diff --git a/frontend/src/lib/components/Expander.svelte b/frontend/src/lib/components/Expander.svelte new file mode 100644 index 0000000..a382658 --- /dev/null +++ b/frontend/src/lib/components/Expander.svelte @@ -0,0 +1,17 @@ +<script lang="ts"> + export let expanded: boolean; + export let title: string; +</script> + +<button + class="flex items-center text-base hover:text-white" + type="button" + on:click={() => (expanded = !expanded)} +> + {#if expanded} + <span class="icon-base icon-[material-symbols--expand-less]" /> + {:else} + <span class="icon-base icon-[material-symbols--expand-more]" /> + {/if} + {title} +</button> diff --git a/frontend/src/lib/components/Guard.svelte b/frontend/src/lib/components/Guard.svelte new file mode 100644 index 0000000..fd7ded4 --- /dev/null +++ b/frontend/src/lib/components/Guard.svelte @@ -0,0 +1,13 @@ +<script lang="ts"> + import { getResultState } from '$lib/Utils'; + import Spinner from './Spinner.svelte'; + + export let result; + $: state = getResultState($result); +</script> + +{#if state.fetching} + <Spinner /> +{:else} + <p>{state.message}</p> +{/if} diff --git a/frontend/src/lib/components/Head.svelte b/frontend/src/lib/components/Head.svelte new file mode 100644 index 0000000..b4aed5b --- /dev/null +++ b/frontend/src/lib/components/Head.svelte @@ -0,0 +1,12 @@ +<script lang="ts"> + export let section: string; + export let title = ''; + + function formatTitle(section: string, title?: string) { + return [title, section, 'hircine'].filter((i) => i).join(' · '); + } +</script> + +<svelte:head> + <title>{formatTitle(section, title)}</title> +</svelte:head> diff --git a/frontend/src/lib/components/Labelled.svelte b/frontend/src/lib/components/Labelled.svelte new file mode 100644 index 0000000..4b36ad6 --- /dev/null +++ b/frontend/src/lib/components/Labelled.svelte @@ -0,0 +1,10 @@ +<script lang="ts"> + import { idFromLabel } from '$lib/Utils'; + + export let label: string; + + const id = idFromLabel(label); +</script> + +<label class="self-center" for={id}>{label}</label> +<slot {id} /> diff --git a/frontend/src/lib/components/LabelledBlock.svelte b/frontend/src/lib/components/LabelledBlock.svelte new file mode 100644 index 0000000..feb563e --- /dev/null +++ b/frontend/src/lib/components/LabelledBlock.svelte @@ -0,0 +1,18 @@ +<script lang="ts"> + import { idFromLabel } from '$lib/Utils'; + + export let label: string; + + const id = idFromLabel(label); +</script> + +<div class="flex flex-col"> + <div class="flex"> + <label for={id}>{label}</label> + {#if $$slots.controls} + <div class="grow" /> + <slot name="controls" /> + {/if} + </div> + <slot {id} /> +</div> diff --git a/frontend/src/lib/components/OrganizedButton.svelte b/frontend/src/lib/components/OrganizedButton.svelte new file mode 100644 index 0000000..9be985c --- /dev/null +++ b/frontend/src/lib/components/OrganizedButton.svelte @@ -0,0 +1,9 @@ +<script lang="ts"> + import Organized from '$lib/icons/Organized.svelte'; + + export let organized: boolean; +</script> + +<button type="button" title="Toggle organized" class="flex text-base" on:click> + <Organized hoverable {organized} /> +</button> diff --git a/frontend/src/lib/components/RefreshButton.svelte b/frontend/src/lib/components/RefreshButton.svelte new file mode 100644 index 0000000..afab640 --- /dev/null +++ b/frontend/src/lib/components/RefreshButton.svelte @@ -0,0 +1,3 @@ +<button class="btn-blue" title="Refresh" on:click> + <span class="icon-base icon-[material-symbols--sync]" /> +</button> diff --git a/frontend/src/lib/components/RemovePageButton.svelte b/frontend/src/lib/components/RemovePageButton.svelte new file mode 100644 index 0000000..e23c079 --- /dev/null +++ b/frontend/src/lib/components/RemovePageButton.svelte @@ -0,0 +1,13 @@ +<script lang="ts"> + import { accelerator } from '$lib/Shortcuts'; +</script> + +<button + type="button" + class="btn-rose" + title="Remove selected pages" + on:click + use:accelerator={'Delete'} +> + <span class="icon-base icon-[material-symbols--scan-delete]" /> +</button> diff --git a/frontend/src/lib/components/Select.svelte b/frontend/src/lib/components/Select.svelte new file mode 100644 index 0000000..83f026c --- /dev/null +++ b/frontend/src/lib/components/Select.svelte @@ -0,0 +1,55 @@ +<script lang="ts"> + import type { ListItem } from '$lib/Utils'; + /* eslint-disable @typescript-eslint/ban-ts-comment, @typescript-eslint/no-explicit-any */ + + // @ts-ignore + import Svelecte from 'svelecte'; + + let inputId: string; + let valueAsObject = false; + let multiple = false; + + type Value = (number | string | ListItem)[] | number | string | ListItem | undefined | null; + + export let clearable = false; + export let placeholder = 'Select...'; + export let options: ListItem[] | undefined; + export let value: Value; + + export { inputId as id, valueAsObject as object, multiple as multi }; + + function optionsPlaceholder(from: Value) { + if (from === undefined || from === null) return []; + + return Array.isArray(from) ? value : [value]; + } +</script> + +{#if options !== null && options !== undefined} + <Svelecte + virtualList + valueField="id" + labelField="name" + {options} + {multiple} + {clearable} + {inputId} + {valueAsObject} + {placeholder} + bind:value + /> +{:else} + <Svelecte + virtualList + valueField="id" + labelField="name" + disabled + options={optionsPlaceholder(value)} + {multiple} + {clearable} + {inputId} + {valueAsObject} + {placeholder} + {value} + /> +{/if} diff --git a/frontend/src/lib/components/Spinner.svelte b/frontend/src/lib/components/Spinner.svelte new file mode 100644 index 0000000..946329c --- /dev/null +++ b/frontend/src/lib/components/Spinner.svelte @@ -0,0 +1,36 @@ +<script lang="ts"> + import { onDestroy } from 'svelte'; + + let show = false; + const timeout = setTimeout(() => (show = true), 150); + + onDestroy(() => clearTimeout(timeout)); +</script> + +{#if show} + <div class="flex h-full w-full items-center justify-center"> + <span class="spinner" /> + </div> +{/if} + +<style lang="postcss"> + .spinner { + width: 64px; + height: 64px; + border: 5px solid theme(colors.gray.200); + border-bottom-color: transparent; + border-radius: 50%; + display: inline-block; + box-sizing: border-box; + animation: rotation 1s linear infinite; + } + + @keyframes rotation { + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(360deg); + } + } +</style> diff --git a/frontend/src/lib/components/SubmitButton.svelte b/frontend/src/lib/components/SubmitButton.svelte new file mode 100644 index 0000000..8ac90b9 --- /dev/null +++ b/frontend/src/lib/components/SubmitButton.svelte @@ -0,0 +1,7 @@ +<script lang="ts"> + export let active = false; + + $: title = active ? 'Save pending changes' : 'Save (no changes pending)'; +</script> + +<button type="submit" class:active class="btn-slate [&.active]:btn-blue" {title}>Save</button> diff --git a/frontend/src/lib/components/Titlebar.svelte b/frontend/src/lib/components/Titlebar.svelte new file mode 100644 index 0000000..8aab2dd --- /dev/null +++ b/frontend/src/lib/components/Titlebar.svelte @@ -0,0 +1,32 @@ +<script lang="ts"> + import Star from '$lib/icons/Star.svelte'; + import { createEventDispatcher } from 'svelte'; + + export let title: string; + export let subtitle: string | null = ''; + export let favourite: boolean | undefined = undefined; + + const dispatch = createEventDispatcher<{ favourite: null }>(); +</script> + +<div class="flex flex-wrap gap-x-4"> + <div class="flex overflow-hidden"> + {#if favourite !== undefined} + <button + type="button" + class="mr-1 flex items-center" + title="Toggle favourite" + on:click={() => dispatch('favourite')} + > + <Star large hoverable {favourite} /> + </button> + {/if} + <h1 class="xl:ellipsis-nowrap text-2xl font-semibold">{title}</h1> + </div> + + {#if subtitle} + <h2 class="xl:ellipsis-nowrap self-end text-lg font-light text-gray-400"> + {subtitle} + </h2> + {/if} +</div> diff --git a/frontend/src/lib/containers/Cardlets.svelte b/frontend/src/lib/containers/Cardlets.svelte new file mode 100644 index 0000000..129da61 --- /dev/null +++ b/frontend/src/lib/containers/Cardlets.svelte @@ -0,0 +1,11 @@ +<script> + import { fadeDefault } from '$lib/Transitions'; + import { fade } from 'svelte/transition'; +</script> + +<div + class="grid gap-4 sm:grid-cols-3 lg:grid-cols-4 xl:grid-cols-6 min-[1600px]:grid-cols-8 min-[1920px]:grid-cols-10" + in:fade={fadeDefault} +> + <slot /> +</div> diff --git a/frontend/src/lib/containers/Cards.svelte b/frontend/src/lib/containers/Cards.svelte new file mode 100644 index 0000000..a19e8be --- /dev/null +++ b/frontend/src/lib/containers/Cards.svelte @@ -0,0 +1,8 @@ +<script> + import { fadeDefault } from '$lib/Transitions'; + import { fade } from 'svelte/transition'; +</script> + +<div class="grid gap-4 xl:grid-cols-2 min-[1920px]:grid-cols-3" in:fade|global={fadeDefault}> + <slot /> +</div> diff --git a/frontend/src/lib/containers/Carousel.svelte b/frontend/src/lib/containers/Carousel.svelte new file mode 100644 index 0000000..1268a78 --- /dev/null +++ b/frontend/src/lib/containers/Carousel.svelte @@ -0,0 +1,15 @@ +<script lang="ts"> + export let title: string; + export let href: string; +</script> + +<div class="flex flex-col gap-1"> + <h2 class="flex text-2xl font-medium"> + <a class="hover:text-white" {href}> + {title} + </a> + </h2> + <div class="flex flex-wrap gap-5"> + <slot /> + </div> +</div> diff --git a/frontend/src/lib/containers/Column.svelte b/frontend/src/lib/containers/Column.svelte new file mode 100644 index 0000000..05daece --- /dev/null +++ b/frontend/src/lib/containers/Column.svelte @@ -0,0 +1,3 @@ +<div class="flex flex-col gap-4"> + <slot /> +</div> diff --git a/frontend/src/lib/containers/Grid.svelte b/frontend/src/lib/containers/Grid.svelte new file mode 100644 index 0000000..1224156 --- /dev/null +++ b/frontend/src/lib/containers/Grid.svelte @@ -0,0 +1,23 @@ +<script> + import { fadeDefault } from '$lib/Transitions'; + + import { fade } from 'svelte/transition'; +</script> + +<div + class="flex flex-col gap-1 lg:grid lg:h-full lg:max-h-full lg:overflow-auto" + in:fade|global={fadeDefault} +> + <slot /> +</div> + +<style> + div { + grid-template-columns: auto 1fr; + grid-template-rows: auto 1fr; + + grid-template-areas: + 'header header' + 'sidebar main'; + } +</style> diff --git a/frontend/src/lib/dialogs/AddArtist.svelte b/frontend/src/lib/dialogs/AddArtist.svelte new file mode 100644 index 0000000..6ec93c5 --- /dev/null +++ b/frontend/src/lib/dialogs/AddArtist.svelte @@ -0,0 +1,30 @@ +<script lang="ts"> + import { addArtist, type ArtistInput } from '$gql/Mutations'; + import Dialog from '$lib/components/Dialog.svelte'; + import SubmitButton from '$lib/components/SubmitButton.svelte'; + import ArtistForm from '$lib/forms/ArtistForm.svelte'; + import { toastFinally } from '$lib/Toasts'; + import { getContextClient } from '@urql/svelte'; + import { closeModal } from 'svelte-modals'; + + const client = getContextClient(); + + export let isOpen: boolean; + + let artist = { name: '' }; + + function add(event: CustomEvent<ArtistInput>) { + addArtist(client, { input: event.detail }).then(closeModal).catch(toastFinally); + } +</script> + +<Dialog {isOpen}> + <svelte:fragment slot="header"> + <h2>Add Artist</h2> + </svelte:fragment> + <ArtistForm bind:artist on:submit={add}> + <div class="flex justify-end gap-4"> + <SubmitButton active={artist.name.length > 0} /> + </div> + </ArtistForm> +</Dialog> diff --git a/frontend/src/lib/dialogs/AddCharacter.svelte b/frontend/src/lib/dialogs/AddCharacter.svelte new file mode 100644 index 0000000..23fea08 --- /dev/null +++ b/frontend/src/lib/dialogs/AddCharacter.svelte @@ -0,0 +1,30 @@ +<script lang="ts"> + import { addCharacter, type CharacterInput } from '$gql/Mutations'; + import Dialog from '$lib/components/Dialog.svelte'; + import SubmitButton from '$lib/components/SubmitButton.svelte'; + import CharacterForm from '$lib/forms/CharacterForm.svelte'; + import { toastFinally } from '$lib/Toasts'; + import { getContextClient } from '@urql/svelte'; + import { closeModal } from 'svelte-modals'; + + const client = getContextClient(); + + export let isOpen: boolean; + + let character = { name: '' }; + + function add(event: CustomEvent<CharacterInput>) { + addCharacter(client, { input: event.detail }).then(closeModal).catch(toastFinally); + } +</script> + +<Dialog {isOpen}> + <svelte:fragment slot="header"> + <h2>Add Character</h2> + </svelte:fragment> + <CharacterForm bind:character on:submit={add}> + <div class="flex justify-end gap-4"> + <SubmitButton active={character.name.length > 0} /> + </div> + </CharacterForm> +</Dialog> diff --git a/frontend/src/lib/dialogs/AddCircle.svelte b/frontend/src/lib/dialogs/AddCircle.svelte new file mode 100644 index 0000000..f0ef014 --- /dev/null +++ b/frontend/src/lib/dialogs/AddCircle.svelte @@ -0,0 +1,30 @@ +<script lang="ts"> + import { addCircle, type CircleInput } from '$gql/Mutations'; + import Dialog from '$lib/components/Dialog.svelte'; + import SubmitButton from '$lib/components/SubmitButton.svelte'; + import CircleForm from '$lib/forms/CircleForm.svelte'; + import { toastFinally } from '$lib/Toasts'; + import { getContextClient } from '@urql/svelte'; + import { closeModal } from 'svelte-modals'; + + const client = getContextClient(); + + export let isOpen: boolean; + + let circle = { name: '' }; + + function add(event: CustomEvent<CircleInput>) { + addCircle(client, { input: event.detail }).then(closeModal).catch(toastFinally); + } +</script> + +<Dialog {isOpen}> + <svelte:fragment slot="header"> + <h2>Add Circle</h2> + </svelte:fragment> + <CircleForm bind:circle on:submit={add}> + <div class="flex justify-end gap-4"> + <SubmitButton active={circle.name.length > 0} /> + </div> + </CircleForm> +</Dialog> diff --git a/frontend/src/lib/dialogs/AddNamespace.svelte b/frontend/src/lib/dialogs/AddNamespace.svelte new file mode 100644 index 0000000..e81b22a --- /dev/null +++ b/frontend/src/lib/dialogs/AddNamespace.svelte @@ -0,0 +1,30 @@ +<script lang="ts"> + import { addNamespace, type NamespaceInput } from '$gql/Mutations'; + import Dialog from '$lib/components/Dialog.svelte'; + import SubmitButton from '$lib/components/SubmitButton.svelte'; + import NamespaceForm from '$lib/forms/NamespaceForm.svelte'; + import { toastFinally } from '$lib/Toasts'; + import { getContextClient } from '@urql/svelte'; + import { closeModal } from 'svelte-modals'; + + const client = getContextClient(); + + export let isOpen: boolean; + + let namespace = { name: '' }; + + function add(event: CustomEvent<NamespaceInput>) { + addNamespace(client, { input: event.detail }).then(closeModal).catch(toastFinally); + } +</script> + +<Dialog {isOpen}> + <svelte:fragment slot="header"> + <h2>Add Namespace</h2> + </svelte:fragment> + <NamespaceForm bind:namespace on:submit={add}> + <div class="flex justify-end gap-4"> + <SubmitButton active={namespace.name.length > 0} /> + </div> + </NamespaceForm> +</Dialog> diff --git a/frontend/src/lib/dialogs/AddTag.svelte b/frontend/src/lib/dialogs/AddTag.svelte new file mode 100644 index 0000000..00d3a03 --- /dev/null +++ b/frontend/src/lib/dialogs/AddTag.svelte @@ -0,0 +1,30 @@ +<script lang="ts"> + import { addTag, type TagInput } from '$gql/Mutations'; + import Dialog from '$lib/components/Dialog.svelte'; + import SubmitButton from '$lib/components/SubmitButton.svelte'; + import TagForm from '$lib/forms/TagForm.svelte'; + import { toastFinally } from '$lib/Toasts'; + import { getContextClient } from '@urql/svelte'; + import { closeModal } from 'svelte-modals'; + + const client = getContextClient(); + + export let isOpen: boolean; + + let tag = { name: '', namespaces: [] }; + + function add(event: CustomEvent<TagInput>) { + addTag(client, { input: event.detail }).then(closeModal).catch(toastFinally); + } +</script> + +<Dialog {isOpen}> + <svelte:fragment slot="header"> + <h2>Add Tag</h2> + </svelte:fragment> + <TagForm bind:tag on:submit={add}> + <div class="flex justify-end gap-4"> + <SubmitButton active={tag.name.length > 0} /> + </div> + </TagForm> +</Dialog> diff --git a/frontend/src/lib/dialogs/AddWorld.svelte b/frontend/src/lib/dialogs/AddWorld.svelte new file mode 100644 index 0000000..ceb946e --- /dev/null +++ b/frontend/src/lib/dialogs/AddWorld.svelte @@ -0,0 +1,30 @@ +<script lang="ts"> + import { addWorld, type WorldInput } from '$gql/Mutations'; + import Dialog from '$lib/components/Dialog.svelte'; + import SubmitButton from '$lib/components/SubmitButton.svelte'; + import WorldForm from '$lib/forms/WorldForm.svelte'; + import { toastFinally } from '$lib/Toasts'; + import { getContextClient } from '@urql/svelte'; + import { closeModal } from 'svelte-modals'; + + const client = getContextClient(); + + export let isOpen: boolean; + + let world = { name: '' }; + + function add(event: CustomEvent<WorldInput>) { + addWorld(client, { input: event.detail }).then(closeModal).catch(toastFinally); + } +</script> + +<Dialog {isOpen}> + <svelte:fragment slot="header"> + <h2>Add World</h2> + </svelte:fragment> + <WorldForm bind:world on:submit={add}> + <div class="flex justify-end gap-4"> + <SubmitButton active={world.name.length > 0} /> + </div> + </WorldForm> +</Dialog> diff --git a/frontend/src/lib/dialogs/ConfirmDeletion.svelte b/frontend/src/lib/dialogs/ConfirmDeletion.svelte new file mode 100644 index 0000000..6b0cbf8 --- /dev/null +++ b/frontend/src/lib/dialogs/ConfirmDeletion.svelte @@ -0,0 +1,51 @@ +<script lang="ts"> + import { accelerator } from '$lib/Shortcuts'; + import Dialog from '$lib/components/Dialog.svelte'; + import { closeModal } from 'svelte-modals'; + + export let isOpen: boolean; + export let callback: () => void; + + export let names: string[]; + export let typename: string; + export let warning: string | undefined = undefined; + const multiple = names.length > 1; + const formattedTypename = multiple ? `${typename}s` : typename; + const formattedNames = multiple ? `${names.length} ${formattedTypename}` : names[0]; + + function confirm() { + callback(); + closeModal(); + } +</script> + +<Dialog {isOpen}> + <svelte:fragment slot="header"> + <h2>Delete {formattedTypename}</h2> + </svelte:fragment> + <form on:submit|preventDefault={confirm}> + <div class="flex flex-col"> + <p class="mb-3"> + Are you sure you want to delete <span class="font-semibold">{formattedNames}</span>? + </p> + {#if multiple} + <ul class="mb-3 ml-8 list-disc"> + {#each names.slice(0, 10) as name} + <li>{name}</li> + {/each} + </ul> + {#if names.length - 10 > 0} + <p>... and {names.length - 10} more.</p> + {/if} + {/if} + {#if warning} + <p class="font-medium text-red-600">Warning: {warning}</p> + {/if} + </div> + + <div class="flex justify-end gap-4"> + <button type="submit" class="btn-rose" use:accelerator={'Enter'}>Delete</button> + <button type="button" on:click={closeModal} class="btn-slate">Cancel</button> + </div> + </form> +</Dialog> diff --git a/frontend/src/lib/dialogs/EditArtist.svelte b/frontend/src/lib/dialogs/EditArtist.svelte new file mode 100644 index 0000000..dd08bc6 --- /dev/null +++ b/frontend/src/lib/dialogs/EditArtist.svelte @@ -0,0 +1,46 @@ +<script lang="ts"> + import { deleteArtists, updateArtists, type ArtistInput } from '$gql/Mutations'; + import { itemEquals } from '$gql/Utils'; + import { type Artist } from '$gql/graphql'; + import { toastFinally } from '$lib/Toasts'; + import { confirmDeletion } from '$lib/Utils'; + import DeleteButton from '$lib/components/DeleteButton.svelte'; + import Dialog from '$lib/components/Dialog.svelte'; + import SubmitButton from '$lib/components/SubmitButton.svelte'; + import ArtistForm from '$lib/forms/ArtistForm.svelte'; + import { getContextClient } from '@urql/svelte'; + import { closeModal } from 'svelte-modals'; + + const client = getContextClient(); + + export let isOpen: boolean; + + export let artist: Artist; + const original = structuredClone(artist); + $: pending = !itemEquals(artist, original); + + function save(event: CustomEvent<ArtistInput>) { + updateArtists(client, { ids: artist.id, input: event.detail }) + .then(closeModal) + .catch(toastFinally); + } + + function deleteArtist() { + confirmDeletion('Artist', artist.name, () => { + deleteArtists(client, { ids: artist.id }).then(closeModal).catch(toastFinally); + }); + } +</script> + +<Dialog {isOpen}> + <svelte:fragment slot="header"> + <h2>Edit Artist</h2> + </svelte:fragment> + <ArtistForm bind:artist on:submit={save}> + <div class="flex gap-4"> + <DeleteButton on:click={deleteArtist} /> + <div class="grow" /> + <SubmitButton active={pending} /> + </div> + </ArtistForm> +</Dialog> diff --git a/frontend/src/lib/dialogs/EditCharacter.svelte b/frontend/src/lib/dialogs/EditCharacter.svelte new file mode 100644 index 0000000..3b45e78 --- /dev/null +++ b/frontend/src/lib/dialogs/EditCharacter.svelte @@ -0,0 +1,46 @@ +<script lang="ts"> + import { deleteCharacters, updateCharacters, type CharacterInput } from '$gql/Mutations'; + import { itemEquals } from '$gql/Utils'; + import { type Character } from '$gql/graphql'; + import { toastFinally } from '$lib/Toasts'; + import { confirmDeletion } from '$lib/Utils'; + import DeleteButton from '$lib/components/DeleteButton.svelte'; + import Dialog from '$lib/components/Dialog.svelte'; + import SubmitButton from '$lib/components/SubmitButton.svelte'; + import CharacterForm from '$lib/forms/CharacterForm.svelte'; + import { getContextClient } from '@urql/svelte'; + import { closeModal } from 'svelte-modals'; + + const client = getContextClient(); + + export let isOpen: boolean; + + export let character: Character; + const original = structuredClone(character); + $: pending = !itemEquals(original, character); + + function save(event: CustomEvent<CharacterInput>) { + updateCharacters(client, { ids: character.id, input: event.detail }) + .then(closeModal) + .catch(toastFinally); + } + + function deleteCharacter() { + confirmDeletion('Character', character.name, () => { + deleteCharacters(client, { ids: character.id }).then(closeModal).catch(toastFinally); + }); + } +</script> + +<Dialog {isOpen}> + <svelte:fragment slot="header"> + <h2>Edit Character</h2> + </svelte:fragment> + <CharacterForm bind:character on:submit={save}> + <div class="flex gap-4"> + <DeleteButton on:click={deleteCharacter} /> + <div class="grow" /> + <SubmitButton active={pending} /> + </div> + </CharacterForm> +</Dialog> diff --git a/frontend/src/lib/dialogs/EditCircle.svelte b/frontend/src/lib/dialogs/EditCircle.svelte new file mode 100644 index 0000000..bdc1217 --- /dev/null +++ b/frontend/src/lib/dialogs/EditCircle.svelte @@ -0,0 +1,46 @@ +<script lang="ts"> + import { deleteCircles, updateCircles, type CircleInput } from '$gql/Mutations'; + import { itemEquals } from '$gql/Utils'; + import { type Circle } from '$gql/graphql'; + import { toastFinally } from '$lib/Toasts'; + import { confirmDeletion } from '$lib/Utils'; + import DeleteButton from '$lib/components/DeleteButton.svelte'; + import Dialog from '$lib/components/Dialog.svelte'; + import SubmitButton from '$lib/components/SubmitButton.svelte'; + import CircleForm from '$lib/forms/CircleForm.svelte'; + import { getContextClient } from '@urql/svelte'; + import { closeModal } from 'svelte-modals'; + + const client = getContextClient(); + + export let isOpen: boolean; + + export let circle: Circle; + const original = structuredClone(circle); + $: pending = !itemEquals(original, circle); + + function save(event: CustomEvent<CircleInput>) { + updateCircles(client, { ids: circle.id, input: event.detail }) + .then(closeModal) + .catch(toastFinally); + } + + function deleteCircle() { + confirmDeletion('Circle', circle.name, () => { + deleteCircles(client, { ids: circle.id }).then(closeModal).catch(toastFinally); + }); + } +</script> + +<Dialog {isOpen}> + <svelte:fragment slot="header"> + <h2>Edit Circle</h2> + </svelte:fragment> + <CircleForm bind:circle on:submit={save}> + <div class="flex gap-4"> + <DeleteButton on:click={deleteCircle} /> + <div class="grow" /> + <SubmitButton active={pending} /> + </div> + </CircleForm> +</Dialog> diff --git a/frontend/src/lib/dialogs/EditNamespace.svelte b/frontend/src/lib/dialogs/EditNamespace.svelte new file mode 100644 index 0000000..f398b21 --- /dev/null +++ b/frontend/src/lib/dialogs/EditNamespace.svelte @@ -0,0 +1,46 @@ +<script lang="ts"> + import { deleteNamespaces, updateNamespaces, type NamespaceInput } from '$gql/Mutations'; + import { itemEquals } from '$gql/Utils'; + import { type Namespace } from '$gql/graphql'; + import { toastFinally } from '$lib/Toasts'; + import { confirmDeletion } from '$lib/Utils'; + import DeleteButton from '$lib/components/DeleteButton.svelte'; + import Dialog from '$lib/components/Dialog.svelte'; + import SubmitButton from '$lib/components/SubmitButton.svelte'; + import NamespaceForm from '$lib/forms/NamespaceForm.svelte'; + import { getContextClient } from '@urql/svelte'; + import { closeModal } from 'svelte-modals'; + + const client = getContextClient(); + + export let isOpen: boolean; + + export let namespace: Namespace; + const original = structuredClone(namespace); + $: pending = !itemEquals(original, namespace); + + function save(event: CustomEvent<NamespaceInput>) { + updateNamespaces(client, { ids: namespace.id, input: event.detail }) + .then(closeModal) + .catch(toastFinally); + } + + function deleteNamespace() { + confirmDeletion('Namespace', namespace.name, () => { + deleteNamespaces(client, { ids: namespace.id }).then(closeModal).catch(toastFinally); + }); + } +</script> + +<Dialog {isOpen}> + <svelte:fragment slot="header"> + <h2>Edit Namespace</h2> + </svelte:fragment> + <NamespaceForm bind:namespace on:submit={save}> + <div class="flex gap-4"> + <DeleteButton on:click={deleteNamespace} /> + <div class="grow" /> + <SubmitButton active={pending} /> + </div> + </NamespaceForm> +</Dialog> diff --git a/frontend/src/lib/dialogs/EditTag.svelte b/frontend/src/lib/dialogs/EditTag.svelte new file mode 100644 index 0000000..d2d0013 --- /dev/null +++ b/frontend/src/lib/dialogs/EditTag.svelte @@ -0,0 +1,44 @@ +<script lang="ts"> + import { deleteTags, updateTags, type TagInput } from '$gql/Mutations'; + import { tagEquals } from '$gql/Utils'; + import { type FullTag } from '$gql/graphql'; + import { toastFinally } from '$lib/Toasts'; + import { confirmDeletion } from '$lib/Utils'; + import DeleteButton from '$lib/components/DeleteButton.svelte'; + import Dialog from '$lib/components/Dialog.svelte'; + import SubmitButton from '$lib/components/SubmitButton.svelte'; + import TagForm from '$lib/forms/TagForm.svelte'; + import { getContextClient } from '@urql/svelte'; + import { closeModal } from 'svelte-modals'; + + const client = getContextClient(); + + export let isOpen: boolean; + + export let tag: FullTag; + const original = structuredClone(tag); + $: pending = !tagEquals(original, tag); + + function save(event: CustomEvent<TagInput>) { + updateTags(client, { ids: tag.id, input: event.detail }).then(closeModal).catch(toastFinally); + } + + function deleteTag() { + confirmDeletion('Tag', tag.name, () => { + deleteTags(client, { ids: tag.id }).then(closeModal).catch(toastFinally); + }); + } +</script> + +<Dialog {isOpen}> + <svelte:fragment slot="header"> + <h2>Edit Tag</h2> + </svelte:fragment> + <TagForm bind:tag on:submit={save}> + <div class="flex gap-4"> + <DeleteButton on:click={deleteTag} /> + <div class="grow" /> + <SubmitButton active={pending} /> + </div> + </TagForm> +</Dialog> diff --git a/frontend/src/lib/dialogs/EditWorld.svelte b/frontend/src/lib/dialogs/EditWorld.svelte new file mode 100644 index 0000000..82afe6a --- /dev/null +++ b/frontend/src/lib/dialogs/EditWorld.svelte @@ -0,0 +1,46 @@ +<script lang="ts"> + import { type World } from '$gql/graphql'; + import { deleteWorlds, updateWorlds, type WorldInput } from '$gql/Mutations'; + import { itemEquals } from '$gql/Utils'; + import DeleteButton from '$lib/components/DeleteButton.svelte'; + import Dialog from '$lib/components/Dialog.svelte'; + import SubmitButton from '$lib/components/SubmitButton.svelte'; + import WorldForm from '$lib/forms/WorldForm.svelte'; + import { toastFinally } from '$lib/Toasts'; + import { confirmDeletion } from '$lib/Utils'; + import { getContextClient } from '@urql/svelte'; + import { closeModal } from 'svelte-modals'; + + const client = getContextClient(); + + export let isOpen: boolean; + + export let world: World; + const original = structuredClone(world); + $: pending = !itemEquals(original, world); + + function save(event: CustomEvent<WorldInput>) { + updateWorlds(client, { ids: world.id, input: event.detail }) + .then(closeModal) + .catch(toastFinally); + } + + function deleteWorld() { + confirmDeletion('World', world.name, () => { + deleteWorlds(client, { ids: world.id }).then(closeModal).catch(toastFinally); + }); + } +</script> + +<Dialog {isOpen}> + <svelte:fragment slot="header"> + <h2>Edit World</h2> + </svelte:fragment> + <WorldForm bind:world on:submit={save}> + <div class="flex gap-4"> + <DeleteButton on:click={deleteWorld} /> + <div class="grow" /> + <SubmitButton active={pending} /> + </div> + </WorldForm> +</Dialog> diff --git a/frontend/src/lib/dialogs/UpdateComics.svelte b/frontend/src/lib/dialogs/UpdateComics.svelte new file mode 100644 index 0000000..8de9622 --- /dev/null +++ b/frontend/src/lib/dialogs/UpdateComics.svelte @@ -0,0 +1,96 @@ +<script lang="ts"> + import { updateComics } from '$gql/Mutations'; + import { artistList, characterList, circleList, comicTagList, worldList } from '$gql/Queries'; + import { categories, censorships, directions, languages, layouts, ratings } from '$lib/Enums'; + import { toastFinally } from '$lib/Toasts'; + import { UpdateComicsControls } from '$lib/Update'; + import Dialog from '$lib/components/Dialog.svelte'; + import Labelled from '$lib/components/Labelled.svelte'; + import LabelledBlock from '$lib/components/LabelledBlock.svelte'; + import Select from '$lib/components/Select.svelte'; + import SubmitButton from '$lib/components/SubmitButton.svelte'; + import { getContextClient } from '@urql/svelte'; + import { closeModal } from 'svelte-modals'; + import UpdateModeSelector from './components/UpdateModeSelector.svelte'; + + const client = getContextClient(); + + export let isOpen: boolean; + export let ids: number[]; + + $: tagsQuery = comicTagList(client); + $: artistsQuery = artistList(client); + $: charactersQuery = characterList(client); + $: circlesQuery = circleList(client); + $: worldsQuery = worldList(client); + + $: tags = $tagsQuery.data?.comicTags.edges; + $: artists = $artistsQuery.data?.artists.edges; + $: characters = $charactersQuery.data?.characters.edges; + $: circles = $circlesQuery.data?.circles.edges; + $: worlds = $worldsQuery.data?.worlds.edges; + + const controls = new UpdateComicsControls(); + + const update = () => { + updateComics(client, { + ids: ids, + input: controls.toInput() + }) + .then(closeModal) + .catch(toastFinally); + }; +</script> + +<Dialog {isOpen}> + <svelte:fragment slot="header"> + <h2>Edit Comics</h2> + </svelte:fragment> + <form on:submit|preventDefault={update}> + <div class="grid-labels"> + <Labelled label="Category" let:id> + <Select clearable {id} options={categories} bind:value={controls.category.value} /> + </Labelled> + <Labelled label="Rating" let:id> + <Select clearable {id} options={ratings} bind:value={controls.rating.value} /> + </Labelled> + <Labelled label="Censorship" let:id> + <Select clearable {id} options={censorships} bind:value={controls.censorship.value} /> + </Labelled> + <Labelled label="Language" let:id> + <Select clearable {id} options={languages} bind:value={controls.language.value} /> + </Labelled> + <Labelled label="Direction" let:id> + <Select clearable {id} options={directions} bind:value={controls.direction.value} /> + </Labelled> + <Labelled label="Layout" let:id> + <Select clearable {id} options={layouts} bind:value={controls.layout.value} /> + </Labelled> + </div> + + <LabelledBlock label="Artists" let:id> + <Select multi {id} options={artists} bind:value={controls.artists.ids} /> + <UpdateModeSelector bind:mode={controls.artists.options.mode} slot="controls" /> + </LabelledBlock> + <LabelledBlock label="Circles" let:id> + <Select multi {id} options={circles} bind:value={controls.circles.ids} /> + <UpdateModeSelector bind:mode={controls.circles.options.mode} slot="controls" /> + </LabelledBlock> + <LabelledBlock label="Characters" let:id> + <Select multi {id} options={characters} bind:value={controls.characters.ids} /> + <UpdateModeSelector bind:mode={controls.characters.options.mode} slot="controls" /> + </LabelledBlock> + <LabelledBlock label="Worlds" let:id> + <Select multi {id} options={worlds} bind:value={controls.worlds.ids} /> + <UpdateModeSelector bind:mode={controls.worlds.options.mode} slot="controls" /> + </LabelledBlock> + <LabelledBlock label="Tags" let:id> + <Select multi {id} options={tags} bind:value={controls.tags.ids} /> + <UpdateModeSelector bind:mode={controls.tags.options.mode} slot="controls" /> + </LabelledBlock> + + <div class="flex justify-end gap-4"> + <SubmitButton active={controls.hasInput()} /> + </div> + </form> +</Dialog> diff --git a/frontend/src/lib/dialogs/UpdateTags.svelte b/frontend/src/lib/dialogs/UpdateTags.svelte new file mode 100644 index 0000000..f753c7f --- /dev/null +++ b/frontend/src/lib/dialogs/UpdateTags.svelte @@ -0,0 +1,45 @@ +<script lang="ts"> + import { updateTags } from '$gql/Mutations'; + import { namespaceList } from '$gql/Queries'; + import { toastFinally } from '$lib/Toasts'; + import { UpdateTagsControls } from '$lib/Update'; + import Dialog from '$lib/components/Dialog.svelte'; + import LabelledBlock from '$lib/components/LabelledBlock.svelte'; + import Select from '$lib/components/Select.svelte'; + import SubmitButton from '$lib/components/SubmitButton.svelte'; + import { getContextClient } from '@urql/svelte'; + import { closeModal } from 'svelte-modals'; + import UpdateModeSelector from './components/UpdateModeSelector.svelte'; + + const client = getContextClient(); + + $: namespaceQuery = namespaceList(client); + $: namespaces = $namespaceQuery.data?.namespaces.edges; + + export let isOpen: boolean; + export let ids: number[]; + + const controls = new UpdateTagsControls(); + + const update = () => { + updateTags(client, { ids: ids, input: controls.toInput() }) + .then(closeModal) + .catch(toastFinally); + }; +</script> + +<Dialog {isOpen}> + <svelte:fragment slot="header"> + <h2>Edit Tags</h2> + </svelte:fragment> + <form on:submit|preventDefault={update}> + <LabelledBlock label="Namespaces" let:id> + <Select multi {id} options={namespaces} bind:value={controls.namespaces.ids} /> + <UpdateModeSelector bind:mode={controls.namespaces.options.mode} slot="controls" /> + </LabelledBlock> + + <div class="flex justify-end gap-4"> + <SubmitButton active={controls.hasInput()} /> + </div> + </form> +</Dialog> diff --git a/frontend/src/lib/dialogs/components/UpdateModeSelector.svelte b/frontend/src/lib/dialogs/components/UpdateModeSelector.svelte new file mode 100644 index 0000000..e4b4479 --- /dev/null +++ b/frontend/src/lib/dialogs/components/UpdateModeSelector.svelte @@ -0,0 +1,24 @@ +<script lang="ts"> + import { UpdateMode } from '$gql/graphql'; + import { UpdateModeLabel } from '$lib/Enums'; + + export let mode: UpdateMode; + + function select(e: string) { + mode = e as UpdateMode; + } +</script> + +<div class="flex gap-1 pb-1 text-xs"> + {#each Object.entries(UpdateModeLabel) as [e, label]} + <button + type="button" + class:active={mode === e} + class:dangerous={mode !== UpdateMode.Add} + class="btn btn-xs hover:bg-slate-700 [&.active.dangerous]:bg-rose-800 [&.active]:bg-indigo-700" + on:click={() => select(e)} + > + {label} + </button> + {/each} +</div> diff --git a/frontend/src/lib/filter/ComicFilterForm.svelte b/frontend/src/lib/filter/ComicFilterForm.svelte new file mode 100644 index 0000000..13b5320 --- /dev/null +++ b/frontend/src/lib/filter/ComicFilterForm.svelte @@ -0,0 +1,48 @@ +<script lang="ts"> + import { page } from '$app/stores'; + import { artistList, characterList, circleList, comicTagList, worldList } from '$gql/Queries'; + import { ComicFilterContext, getFilterContext } from '$lib/Filter'; + import { getContextClient } from '@urql/svelte'; + import ComicFilterGroup from './components/ComicFilterGroup.svelte'; + import FilterForm from './components/FilterForm.svelte'; + + const client = getContextClient(); + + $: tagsQuery = comicTagList(client, { forFilter: true }); + $: artistsQuery = artistList(client); + $: charactersQuery = characterList(client); + $: circlesQuery = circleList(client); + $: worldsQuery = worldList(client); + + $: tags = $tagsQuery.data?.comicTags.edges; + $: artists = $artistsQuery.data?.artists.edges; + $: characters = $charactersQuery.data?.characters.edges; + $: circles = $circlesQuery.data?.circles.edges; + $: worlds = $worldsQuery.data?.worlds.edges; + + const filter = getFilterContext<ComicFilterContext>(); + const apply = () => $filter.apply($page.url.searchParams); +</script> + +<FilterForm type="grid" on:submit={apply}> + <ComicFilterGroup + slot="include" + type="include" + bind:controls={$filter.include.controls} + {tags} + {artists} + {characters} + {circles} + {worlds} + /> + <ComicFilterGroup + slot="exclude" + type="exclude" + bind:controls={$filter.exclude.controls} + {tags} + {artists} + {characters} + {circles} + {worlds} + /> +</FilterForm> diff --git a/frontend/src/lib/filter/TagFilterForm.svelte b/frontend/src/lib/filter/TagFilterForm.svelte new file mode 100644 index 0000000..be5996e --- /dev/null +++ b/frontend/src/lib/filter/TagFilterForm.svelte @@ -0,0 +1,31 @@ +<script lang="ts"> + import { page } from '$app/stores'; + import { namespaceList } from '$gql/Queries'; + import { TagFilterContext, getFilterContext } from '$lib/Filter'; + import { getContextClient } from '@urql/svelte'; + import FilterForm from './components/FilterForm.svelte'; + import TagFilterGroup from './components/TagFilterGroup.svelte'; + + const client = getContextClient(); + + $: namespaceQuery = namespaceList(client); + $: namespaces = $namespaceQuery.data?.namespaces.edges; + + const filter = getFilterContext<TagFilterContext>(); + const apply = () => $filter.apply($page.url.searchParams); +</script> + +<FilterForm on:submit={apply}> + <TagFilterGroup + slot="include" + type="include" + bind:controls={$filter.include.controls} + {namespaces} + /> + <TagFilterGroup + slot="exclude" + type="exclude" + bind:controls={$filter.exclude.controls} + {namespaces} + /> +</FilterForm> diff --git a/frontend/src/lib/filter/components/ComicFilterGroup.svelte b/frontend/src/lib/filter/components/ComicFilterGroup.svelte new file mode 100644 index 0000000..d302de4 --- /dev/null +++ b/frontend/src/lib/filter/components/ComicFilterGroup.svelte @@ -0,0 +1,27 @@ +<script lang="ts"> + import { categories, censorships, languages, ratings } from '$lib/Enums'; + import { ComicFilterControls } from '$lib/Filter'; + import type { ListItem } from '$lib/Utils'; + import { setContext } from 'svelte'; + import Filter from './Filter.svelte'; + + export let tags: ListItem[] | undefined; + export let artists: ListItem[] | undefined; + export let circles: ListItem[] | undefined; + export let characters: ListItem[] | undefined; + export let worlds: ListItem[] | undefined; + export let controls: ComicFilterControls; + export let type: 'include' | 'exclude'; + + setContext('filter-type', type); +</script> + +<Filter title="Tags" options={tags} bind:filter={controls.tags} --grid-column="span 2" /> +<Filter title="Artists" options={artists} bind:filter={controls.artists} /> +<Filter title="Circles" options={circles} bind:filter={controls.circles} /> +<Filter title="Characters" options={characters} bind:filter={controls.characters} /> +<Filter title="Worlds" options={worlds} bind:filter={controls.worlds} /> +<Filter title="Categories" options={categories} bind:filter={controls.categories} /> +<Filter title="Ratings" options={ratings} bind:filter={controls.ratings} /> +<Filter title="Censorship" options={censorships} bind:filter={controls.censorships} /> +<Filter title="Languages" options={languages} bind:filter={controls.languages} /> diff --git a/frontend/src/lib/filter/components/Filter.svelte b/frontend/src/lib/filter/components/Filter.svelte new file mode 100644 index 0000000..ead5c4d --- /dev/null +++ b/frontend/src/lib/filter/components/Filter.svelte @@ -0,0 +1,77 @@ +<script lang="ts"> + import { Association, Enum } from '$lib/Filter'; + import type { ListItem } from '$lib/Utils'; + import Select from '$lib/components/Select.svelte'; + import { getContext } from 'svelte'; + + export let title: string; + const context: 'include' | 'exclude' = getContext('filter-type'); + $: exclude = context === 'exclude'; + + const id = `${context}-${title.toLowerCase()}`; + + export let options: ListItem[] | undefined; + export let filter: Association<string> | Enum<string>; +</script> + +<div class:exclude class="filter-container"> + <div class="flex gap-2"> + <label for={id}>{title}</label> + <div class="ml-auto flex items-center gap-1 self-center text-xs"> + {#if filter instanceof Association} + <button + type="button" + title="matches all" + class:active={filter.mode === 'all'} + class="btn btn-xs" + on:click={() => (filter.mode = 'all')} + > + ∀ + </button> + <button + type="button" + title="matches any of" + class:active={filter.mode === 'any'} + class="btn btn-xs" + on:click={() => (filter.mode = 'any')} + > + ∃ + </button> + <button + type="button" + title="matches exactly" + class:active={filter.mode === 'exact'} + class="btn btn-xs" + on:click={() => (filter.mode = 'exact')} + > + = + </button> + <hr class="border-px border-slate-600" /> + {/if} + <button + type="button" + title="empty" + class:active={filter.empty} + class="btn btn-xs" + on:click={() => (filter.empty = !filter.empty)} + > + ∅ + </button> + </div> + </div> + <Select multi clearable {options} {id} bind:value={filter.values} /> +</div> + +<style lang="postcss"> + button:hover { + @apply bg-slate-700; + } + + button.active { + @apply bg-indigo-800; + } + + .filter-container { + grid-column: var(--grid-column); + } +</style> diff --git a/frontend/src/lib/filter/components/FilterForm.svelte b/frontend/src/lib/filter/components/FilterForm.svelte new file mode 100644 index 0000000..6fc4c90 --- /dev/null +++ b/frontend/src/lib/filter/components/FilterForm.svelte @@ -0,0 +1,47 @@ +<script lang="ts"> + import Expander from '$lib/components/Expander.svelte'; + import { getFilterContext } from '$lib/Filter'; + + const filter = getFilterContext(); + export let type: 'grid' | 'row' = 'row'; + + let exclude = false; + + $: if ($filter.exclude.size > 0) { + exclude = true; + } +</script> + +<form on:submit|preventDefault class="gap-0"> + {#if type === 'grid'} + <div class="flex flex-col gap-4 px-2 md:grid md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-6"> + <slot name="include" /> + </div> + <div class="my-2 flex justify-start"> + <Expander title="Exclude" bind:expanded={exclude} /> + </div> + {#if exclude} + <div + class="flex flex-col gap-4 bg-rose-950/50 p-2 md:grid md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-6" + > + <slot name="exclude" /> + </div> + {/if} + {:else} + <div + class="flex flex-wrap justify-center gap-2 [&>*]:basis-full xl:[&>*]:basis-1/3 2xl:[&>*]:basis-1/5" + > + <div class="p-2"> + <slot name="include" /> + </div> + <div class="bg-rose-950/50 p-2"> + <slot name="exclude" /> + </div> + </div> + {/if} + <div class=" mt-4 flex items-center"> + <hr class="flex-1 border-slate-700/70" /> + <button type="submit" class="btn-blue mx-2">Apply</button> + <hr class="flex-1 border-slate-700/70" /> + </div> +</form> diff --git a/frontend/src/lib/filter/components/TagFilterGroup.svelte b/frontend/src/lib/filter/components/TagFilterGroup.svelte new file mode 100644 index 0000000..83b6997 --- /dev/null +++ b/frontend/src/lib/filter/components/TagFilterGroup.svelte @@ -0,0 +1,14 @@ +<script lang="ts"> + import { TagFilterControls } from '$lib/Filter'; + import type { ListItem } from '$lib/Utils'; + import { setContext } from 'svelte'; + import Filter from './Filter.svelte'; + + export let namespaces: ListItem[] | undefined; + export let controls: TagFilterControls; + export let type: 'include' | 'exclude'; + + setContext('filter-type', type); +</script> + +<Filter title="Namespaces" options={namespaces} bind:filter={controls.namespaces} /> diff --git a/frontend/src/lib/forms/ArtistForm.svelte b/frontend/src/lib/forms/ArtistForm.svelte new file mode 100644 index 0000000..7df5e8b --- /dev/null +++ b/frontend/src/lib/forms/ArtistForm.svelte @@ -0,0 +1,25 @@ +<script lang="ts"> + import { type ArtistInput } from '$gql/Mutations'; + import { type OmitIdentifiers } from '$gql/Utils'; + import { type Artist } from '$gql/graphql'; + import Labelled from '$lib/components/Labelled.svelte'; + import { createEventDispatcher } from 'svelte'; + + const dispatch = createEventDispatcher<{ submit: ArtistInput }>(); + + export let artist: OmitIdentifiers<Artist>; + + function submit() { + dispatch('submit', { name: artist.name }); + } +</script> + +<form on:submit|preventDefault={submit}> + <div class="grid-labels"> + <Labelled label="Name" let:id> + <!-- svelte-ignore a11y-autofocus --> + <input autofocus required {id} bind:value={artist.name} /> + </Labelled> + </div> + <slot /> +</form> diff --git a/frontend/src/lib/forms/CharacterForm.svelte b/frontend/src/lib/forms/CharacterForm.svelte new file mode 100644 index 0000000..4cec37c --- /dev/null +++ b/frontend/src/lib/forms/CharacterForm.svelte @@ -0,0 +1,25 @@ +<script lang="ts"> + import { type CharacterInput } from '$gql/Mutations'; + import { type OmitIdentifiers } from '$gql/Utils'; + import { type Character } from '$gql/graphql'; + import Labelled from '$lib/components/Labelled.svelte'; + import { createEventDispatcher } from 'svelte'; + + const dispatch = createEventDispatcher<{ submit: CharacterInput }>(); + + export let character: OmitIdentifiers<Character>; + + function submit() { + dispatch('submit', { name: character.name }); + } +</script> + +<form on:submit|preventDefault={submit}> + <div class="grid-labels"> + <Labelled label="Name" let:id> + <!-- svelte-ignore a11y-autofocus --> + <input autofocus required {id} bind:value={character.name} /> + </Labelled> + </div> + <slot /> +</form> diff --git a/frontend/src/lib/forms/CircleForm.svelte b/frontend/src/lib/forms/CircleForm.svelte new file mode 100644 index 0000000..b71256c --- /dev/null +++ b/frontend/src/lib/forms/CircleForm.svelte @@ -0,0 +1,25 @@ +<script lang="ts"> + import { type CircleInput } from '$gql/Mutations'; + import { type OmitIdentifiers } from '$gql/Utils'; + import { type Circle } from '$gql/graphql'; + import Labelled from '$lib/components/Labelled.svelte'; + import { createEventDispatcher } from 'svelte'; + + const dispatch = createEventDispatcher<{ submit: CircleInput }>(); + + export let circle: OmitIdentifiers<Circle>; + + function submit() { + dispatch('submit', { name: circle.name }); + } +</script> + +<form on:submit|preventDefault={submit}> + <div class="grid-labels"> + <Labelled label="Name" let:id> + <!-- svelte-ignore a11y-autofocus --> + <input required autofocus {id} bind:value={circle.name} /> + </Labelled> + </div> + <slot /> +</form> diff --git a/frontend/src/lib/forms/ComicForm.svelte b/frontend/src/lib/forms/ComicForm.svelte new file mode 100644 index 0000000..74051c8 --- /dev/null +++ b/frontend/src/lib/forms/ComicForm.svelte @@ -0,0 +1,100 @@ +<script lang="ts"> + import { artistList, characterList, circleList, comicTagList, worldList } from '$gql/Queries'; + import { type OmitIdentifiers } from '$gql/Utils'; + import type { FullComicFragment, UpdateComicInput } from '$gql/graphql'; + import { categories, censorships, directions, languages, layouts, ratings } from '$lib/Enums'; + import Labelled from '$lib/components/Labelled.svelte'; + import LabelledBlock from '$lib/components/LabelledBlock.svelte'; + import Select from '$lib/components/Select.svelte'; + import { getContextClient } from '@urql/svelte'; + import { createEventDispatcher } from 'svelte'; + + const client = getContextClient(); + const dispatch = createEventDispatcher<{ submit: UpdateComicInput }>(); + + export let comic: OmitIdentifiers<FullComicFragment>; + + $: tagsQuery = comicTagList(client); + $: artistsQuery = artistList(client); + $: charactersQuery = characterList(client); + $: circlesQuery = circleList(client); + $: worldsQuery = worldList(client); + + $: tags = $tagsQuery.data?.comicTags.edges; + $: artists = $artistsQuery.data?.artists.edges; + $: characters = $charactersQuery.data?.characters.edges; + $: circles = $circlesQuery.data?.circles.edges; + $: worlds = $worldsQuery.data?.worlds.edges; + + function submit() { + dispatch('submit', { + direction: comic.direction, + layout: comic.layout, + rating: comic.rating, + category: comic.category, + censorship: comic.censorship, + title: comic.title, + originalTitle: comic.originalTitle, + url: comic.url, + date: comic.date === '' ? null : comic.date, + language: comic.language, + tags: { ids: comic.tags.map((t) => t.id) }, + artists: { ids: comic.artists.map((a) => a.id) }, + characters: { ids: comic.characters.map((c) => c.id) }, + circles: { ids: comic.circles.map((c) => c.id) }, + worlds: { ids: comic.worlds.map((w) => w.id) } + }); + } +</script> + +<form on:submit|preventDefault={submit}> + <div class="grid-labels"> + <Labelled label="Title" let:id> + <input required {id} bind:value={comic.title} title={comic.title} /> + </Labelled> + <Labelled label="Original Title" let:id> + <input {id} bind:value={comic.originalTitle} title={comic.originalTitle} /> + </Labelled> + <Labelled label="URL" let:id> + <input {id} bind:value={comic.url} /> + </Labelled> + <Labelled label="Date" let:id> + <input {id} type="date" bind:value={comic.date} pattern={'d{4}-d{2}-d{2}'} /> + </Labelled> + <Labelled label="Category" let:id> + <Select {id} options={categories} bind:value={comic.category} /> + </Labelled> + <Labelled label="Rating" let:id> + <Select {id} options={ratings} bind:value={comic.rating} /> + </Labelled> + <Labelled label="Censorship" let:id> + <Select {id} options={censorships} bind:value={comic.censorship} /> + </Labelled> + <Labelled label="Language" let:id> + <Select {id} options={languages} bind:value={comic.language} /> + </Labelled> + <Labelled label="Direction" let:id> + <Select {id} options={directions} bind:value={comic.direction} /> + </Labelled> + <Labelled label="Layout" let:id> + <Select {id} options={layouts} bind:value={comic.layout} /> + </Labelled> + </div> + + <LabelledBlock label="Artists" let:id> + <Select multi object {id} options={artists} bind:value={comic.artists} /> + </LabelledBlock> + <LabelledBlock label="Circles" let:id> + <Select multi object {id} options={circles} bind:value={comic.circles} /> + </LabelledBlock> + <LabelledBlock label="Characters" let:id> + <Select multi object {id} options={characters} bind:value={comic.characters} /> + </LabelledBlock> + <LabelledBlock label="Worlds" let:id> + <Select multi object {id} options={worlds} bind:value={comic.worlds} /> + </LabelledBlock> + <LabelledBlock label="Tags" let:id> + <Select multi object {id} options={tags} bind:value={comic.tags} /> + </LabelledBlock> + <slot /> +</form> diff --git a/frontend/src/lib/forms/NamespaceForm.svelte b/frontend/src/lib/forms/NamespaceForm.svelte new file mode 100644 index 0000000..c05b6d8 --- /dev/null +++ b/frontend/src/lib/forms/NamespaceForm.svelte @@ -0,0 +1,28 @@ +<script lang="ts"> + import { type NamespaceInput } from '$gql/Mutations'; + import { type OmitIdentifiers } from '$gql/Utils'; + import { type Namespace } from '$gql/graphql'; + import Labelled from '$lib/components/Labelled.svelte'; + import { createEventDispatcher } from 'svelte'; + + const dispatch = createEventDispatcher<{ submit: NamespaceInput }>(); + + export let namespace: OmitIdentifiers<Namespace>; + + function submit() { + dispatch('submit', { name: namespace.name, sortName: namespace.sortName }); + } +</script> + +<form on:submit|preventDefault={submit}> + <div class="grid-labels"> + <Labelled label="Name" let:id> + <!-- svelte-ignore a11y-autofocus --> + <input required autofocus {id} bind:value={namespace.name} /> + </Labelled> + <Labelled label="Sort name" let:id> + <input {id} bind:value={namespace.sortName} /> + </Labelled> + </div> + <slot /> +</form> diff --git a/frontend/src/lib/forms/TagForm.svelte b/frontend/src/lib/forms/TagForm.svelte new file mode 100644 index 0000000..6cc2227 --- /dev/null +++ b/frontend/src/lib/forms/TagForm.svelte @@ -0,0 +1,42 @@ +<script lang="ts"> + import type { TagInput } from '$gql/Mutations'; + import { namespaceList } from '$gql/Queries'; + import type { OmitIdentifiers } from '$gql/Utils'; + import type { FullTag } from '$gql/graphql'; + import Labelled from '$lib/components/Labelled.svelte'; + import Select from '$lib/components/Select.svelte'; + import { getContextClient } from '@urql/svelte'; + import { createEventDispatcher } from 'svelte'; + + const client = getContextClient(); + const dispatch = createEventDispatcher<{ submit: TagInput }>(); + + export let tag: OmitIdentifiers<FullTag>; + + $: namespaceQuery = namespaceList(client); + $: namespaces = $namespaceQuery.data?.namespaces.edges; + + function submit() { + dispatch('submit', { + name: tag.name, + description: tag.description, + namespaces: { ids: tag.namespaces.map((n) => n.id) } + }); + } +</script> + +<form on:submit|preventDefault={submit}> + <div class="grid-labels"> + <Labelled label="Name" let:id> + <!-- svelte-ignore a11y-autofocus --> + <input autofocus required {id} bind:value={tag.name} /> + </Labelled> + <Labelled label="Description" let:id> + <textarea rows={3} {id} bind:value={tag.description} /> + </Labelled> + <Labelled label="Namespaces" let:id> + <Select multi object {id} options={namespaces} bind:value={tag.namespaces} /> + </Labelled> + </div> + <slot /> +</form> diff --git a/frontend/src/lib/forms/WorldForm.svelte b/frontend/src/lib/forms/WorldForm.svelte new file mode 100644 index 0000000..103dd5b --- /dev/null +++ b/frontend/src/lib/forms/WorldForm.svelte @@ -0,0 +1,25 @@ +<script lang="ts"> + import { type WorldInput } from '$gql/Mutations'; + import { type OmitIdentifiers } from '$gql/Utils'; + import { type World } from '$gql/graphql'; + import Labelled from '$lib/components/Labelled.svelte'; + import { createEventDispatcher } from 'svelte'; + + const dispatch = createEventDispatcher<{ submit: WorldInput }>(); + + export let world: OmitIdentifiers<World>; + + function submit() { + dispatch('submit', { name: world.name }); + } +</script> + +<form on:submit|preventDefault={submit}> + <div class="grid-labels"> + <Labelled label="Name" let:id> + <!-- svelte-ignore a11y-autofocus --> + <input autofocus required {id} bind:value={world.name} /> + </Labelled> + </div> + <slot /> +</form> diff --git a/frontend/src/lib/gallery/Gallery.svelte b/frontend/src/lib/gallery/Gallery.svelte new file mode 100644 index 0000000..c3b6386 --- /dev/null +++ b/frontend/src/lib/gallery/Gallery.svelte @@ -0,0 +1,42 @@ +<script lang="ts"> + import type { PageFragment } from '$gql/graphql'; + import GalleryPage from './GalleryPage.svelte'; + + export let pages: PageFragment[]; +</script> + +<div class="max-h-full gap-2 overflow-auto p-1 pr-3"> + {#each pages as page, index} + <GalleryPage {page} {index} on:open on:cover /> + {/each} +</div> + +<style> + :root { + --gallery-image-size: 100px; + } + + @media (min-width: 1280px) { + :root { + --gallery-image-size: 180px; + } + } + + @media (min-width: 1600px) { + :root { + --gallery-image-size: 200px; + } + } + + @media (min-width: 1920px) { + :root { + --gallery-image-size: 240px; + } + } + + div { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(var(--gallery-image-size), 1fr)); + grid-auto-rows: fit-content(400px); + } +</style> diff --git a/frontend/src/lib/gallery/GalleryPage.svelte b/frontend/src/lib/gallery/GalleryPage.svelte new file mode 100644 index 0000000..449321c --- /dev/null +++ b/frontend/src/lib/gallery/GalleryPage.svelte @@ -0,0 +1,93 @@ +<script lang="ts"> + import type { PageFragment } from '$gql/graphql'; + import { getSelectionContext } from '$lib/Selection'; + import SelectionOverlay from '$lib/selection/SelectionOverlay.svelte'; + import { src } from '$lib/Utils'; + import { createEventDispatcher } from 'svelte'; + + export let page: PageFragment; + export let index: number; + + const selection = getSelectionContext<PageFragment>(); + + let span: 'single' | 'double' | 'triple'; + + $: page.image.aspectRatio, updateSpan(); + + function updateSpan() { + const aspectRatio = page.image.aspectRatio; + + if (aspectRatio <= 1) { + span = 'single'; + } else if (aspectRatio > 1 && aspectRatio <= 2) { + span = 'double'; + } else if (aspectRatio > 2) { + span = 'triple'; + } + } + + const dispatch = createEventDispatcher<{ open: number; cover: number }>(); + + function press(event: MouseEvent | KeyboardEvent) { + if (event instanceof KeyboardEvent && event.key !== 'Enter') { + return; + } + + if ($selection.active) { + if (event.ctrlKey) { + dispatch('open', index); + } else if (selectable) { + $selection = $selection.update(index, event.shiftKey); + } + } else if (event.ctrlKey) { + dispatch('cover', page.id); + } else { + dispatch('open', index); + } + + event.preventDefault(); + } + + $: selectable = $selection.selectable(page); + $: dim = $selection.active && !selectable; + $: selected = $selection.contains(page.id); +</script> + +<div + class:dim + role="button" + tabindex="0" + class="{span} relative overflow-hidden rounded" + on:click={press} + on:keydown={press} +> + <SelectionOverlay position="top" {selected} /> + <img + class="h-full w-full object-cover object-[center_top] transition-opacity" + loading="lazy" + alt="" + width={page.image.width} + height={page.image.height} + src={src(page.image)} + title={`${page.path} (${page.image.width} x ${page.image.height})`} + /> +</div> + +<style> + .dim { + cursor: not-allowed; + } + + .dim > img { + opacity: 0.2; + filter: grayscale(1); + } + + .double { + grid-column: span 2; + } + + .triple { + grid-column: span 3; + } +</style> diff --git a/frontend/src/lib/icons/Bookmark.svelte b/frontend/src/lib/icons/Bookmark.svelte new file mode 100644 index 0000000..6f8e192 --- /dev/null +++ b/frontend/src/lib/icons/Bookmark.svelte @@ -0,0 +1,10 @@ +<script lang="ts"> + export let bookmarked: boolean | undefined = undefined; + export let hoverable = false; +</script> + +{#if bookmarked} + <span class:hoverable class="icon-gray icon-base icon-[material-symbols--bookmark]" /> +{:else} + <span class:hoverable class="icon-gray icon-base dim icon-[material-symbols--bookmark-outline]" /> +{/if} diff --git a/frontend/src/lib/icons/Female.svelte b/frontend/src/lib/icons/Female.svelte new file mode 100644 index 0000000..c772a6a --- /dev/null +++ b/frontend/src/lib/icons/Female.svelte @@ -0,0 +1 @@ +<span class="icon-xs icon-[material-symbols--female] -mx-[3px]" /> diff --git a/frontend/src/lib/icons/Location.svelte b/frontend/src/lib/icons/Location.svelte new file mode 100644 index 0000000..e345f83 --- /dev/null +++ b/frontend/src/lib/icons/Location.svelte @@ -0,0 +1 @@ +<span class="icon-xs icon-[material-symbols--location-on-outline]" /> diff --git a/frontend/src/lib/icons/Male.svelte b/frontend/src/lib/icons/Male.svelte new file mode 100644 index 0000000..e3578b7 --- /dev/null +++ b/frontend/src/lib/icons/Male.svelte @@ -0,0 +1 @@ +<span class="icon-xs icon-[material-symbols--male] -mx-px" /> diff --git a/frontend/src/lib/icons/Organized.svelte b/frontend/src/lib/icons/Organized.svelte new file mode 100644 index 0000000..66b5b00 --- /dev/null +++ b/frontend/src/lib/icons/Organized.svelte @@ -0,0 +1,21 @@ +<script lang="ts"> + export let organized: boolean | undefined = undefined; + export let hoverable = false; + export let tristate = false; + export let dim = false; +</script> + +{#if organized} + <span class:hoverable class="icon-gray icon-base icon-[material-symbols--check-circle]" /> +{:else if organized === undefined || !tristate} + <span + class:hoverable + class="icon-gray dim icon-base icon-[material-symbols--check-circle-outline]" + /> +{:else} + <span + class:hoverable + class:dim + class="icon-gray icon-base icon-[material-symbols--unpublished]" + /> +{/if} diff --git a/frontend/src/lib/icons/Star.svelte b/frontend/src/lib/icons/Star.svelte new file mode 100644 index 0000000..7613c55 --- /dev/null +++ b/frontend/src/lib/icons/Star.svelte @@ -0,0 +1,25 @@ +<script lang="ts"> + export let large = false; + export let favourite: boolean | undefined = undefined; + export let hoverable = false; +</script> + +{#if favourite} + <span class:hoverable class:large class="icon-yellow icon-[material-symbols--star-rounded]" /> +{:else} + <span + class:hoverable + class:large + class="icon-yellow dim icon-[material-symbols--star-outline-rounded]" + /> +{/if} + +<style lang="postcss"> + span { + @apply -m-px -translate-y-px text-[26px]; + } + + span.large { + @apply text-[34px]; + } +</style> diff --git a/frontend/src/lib/icons/Transgender.svelte b/frontend/src/lib/icons/Transgender.svelte new file mode 100644 index 0000000..7d9adc6 --- /dev/null +++ b/frontend/src/lib/icons/Transgender.svelte @@ -0,0 +1 @@ +<span class="icon-xs icon-[material-symbols--transgender]" /> diff --git a/frontend/src/lib/navigation/Link.svelte b/frontend/src/lib/navigation/Link.svelte new file mode 100644 index 0000000..7297a69 --- /dev/null +++ b/frontend/src/lib/navigation/Link.svelte @@ -0,0 +1,20 @@ +<script lang="ts"> + import { page } from '$app/stores'; + import { accelerator, type Shortcut } from '$lib/Shortcuts'; + import type { HTMLAttributeAnchorTarget } from 'svelte/elements'; + + export let href: string; + export let title: string; + export let accel: Shortcut; + export let matchExact = false; + export let target: HTMLAttributeAnchorTarget | undefined = undefined; + $: active = matchExact ? $page.url.pathname === href : $page.url.pathname.startsWith(href); +</script> + +<li class:active class="items-center hover:bg-indigo-700 [&.active]:bg-indigo-700"> + <a class="flex items-center" {target} {title} {href} use:accelerator={accel}> + <div class="flex p-3"> + <slot /> + </div> + </a> +</li> diff --git a/frontend/src/lib/navigation/Navigation.svelte b/frontend/src/lib/navigation/Navigation.svelte new file mode 100644 index 0000000..76096c8 --- /dev/null +++ b/frontend/src/lib/navigation/Navigation.svelte @@ -0,0 +1,5 @@ +<nav> + <ul class="flex h-full flex-col bg-slate-700/70 font-medium"> + <slot /> + </ul> +</nav> diff --git a/frontend/src/lib/pagination/Pagination.svelte b/frontend/src/lib/pagination/Pagination.svelte new file mode 100644 index 0000000..51612f4 --- /dev/null +++ b/frontend/src/lib/pagination/Pagination.svelte @@ -0,0 +1,45 @@ +<script lang="ts"> + import { getPaginationContext } from '$lib/Pagination'; + import Target from './Target.svelte'; + + const pagination = getPaginationContext(); + export let context = 2; + + $: totalPages = Math.ceil($pagination.total / $pagination.items); + $: rightBoundary = $pagination.page - context; + $: leftBoundary = $pagination.page + context; + + $: shiftRight = leftBoundary - totalPages; + $: shiftLeft = 1 - rightBoundary; + + $: containedLeft = leftBoundary <= totalPages; + $: containedRight = rightBoundary > 0; + + $: start = Math.max(1, containedLeft ? rightBoundary : rightBoundary - shiftRight); + $: end = Math.min(totalPages, containedRight ? leftBoundary : leftBoundary + shiftLeft); + + $: leftmost = $pagination.page <= 1; + $: rightmost = $pagination.page >= totalPages; +</script> + +{#if totalPages > 1} + <div class="flex justify-center gap-2"> + <Target disabled={leftmost} page={1}> + <span class="icon-base icon-[material-symbols--keyboard-double-arrow-left]" /> + </Target> + <Target disabled={leftmost} page={$pagination.page - 1}> + <span class="icon-base icon-[material-symbols--keyboard-arrow-left]" /> + </Target> + {#each Array.from({ length: end + 1 - start }, (_, i) => i + start) as page} + <Target active={$pagination.page === page} {page}> + <p>{page.toString()}</p> + </Target> + {/each} + <Target disabled={rightmost} page={$pagination.page + 1}> + <span class="icon-base icon-[material-symbols--keyboard-arrow-right]" /> + </Target> + <Target disabled={rightmost} page={totalPages}> + <span class="icon-base icon-[material-symbols--keyboard-double-arrow-right]" /> + </Target> + </div> +{/if} diff --git a/frontend/src/lib/pagination/Target.svelte b/frontend/src/lib/pagination/Target.svelte new file mode 100644 index 0000000..9044bb9 --- /dev/null +++ b/frontend/src/lib/pagination/Target.svelte @@ -0,0 +1,21 @@ +<script lang="ts"> + import { page as pageStore } from '$app/stores'; + import { navigate } from '$lib/Navigation'; + + export let active = false; + + export let disabled = false; + export let page: number; +</script> + +<button + on:click={() => { + navigate({ pagination: { page: page } }, $pageStore.url.searchParams); + }} + class:bg-slate-700={active} + class:bg-slate-800={!active} + class="flex h-8 w-8 items-center justify-center rounded-sm p-0 text-base hover:text-white disabled:text-slate-600" + {disabled} +> + <slot /> +</button> diff --git a/frontend/src/lib/pills/AssociationPill.svelte b/frontend/src/lib/pills/AssociationPill.svelte new file mode 100644 index 0000000..85dbe39 --- /dev/null +++ b/frontend/src/lib/pills/AssociationPill.svelte @@ -0,0 +1,30 @@ +<script lang="ts"> + import Pill from './Pill.svelte'; + + type Association = 'artist' | 'circle' | 'world' | 'character'; + + export let name: string; + export let type: Association; +</script> + +<Pill {name}> + <span class={`${type} icon-xs`} slot="icon" /> +</Pill> + +<style lang="postcss"> + .artist { + @apply icon-[material-symbols--person] -mx-px; + } + + .character { + @apply icon-[material-symbols--face]; + } + + .circle { + @apply icon-[material-symbols--group] mx-px; + } + + .world { + @apply icon-[material-symbols--public]; + } +</style> diff --git a/frontend/src/lib/pills/ComicPills.svelte b/frontend/src/lib/pills/ComicPills.svelte new file mode 100644 index 0000000..671bbf2 --- /dev/null +++ b/frontend/src/lib/pills/ComicPills.svelte @@ -0,0 +1,37 @@ +<script lang="ts"> + import type { ComicFragment } from '$gql/graphql'; + import AssociationPill from '$lib/pills/AssociationPill.svelte'; + import TagPill from '$lib/pills/TagPill.svelte'; + + export let comic: ComicFragment; +</script> + +<div class="flex flex-col gap-1"> + {#if comic.artists.length || comic.circles.length} + <div class="flex flex-wrap gap-1"> + {#each comic.artists as { name } (name)} + <AssociationPill {name} type="artist" /> + {/each} + {#each comic.circles as { name } (name)} + <AssociationPill {name} type="circle" /> + {/each} + </div> + {/if} + {#if comic.characters.length || comic.worlds.length} + <div class="flex flex-wrap gap-1"> + {#each comic.worlds as { name } (name)} + <AssociationPill {name} type="world" /> + {/each} + {#each comic.characters as { name } (name)} + <AssociationPill {name} type="character" /> + {/each} + </div> + {/if} + {#if comic.tags.length} + <div class="flex flex-wrap gap-1"> + {#each comic.tags as { name, description } (name)} + <TagPill {name} {description} /> + {/each} + </div> + {/if} +</div> diff --git a/frontend/src/lib/pills/Pill.svelte b/frontend/src/lib/pills/Pill.svelte new file mode 100644 index 0000000..7aa9670 --- /dev/null +++ b/frontend/src/lib/pills/Pill.svelte @@ -0,0 +1,40 @@ +<script lang="ts" context="module"> + export type PillColour = 'pink' | 'blue' | 'violet' | 'amber' | 'zinc' | 'sky'; +</script> + +<script lang="ts"> + export let name: string; + export let tooltip: string | null | undefined = undefined; + export let colour: PillColour = 'zinc'; +</script> + +<div class="flex items-center rounded border p-0.5 {colour}" title={tooltip}> + <slot name="icon" /> + <span>{name}</span> +</div> + +<style lang="postcss"> + .pink { + @apply border-pink-800 bg-pink-800/20 text-pink-200; + } + + .blue { + @apply border-blue-800 bg-blue-800/20 text-blue-200; + } + + .violet { + @apply border-violet-800 bg-violet-800/20 text-violet-200; + } + + .amber { + @apply border-amber-800 bg-amber-800/20 text-amber-200; + } + + .sky { + @apply border-sky-800 bg-sky-800/20 text-sky-200; + } + + .zinc { + @apply border-zinc-700 bg-zinc-700/20 text-zinc-300; + } +</style> diff --git a/frontend/src/lib/pills/TagPill.svelte b/frontend/src/lib/pills/TagPill.svelte new file mode 100644 index 0000000..60221bd --- /dev/null +++ b/frontend/src/lib/pills/TagPill.svelte @@ -0,0 +1,40 @@ +<script lang="ts"> + import Female from '$lib/icons/Female.svelte'; + import Location from '$lib/icons/Location.svelte'; + import Male from '$lib/icons/Male.svelte'; + import Transgender from '$lib/icons/Transgender.svelte'; + import { SvelteComponent } from 'svelte'; + import Pill, { type PillColour } from './Pill.svelte'; + + export let name: string; + export let description: string | undefined | null = undefined; + + let [namespace, tag] = name.split(':'); + + const styles: Record<string, PillColour> = { + female: 'pink', + male: 'blue', + trans: 'violet', + mixed: 'amber', + location: 'sky', + rest: 'zinc' + }; + + const icons: Record<string, typeof SvelteComponent<Record<string, unknown>>> = { + female: Female, + male: Male, + trans: Transgender, + location: Location + }; + + const colour = styles[namespace] ?? styles.rest; + const icon = icons[namespace]; + + function formatTooltip() { + return [name, description].filter((v) => v).join('\n\n'); + } +</script> + +<Pill name={tag} tooltip={formatTooltip()} {colour}> + <svelte:component this={icon} slot="icon" /> +</Pill> diff --git a/frontend/src/lib/reader/PageView.svelte b/frontend/src/lib/reader/PageView.svelte new file mode 100644 index 0000000..cc4d10e --- /dev/null +++ b/frontend/src/lib/reader/PageView.svelte @@ -0,0 +1,67 @@ +<script lang="ts"> + import { Direction, Layout, type PageFragment } from '$gql/graphql'; + import { getReaderContext, partition, type Chunk } from '$lib/Reader'; + import { binds } from '$lib/Shortcuts'; + import ReaderPage from './ReaderPage.svelte'; + + const reader = getReaderContext(); + + export let direction: Direction; + export let layout: Layout; + + let chunks: Chunk[] = []; + let lookup: number[] = []; + + let main: PageFragment; + let secondary: PageFragment | undefined; + + function gotoChunk(to: number) { + if (to < 0 || to >= chunks.length) return; + + $reader.page = chunks[to].index; + } + + const next = () => gotoChunk(lookup[$reader.page] + 1); + const prev = () => gotoChunk(lookup[$reader.page] - 1); + + const clickLeft = () => (direction === Direction.LeftToRight ? prev() : next()); + const clickRight = () => (direction === Direction.RightToLeft ? prev() : next()); + + function clickMain(event: MouseEvent & { currentTarget: EventTarget | null }) { + if (event.currentTarget instanceof Element) { + const rect = event.currentTarget.getBoundingClientRect(); + + if (event.clientX - rect.left < rect.width / 2) { + clickLeft(); + } else { + clickRight(); + } + } + } + + $: [chunks, lookup] = partition($reader.pages, layout); + $: layout, ({ main, secondary } = chunks[lookup[$reader.page]]); +</script> + +<svelte:document + use:binds={[ + ['ArrowLeft', clickLeft], + ['ArrowRight', clickRight], + ['ArrowUp', prev], + ['ArrowDown', next], + ['PageUp', prev], + ['PageDown', next], + [' ', next], + ['Backspace', prev] + ]} +/> + +{#if !secondary} + <ReaderPage page={main} on:click={clickMain} --justify="center" /> +{:else if direction === Direction.LeftToRight} + <ReaderPage page={main} on:click={prev} --justify="flex-end" /> + <ReaderPage page={secondary} on:click={next} --justify="flex-start" /> +{:else} + <ReaderPage page={secondary} on:click={next} --justify="flex-end" /> + <ReaderPage page={main} on:click={prev} --justify="flex-start" /> +{/if} diff --git a/frontend/src/lib/reader/Reader.svelte b/frontend/src/lib/reader/Reader.svelte new file mode 100644 index 0000000..0b1450a --- /dev/null +++ b/frontend/src/lib/reader/Reader.svelte @@ -0,0 +1,39 @@ +<script lang="ts"> + import { trapFocus } from '$lib/Actions'; + import { getReaderContext } from '$lib/Reader'; + import { fadeDefault, slideXDefault } from '$lib/Transitions'; + import { fade, slide } from 'svelte/transition'; + import CloseReaderButton from './components/CloseReaderButton.svelte'; + import ReaderMenuButton from './components/ReaderMenuButton.svelte'; + + const reader = getReaderContext(); +</script> + +{#if $reader.visible} + <div + role="dialog" + class="fixed bottom-0 left-0 right-0 top-0 z-10 flex h-full w-full bg-black" + transition:fade={fadeDefault} + use:trapFocus + > + {#if $$slots.sidebar && $reader.sidebar} + <aside class="w-[36rem] shrink-0 bg-slate-800" transition:slide={slideXDefault}> + <div class="flex h-full min-w-[36rem] flex-col gap-4 overflow-auto p-4"> + <slot name="sidebar" /> + </div> + </aside> + {/if} + <main class="relative flex grow"> + <div class="absolute flex w-full p-1 text-lg [&>*:last-child]:ml-auto"> + {#if $$slots.sidebar} + <ReaderMenuButton /> + {/if} + <CloseReaderButton /> + </div> + + <div class="flex grow"> + <slot /> + </div> + </main> + </div> +{/if} diff --git a/frontend/src/lib/reader/ReaderPage.svelte b/frontend/src/lib/reader/ReaderPage.svelte new file mode 100644 index 0000000..fb3e780 --- /dev/null +++ b/frontend/src/lib/reader/ReaderPage.svelte @@ -0,0 +1,24 @@ +<script lang="ts"> + import type { PageFragment } from '$gql/graphql'; + import { src } from '$lib/Utils'; + + export let page: PageFragment; +</script> + +<!-- svelte-ignore a11y-click-events-have-key-events --> +<!-- svelte-ignore a11y-no-static-element-interactions --> +<div class="flex grow" on:click> + <img + class="h-auto w-auto object-contain" + width={page.image.width} + height={page.image.height} + src={src(page.image, 'full')} + alt={page.path} + /> +</div> + +<style> + div { + justify-content: var(--justify); + } +</style> diff --git a/frontend/src/lib/reader/components/CloseReaderButton.svelte b/frontend/src/lib/reader/components/CloseReaderButton.svelte new file mode 100644 index 0000000..0c88323 --- /dev/null +++ b/frontend/src/lib/reader/components/CloseReaderButton.svelte @@ -0,0 +1,19 @@ +<script lang="ts"> + import { getReaderContext } from '$lib/Reader'; + import { accelerator } from '$lib/Shortcuts'; + + const reader = getReaderContext(); +</script> + +<button + type="button" + class="btn floating" + title="Close reader" + on:click={() => { + $reader.visible = false; + $reader.sidebar = false; + }} + use:accelerator={'Escape'} +> + <span class="icon-lg icon-[material-symbols--close]" /> +</button> diff --git a/frontend/src/lib/reader/components/ReaderMenuButton.svelte b/frontend/src/lib/reader/components/ReaderMenuButton.svelte new file mode 100644 index 0000000..aa20206 --- /dev/null +++ b/frontend/src/lib/reader/components/ReaderMenuButton.svelte @@ -0,0 +1,16 @@ +<script lang="ts"> + import { getReaderContext } from '$lib/Reader'; + import { accelerator } from '$lib/Shortcuts'; + + const reader = getReaderContext(); +</script> + +<button + type="button" + class="btn floating invisible xl:visible" + title={`${$reader.sidebar ? 'Hide' : 'Show'} menu`} + on:click={() => ($reader.sidebar = !$reader.sidebar)} + use:accelerator={'z'} +> + <span class="icon-lg icon-[material-symbols--dock-to-right]" /> +</button> diff --git a/frontend/src/lib/scraper/ComicScrapeForm.svelte b/frontend/src/lib/scraper/ComicScrapeForm.svelte new file mode 100644 index 0000000..30ad89b --- /dev/null +++ b/frontend/src/lib/scraper/ComicScrapeForm.svelte @@ -0,0 +1,138 @@ +<script lang="ts"> + import { upsertComics } from '$gql/Mutations'; + import { comicScrapersQuery, scrapeComic } from '$gql/Queries'; + import { isError } from '$gql/Utils'; + import { OnMissing, type FullComicFragment } from '$gql/graphql'; + import { ScrapedComicSelector, getScraperContext } from '$lib/Scraper'; + import { toastError, toastFinally } from '$lib/Toasts'; + import Select from '$lib/components/Select.svelte'; + import Spinner from '$lib/components/Spinner.svelte'; + import { getContextClient } from '@urql/svelte'; + import SelectorGroup from './components/SelectorGroup.svelte'; + import SelectorItem from './components/SelectorItem.svelte'; + + let client = getContextClient(); + const context = getScraperContext(); + + export let comic: FullComicFragment; + let createMissing = false; + let loading = false; + + $: scrapersResult = comicScrapersQuery(client, { id: comic.id }); + $: scrapers = $scrapersResult.data?.comicScrapers; + + function scrape() { + loading = true; + scrapeComic(client, { id: comic.id, scraper: $context.scraper }) + .then((result) => { + if (result.error) { + toastError(result.error.message); + return; + } + + if (result.data) { + if (isError(result.data.scrapeComic)) { + toastError(result.data.scrapeComic.message); + return; + } + + if (result.data.scrapeComic.__typename === 'ScrapeComicResult') { + $context.selector = new ScrapedComicSelector(result.data.scrapeComic.data, comic); + $context.warnings = result.data.scrapeComic.warnings; + } + } + }) + .catch(toastFinally) + .finally(() => (loading = false)); + } + + function updateFromScrape(createMissing: boolean) { + if (!$context.selector) return; + + upsertComics(client, { + ids: comic.id, + input: $context.selector.toInput(createMissing ? OnMissing.Create : OnMissing.Ignore) + }) + .then(() => { + $context.selector = undefined; + $context.warnings = []; + }) + .catch(toastFinally); + } +</script> + +<div class="flex flex-col gap-4 text-sm"> + {#if scrapers && scrapers.length === 0} + <h2 class="text-base">No scrapers available.</h2> + {:else} + <form on:submit|preventDefault={scrape}> + <div class="grid grid-cols-6 gap-2"> + <div class="col-span-5"> + <Select + id="scrapers" + options={scrapers} + placeholder={'Select scraper...'} + bind:value={$context.scraper} + /> + </div> + <button type="submit" disabled={!$context.scraper} class="btn-blue">Scrape</button> + </div> + </form> + {/if} + + {#if loading} + <Spinner /> + {:else if $context.selector} + {#if $context.warnings.length > 0} + <div class="flex flex-col gap-2"> + <h2 class="flex gap-1 border-b border-slate-700 text-base font-medium">Warnings</h2> + <ul class="ml-2 list-inside list-disc"> + {#each $context.warnings as warning} + <li>{warning}</li> + {/each} + </ul> + </div> + {/if} + {#if !$context.selector.hasData()} + <h2 class="text-base">No data to merge.</h2> + {:else} + <div class="flex flex-col gap-2"> + <h2 class="border-b border-slate-700 text-base font-medium">Results</h2> + <form on:submit|preventDefault={() => updateFromScrape(createMissing)}> + <div class="grid grid-cols-6 gap-4 pb-2"> + <SelectorItem title="Title" selector={$context.selector.title} /> + <SelectorItem title="Original Title" selector={$context.selector.originalTitle} /> + <SelectorItem title="URL" selector={$context.selector.url} /> + <SelectorItem title="Date" selector={$context.selector.date} --span="2" /> + <SelectorItem title="Category" selector={$context.selector.category} --span="2" /> + <SelectorItem title="Language" selector={$context.selector.language} --span="2" /> + <SelectorItem title="Rating" selector={$context.selector.rating} --span="2" /> + <SelectorItem title="Censorship" selector={$context.selector.censorship} --span="2" /> + <SelectorItem title="Direction" selector={$context.selector.direction} --span="2" /> + <SelectorItem title="Layout" selector={$context.selector.layout} --span="2" /> + <SelectorGroup title="Artists" selectors={$context.selector.artists} /> + <SelectorGroup title="Circles" selectors={$context.selector.circles} /> + <SelectorGroup title="Characters" selectors={$context.selector.characters} /> + <SelectorGroup title="Worlds" selectors={$context.selector.worlds} /> + <SelectorGroup title="Tags" selectors={$context.selector.tags} /> + </div> + <div class="flex flex-col gap-2"> + <h2 class="border-b border-slate-700 text-base font-medium">Options</h2> + <div class="flex items-center gap-1"> + <input + class="h-4 w-4" + type="checkbox" + id="create-missing" + bind:checked={createMissing} + /> + <label class="shrink-0" for="create-missing">Create missing items</label> + </div> + </div> + <div class="flex gap-4"> + <button type="submit" class="btn-blue">Merge</button> + </div> + </form> + </div> + {/if} + {/if} +</div> diff --git a/frontend/src/lib/scraper/components/SelectorButton.svelte b/frontend/src/lib/scraper/components/SelectorButton.svelte new file mode 100644 index 0000000..b786f89 --- /dev/null +++ b/frontend/src/lib/scraper/components/SelectorButton.svelte @@ -0,0 +1,22 @@ +<script lang="ts"> + import { Selector } from '$lib/Scraper'; + + export let selector: Selector<string>; +</script> + +<button + type="button" + class="ml-1 flex rounded-sm border-slate-700 bg-slate-900 hover:brightness-110" + on:click={() => (selector.keep = !selector.keep)} +> + <div class="flex self-center pl-1"> + {#if selector.keep} + <span class="icon-base icon-[material-symbols--check] text-green-400" /> + {:else} + <span class="icon-base icon-[material-symbols--close] text-red-400" /> + {/if} + </div> + <p class:opacity-50={!selector.keep} class="p-1 text-left"> + {selector} + </p> +</button> diff --git a/frontend/src/lib/scraper/components/SelectorGroup.svelte b/frontend/src/lib/scraper/components/SelectorGroup.svelte new file mode 100644 index 0000000..ae7287a --- /dev/null +++ b/frontend/src/lib/scraper/components/SelectorGroup.svelte @@ -0,0 +1,35 @@ +<script lang="ts"> + import { Selector } from '$lib/Scraper'; + import SelectorButton from './SelectorButton.svelte'; + + export let title: string; + export let selectors: Selector<string>[]; + + function invert() { + for (let selector of selectors) { + selector.keep = !selector.keep; + } + selectors = selectors; + } +</script> + +{#if selectors.length > 0} + <div class="group col-span-6 flex flex-col gap-1"> + <div class="flex gap-2"> + <h2>{title}</h2> + <button + type="button" + class="flex items-end opacity-0 brightness-75 transition-opacity hover:brightness-110 group-hover:opacity-100" + on:click={invert} + title="Invert selection" + > + <span class="icon-xs icon-[material-symbols--compare-arrows]"></span> + </button> + </div> + <div class="flex flex-wrap gap-y-1"> + {#each selectors as selector} + <SelectorButton {selector} /> + {/each} + </div> + </div> +{/if} diff --git a/frontend/src/lib/scraper/components/SelectorItem.svelte b/frontend/src/lib/scraper/components/SelectorItem.svelte new file mode 100644 index 0000000..dd3f5b4 --- /dev/null +++ b/frontend/src/lib/scraper/components/SelectorItem.svelte @@ -0,0 +1,24 @@ +<script lang="ts"> + import { Selector } from '$lib/Scraper'; + import SelectorButton from './SelectorButton.svelte'; + + export let title: string; + export let selector: Selector<string> | undefined; +</script> + +{#if selector} + <div class="flex flex-col gap-1"> + <h2>{title}</h2> + <SelectorButton {selector} /> + </div> +{/if} + +<style> + :root { + --span: 6; + } + + div { + grid-column: span var(--span) / span var(--span); + } +</style> diff --git a/frontend/src/lib/selection/Selectable.svelte b/frontend/src/lib/selection/Selectable.svelte new file mode 100644 index 0000000..48b6ac7 --- /dev/null +++ b/frontend/src/lib/selection/Selectable.svelte @@ -0,0 +1,24 @@ +<script lang="ts"> + import { getSelectionContext } from '$lib/Selection'; + + export let id: number; + export let index: number; + + export let edit: ((id: number) => void) | undefined = undefined; + + const selection = getSelectionContext(); + + $: selected = $selection.contains(id); + + const handle = (event: MouseEvent) => { + if ($selection.active) { + $selection = $selection.update(index, event.shiftKey); + event.preventDefault(); + } else if (edit) { + edit(id); + event.preventDefault(); + } + }; +</script> + +<slot {handle} {selected} /> diff --git a/frontend/src/lib/selection/SelectionOverlay.svelte b/frontend/src/lib/selection/SelectionOverlay.svelte new file mode 100644 index 0000000..04ff382 --- /dev/null +++ b/frontend/src/lib/selection/SelectionOverlay.svelte @@ -0,0 +1,34 @@ +<script lang="ts"> + export let selected: boolean; + export let position: 'top' | 'right' | 'left' | 'bottom'; + export let centered = false; +</script> + +{#if selected} + <div + class:items-center={centered} + class="{position} pointer-events-none absolute z-[1] flex bg-emerald-700/95" + > + <span class="icon-base icon-[material-symbols--check] text-[2rem]" /> + </div> +{/if} + +<style lang="postcss"> + .top, + .bottom { + width: 100%; + } + + .left, + .right { + height: 100%; + } + + .bottom { + bottom: 0; + } + + .right { + right: 0; + } +</style> diff --git a/frontend/src/lib/tabs/AddOverlay.svelte b/frontend/src/lib/tabs/AddOverlay.svelte new file mode 100644 index 0000000..b1c98bf --- /dev/null +++ b/frontend/src/lib/tabs/AddOverlay.svelte @@ -0,0 +1,36 @@ +<script lang="ts"> + import { updateComics } from '$gql/Mutations'; + import { UpdateMode } from '$gql/graphql'; + import { getSelectionContext } from '$lib/Selection'; + import { toastFinally } from '$lib/Toasts'; + import { fadeDefault } from '$lib/Transitions'; + import { getContextClient } from '@urql/svelte'; + import { fade } from 'svelte/transition'; + + const client = getContextClient(); + const selection = getSelectionContext(); + + export let id: number; + + function addPages() { + updateComics(client, { + ids: id, + input: { pages: { ids: $selection.ids, options: { mode: UpdateMode.Add } } } + }) + .then(() => ($selection = $selection.none())) + .catch(toastFinally); + } +</script> + +{#if $selection.size > 0} + <div class="absolute left-1 top-1" transition:fade={fadeDefault}> + <button + type="button" + class="btn-blue rounded-full shadow-sm shadow-black" + title="Add to this comic" + on:click|preventDefault={addPages} + > + <span class="icon-base icon-[material-symbols--note-add]" /> + </button> + </div> +{/if} diff --git a/frontend/src/lib/tabs/ArchiveDelete.svelte b/frontend/src/lib/tabs/ArchiveDelete.svelte new file mode 100644 index 0000000..b0e3c58 --- /dev/null +++ b/frontend/src/lib/tabs/ArchiveDelete.svelte @@ -0,0 +1,42 @@ +<script lang="ts"> + import { goto } from '$app/navigation'; + import { deleteArchives } from '$gql/Mutations'; + import type { FullArchiveFragment } from '$gql/graphql'; + import { toastFinally } from '$lib/Toasts'; + import { confirmDeletion } from '$lib/Utils'; + import DeleteButton from '$lib/components/DeleteButton.svelte'; + import { getContextClient } from '@urql/svelte'; + + const client = getContextClient(); + + export let archive: FullArchiveFragment; + + function deleteArchive() { + confirmDeletion('Archive', archive.name, () => { + deleteArchives(client, { ids: archive.id }) + .then(() => goto('/archives/')) + .catch(toastFinally); + }); + } +</script> + +<div class="flex flex-col gap-2"> + <div> + <p> + Deleting this archive will remove the + <span class="cursor-help font-medium underline" title={archive.path}>archive file</span> on disk. + </p> + {#if archive.comics.length > 0} + <p>The following comics will also be deleted:</p> + <ul class="ml-8 list-disc"> + {#each archive.comics as comic} + <li><a href="/comics/{comic.id}" class="underline">{comic.title}</a></li> + {/each} + </ul> + {/if} + <p class="mt-2 font-medium">This action is irrevocable.</p> + </div> + <div class="flex"> + <DeleteButton prominent on:click={deleteArchive} /> + </div> +</div> diff --git a/frontend/src/lib/tabs/ArchiveDetails.svelte b/frontend/src/lib/tabs/ArchiveDetails.svelte new file mode 100644 index 0000000..9554557 --- /dev/null +++ b/frontend/src/lib/tabs/ArchiveDetails.svelte @@ -0,0 +1,50 @@ +<script lang="ts"> + import type { FullArchiveFragment } from '$gql/graphql'; + import { formatListSize, joinText } from '$lib/Utils'; + import Card, { comicCard } from '$lib/components/Card.svelte'; + import ComicPills from '$lib/pills/ComicPills.svelte'; + import { formatDistance, formatISO9075 } from 'date-fns'; + import { filesize } from 'filesize'; + import Header from './DetailsHeader.svelte'; + import Section from './DetailsSection.svelte'; + + export let archive: FullArchiveFragment; + + const now = Date.now(); + const modifiedDate = new Date(archive.mtime); + const createdDate = new Date(archive.createdAt); + + const title = joinText(['Archive', formatListSize('image', archive.pageCount)]); +</script> + +<div class="flex flex-col gap-4 text-sm"> + <Header {title} /> + <div class="grid grid-cols-3 gap-4"> + <Section title="Size"> + <span>{filesize(archive.size, { base: 2 })}</span> + </Section> + <Section title="Created"> + <span title={formatISO9075(createdDate)}> + {formatDistance(createdDate, now, { addSuffix: true })} + </span> + </Section> + <Section title="File last modified"> + <span title={formatISO9075(modifiedDate)}> + {formatDistance(modifiedDate, now, { addSuffix: true })} + </span> + </Section> + </div> + + {#if archive.comics.length > 0} + <div class="flex flex-col gap-1"> + <h2 class="text-base font-medium">Comics</h2> + <div class="flex shrink-0 flex-col gap-4"> + {#each archive.comics as comic} + <Card compact {...comicCard(comic)}> + <ComicPills {comic} /> + </Card> + {/each} + </div> + </div> + {/if} +</div> diff --git a/frontend/src/lib/tabs/ArchiveEdit.svelte b/frontend/src/lib/tabs/ArchiveEdit.svelte new file mode 100644 index 0000000..80efaed --- /dev/null +++ b/frontend/src/lib/tabs/ArchiveEdit.svelte @@ -0,0 +1,68 @@ +<script lang="ts"> + import { addComic, updateArchives } from '$gql/Mutations'; + import { type FullArchiveFragment } from '$gql/graphql'; + import { getSelectionContext } from '$lib/Selection'; + import { toastFinally } from '$lib/Toasts'; + import AddButton from '$lib/components/AddButton.svelte'; + import Card, { comicCard } from '$lib/components/Card.svelte'; + import OrganizedButton from '$lib/components/OrganizedButton.svelte'; + import ComicPills from '$lib/pills/ComicPills.svelte'; + import SelectionControls from '$lib/toolbar/SelectionControls.svelte'; + import { getContextClient } from '@urql/svelte'; + import AddOverlay from './AddOverlay.svelte'; + + const client = getContextClient(); + const selection = getSelectionContext(); + + export let archive: FullArchiveFragment; + + function addNew() { + addComic(client, { + input: { + archive: { id: archive.id }, + title: archive.name, + pages: { ids: $selection.ids }, + cover: { id: archive.pages[$selection.indices.toSorted((a, b) => a - b)[0]].id } + } + }) + .then((mutatation) => { + const data = mutatation.addComic; + if (data.__typename === 'AddComicSuccess' && !data.archivePagesRemaining) { + $selection = $selection.clear(); + } else { + $selection = $selection.none(); + } + }) + .catch(toastFinally); + } + + function toggleOrganized() { + updateArchives(client, { ids: archive.id, input: { organized: !archive.organized } }).catch( + toastFinally + ); + } +</script> + +<div class="flex flex-col gap-4"> + <div class="flex gap-2 text-sm"> + <SelectionControls page> + <AddButton title="Add Comic from selected" on:click={addNew} /> + </SelectionControls> + <div class="grow" /> + <OrganizedButton organized={archive.organized} on:click={toggleOrganized} /> + </div> + + {#if archive.comics.length > 0} + <div class="flex flex-col gap-1"> + <h2 class="text-base font-medium">Comics</h2> + <div class="flex shrink-0 flex-col gap-4"> + {#each archive.comics as comic} + <Card compact {...comicCard(comic)}> + <AddOverlay slot="overlay" id={comic.id} /> + <ComicPills {comic} /> + </Card> + {/each} + </div> + </div> + {/if} +</div> diff --git a/frontend/src/lib/tabs/ComicDelete.svelte b/frontend/src/lib/tabs/ComicDelete.svelte new file mode 100644 index 0000000..a10f6b2 --- /dev/null +++ b/frontend/src/lib/tabs/ComicDelete.svelte @@ -0,0 +1,34 @@ +<script lang="ts"> + import { goto } from '$app/navigation'; + import { deleteComics } from '$gql/Mutations'; + import type { FullComicFragment } from '$gql/graphql'; + import { toastFinally } from '$lib/Toasts'; + import { confirmDeletion } from '$lib/Utils'; + import DeleteButton from '$lib/components/DeleteButton.svelte'; + import { getContextClient } from '@urql/svelte'; + + const client = getContextClient(); + + export let comic: FullComicFragment; + + function deleteComic() { + confirmDeletion('Comic', comic.title, () => { + deleteComics(client, { ids: comic.id }) + .then(() => goto('/comics/')) + .catch(toastFinally); + }); + } +</script> + +<div class="flex flex-col gap-2"> + <div> + <p> + Deleting this comic will make all of its pages available again for allocation. All of its + metadata will be lost. + </p> + <p class="mt-2 font-medium">This action is irrevocable.</p> + </div> + <div class="flex"> + <DeleteButton prominent on:click={deleteComic} /> + </div> +</div> diff --git a/frontend/src/lib/tabs/ComicDetails.svelte b/frontend/src/lib/tabs/ComicDetails.svelte new file mode 100644 index 0000000..0a131af --- /dev/null +++ b/frontend/src/lib/tabs/ComicDetails.svelte @@ -0,0 +1,121 @@ +<script lang="ts"> + import type { ComicFilter, FullComicFragment } from '$gql/graphql'; + import { CategoryLabel, CensorshipLabel, LanguageLabel, RatingLabel } from '$lib/Enums'; + import { href } from '$lib/Navigation'; + import { formatListSize, joinText } from '$lib/Utils'; + import AssociationPill from '$lib/pills/AssociationPill.svelte'; + import TagPill from '$lib/pills/TagPill.svelte'; + import { formatDistance, formatISO9075 } from 'date-fns'; + import Header from './DetailsHeader.svelte'; + import Section from './DetailsSection.svelte'; + + export let comic: FullComicFragment; + + const now = Date.now(); + const updatedDate = new Date(comic.updatedAt); + const createdDate = new Date(comic.createdAt); + + const title = joinText([ + comic.category ? CategoryLabel[comic.category] : '', + formatListSize('page', comic.pages.length) + ]); + + function filterFor(filter: keyof ComicFilter, id: number | string) { + return href('comics', { filter: { include: { [filter]: { all: [id] } } } }); + } +</script> + +<div class="flex flex-col gap-4 text-sm"> + <Header {title}> + {#if comic.url} + <a href={comic.url} target="_blank" rel="noreferrer" class="btn-slate" title="Open URL"> + <span class="icon-base icon-[material-symbols--link]" /> + </a> + {/if} + <a href={`/archives/${comic.archive.id}`} class="btn-slate" title="Go to Archive"> + <span class="icon-base icon-[material-symbols--folder-zip]" /> + </a> + </Header> + + <div class="grid grid-cols-3 gap-4"> + {#if comic.language} + <Section title="Language"> + <span>{LanguageLabel[comic.language]}</span> + </Section> + {/if} + {#if comic.censorship} + <Section title="Censorship"> + <span>{CensorshipLabel[comic.censorship]}</span> + </Section> + {/if} + {#if comic.rating} + <Section title="Rating"> + <span>{RatingLabel[comic.rating]}</span> + </Section> + {/if} + </div> + + <div class="grid grid-cols-3 gap-4"> + {#if comic.date} + <Section title="Released"> + <span>{formatISO9075(new Date(comic.date), { representation: 'date' })}</span> + </Section> + {/if} + <Section title="Created"> + <span title={formatISO9075(createdDate)}> + {formatDistance(createdDate, now, { addSuffix: true })} + </span> + </Section> + <Section title="Updated"> + <span title={formatISO9075(updatedDate)}> + {formatDistance(updatedDate, now, { addSuffix: true })} + </span> + </Section> + </div> + + {#if comic.artists.length} + <Section title="Artists"> + {#each comic.artists as { id, name } (id)} + <a href={filterFor('artists', id)}> + <AssociationPill {name} type="artist" /> + </a> + {/each} + </Section> + {/if} + {#if comic.circles.length} + <Section title="Circles"> + {#each comic.circles as { id, name } (id)} + <a href={filterFor('circles', id)}> + <AssociationPill {name} type="circle" /> + </a> + {/each} + </Section> + {/if} + {#if comic.characters.length} + <Section title="Characters"> + {#each comic.characters as { id, name } (id)} + <a href={filterFor('characters', id)}> + <AssociationPill {name} type="character" /> + </a> + {/each} + </Section> + {/if} + {#if comic.worlds.length} + <Section title="Worlds"> + {#each comic.worlds as { id, name } (id)} + <a href={filterFor('worlds', id)}> + <AssociationPill {name} type="world" /> + </a> + {/each} + </Section> + {/if} + {#if comic.tags.length} + <Section title="Tags"> + {#each comic.tags as { id, name, description } (id)} + <a href={filterFor('tags', id)}> + <TagPill {name} {description} /> + </a> + {/each} + </Section> + {/if} +</div> diff --git a/frontend/src/lib/tabs/DetailsHeader.svelte b/frontend/src/lib/tabs/DetailsHeader.svelte new file mode 100644 index 0000000..f980f75 --- /dev/null +++ b/frontend/src/lib/tabs/DetailsHeader.svelte @@ -0,0 +1,11 @@ +<script lang="ts"> + export let title: string; +</script> + +<div class="flex items-center gap-2"> + <h2 class="flex text-base"> + {title} + </h2> + <div class="grow"></div> + <slot /> +</div> diff --git a/frontend/src/lib/tabs/DetailsSection.svelte b/frontend/src/lib/tabs/DetailsSection.svelte new file mode 100644 index 0000000..9a6ad51 --- /dev/null +++ b/frontend/src/lib/tabs/DetailsSection.svelte @@ -0,0 +1,10 @@ +<script lang="ts"> + export let title: string; +</script> + +<section class="flex flex-col gap-1"> + <h2 class="text-base font-medium">{title}</h2> + <div class="flex flex-wrap gap-1 text-gray-300"> + <slot /> + </div> +</section> diff --git a/frontend/src/lib/tabs/Tab.svelte b/frontend/src/lib/tabs/Tab.svelte new file mode 100644 index 0000000..0a6be57 --- /dev/null +++ b/frontend/src/lib/tabs/Tab.svelte @@ -0,0 +1,14 @@ +<script lang="ts"> + import { getTabContext } from '$lib/Tabs'; + import { fadeDefault } from '$lib/Transitions'; + import { fade } from 'svelte/transition'; + + const context = getTabContext(); + export let id: string; +</script> + +{#if $context.current === id} + <div class="h-full overflow-auto py-2 pe-3" in:fade={fadeDefault}> + <slot /> + </div> +{/if} diff --git a/frontend/src/lib/tabs/Tabs.svelte b/frontend/src/lib/tabs/Tabs.svelte new file mode 100644 index 0000000..09cdbdd --- /dev/null +++ b/frontend/src/lib/tabs/Tabs.svelte @@ -0,0 +1,40 @@ +<script lang="ts"> + import { getTabContext } from '$lib/Tabs'; + import { fadeFast } from '$lib/Transitions'; + import { fade } from 'svelte/transition'; + + const context = getTabContext(); +</script> + +<div class="flex h-full max-h-full flex-col"> + <nav> + <ul class="me-3 flex border-b-2 border-slate-700 text-sm"> + {#each Object.entries($context.tabs) as [id, { title, badge }]} + <li class="-mb-0.5"> + <button + type="button" + class:active={$context.current === id} + class="relative flex gap-1 p-1 px-3 hover:border-b-2 hover:border-slate-200" + on:click={() => ($context.current = id)} + > + {#if badge} + <div + class="absolute right-0 top-1 h-2 w-2 rounded-full bg-emerald-400" + title="There are pending changes" + transition:fade={fadeFast} + /> + {/if} + <span>{title}</span> + </button> + </li> + {/each} + </ul> + </nav> + <slot /> +</div> + +<style lang="postcss"> + button.active { + @apply border-b-2 border-indigo-500; + } +</style> diff --git a/frontend/src/lib/toolbar/DeleteSelection.svelte b/frontend/src/lib/toolbar/DeleteSelection.svelte new file mode 100644 index 0000000..7459a87 --- /dev/null +++ b/frontend/src/lib/toolbar/DeleteSelection.svelte @@ -0,0 +1,26 @@ +<script lang="ts"> + import type { DeleteMutation } from '$gql/Mutations'; + import { getSelectionContext } from '$lib/Selection'; + import { toastFinally } from '$lib/Toasts'; + import { confirmDeletion } from '$lib/Utils'; + import DeleteButton from '$lib/components/DeleteButton.svelte'; + import { getContextClient } from '@urql/svelte'; + + const client = getContextClient(); + const selection = getSelectionContext(); + + export let mutation: DeleteMutation; + export let warning: string | undefined = undefined; + + function remove() { + const mutate = () => { + mutation(client, { ids: $selection.ids }) + .then(() => ($selection = $selection.clear())) + .catch(toastFinally); + }; + + confirmDeletion($selection.typename, $selection.names, mutate, warning); + } +</script> + +<DeleteButton on:click={remove} /> diff --git a/frontend/src/lib/toolbar/EditSelection.svelte b/frontend/src/lib/toolbar/EditSelection.svelte new file mode 100644 index 0000000..50e6656 --- /dev/null +++ b/frontend/src/lib/toolbar/EditSelection.svelte @@ -0,0 +1,29 @@ +<script lang="ts"> + import { getSelectionContext } from '$lib/Selection'; + import { accelerator } from '$lib/Shortcuts'; + import type { SvelteComponent } from 'svelte'; + import { openModal } from 'svelte-modals'; + + const selection = getSelectionContext(); + + export let dialog: typeof SvelteComponent<{ + isOpen: boolean; + ids: number[]; + }>; + + function edit() { + openModal(dialog, { + ids: $selection.ids + }); + } +</script> + +<button + type="button" + class="btn-slate hover:bg-blue-700" + title="Edit selection" + on:click={edit} + use:accelerator={'e'} +> + <span class="icon-base icon-[material-symbols--edit]" /> +</button> diff --git a/frontend/src/lib/toolbar/FilterBookmarked.svelte b/frontend/src/lib/toolbar/FilterBookmarked.svelte new file mode 100644 index 0000000..bcbe295 --- /dev/null +++ b/frontend/src/lib/toolbar/FilterBookmarked.svelte @@ -0,0 +1,24 @@ +<script lang="ts"> + import { page } from '$app/stores'; + import { ComicFilterContext, cycleBooleanFilter, getFilterContext } from '$lib/Filter'; + import { accelerator } from '$lib/Shortcuts'; + import Bookmark from '$lib/icons/Bookmark.svelte'; + + const filter = getFilterContext<ComicFilterContext>(); + $: bookmarked = $filter.include.controls.bookmarked.value; + + const toggle = () => { + $filter.include.controls.bookmarked.value = cycleBooleanFilter(bookmarked, false); + $filter.apply($page.url.searchParams); + }; +</script> + +<button + class:toggled={bookmarked} + class="btn-slate" + title="Filter bookmarked" + on:click={toggle} + use:accelerator={'b'} +> + <Bookmark {bookmarked} /> +</button> diff --git a/frontend/src/lib/toolbar/FilterFavourites.svelte b/frontend/src/lib/toolbar/FilterFavourites.svelte new file mode 100644 index 0000000..6591cef --- /dev/null +++ b/frontend/src/lib/toolbar/FilterFavourites.svelte @@ -0,0 +1,24 @@ +<script lang="ts"> + import { page } from '$app/stores'; + import { ComicFilterContext, cycleBooleanFilter, getFilterContext } from '$lib/Filter'; + import { accelerator } from '$lib/Shortcuts'; + import Star from '$lib/icons/Star.svelte'; + + const filter = getFilterContext<ComicFilterContext>(); + $: favourite = $filter.include.controls.favourite.value; + + const toggle = () => { + $filter.include.controls.favourite.value = cycleBooleanFilter(favourite, false); + $filter.apply($page.url.searchParams); + }; +</script> + +<button + class:toggled={favourite} + class="btn-slate" + title="Filter favourites" + on:click={toggle} + use:accelerator={'f'} +> + <Star {favourite} /> +</button> diff --git a/frontend/src/lib/toolbar/FilterOrganized.svelte b/frontend/src/lib/toolbar/FilterOrganized.svelte new file mode 100644 index 0000000..754e663 --- /dev/null +++ b/frontend/src/lib/toolbar/FilterOrganized.svelte @@ -0,0 +1,30 @@ +<script lang="ts"> + import { page } from '$app/stores'; + import { + ArchiveFilterContext, + ComicFilterContext, + cycleBooleanFilter, + getFilterContext + } from '$lib/Filter'; + import { accelerator } from '$lib/Shortcuts'; + import Organized from '$lib/icons/Organized.svelte'; + + const filter = getFilterContext<ArchiveFilterContext | ComicFilterContext>(); + $: organized = $filter.include.controls.organized.value; + + const toggle = () => { + $filter.include.controls.organized.value = cycleBooleanFilter(organized); + $filter.apply($page.url.searchParams); + }; +</script> + +<button + type="button" + class:toggled={organized !== undefined} + class="btn-slate" + title="Filter organized" + on:click={toggle} + use:accelerator={'o'} +> + <Organized tristate {organized} /> +</button> diff --git a/frontend/src/lib/toolbar/MarkBookmark.svelte b/frontend/src/lib/toolbar/MarkBookmark.svelte new file mode 100644 index 0000000..792b84f --- /dev/null +++ b/frontend/src/lib/toolbar/MarkBookmark.svelte @@ -0,0 +1,27 @@ +<script lang="ts"> + import { getSelectionContext } from '$lib/Selection'; + import { toastFinally } from '$lib/Toasts'; + import Bookmark from '$lib/icons/Bookmark.svelte'; + import { Client, getContextClient } from '@urql/svelte'; + + const client = getContextClient(); + const selection = getSelectionContext(); + + export let mutation: ( + client: Client, + args: { ids: number[]; input: { bookmarked: boolean } } + ) => Promise<unknown>; + + function mutate(bookmarked: boolean) { + mutation(client, { ids: $selection.ids, input: { bookmarked } }).catch(toastFinally); + } +</script> + +<button type="button" class="btn-slate flex justify-start gap-1" on:click={() => mutate(true)}> + <Bookmark bookmarked={true} /> + <span>Bookmark</span> +</button> +<button type="button" class="btn-slate flex justify-start gap-1" on:click={() => mutate(false)}> + <Bookmark bookmarked={false} /> + <span>Unbookmark</span> +</button> diff --git a/frontend/src/lib/toolbar/MarkFavourite.svelte b/frontend/src/lib/toolbar/MarkFavourite.svelte new file mode 100644 index 0000000..42eaa39 --- /dev/null +++ b/frontend/src/lib/toolbar/MarkFavourite.svelte @@ -0,0 +1,27 @@ +<script lang="ts"> + import { getSelectionContext } from '$lib/Selection'; + import { toastFinally } from '$lib/Toasts'; + import Star from '$lib/icons/Star.svelte'; + import { Client, getContextClient } from '@urql/svelte'; + + const client = getContextClient(); + const selection = getSelectionContext(); + + export let mutation: ( + client: Client, + args: { ids: number[]; input: { favourite: boolean } } + ) => Promise<unknown>; + + function mutate(favourite: boolean) { + mutation(client, { ids: $selection.ids, input: { favourite } }).catch(toastFinally); + } +</script> + +<button type="button" class="btn-slate justify-start gap-1" on:click={() => mutate(true)}> + <Star favourite={true} /> + <span>Favourite</span> +</button> +<button type="button" class="btn-slate justify-start gap-1" on:click={() => mutate(false)}> + <Star favourite={false} /> + <span>Unfavourite</span> +</button> diff --git a/frontend/src/lib/toolbar/MarkOrganized.svelte b/frontend/src/lib/toolbar/MarkOrganized.svelte new file mode 100644 index 0000000..4dc3a83 --- /dev/null +++ b/frontend/src/lib/toolbar/MarkOrganized.svelte @@ -0,0 +1,27 @@ +<script lang="ts"> + import { getSelectionContext } from '$lib/Selection'; + import { toastFinally } from '$lib/Toasts'; + import Organized from '$lib/icons/Organized.svelte'; + import { Client, getContextClient } from '@urql/svelte'; + + const client = getContextClient(); + const selection = getSelectionContext(); + + export let mutation: ( + client: Client, + args: { ids: number[]; input: { organized: boolean } } + ) => Promise<unknown>; + + function mutate(organized: boolean) { + mutation(client, { ids: $selection.ids, input: { organized } }).catch(toastFinally); + } +</script> + +<button type="button" class="btn-slate flex justify-start gap-1" on:click={() => mutate(true)}> + <Organized tristate organized={true} /> + <span>Organized</span> +</button> +<button type="button" class="btn-slate flex justify-start gap-1" on:click={() => mutate(false)}> + <Organized dim tristate organized={false} /> + <span>Unorganized</span> +</button> diff --git a/frontend/src/lib/toolbar/MarkSelection.svelte b/frontend/src/lib/toolbar/MarkSelection.svelte new file mode 100644 index 0000000..27eb2c7 --- /dev/null +++ b/frontend/src/lib/toolbar/MarkSelection.svelte @@ -0,0 +1,24 @@ +<script lang="ts"> + import Dropdown from '$lib/components/Dropdown.svelte'; + + let visible = false; + let button: HTMLElement; +</script> + +<div class="relative"> + <button + type="button" + class="btn-slate rounded-inherit relative hover:bg-blue-700 [&:not(:only-child)]:bg-blue-700" + title="Set flag..." + bind:this={button} + on:click={() => (visible = !visible)} + > + <span class="icon-base icon-[material-symbols--flag] pointer-events-none" /> + </button> + + <Dropdown parent={button} bind:visible> + <div class="grid grid-cols-[min-content_min-content] gap-1"> + <slot /> + </div> + </Dropdown> +</div> diff --git a/frontend/src/lib/toolbar/Search.svelte b/frontend/src/lib/toolbar/Search.svelte new file mode 100644 index 0000000..f033258 --- /dev/null +++ b/frontend/src/lib/toolbar/Search.svelte @@ -0,0 +1,21 @@ +<script lang="ts"> + import { page } from '$app/stores'; + import { debounce } from '$lib/Actions'; + import { BasicFilterContext, getFilterContext } from '$lib/Filter'; + import { accelerator } from '$lib/Shortcuts'; + + const filter = getFilterContext<BasicFilterContext>(); + + export let name: string; + export let field: string; +</script> + +<input + type="text" + size={25} + class="btn-slate w-min" + placeholder="Search {name}..." + bind:value={field} + use:debounce={{ callback: () => $filter.apply($page.url.searchParams) }} + use:accelerator={'F'} +/> diff --git a/frontend/src/lib/toolbar/SelectItems.svelte b/frontend/src/lib/toolbar/SelectItems.svelte new file mode 100644 index 0000000..7ff339e --- /dev/null +++ b/frontend/src/lib/toolbar/SelectItems.svelte @@ -0,0 +1,19 @@ +<script lang="ts"> + import { page } from '$app/stores'; + import { getPaginationContext } from '$lib/Pagination'; + + const pagination = getPaginationContext(); + + $: values = new Set([24, 48, 72, 90, 120, 150, 180, $pagination.items].sort((a, b) => a - b)); +</script> + +<select + class="btn-slate" + bind:value={$pagination.items} + on:change={() => $pagination.apply($page.url.searchParams)} + title="Limit displayed items to..." +> + {#each values as value} + <option {value}>{value}</option> + {/each} +</select> diff --git a/frontend/src/lib/toolbar/SelectSort.svelte b/frontend/src/lib/toolbar/SelectSort.svelte new file mode 100644 index 0000000..fdcb057 --- /dev/null +++ b/frontend/src/lib/toolbar/SelectSort.svelte @@ -0,0 +1,61 @@ +<script lang="ts"> + import { page } from '$app/stores'; + import { SortDirection } from '$gql/graphql'; + + import { getSortContext } from '$lib/Sort'; + import { slideXFast } from '$lib/Transitions'; + import { getRandomInt } from '$lib/Utils'; + import { slide } from 'svelte/transition'; + + const sort = getSortContext(); + + function toggle() { + if ($sort.direction === SortDirection.Ascending) { + $sort.direction = SortDirection.Descending; + } else { + $sort.direction = SortDirection.Ascending; + } + + apply(); + } + + function apply() { + if ($sort.on === 'RANDOM' && $sort.seed === undefined) { + $sort.seed = getRandomInt(0, 1000000000); + } + $sort.apply($page.url.searchParams); + } + + function reshuffle() { + $sort.seed = undefined; + apply(); + } +</script> + +<div class="rounded-group flex flex-row"> + <select class="btn-slate" bind:value={$sort.on} on:change={apply} title="Sort on..."> + {#each Object.entries($sort.labels) as [value, label]} + <option {value}>{label}</option> + {/each} + </select> + <button type="button" class="btn-slate" title="Toggle sort direction" on:click={toggle}> + {#if $sort.direction === SortDirection.Ascending} + <span class="icon-base icon-[material-symbols--sort] -scale-y-100" /> + {:else} + <span class="icon-base icon-[material-symbols--sort]" /> + {/if} + </button> + {#if $sort.on === 'RANDOM'} + <button + type="button" + class="btn-slate" + title="Reshuffle" + on:click={reshuffle} + transition:slide={slideXFast} + > + <div class="flex"> + <span class="icon-base icon-[material-symbols--shuffle]" /> + </div> + </button> + {/if} +</div> diff --git a/frontend/src/lib/toolbar/SelectionControls.svelte b/frontend/src/lib/toolbar/SelectionControls.svelte new file mode 100644 index 0000000..4d309df --- /dev/null +++ b/frontend/src/lib/toolbar/SelectionControls.svelte @@ -0,0 +1,57 @@ +<script lang="ts"> + import { getSelectionContext } from '$lib/Selection'; + import { accelerator } from '$lib/Shortcuts'; + import { fadeDefault, slideXFast } from '$lib/Transitions'; + import Badge from '$lib/components/Badge.svelte'; + import { onDestroy } from 'svelte'; + import { fade, slide } from 'svelte/transition'; + + const selection = getSelectionContext(); + + export let page = false; + + const toggle = () => ($selection = $selection.toggle()); + const all = () => ($selection = $selection.all()); + const none = () => ($selection = $selection.none()); + + onDestroy(() => ($selection = $selection.clear())); +</script> + +<div class="rounded-group flex"> + <button + type="button" + class="btn-slate relative" + class:toggled={$selection.active} + title={`${$selection.active ? 'Exit' : 'Enter'} ${page ? 'page ' : ' '}selection mode`} + on:click={toggle} + use:accelerator={'s'} + > + {#if $selection.active} + {#if page} + <span class="icon-base icon-[material-symbols--edit-document]" /> + {:else} + <span class="icon-base icon-[material-symbols--remove-selection]" /> + {/if} + {:else if page} + <span class="icon-base icon-[material-symbols--edit-document-outline]" /> + {:else} + <span class="icon-base icon-[material-symbols--select]" /> + {/if} + <Badge number={$selection.size} /> + </button> + {#if $selection.active} + <div class="rounded-group-end flex" transition:slide={slideXFast}> + <button type="button" class="btn-slate" title="Select all" on:click={all}> + <span class="icon-base icon-[material-symbols--select-all]" /> + </button> + <button type="button" class="btn-slate" title="Select none" on:click={none}> + <span class="icon-base icon-[material-symbols--deselect]" /> + </button> + </div> + {/if} +</div> +{#if $selection.size > 0} + <div class="rounded-group flex" transition:fade={fadeDefault}> + <slot /> + </div> +{/if} diff --git a/frontend/src/lib/toolbar/ToggleAdvancedFilters.svelte b/frontend/src/lib/toolbar/ToggleAdvancedFilters.svelte new file mode 100644 index 0000000..2e7869f --- /dev/null +++ b/frontend/src/lib/toolbar/ToggleAdvancedFilters.svelte @@ -0,0 +1,40 @@ +<script lang="ts"> + import { page } from '$app/stores'; + import { getFilterContext } from '$lib/Filter'; + import { navigate } from '$lib/Navigation'; + import { slideXFast } from '$lib/Transitions'; + import Badge from '$lib/components/Badge.svelte'; + import { slide } from 'svelte/transition'; + import { getToolbarContext } from './Toolbar.svelte'; + + const toolbar = getToolbarContext(); + const filter = getFilterContext(); +</script> + +<div class="rounded-group flex"> + <button + class:toggled={$toolbar.expand} + class="btn-slate relative" + title={`${$toolbar.expand ? 'Hide' : 'Show'} filters`} + on:click={() => ($toolbar.expand = !$toolbar.expand)} + > + {#if $toolbar.expand} + <span class="icon-base icon-[material-symbols--filter-alt]" /> + {:else} + <span class="icon-base icon-[material-symbols--filter-alt-outline]" /> + {/if} + <Badge number={$filter.include.size + $filter.exclude.size} /> + </button> + {#if $filter.include.size + $filter.exclude.size > 0} + <button + class="btn-slate relative hover:bg-rose-700" + on:click={() => navigate({ filter: {} }, $page.url.searchParams)} + transition:slide={slideXFast} + title="Reset filters" + > + <div class="flex"> + <span class="icon-base icon-[material-symbols--filter-alt-off]" /> + </div> + </button> + {/if} +</div> diff --git a/frontend/src/lib/toolbar/Toolbar.svelte b/frontend/src/lib/toolbar/Toolbar.svelte new file mode 100644 index 0000000..e87d731 --- /dev/null +++ b/frontend/src/lib/toolbar/Toolbar.svelte @@ -0,0 +1,42 @@ +<script lang="ts" context="module"> + import { writable, type Writable } from 'svelte/store'; + + interface ToolbarContext { + expand: boolean; + } + + function initToolbarContext() { + return setContext<Writable<ToolbarContext>>('toolbar', writable({ expand: false })); + } + + export function getToolbarContext() { + return getContext<Writable<ToolbarContext>>('toolbar'); + } +</script> + +<script lang="ts"> + import { getContext, setContext } from 'svelte'; + + const toolbar = initToolbarContext(); +</script> + +<div class="flex flex-col"> + <div + class="flex flex-row flex-wrap gap-4 text-sm xl:grid xl:grid-flow-col xl:grid-cols-[1fr_2fr_1fr]" + > + <div class="flex flex-row justify-start gap-2"> + <slot name="start" /> + </div> + <div class="flex flex-row flex-wrap justify-start gap-2 xl:flex-nowrap xl:justify-center"> + <slot name="center" /> + </div> + <div class="flex flex-row justify-end gap-2"> + <slot name="end" /> + </div> + </div> + {#if $toolbar.expand} + <div class="mt-4"> + <slot /> + </div> + {/if} +</div> diff --git a/frontend/src/routes/+layout.svelte b/frontend/src/routes/+layout.svelte new file mode 100644 index 0000000..0eefed1 --- /dev/null +++ b/frontend/src/routes/+layout.svelte @@ -0,0 +1,95 @@ +<script lang="ts"> + import { addShortcut, handleShortcuts } from '$lib/Shortcuts'; + import { fadeDefault } from '$lib/Transitions'; + import AddArtist from '$lib/dialogs/AddArtist.svelte'; + import AddCharacter from '$lib/dialogs/AddCharacter.svelte'; + import AddCircle from '$lib/dialogs/AddCircle.svelte'; + import AddNamespace from '$lib/dialogs/AddNamespace.svelte'; + import AddTag from '$lib/dialogs/AddTag.svelte'; + import AddWorld from '$lib/dialogs/AddWorld.svelte'; + import Link from '$lib/navigation/Link.svelte'; + import Navigation from '$lib/navigation/Navigation.svelte'; + import { cacheExchange, fetchExchange, initContextClient } from '@urql/svelte'; + import { SvelteToast } from '@zerodevx/svelte-toast'; + import { Modals, closeModal, openModal } from 'svelte-modals'; + import { fade } from 'svelte/transition'; + import '../app.css'; + + initContextClient({ + url: import.meta.env.VITE_GQL_ENDPOINT ?? '/graphql', + exchanges: [cacheExchange, fetchExchange] + }); + + addShortcut('na', () => openModal(AddArtist)); + addShortcut('nh', () => openModal(AddCharacter)); + addShortcut('ni', () => openModal(AddCircle)); + addShortcut('nn', () => openModal(AddNamespace)); + addShortcut('nt', () => openModal(AddTag)); + addShortcut('nw', () => openModal(AddWorld)); + + function keydown(event: KeyboardEvent) { + handleShortcuts(event); + } +</script> + +<svelte:document on:keydown={keydown} /> + +<Navigation> + <Link matchExact href="/" title="Home" accel="go"> + <span class="icon-base icon-[material-symbols--home]" /> + </Link> + <Link href="/comics/" title="Comics" accel="gc"> + <span class="icon-base icon-[material-symbols--menu-book]" /> + </Link> + <Link href="/namespaces/" title="Namespaces" accel="gn"> + <span class="icon-base icon-[material-symbols--inbox]" /> + </Link> + <Link href="/tags/" title="Tags" accel="gt"> + <span class="icon-base icon-[material-symbols--label]" /> + </Link> + <Link href="/artists/" title="Artists" accel="ga"> + <span class="icon-base icon-[material-symbols--person]" /> + </Link> + <Link href="/circles/" title="Circles" accel="gi"> + <span class="icon-base icon-[material-symbols--group]" /> + </Link> + <Link href="/characters/" title="Characters" accel="gh"> + <span class="icon-base icon-[material-symbols--face]" /> + </Link> + <Link href="/worlds/" title="Worlds" accel="gw"> + <span class="icon-base icon-[material-symbols--public]" /> + </Link> + <Link href="/archives/" title="Archives" accel="gz"> + <span class="icon-base icon-[material-symbols--folder-zip]" /> + </Link> + <div class="mb-auto" /> + <Link href="/help/" title="Help" accel="?" target="_blank"> + <span class="icon-base icon-[material-symbols--help]" /> + </Link> +</Navigation> + +<div class="min-w-[360px] overflow-auto p-4"> + <slot /> +</div> + +<Modals> + <!-- svelte-ignore a11y-no-static-element-interactions --> + <!-- svelte-ignore a11y-click-events-have-key-events --> + <div + slot="backdrop" + on:click={closeModal} + transition:fade={fadeDefault} + class="fixed bottom-0 left-0 right-0 top-0 z-20 bg-stone-800/80" + /> +</Modals> + +<SvelteToast options={{ reversed: true, intro: { y: 192 } }} /> + +<style> + :root { + --toastBarHeight: 0; + --toastContainerTop: auto; + --toastContainerLeft: 4rem; + --toastContainerBottom: 1rem; + } +</style> diff --git a/frontend/src/routes/+layout.ts b/frontend/src/routes/+layout.ts new file mode 100644 index 0000000..a3d1578 --- /dev/null +++ b/frontend/src/routes/+layout.ts @@ -0,0 +1 @@ +export const ssr = false; diff --git a/frontend/src/routes/+page.svelte b/frontend/src/routes/+page.svelte new file mode 100644 index 0000000..97a7a60 --- /dev/null +++ b/frontend/src/routes/+page.svelte @@ -0,0 +1,66 @@ +<script lang="ts"> + import { version } from '$app/environment'; + import { frontpageQuery } from '$gql/Queries'; + import { ComicSort, SortDirection } from '$gql/graphql'; + import { codename } from '$lib/Meta'; + import { href } from '$lib/Navigation'; + import { fadeDefault } from '$lib/Transitions'; + import logo from '$lib/assets/logo.webp'; + import Card, { comicCard } from '$lib/components/Card.svelte'; + import Guard from '$lib/components/Guard.svelte'; + import Head from '$lib/components/Head.svelte'; + import Carousel from '$lib/containers/Carousel.svelte'; + import { getContextClient } from '@urql/svelte'; + import { fade } from 'svelte/transition'; + + const bookmarkLink = href('comics', { filter: { include: { bookmarked: true } } }); + const recentLink = href('comics', { + sort: { on: ComicSort.CreatedAt, direction: SortDirection.Descending } + }); + const favouriteLink = href('comics', { filter: { include: { favourite: true } } }); + + $: query = frontpageQuery(getContextClient()); + $: recent = $query.data?.recent; + $: favourites = $query.data?.favourites; + $: bookmarked = $query.data?.bookmarked; +</script> + +<Head section="Home" /> + +<div class="flex flex-col justify-center gap-16 xl:flex-row"> + {#if $query.data} + <div class="flex flex-col items-center gap-1"> + <img src={logo} width="512" height="512" class="min-w-[400px]" alt="" /> + <h1 class="text-4xl font-medium"> + <span>hircine</span> + <span>{version}</span> + </h1> + <h2 class="text-2xl font-light text-zinc-400">{codename}</h2> + </div> + <div class="flex flex-col gap-8" in:fade={fadeDefault}> + {#if recent && recent.count > 0} + <Carousel title="Recently added" href={recentLink}> + {#each recent.edges as comic} + <Card coverOnly {...comicCard(comic)} /> + {/each} + </Carousel> + {/if} + {#if favourites && favourites.count > 0} + <Carousel title="Favourites" href={favouriteLink}> + {#each favourites.edges as comic} + <Card coverOnly {...comicCard(comic)} /> + {/each} + </Carousel> + {/if} + {#if bookmarked && bookmarked.count > 0} + <Carousel title="Bookmarks" href={bookmarkLink}> + {#each bookmarked.edges as comic} + <Card coverOnly {...comicCard(comic)} /> + {/each} + </Carousel> + {/if} + </div> + {:else} + <Guard result={query} /> + {/if} +</div> diff --git a/frontend/src/routes/archives/+page.svelte b/frontend/src/routes/archives/+page.svelte new file mode 100644 index 0000000..545058a --- /dev/null +++ b/frontend/src/routes/archives/+page.svelte @@ -0,0 +1,119 @@ +<script lang="ts"> + import { deleteArchives, updateArchives } from '$gql/Mutations'; + import { archivesQuery } from '$gql/Queries'; + import type { ArchiveFragment } from '$gql/graphql'; + import { ArchiveSortLabel } from '$lib/Enums'; + import { ArchiveFilterContext, initFilterContext } from '$lib/Filter'; + import { initPaginationContext } from '$lib/Pagination'; + import { initSelectionContext } from '$lib/Selection'; + import { initSortContext } from '$lib/Sort'; + import Card from '$lib/components/Card.svelte'; + import Empty from '$lib/components/Empty.svelte'; + import Guard from '$lib/components/Guard.svelte'; + import Head from '$lib/components/Head.svelte'; + import RefreshButton from '$lib/components/RefreshButton.svelte'; + import Cards from '$lib/containers/Cards.svelte'; + import Column from '$lib/containers/Column.svelte'; + import Pagination from '$lib/pagination/Pagination.svelte'; + import Pill from '$lib/pills/Pill.svelte'; + import Selectable from '$lib/selection/Selectable.svelte'; + import SelectionOverlay from '$lib/selection/SelectionOverlay.svelte'; + import DeleteSelection from '$lib/toolbar/DeleteSelection.svelte'; + import FilterOrganized from '$lib/toolbar/FilterOrganized.svelte'; + import MarkOrganized from '$lib/toolbar/MarkOrganized.svelte'; + import MarkSelection from '$lib/toolbar/MarkSelection.svelte'; + import Search from '$lib/toolbar/Search.svelte'; + import SelectItems from '$lib/toolbar/SelectItems.svelte'; + import SelectSort from '$lib/toolbar/SelectSort.svelte'; + import SelectionControls from '$lib/toolbar/SelectionControls.svelte'; + import Toolbar from '$lib/toolbar/Toolbar.svelte'; + import { getContextClient } from '@urql/svelte'; + import { filesize } from 'filesize'; + import type { PageData } from './$types'; + + let client = getContextClient(); + + export let data: PageData; + + $: result = archivesQuery(client, { + pagination: data.pagination, + filter: data.filter, + sort: data.sort + }); + + $: archives = $result.data?.archives; + + const selection = initSelectionContext<ArchiveFragment>('Archive', (a) => a.name); + $: if (archives) { + $selection.view = archives.edges; + $pagination.total = archives.count; + } + + const pagination = initPaginationContext(); + $: $pagination.update = data.pagination; + + const filter = initFilterContext<ArchiveFilterContext>(); + $: $filter = new ArchiveFilterContext(data.filter); + + const sort = initSortContext(data.sort, ArchiveSortLabel); + $: $sort.update = data.sort; + + function refresh() { + result.reexecute({ requestPolicy: 'network-only' }); + } +</script> + +<Head section="Archives" /> + +<Column> + <Toolbar> + <SelectionControls slot="start"> + <MarkSelection> + <MarkOrganized mutation={updateArchives} /> + </MarkSelection> + <DeleteSelection + mutation={deleteArchives} + warning="Deleting an archive will also delete its archive file on disk as well as all comics that belong to it." + /> + </SelectionControls> + <svelte:fragment slot="center"> + <Search name="Archives" bind:field={$filter.include.controls.path.contains} /> + <FilterOrganized /> + <SelectSort /> + <SelectItems /> + </svelte:fragment> + <RefreshButton slot="end" on:click={refresh} /> + </Toolbar> + {#if archives} + <Pagination /> + <main> + <Cards> + {#each archives.edges as { id, name, cover, size, pageCount }, index (id)} + <Selectable {index} {id} let:handle let:selected> + <Card + ellipsis={false} + href={id.toString()} + details={{ title: name, cover: cover }} + on:click={handle} + > + <SelectionOverlay position="left" {selected} slot="overlay" /> + <div class="flex gap-1 text-xs"> + <Pill name={`${pageCount} pages`}> + <span class="icon-[material-symbols--note] mr-0.5" slot="icon" /> + </Pill> + <Pill name={filesize(size, { base: 2 })}> + <span class="icon-[material-symbols--hard-drive] mr-0.5" slot="icon" /> + </Pill> + </div> + </Card> + </Selectable> + {:else} + <Empty /> + {/each} + </Cards> + </main> + <Pagination /> + {:else} + <Guard {result} /> + {/if} +</Column> diff --git a/frontend/src/routes/archives/+page.ts b/frontend/src/routes/archives/+page.ts new file mode 100644 index 0000000..88acade --- /dev/null +++ b/frontend/src/routes/archives/+page.ts @@ -0,0 +1,12 @@ +import { ArchiveSort, type ArchiveFilterInput } from '$gql/graphql'; +import { parseFilter, parsePaginationData, parseSortData } from '$lib/Navigation'; + +export const trailingSlash = 'always'; + +export function load({ url }: { url: URL; params: Record<string, string> }) { + return { + sort: parseSortData(url.searchParams, ArchiveSort.Path), + filter: parseFilter<ArchiveFilterInput>(url.searchParams), + pagination: parsePaginationData(url.searchParams, 24) + }; +} diff --git a/frontend/src/routes/archives/[id]/+page.svelte b/frontend/src/routes/archives/[id]/+page.svelte new file mode 100644 index 0000000..50a2940 --- /dev/null +++ b/frontend/src/routes/archives/[id]/+page.svelte @@ -0,0 +1,99 @@ +<script lang="ts"> + import { updateArchives } from '$gql/Mutations'; + import { archiveQuery } from '$gql/Queries'; + import { Direction, Layout, type FullArchiveFragment, type PageFragment } from '$gql/graphql'; + import { initReaderContext } from '$lib/Reader'; + import { initSelectionContext } from '$lib/Selection'; + import { setTabContext } from '$lib/Tabs'; + import { toastFinally } from '$lib/Toasts'; + import Guard from '$lib/components/Guard.svelte'; + import Head from '$lib/components/Head.svelte'; + import Titlebar from '$lib/components/Titlebar.svelte'; + import Grid from '$lib/containers/Grid.svelte'; + import Gallery from '$lib/gallery/Gallery.svelte'; + import PageView from '$lib/reader/PageView.svelte'; + import Reader from '$lib/reader/Reader.svelte'; + import ArchiveDelete from '$lib/tabs/ArchiveDelete.svelte'; + import ArchiveDetails from '$lib/tabs/ArchiveDetails.svelte'; + import ArchiveEdit from '$lib/tabs/ArchiveEdit.svelte'; + import Tab from '$lib/tabs/Tab.svelte'; + import Tabs from '$lib/tabs/Tabs.svelte'; + import { getContextClient } from '@urql/svelte'; + import type { PageData } from './$types'; + + export let data: PageData; + const client = getContextClient(); + const reader = initReaderContext(); + setTabContext({ + tabs: { + details: { title: 'Details' }, + edit: { title: 'Edit' }, + deletion: { title: 'Delete' } + }, + current: 'details' + }); + + $: result = archiveQuery(client, { id: data.id }); + + function updateCover(event: CustomEvent<number>) { + updateArchives(client, { ids: archive.id, input: { cover: { id: event.detail } } }).catch( + toastFinally + ); + } + + let archive: FullArchiveFragment; + + $: $result, update(); + function update() { + if (!$result.stale && $result.data?.archive.__typename === 'FullArchive') { + archive = structuredClone($result.data.archive); + + $reader.pages = archive.pages; + } + } + + const selection = initSelectionContext<PageFragment>('Page', (p) => p.path); + $selection.selectable = (p) => p.comicId === null; + + $: if (archive) { + $selection.view = archive.pages; + } +</script> + +<Head section="Archive" title={archive?.name} /> + +{#if archive} + <Grid> + <header> + <Titlebar title={archive.name} /> + </header> + + <aside> + <Tabs> + <Tab id="details"> + <ArchiveDetails {archive} /> + </Tab> + <Tab id="edit"> + <ArchiveEdit {archive} /> + </Tab> + <Tab id="deletion"> + <ArchiveDelete {archive} /> + </Tab> + </Tabs> + </aside> + + <main class="overflow-auto"> + <Gallery + pages={archive.pages} + on:open={(e) => ($reader = $reader.open(e.detail))} + on:cover={updateCover} + /> + </main> + </Grid> +{:else} + <Guard {result} /> +{/if} + +<Reader> + <PageView layout={Layout.Single} direction={Direction.LeftToRight} /> +</Reader> diff --git a/frontend/src/routes/archives/[id]/+page.ts b/frontend/src/routes/archives/[id]/+page.ts new file mode 100644 index 0000000..d872ba2 --- /dev/null +++ b/frontend/src/routes/archives/[id]/+page.ts @@ -0,0 +1,5 @@ +export function load({ params }: { params: Record<string, string> }) { + return { + id: +params.id + }; +} diff --git a/frontend/src/routes/artists/+page.svelte b/frontend/src/routes/artists/+page.svelte new file mode 100644 index 0000000..e07338c --- /dev/null +++ b/frontend/src/routes/artists/+page.svelte @@ -0,0 +1,101 @@ +<script lang="ts"> + import { deleteArtists } from '$gql/Mutations'; + import { artistsQuery, fetchArtist } from '$gql/Queries'; + import type { Artist } from '$gql/graphql'; + import { ArtistSortLabel } from '$lib/Enums'; + import { BasicFilterContext, initFilterContext } from '$lib/Filter'; + import { initPaginationContext } from '$lib/Pagination'; + import { initSelectionContext } from '$lib/Selection'; + import { initSortContext } from '$lib/Sort'; + import { toastFinally } from '$lib/Toasts'; + import AddButton from '$lib/components/AddButton.svelte'; + import Cardlet from '$lib/components/Cardlet.svelte'; + import Empty from '$lib/components/Empty.svelte'; + import Guard from '$lib/components/Guard.svelte'; + import Head from '$lib/components/Head.svelte'; + import Cardlets from '$lib/containers/Cardlets.svelte'; + import Column from '$lib/containers/Column.svelte'; + import AddArtist from '$lib/dialogs/AddArtist.svelte'; + import EditArtist from '$lib/dialogs/EditArtist.svelte'; + import Pagination from '$lib/pagination/Pagination.svelte'; + import Selectable from '$lib/selection/Selectable.svelte'; + import SelectionOverlay from '$lib/selection/SelectionOverlay.svelte'; + import DeleteSelection from '$lib/toolbar/DeleteSelection.svelte'; + import Search from '$lib/toolbar/Search.svelte'; + import SelectItems from '$lib/toolbar/SelectItems.svelte'; + import SelectSort from '$lib/toolbar/SelectSort.svelte'; + import SelectionControls from '$lib/toolbar/SelectionControls.svelte'; + import Toolbar from '$lib/toolbar/Toolbar.svelte'; + import { getContextClient } from '@urql/svelte'; + import { openModal } from 'svelte-modals'; + import type { PageData } from './$types'; + + const client = getContextClient(); + export let data: PageData; + + $: result = artistsQuery(client, { + pagination: data.pagination, + filter: data.filter, + sort: data.sort + }); + + $: artists = $result.data?.artists; + + const selection = initSelectionContext<Artist>('Artist', (a) => a.name); + $: if (artists) { + $selection.view = artists.edges; + $pagination.total = artists.count; + } + + const filter = initFilterContext<BasicFilterContext>(); + $: $filter = new BasicFilterContext(data.filter); + + const sort = initSortContext(data.sort, ArtistSortLabel); + $: $sort.update = data.sort; + + const pagination = initPaginationContext(); + $: $pagination.update = data.pagination; + + const edit = (id: number) => { + fetchArtist(client, id) + .then((artist) => openModal(EditArtist, { artist })) + .catch(toastFinally); + }; +</script> + +<Head section="artists" /> + +<Column> + <Toolbar> + <SelectionControls slot="start"> + <DeleteSelection mutation={deleteArtists} /> + </SelectionControls> + <svelte:fragment slot="center"> + <Search name="Artists" bind:field={$filter.include.controls.name.contains} /> + <SelectSort /> + <SelectItems /> + </svelte:fragment> + <svelte:fragment slot="end"> + <AddButton title="Add Artist" on:click={() => openModal(AddArtist)} /> + </svelte:fragment> + </Toolbar> + {#if artists} + <Pagination /> + <main> + <Cardlets> + {#each artists.edges as { id, name }, index (id)} + <Selectable {index} {id} {edit} let:handle let:selected> + <Cardlet {name} on:click={handle} filter="artists" {id}> + <SelectionOverlay slot="overlay" position="right" centered {selected} /> + </Cardlet> + </Selectable> + {:else} + <Empty /> + {/each} + </Cardlets> + </main> + <Pagination /> + {:else} + <Guard {result} /> + {/if} +</Column> diff --git a/frontend/src/routes/artists/+page.ts b/frontend/src/routes/artists/+page.ts new file mode 100644 index 0000000..5a76550 --- /dev/null +++ b/frontend/src/routes/artists/+page.ts @@ -0,0 +1,12 @@ +import { ArtistSort, type ArtistFilterInput } from '$gql/graphql'; +import { parseFilter, parsePaginationData, parseSortData } from '$lib/Navigation'; + +export const trailingSlash = 'always'; + +export function load({ url }: { url: URL; params: Record<string, string> }) { + return { + sort: parseSortData(url.searchParams, ArtistSort.Name), + filter: parseFilter<ArtistFilterInput>(url.searchParams), + pagination: parsePaginationData(url.searchParams) + }; +} diff --git a/frontend/src/routes/characters/+page.svelte b/frontend/src/routes/characters/+page.svelte new file mode 100644 index 0000000..0934bab --- /dev/null +++ b/frontend/src/routes/characters/+page.svelte @@ -0,0 +1,101 @@ +<script lang="ts"> + import { deleteCharacters } from '$gql/Mutations'; + import { charactersQuery, fetchCharacter } from '$gql/Queries'; + import type { Character } from '$gql/graphql'; + import { CharacterSortLabel } from '$lib/Enums'; + import { BasicFilterContext, initFilterContext } from '$lib/Filter'; + import { initPaginationContext } from '$lib/Pagination'; + import { initSelectionContext } from '$lib/Selection'; + import { initSortContext } from '$lib/Sort'; + import { toastFinally } from '$lib/Toasts'; + import AddButton from '$lib/components/AddButton.svelte'; + import Cardlet from '$lib/components/Cardlet.svelte'; + import Empty from '$lib/components/Empty.svelte'; + import Guard from '$lib/components/Guard.svelte'; + import Head from '$lib/components/Head.svelte'; + import Cardlets from '$lib/containers/Cardlets.svelte'; + import Column from '$lib/containers/Column.svelte'; + import AddCharacter from '$lib/dialogs/AddCharacter.svelte'; + import EditCharacter from '$lib/dialogs/EditCharacter.svelte'; + import Pagination from '$lib/pagination/Pagination.svelte'; + import Selectable from '$lib/selection/Selectable.svelte'; + import SelectionOverlay from '$lib/selection/SelectionOverlay.svelte'; + import DeleteSelection from '$lib/toolbar/DeleteSelection.svelte'; + import Search from '$lib/toolbar/Search.svelte'; + import SelectItems from '$lib/toolbar/SelectItems.svelte'; + import SelectSort from '$lib/toolbar/SelectSort.svelte'; + import SelectionControls from '$lib/toolbar/SelectionControls.svelte'; + import Toolbar from '$lib/toolbar/Toolbar.svelte'; + import { getContextClient } from '@urql/svelte'; + import { openModal } from 'svelte-modals'; + import type { PageData } from './$types'; + + const client = getContextClient(); + export let data: PageData; + + $: result = charactersQuery(client, { + pagination: data.pagination, + filter: data.filter, + sort: data.sort + }); + + $: characters = $result.data?.characters; + + const selection = initSelectionContext<Character>('Character', (c) => c.name); + $: if (characters) { + $selection.view = characters.edges; + $pagination.total = characters.count; + } + + const filter = initFilterContext<BasicFilterContext>(); + $: $filter = new BasicFilterContext(data.filter); + + const sort = initSortContext(data.sort, CharacterSortLabel); + $: $sort.update = data.sort; + + const pagination = initPaginationContext(); + $: $pagination.update = data.pagination; + + const edit = (id: number) => { + fetchCharacter(client, id) + .then((character) => openModal(EditCharacter, { character })) + .catch(toastFinally); + }; +</script> + +<Head section="characters" /> + +<Column> + <Toolbar> + <SelectionControls slot="start"> + <DeleteSelection mutation={deleteCharacters} /> + </SelectionControls> + <svelte:fragment slot="center"> + <Search name="Characters" bind:field={$filter.include.controls.name.contains} /> + <SelectSort /> + <SelectItems /> + </svelte:fragment> + <svelte:fragment slot="end"> + <AddButton title="Add Character" on:click={() => openModal(AddCharacter)} /> + </svelte:fragment> + </Toolbar> + {#if characters} + <Pagination /> + <main> + <Cardlets> + {#each characters.edges as { id, name }, index (id)} + <Selectable {index} {id} {edit} let:handle let:selected> + <Cardlet {name} on:click={handle} filter="characters" {id}> + <SelectionOverlay slot="overlay" position="right" centered {selected} /> + </Cardlet> + </Selectable> + {:else} + <Empty /> + {/each} + </Cardlets> + </main> + <Pagination /> + {:else} + <Guard {result} /> + {/if} +</Column> diff --git a/frontend/src/routes/characters/+page.ts b/frontend/src/routes/characters/+page.ts new file mode 100644 index 0000000..4f7a3cf --- /dev/null +++ b/frontend/src/routes/characters/+page.ts @@ -0,0 +1,12 @@ +import { CharacterSort, type CharacterFilterInput } from '$gql/graphql'; +import { parseFilter, parsePaginationData, parseSortData } from '$lib/Navigation'; + +export const trailingSlash = 'always'; + +export function load({ url }: { url: URL; params: Record<string, string> }) { + return { + sort: parseSortData(url.searchParams, CharacterSort.Name), + filter: parseFilter<CharacterFilterInput>(url.searchParams), + pagination: parsePaginationData(url.searchParams) + }; +} diff --git a/frontend/src/routes/circles/+page.svelte b/frontend/src/routes/circles/+page.svelte new file mode 100644 index 0000000..14b0866 --- /dev/null +++ b/frontend/src/routes/circles/+page.svelte @@ -0,0 +1,101 @@ +<script lang="ts"> + import { deleteCircles } from '$gql/Mutations'; + import { circlesQuery, fetchCircle } from '$gql/Queries'; + import type { Circle } from '$gql/graphql'; + import { CircleSortLabel } from '$lib/Enums'; + import { BasicFilterContext, initFilterContext } from '$lib/Filter'; + import { initPaginationContext } from '$lib/Pagination'; + import { initSelectionContext } from '$lib/Selection'; + import { initSortContext } from '$lib/Sort'; + import { toastFinally } from '$lib/Toasts'; + import AddButton from '$lib/components/AddButton.svelte'; + import Cardlet from '$lib/components/Cardlet.svelte'; + import Empty from '$lib/components/Empty.svelte'; + import Guard from '$lib/components/Guard.svelte'; + import Head from '$lib/components/Head.svelte'; + import Cardlets from '$lib/containers/Cardlets.svelte'; + import Column from '$lib/containers/Column.svelte'; + import AddCircle from '$lib/dialogs/AddCircle.svelte'; + import EditCircle from '$lib/dialogs/EditCircle.svelte'; + import Pagination from '$lib/pagination/Pagination.svelte'; + import Selectable from '$lib/selection/Selectable.svelte'; + import SelectionOverlay from '$lib/selection/SelectionOverlay.svelte'; + import DeleteSelection from '$lib/toolbar/DeleteSelection.svelte'; + import Search from '$lib/toolbar/Search.svelte'; + import SelectItems from '$lib/toolbar/SelectItems.svelte'; + import SelectSort from '$lib/toolbar/SelectSort.svelte'; + import SelectionControls from '$lib/toolbar/SelectionControls.svelte'; + import Toolbar from '$lib/toolbar/Toolbar.svelte'; + import { getContextClient } from '@urql/svelte'; + import { openModal } from 'svelte-modals'; + import type { PageData } from './$types'; + + const client = getContextClient(); + export let data: PageData; + + $: result = circlesQuery(client, { + pagination: data.pagination, + filter: data.filter, + sort: data.sort + }); + + $: circles = $result.data?.circles; + + const selection = initSelectionContext<Circle>('Circle', (c) => c.name); + $: if (circles) { + $selection.view = circles.edges; + $pagination.total = circles.count; + } + + const filter = initFilterContext<BasicFilterContext>(); + $: $filter = new BasicFilterContext(data.filter); + + const sort = initSortContext(data.sort, CircleSortLabel); + $: $sort.update = data.sort; + + const pagination = initPaginationContext(); + $: $pagination.update = data.pagination; + + const edit = (id: number) => { + fetchCircle(client, id) + .then((circle) => openModal(EditCircle, { circle })) + .catch(toastFinally); + }; +</script> + +<Head section="circles" /> + +<Column> + <Toolbar> + <SelectionControls slot="start"> + <DeleteSelection mutation={deleteCircles} /> + </SelectionControls> + <svelte:fragment slot="center"> + <Search name="Circles" bind:field={$filter.include.controls.name.contains} /> + <SelectSort /> + <SelectItems /> + </svelte:fragment> + <svelte:fragment slot="end"> + <AddButton title="Add Circle" on:click={() => openModal(AddCircle)} /> + </svelte:fragment> + </Toolbar> + {#if circles} + <Pagination /> + <main> + <Cardlets> + {#each circles.edges as { id, name }, index (id)} + <Selectable {index} {id} {edit} let:handle let:selected> + <Cardlet {name} on:click={handle} filter="circles" {id}> + <SelectionOverlay slot="overlay" position="right" centered {selected} /> + </Cardlet> + </Selectable> + {:else} + <Empty /> + {/each} + </Cardlets> + </main> + <Pagination /> + {:else} + <Guard {result} /> + {/if} +</Column> diff --git a/frontend/src/routes/circles/+page.ts b/frontend/src/routes/circles/+page.ts new file mode 100644 index 0000000..ea5c3df --- /dev/null +++ b/frontend/src/routes/circles/+page.ts @@ -0,0 +1,12 @@ +import { CircleSort, type CircleFilterInput } from '$gql/graphql'; +import { parseFilter, parsePaginationData, parseSortData } from '$lib/Navigation'; + +export const trailingSlash = 'always'; + +export function load({ url }: { url: URL; params: Record<string, string> }) { + return { + sort: parseSortData(url.searchParams, CircleSort.Name), + filter: parseFilter<CircleFilterInput>(url.searchParams), + pagination: parsePaginationData(url.searchParams) + }; +} diff --git a/frontend/src/routes/comics/+page.svelte b/frontend/src/routes/comics/+page.svelte new file mode 100644 index 0000000..353d69c --- /dev/null +++ b/frontend/src/routes/comics/+page.svelte @@ -0,0 +1,116 @@ +<script lang="ts"> + import { deleteComics, updateComics } from '$gql/Mutations'; + import { comicsQuery } from '$gql/Queries'; + import { type ComicFragment } from '$gql/graphql'; + import { ComicSortLabel } from '$lib/Enums'; + import { ComicFilterContext, initFilterContext } from '$lib/Filter'; + import { initPaginationContext } from '$lib/Pagination'; + import { initSelectionContext } from '$lib/Selection'; + import { initSortContext } from '$lib/Sort'; + import Card, { comicCard } from '$lib/components/Card.svelte'; + import Empty from '$lib/components/Empty.svelte'; + import Guard from '$lib/components/Guard.svelte'; + import Head from '$lib/components/Head.svelte'; + import Cards from '$lib/containers/Cards.svelte'; + import Column from '$lib/containers/Column.svelte'; + import UpdateComicsDialog from '$lib/dialogs/UpdateComics.svelte'; + import ComicFilterForm from '$lib/filter/ComicFilterForm.svelte'; + import Pagination from '$lib/pagination/Pagination.svelte'; + import ComicPills from '$lib/pills/ComicPills.svelte'; + import Selectable from '$lib/selection/Selectable.svelte'; + import SelectionOverlay from '$lib/selection/SelectionOverlay.svelte'; + import DeleteSelection from '$lib/toolbar/DeleteSelection.svelte'; + import EditSelection from '$lib/toolbar/EditSelection.svelte'; + import FilterBookmarked from '$lib/toolbar/FilterBookmarked.svelte'; + import FilterFavourites from '$lib/toolbar/FilterFavourites.svelte'; + import FilterOrganized from '$lib/toolbar/FilterOrganized.svelte'; + import MarkBookmark from '$lib/toolbar/MarkBookmark.svelte'; + import MarkFavourite from '$lib/toolbar/MarkFavourite.svelte'; + import MarkOrganized from '$lib/toolbar/MarkOrganized.svelte'; + import MarkSelection from '$lib/toolbar/MarkSelection.svelte'; + import Search from '$lib/toolbar/Search.svelte'; + import SelectItems from '$lib/toolbar/SelectItems.svelte'; + import SelectSort from '$lib/toolbar/SelectSort.svelte'; + import SelectionControls from '$lib/toolbar/SelectionControls.svelte'; + import ToggleAdvancedFilters from '$lib/toolbar/ToggleAdvancedFilters.svelte'; + import Toolbar from '$lib/toolbar/Toolbar.svelte'; + import { getContextClient } from '@urql/svelte'; + import type { PageData } from './$types'; + + export let data: PageData; + + const client = getContextClient(); + + $: result = comicsQuery(client, { + pagination: data.pagination, + filter: data.filter, + sort: data.sort + }); + + $: comics = $result.data?.comics; + + const selection = initSelectionContext<ComicFragment>('Comic', (c) => c.title); + $: if (comics) { + $selection.view = comics.edges; + $pagination.total = comics.count; + } + + const filter = initFilterContext<ComicFilterContext>(); + $: $filter = new ComicFilterContext(data.filter); + + const sort = initSortContext(data.sort, ComicSortLabel); + $: $sort.update = data.sort; + + const pagination = initPaginationContext(); + $: $pagination.update = data.pagination; +</script> + +<Head section="Comics" /> + +<Column> + <Toolbar> + <SelectionControls slot="start"> + <MarkSelection> + <MarkFavourite mutation={updateComics} /> + <hr class="col-span-2 border-slate-600" /> + <MarkBookmark mutation={updateComics} /> + <hr class="col-span-2 border-slate-600" /> + <MarkOrganized mutation={updateComics} /> + </MarkSelection> + <EditSelection dialog={UpdateComicsDialog} /> + <DeleteSelection mutation={deleteComics} /> + </SelectionControls> + <svelte:fragment slot="center"> + <Search name="Comics" bind:field={$filter.include.controls.title.contains} /> + <ToggleAdvancedFilters /> + <div class="rounded-group flex"> + <FilterFavourites /> + <FilterBookmarked /> + <FilterOrganized /> + </div> + <SelectSort /> + <SelectItems /> + </svelte:fragment> + <ComicFilterForm /> + </Toolbar> + {#if comics} + <Pagination /> + <main> + <Cards> + {#each comics.edges as comic, index (comic.id)} + <Selectable {index} id={comic.id} let:handle let:selected> + <Card {...comicCard(comic)} on:click={handle}> + <SelectionOverlay position="left" {selected} slot="overlay" /> + <ComicPills {comic} /> + </Card> + </Selectable> + {:else} + <Empty /> + {/each} + </Cards> + </main> + <Pagination /> + {:else} + <Guard {result} /> + {/if} +</Column> diff --git a/frontend/src/routes/comics/+page.ts b/frontend/src/routes/comics/+page.ts new file mode 100644 index 0000000..4558804 --- /dev/null +++ b/frontend/src/routes/comics/+page.ts @@ -0,0 +1,12 @@ +import { ComicSort, type ComicFilterInput } from '$gql/graphql'; +import { parseFilter, parsePaginationData, parseSortData } from '$lib/Navigation'; + +export const trailingSlash = 'always'; + +export function load({ url }: { url: URL; params: Record<string, string> }) { + return { + sort: parseSortData(url.searchParams, ComicSort.Title), + filter: parseFilter<ComicFilterInput>(url.searchParams), + pagination: parsePaginationData(url.searchParams, 24) + }; +} diff --git a/frontend/src/routes/comics/[id]/+page.svelte b/frontend/src/routes/comics/[id]/+page.svelte new file mode 100644 index 0000000..cfc5840 --- /dev/null +++ b/frontend/src/routes/comics/[id]/+page.svelte @@ -0,0 +1,176 @@ +<script lang="ts"> + import { beforeNavigate } from '$app/navigation'; + import { updateComics } from '$gql/Mutations'; + import { comicQuery } from '$gql/Queries'; + import { comicEquals } from '$gql/Utils'; + import { UpdateMode, type FullComicFragment, type UpdateComicInput } from '$gql/graphql'; + import { initReaderContext } from '$lib/Reader'; + import { initScraperContext } from '$lib/Scraper'; + import { initSelectionContext } from '$lib/Selection'; + import { setTabContext } from '$lib/Tabs'; + import { toastFinally } from '$lib/Toasts'; + import { preventOnPending } from '$lib/Utils'; + import BookmarkButton from '$lib/components/BookmarkButton.svelte'; + import Guard from '$lib/components/Guard.svelte'; + import Head from '$lib/components/Head.svelte'; + import OrganizedButton from '$lib/components/OrganizedButton.svelte'; + import RemovePageButton from '$lib/components/RemovePageButton.svelte'; + import SubmitButton from '$lib/components/SubmitButton.svelte'; + import Titlebar from '$lib/components/Titlebar.svelte'; + import Grid from '$lib/containers/Grid.svelte'; + import ComicForm from '$lib/forms/ComicForm.svelte'; + import Gallery from '$lib/gallery/Gallery.svelte'; + import PageView from '$lib/reader/PageView.svelte'; + import Reader from '$lib/reader/Reader.svelte'; + import ComicScrapeForm from '$lib/scraper/ComicScrapeForm.svelte'; + import ComicDelete from '$lib/tabs/ComicDelete.svelte'; + import ComicDetails from '$lib/tabs/ComicDetails.svelte'; + import Tab from '$lib/tabs/Tab.svelte'; + import Tabs from '$lib/tabs/Tabs.svelte'; + import SelectionControls from '$lib/toolbar/SelectionControls.svelte'; + import { getContextClient } from '@urql/svelte'; + import type { PageData } from './$types'; + + const client = getContextClient(); + const reader = initReaderContext(); + const selection = initSelectionContext(); + const scraper = initScraperContext(); + const tabContext = setTabContext({ + tabs: { + details: { title: 'Details' }, + edit: { title: 'Edit' }, + scrape: { title: 'Scrape' }, + deletion: { title: 'Delete' } + }, + current: 'details' + }); + + export let data: PageData; + $: result = comicQuery(client, { id: data.id }); + + let comic: FullComicFragment; + let original: Readonly<FullComicFragment>; + let updatePartial = false; + + $: $result, update(); + $: pending = !comicEquals(comic, original); + $: $tabContext.tabs.edit.badge = pending; + + function update() { + if (!$result.stale && $result.data?.comic.__typename === 'FullComic') { + original = $result.data.comic; + if (updatePartial) { + comic.pages = structuredClone(original.pages); + comic.favourite = original.favourite; + comic.bookmarked = original.bookmarked; + comic.organized = original.organized; + comic.updatedAt = original.updatedAt; + updatePartial = false; + } else { + comic = structuredClone(original); + } + + $reader.pages = original.pages; + $selection.view = comic.pages; + $scraper.selector = undefined; + } + } + + function toggle(field: keyof Omit<UpdateComicInput, 'cover'>) { + updateComics(client, { ids: comic.id, input: { [field]: !comic[field] } }) + .then(() => (updatePartial = true)) + .catch(toastFinally); + } + + function updateComic(event: CustomEvent<UpdateComicInput>) { + updateComics(client, { ids: comic.id, input: event.detail }).catch(toastFinally); + } + + function updateCover(event: CustomEvent<number>) { + updateComics(client, { ids: comic.id, input: { cover: { id: event.detail } } }) + .then(() => (updatePartial = true)) + .catch(toastFinally); + } + + function removePages() { + updateComics(client, { + ids: comic.id, + input: { pages: { ids: $selection.ids, options: { mode: UpdateMode.Remove } } } + }) + .then(() => { + updatePartial = true; + $selection = $selection.clear(); + }) + .catch(toastFinally); + } + + beforeNavigate((navigation) => preventOnPending(navigation, pending)); +</script> + +<Head section="Comic" title={original?.title} /> + +{#if comic} + <Grid> + <header> + <Titlebar + title={original.title} + subtitle={original.originalTitle} + bind:favourite={comic.favourite} + on:favourite={() => toggle('favourite')} + /> + </header> + + <aside> + <Tabs> + <Tab id="details"> + <ComicDetails comic={original} /> + </Tab> + <Tab id="edit"> + <div class="flex flex-col gap-4"> + <div class="flex gap-2 text-sm"> + <SelectionControls page> + <RemovePageButton on:click={removePages} /> + </SelectionControls> + <div class="grow" /> + <BookmarkButton bookmarked={comic.bookmarked} on:click={() => toggle('bookmarked')} /> + <OrganizedButton organized={comic.organized} on:click={() => toggle('organized')} /> + </div> + <ComicForm bind:comic on:submit={updateComic}> + <div class="flex gap-2"> + <div class="grow" /> + <SubmitButton active={pending} /> + </div> + </ComicForm> + </div> + </Tab> + <Tab id="scrape"> + <ComicScrapeForm {comic} /> + </Tab> + <Tab id="deletion"> + <ComicDelete {comic} /> + </Tab> + </Tabs> + </aside> + + <main class="overflow-auto"> + <Gallery + pages={comic.pages} + on:open={(e) => ($reader = $reader.open(e.detail))} + on:cover={updateCover} + /> + </main> + </Grid> + + <Reader> + <PageView layout={comic.layout} direction={comic.direction} /> + <svelte:fragment slot="sidebar"> + <ComicForm bind:comic on:submit={updateComic}> + <div class="flex justify-end gap-2"> + <SubmitButton active={pending} /> + </div> + </ComicForm> + </svelte:fragment> + </Reader> +{:else} + <Guard {result} /> +{/if} diff --git a/frontend/src/routes/comics/[id]/+page.ts b/frontend/src/routes/comics/[id]/+page.ts new file mode 100644 index 0000000..d872ba2 --- /dev/null +++ b/frontend/src/routes/comics/[id]/+page.ts @@ -0,0 +1,5 @@ +export function load({ params }: { params: Record<string, string> }) { + return { + id: +params.id + }; +} diff --git a/frontend/src/routes/namespaces/+page.svelte b/frontend/src/routes/namespaces/+page.svelte new file mode 100644 index 0000000..f6568f9 --- /dev/null +++ b/frontend/src/routes/namespaces/+page.svelte @@ -0,0 +1,101 @@ +<script lang="ts"> + import { deleteNamespaces } from '$gql/Mutations'; + import { fetchNamespace, namespacesQuery } from '$gql/Queries'; + import type { Namespace } from '$gql/graphql'; + import { NamespaceSortLabel } from '$lib/Enums'; + import { BasicFilterContext, initFilterContext } from '$lib/Filter'; + import { initPaginationContext } from '$lib/Pagination'; + import { initSelectionContext } from '$lib/Selection'; + import { initSortContext } from '$lib/Sort'; + import { toastFinally } from '$lib/Toasts'; + import AddButton from '$lib/components/AddButton.svelte'; + import Cardlet from '$lib/components/Cardlet.svelte'; + import Empty from '$lib/components/Empty.svelte'; + import Guard from '$lib/components/Guard.svelte'; + import Head from '$lib/components/Head.svelte'; + import Cardlets from '$lib/containers/Cardlets.svelte'; + import Column from '$lib/containers/Column.svelte'; + import AddNamespace from '$lib/dialogs/AddNamespace.svelte'; + import EditNamespace from '$lib/dialogs/EditNamespace.svelte'; + import Pagination from '$lib/pagination/Pagination.svelte'; + import Selectable from '$lib/selection/Selectable.svelte'; + import SelectionOverlay from '$lib/selection/SelectionOverlay.svelte'; + import DeleteSelection from '$lib/toolbar/DeleteSelection.svelte'; + import Search from '$lib/toolbar/Search.svelte'; + import SelectItems from '$lib/toolbar/SelectItems.svelte'; + import SelectSort from '$lib/toolbar/SelectSort.svelte'; + import SelectionControls from '$lib/toolbar/SelectionControls.svelte'; + import Toolbar from '$lib/toolbar/Toolbar.svelte'; + import { getContextClient } from '@urql/svelte'; + import { openModal } from 'svelte-modals'; + import type { PageData } from './$types'; + + const client = getContextClient(); + export let data: PageData; + + $: result = namespacesQuery(client, { + pagination: data.pagination, + filter: data.filter, + sort: data.sort + }); + + $: namespaces = $result.data?.namespaces; + + const selection = initSelectionContext<Namespace>('Namespace', (n) => n.name); + $: if (namespaces) { + $selection.view = namespaces.edges; + $pagination.total = namespaces.count; + } + + const filter = initFilterContext<BasicFilterContext>(); + $: $filter = new BasicFilterContext(data.filter); + + const sort = initSortContext(data.sort, NamespaceSortLabel); + $: $sort.update = data.sort; + + const pagination = initPaginationContext(); + $: $pagination.update = data.pagination; + + const edit = (id: number) => { + fetchNamespace(client, id) + .then((namespace) => openModal(EditNamespace, { namespace })) + .catch(toastFinally); + }; +</script> + +<Head section="Namespaces" /> + +<Column> + <Toolbar> + <SelectionControls slot="start"> + <DeleteSelection mutation={deleteNamespaces} /> + </SelectionControls> + <svelte:fragment slot="center"> + <Search name="Namespaces" bind:field={$filter.include.controls.name.contains} /> + <SelectSort /> + <SelectItems /> + </svelte:fragment> + <svelte:fragment slot="end"> + <AddButton title="Add Namespace" on:click={() => openModal(AddNamespace)} /> + </svelte:fragment> + </Toolbar> + {#if namespaces} + <Pagination /> + <main> + <Cardlets> + {#each namespaces.edges as { id, name }, index (id)} + <Selectable {index} {id} {edit} let:handle let:selected> + <Cardlet {name} on:click={handle} filter="tags" id={`${id}:`}> + <SelectionOverlay slot="overlay" position="right" centered {selected} /> + </Cardlet> + </Selectable> + {:else} + <Empty /> + {/each} + </Cardlets> + </main> + <Pagination /> + {:else} + <Guard {result} /> + {/if} +</Column> diff --git a/frontend/src/routes/namespaces/+page.ts b/frontend/src/routes/namespaces/+page.ts new file mode 100644 index 0000000..893b540 --- /dev/null +++ b/frontend/src/routes/namespaces/+page.ts @@ -0,0 +1,12 @@ +import { NamespaceSort, type NamespaceFilterInput } from '$gql/graphql'; +import { parseFilter, parsePaginationData, parseSortData } from '$lib/Navigation'; + +export const trailingSlash = 'always'; + +export function load({ url }: { url: URL; params: Record<string, string> }) { + return { + sort: parseSortData(url.searchParams, NamespaceSort.Name), + filter: parseFilter<NamespaceFilterInput>(url.searchParams), + pagination: parsePaginationData(url.searchParams) + }; +} diff --git a/frontend/src/routes/tags/+page.svelte b/frontend/src/routes/tags/+page.svelte new file mode 100644 index 0000000..e0909ad --- /dev/null +++ b/frontend/src/routes/tags/+page.svelte @@ -0,0 +1,109 @@ +<script lang="ts"> + import { deleteTags } from '$gql/Mutations'; + import { fetchTag, tagsQuery } from '$gql/Queries'; + import { type Tag } from '$gql/graphql'; + import { TagSortLabel } from '$lib/Enums'; + import { TagFilterContext, initFilterContext } from '$lib/Filter'; + import { initPaginationContext } from '$lib/Pagination'; + import { initSelectionContext } from '$lib/Selection'; + import { initSortContext } from '$lib/Sort'; + import { toastFinally } from '$lib/Toasts'; + import AddButton from '$lib/components/AddButton.svelte'; + import Cardlet from '$lib/components/Cardlet.svelte'; + import Empty from '$lib/components/Empty.svelte'; + import Guard from '$lib/components/Guard.svelte'; + import Head from '$lib/components/Head.svelte'; + import Cardlets from '$lib/containers/Cardlets.svelte'; + import Column from '$lib/containers/Column.svelte'; + import AddTag from '$lib/dialogs/AddTag.svelte'; + import EditTag from '$lib/dialogs/EditTag.svelte'; + import UpdateTagsDialog from '$lib/dialogs/UpdateTags.svelte'; + import TagFilterForm from '$lib/filter/TagFilterForm.svelte'; + import Pagination from '$lib/pagination/Pagination.svelte'; + import Selectable from '$lib/selection/Selectable.svelte'; + import SelectionOverlay from '$lib/selection/SelectionOverlay.svelte'; + import DeleteSelection from '$lib/toolbar/DeleteSelection.svelte'; + import EditSelection from '$lib/toolbar/EditSelection.svelte'; + import Search from '$lib/toolbar/Search.svelte'; + import SelectItems from '$lib/toolbar/SelectItems.svelte'; + import SelectSort from '$lib/toolbar/SelectSort.svelte'; + import SelectionControls from '$lib/toolbar/SelectionControls.svelte'; + import ToggleAdvancedFilters from '$lib/toolbar/ToggleAdvancedFilters.svelte'; + import Toolbar from '$lib/toolbar/Toolbar.svelte'; + import { getContextClient } from '@urql/svelte'; + import { openModal } from 'svelte-modals'; + import type { PageData } from './$types'; + + const client = getContextClient(); + + export let data: PageData; + + $: result = tagsQuery(client, { + pagination: data.pagination, + filter: data.filter, + sort: data.sort + }); + + $: tags = $result.data?.tags; + + const selection = initSelectionContext<Tag>('Tag', (t) => t.name); + $: if (tags) { + $selection.view = tags.edges; + $pagination.total = tags.count; + } + + const filter = initFilterContext<TagFilterContext>(); + $: $filter = new TagFilterContext(data.filter); + + const sort = initSortContext(data.sort, TagSortLabel); + $: $sort.update = data.sort; + + const pagination = initPaginationContext(); + $: $pagination.update = data.pagination; + + const edit = (id: number) => { + fetchTag(client, id) + .then((tag) => openModal(EditTag, { tag })) + .catch(toastFinally); + }; +</script> + +<Head section="Tags" /> + +<Column> + <Toolbar> + <SelectionControls slot="start"> + <EditSelection dialog={UpdateTagsDialog} /> + <DeleteSelection mutation={deleteTags} /> + </SelectionControls> + <svelte:fragment slot="center"> + <Search name="Tags" bind:field={$filter.include.controls.name.contains} /> + <ToggleAdvancedFilters /> + <SelectSort /> + <SelectItems /> + </svelte:fragment> + <svelte:fragment slot="end"> + <AddButton title="Add Tag" on:click={() => openModal(AddTag)} /> + </svelte:fragment> + <TagFilterForm /> + </Toolbar> + {#if tags} + <Pagination /> + <main> + <Cardlets> + {#each tags.edges as { id, name, description }, index (id)} + <Selectable {index} {id} {edit} let:handle let:selected> + <Cardlet {name} title={description} on:click={handle} filter="tags" id={`:${id}`}> + <SelectionOverlay slot="overlay" position="right" centered {selected} /> + </Cardlet> + </Selectable> + {:else} + <Empty /> + {/each} + </Cardlets> + </main> + <Pagination /> + {:else} + <Guard {result} /> + {/if} +</Column> diff --git a/frontend/src/routes/tags/+page.ts b/frontend/src/routes/tags/+page.ts new file mode 100644 index 0000000..f584b6f --- /dev/null +++ b/frontend/src/routes/tags/+page.ts @@ -0,0 +1,12 @@ +import { TagSort, type TagFilterInput } from '$gql/graphql'; +import { parseFilter, parsePaginationData, parseSortData } from '$lib/Navigation'; + +export const trailingSlash = 'always'; + +export function load({ url }: { url: URL; params: Record<string, string> }) { + return { + sort: parseSortData(url.searchParams, TagSort.Name), + filter: parseFilter<TagFilterInput>(url.searchParams), + pagination: parsePaginationData(url.searchParams) + }; +} diff --git a/frontend/src/routes/worlds/+page.svelte b/frontend/src/routes/worlds/+page.svelte new file mode 100644 index 0000000..e0366e9 --- /dev/null +++ b/frontend/src/routes/worlds/+page.svelte @@ -0,0 +1,102 @@ +<script lang="ts"> + import { deleteWorlds } from '$gql/Mutations'; + import { fetchWorld, worldsQuery } from '$gql/Queries'; + import type { World } from '$gql/graphql'; + import { WorldSortLabel } from '$lib/Enums'; + import { BasicFilterContext, initFilterContext } from '$lib/Filter'; + import { initPaginationContext } from '$lib/Pagination'; + import { initSelectionContext } from '$lib/Selection'; + import { initSortContext } from '$lib/Sort'; + import { toastFinally } from '$lib/Toasts'; + import AddButton from '$lib/components/AddButton.svelte'; + import Cardlet from '$lib/components/Cardlet.svelte'; + import Empty from '$lib/components/Empty.svelte'; + import Guard from '$lib/components/Guard.svelte'; + import Head from '$lib/components/Head.svelte'; + import Cardlets from '$lib/containers/Cardlets.svelte'; + import Column from '$lib/containers/Column.svelte'; + import AddWorld from '$lib/dialogs/AddWorld.svelte'; + import EditWorld from '$lib/dialogs/EditWorld.svelte'; + import Pagination from '$lib/pagination/Pagination.svelte'; + import Selectable from '$lib/selection/Selectable.svelte'; + import SelectionOverlay from '$lib/selection/SelectionOverlay.svelte'; + import DeleteSelection from '$lib/toolbar/DeleteSelection.svelte'; + import Search from '$lib/toolbar/Search.svelte'; + import SelectItems from '$lib/toolbar/SelectItems.svelte'; + import SelectSort from '$lib/toolbar/SelectSort.svelte'; + import SelectionControls from '$lib/toolbar/SelectionControls.svelte'; + import Toolbar from '$lib/toolbar/Toolbar.svelte'; + import { getContextClient } from '@urql/svelte'; + import { openModal } from 'svelte-modals'; + import type { PageData } from './$types'; + + const client = getContextClient(); + + export let data: PageData; + + $: result = worldsQuery(client, { + pagination: data.pagination, + filter: data.filter, + sort: data.sort + }); + + $: worlds = $result.data?.worlds; + + const selection = initSelectionContext<World>('World', (w) => w.name); + $: if (worlds) { + $selection.view = worlds.edges; + $pagination.total = worlds.count; + } + + const filter = initFilterContext<BasicFilterContext>(); + $: $filter = new BasicFilterContext(data.filter); + + const sort = initSortContext(data.sort, WorldSortLabel); + $: $sort.update = data.sort; + + const pagination = initPaginationContext(); + $: $pagination.update = data.pagination; + + const edit = (id: number) => { + fetchWorld(client, id) + .then((world) => openModal(EditWorld, { world })) + .catch(toastFinally); + }; +</script> + +<Head section="Worlds" /> + +<Column> + <Toolbar> + <SelectionControls slot="start"> + <DeleteSelection mutation={deleteWorlds} /> + </SelectionControls> + <svelte:fragment slot="center"> + <Search name="Worlds" bind:field={$filter.include.controls.name.contains} /> + <SelectSort /> + <SelectItems /> + </svelte:fragment> + <svelte:fragment slot="end"> + <AddButton title="Add World" on:click={() => openModal(AddWorld)} /> + </svelte:fragment> + </Toolbar> + {#if worlds} + <Pagination /> + <main> + <Cardlets> + {#each worlds.edges as { id, name }, index (id)} + <Selectable {index} {id} {edit} let:handle let:selected> + <Cardlet {name} on:click={handle} filter="worlds" {id}> + <SelectionOverlay slot="overlay" position="right" centered {selected} /> + </Cardlet> + </Selectable> + {:else} + <Empty /> + {/each} + </Cardlets> + </main> + <Pagination /> + {:else} + <Guard {result} /> + {/if} +</Column> diff --git a/frontend/src/routes/worlds/+page.ts b/frontend/src/routes/worlds/+page.ts new file mode 100644 index 0000000..3b85f4c --- /dev/null +++ b/frontend/src/routes/worlds/+page.ts @@ -0,0 +1,12 @@ +import { WorldSort, type WorldFilterInput } from '$gql/graphql'; +import { parseFilter, parsePaginationData, parseSortData } from '$lib/Navigation'; + +export const trailingSlash = 'always'; + +export function load({ url }: { url: URL; params: Record<string, string> }) { + return { + sort: parseSortData(url.searchParams, WorldSort.Name), + filter: parseFilter<WorldFilterInput>(url.searchParams), + pagination: parsePaginationData(url.searchParams) + }; +} diff --git a/frontend/static/favicon.svg b/frontend/static/favicon.svg new file mode 100644 index 0000000..6c7be45 --- /dev/null +++ b/frontend/static/favicon.svg @@ -0,0 +1,25 @@ +<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="64"> + <defs> + <linearGradient id="b"> + <stop offset=".261" stop-color="#d9825f"/> + <stop offset="1" stop-color="#f1d6b0"/> + </linearGradient> + <linearGradient id="a"> + <stop offset="0" stop-color="#b46643"/> + <stop offset=".521" stop-color="#400d02"/> + </linearGradient> + <linearGradient xlink:href="#a" id="d" x1="6.023" x2="57.975" y1="31.667" y2="31.667" gradientUnits="userSpaceOnUse"/> + <linearGradient xlink:href="#a" id="e" x1="5.523" x2="58.48" y1="31.67" y2="31.67" gradientUnits="userSpaceOnUse"/> + <radialGradient xlink:href="#b" id="c" cx="35.966" cy="29.958" r="17.403" fx="35.966" fy="29.958" gradientTransform="matrix(.98534 0 0 .67716 .782 9.643)" gradientUnits="userSpaceOnUse"/> + <filter id="f" width="1.316" height="1.453" x="-.167" y="-.24" color-interpolation-filters="sRGB"> + <feFlood flood-color="#b46643" flood-opacity=".498" result="flood"/> + <feGaussianBlur in="SourceGraphic" result="blur" stdDeviation="3"/> + <feOffset dx="-1" dy="-1" in="blur" result="offset"/> + <feComposite in="flood" in2="offset" operator="in" result="comp1"/> + <feComposite in="SourceGraphic" in2="comp1" result="comp2"/> + </filter> + </defs> + <path fill="url(#c)" d="M51.66 18.146c-2.207 0-23.763 6.417-28.092 8.362-3.382 1.52-4.51 3.09-4.495 6.252.016 3.116-3.929 3.866-.79 5.738 3.693 2.203 18.797 3.788 23.607 1.634 1.805-.809 4.193-2.037 5.309-2.733 2.642-1.647 5.336-8.207 5.926-14.434.452-4.77.436-4.82-1.464-4.82z" transform="translate(-5.778 -5.386) scale(1.1806)"/> + <path fill="url(#d)" stroke="url(#e)" d="M53.375 13.541c-1.724.004-23.937 8.24-28.492 10.564-3.433 1.753-4.371 2.931-7.09 8.909-1.287 2.828-3.65 6.58-5.252 8.334-4.408 4.826-6.518 7.542-6.518 8.392 0 .422 2.505-1.723 5.565-4.767 6.321-6.289 5.42-6.1 15.758-3.297 16.264 4.408 28.65-4.69 30.476-22.383.33-3.2.208-3.676-1.197-4.66-.86-.603-2.323-1.094-3.25-1.092Zm-1.467 4.662c1.626 0 1.639.047 1.252 4.656-.504 6.018-2.808 12.358-5.068 13.95-.954.672-2.997 1.859-4.541 2.64-4.114 2.082-12.428 2.03-15.586-.1-2.686-1.809-3.918-4.011-3.932-7.023-.013-3.056.952-4.574 3.846-6.043 3.703-1.88 22.14-8.08 24.03-8.08zM21.014 32.086l.42 2.055c.23 1.13.795 2.506 1.253 3.058.72.867.459 1.004-1.906 1.004h-2.74l1.486-3.058z" filter="url(#f)" transform="translate(-5.778 -5.386) scale(1.1806)"/> + <path fill="#360c03" d="M30.712 34.768c-1.46-1.157-2.165-2.45-2.165-3.973 0-2.867.69-3.258 6.233-3.543a20.459 20.459 0 0 0 8.539-2.328c5.15-2.693 9.132-2.536 9.447.372.574 5.307-6.13 10.22-14.774 10.828-4.394.308-5.421.117-7.28-1.356z"/> +</svg> diff --git a/frontend/svelte.config.js b/frontend/svelte.config.js new file mode 100644 index 0000000..dbfdf53 --- /dev/null +++ b/frontend/svelte.config.js @@ -0,0 +1,44 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +import adapter from '@sveltejs/adapter-static'; +import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'; +import { readFileSync } from 'fs'; +import { fileURLToPath } from 'url'; + +const packageFile = fileURLToPath(new URL('package.json', import.meta.url)); +const packageJSON = readFileSync(packageFile, 'utf8'); +const pkg = JSON.parse(packageJSON); + +/** @type {import('@sveltejs/kit').Config} */ +const config = { + // Consult https://kit.svelte.dev/docs/integrations#preprocessors + // for more information about preprocessors + preprocess: vitePreprocess(), + + kit: { + adapter: adapter({ + fallback: 'index.html', + pages: '../src/hircine/static/app' + }), + prerender: { entries: [] }, + alias: { + $gql: './src/gql' + }, + version: { + name: pkg.version + }, + typescript: { + config: (tsconfig) => { + const { ...compilerOptions } = tsconfig.compilerOptions; + + return { + ...tsconfig, + compilerOptions: { + ...compilerOptions + } + }; + } + } + } +}; + +export default config; diff --git a/frontend/tailwind.config.cjs b/frontend/tailwind.config.cjs new file mode 100644 index 0000000..99307cd --- /dev/null +++ b/frontend/tailwind.config.cjs @@ -0,0 +1,7 @@ +const { addDynamicIconSelectors } = require('@iconify/tailwind'); + +/** @type {import('tailwindcss').Config} */ +module.exports = { + content: ['./src/**/*.{html,js,svelte,ts}'], + plugins: [addDynamicIconSelectors()] +}; diff --git a/frontend/tests/Reader.test.ts b/frontend/tests/Reader.test.ts new file mode 100644 index 0000000..e12d69b --- /dev/null +++ b/frontend/tests/Reader.test.ts @@ -0,0 +1,45 @@ +import { Layout, type PageFragment } from '$gql/graphql'; +import { partition, type Chunk } from '$lib/Reader'; +import { expect, test } from 'vitest'; + +const normalAttrs = { aspectRatio: 0.7, width: 140, height: 200 }; +const wideAttrs = { aspectRatio: 1.4, width: 280, height: 200 }; + +const pages: PageFragment[] = [ + { id: 0, path: '000.png', image: { id: 0, hash: '0', ...normalAttrs } }, + { id: 1, path: '001.png', image: { id: 1, hash: '1', ...normalAttrs } }, + { id: 2, path: '002.png', image: { id: 2, hash: '2', ...normalAttrs } }, + { id: 3, path: '003.png', image: { id: 3, hash: '3', ...normalAttrs } }, + { id: 4, path: '004.png', image: { id: 4, hash: '4', ...wideAttrs } }, + { id: 5, path: '005.png', image: { id: 5, hash: '5', ...normalAttrs } }, + { id: 6, path: '006.png', image: { id: 6, hash: '6', ...normalAttrs } } +]; + +const ids = (chunks: Chunk[]) => + chunks.map((c) => (c.secondary ? [c.main.id, c.secondary.id] : [c.main.id])); + +const indices = (chunks: Chunk[]) => chunks.map((c) => c.index); + +test('partitions single layout', () => { + const [chunks, lookup] = partition(pages, Layout.Single); + + expect(ids(chunks)).toStrictEqual([[0], [1], [2], [3], [4], [5], [6]]); + expect(indices(chunks)).toStrictEqual([0, 1, 2, 3, 4, 5, 6]); + expect(lookup).toStrictEqual([0, 1, 2, 3, 4, 5, 6]); +}); + +test('partitions double layout', () => { + const [chunks, lookup] = partition(pages, Layout.Double); + + expect(ids(chunks)).toStrictEqual([[0, 1], [2, 3], [4], [5, 6]]); + expect(indices(chunks)).toStrictEqual([0, 2, 4, 5]); + expect(lookup).toStrictEqual([0, 0, 1, 1, 2, 3, 3]); +}); + +test('partitions double (offset) layout', () => { + const [chunks, lookup] = partition(pages, Layout.DoubleOffset); + + expect(ids(chunks)).toStrictEqual([[0], [1, 2], [3], [4], [5, 6]]); + expect(indices(chunks)).toStrictEqual([0, 1, 3, 4, 5]); + expect(lookup).toStrictEqual([0, 1, 1, 2, 3, 4, 4]); +}); diff --git a/frontend/tests/Selection.test.ts b/frontend/tests/Selection.test.ts new file mode 100644 index 0000000..67e8c4c --- /dev/null +++ b/frontend/tests/Selection.test.ts @@ -0,0 +1,183 @@ +import { ItemSelection } from '$lib/Selection'; +import { expect, test } from 'vitest'; + +interface TestItem { + id: number; + selectable: boolean; +} + +const items: TestItem[] = [ + { id: 1, selectable: true }, + { id: 2, selectable: true }, + { id: 3, selectable: false }, + { id: 4, selectable: true } +]; + +const all = items.map((i) => i.id); +const selectable = items.filter((i) => i.selectable).map((i) => i.id); + +const setup = () => { + const selection = new ItemSelection<TestItem>(); + selection.view = items; + return selection; +}; + +test('selects a single item', () => { + let selection = setup(); + + selection = selection.update(0, false); + + expect(selection.ids).toStrictEqual([items[0].id]); +}); + +test('selects a single item (with empty shift select)', () => { + let selection = setup(); + + selection = selection.update(0, true); + + expect(selection.ids).toStrictEqual([items[0].id]); +}); + +test('selects multiple items (forwards)', () => { + let selection = setup(); + + selection = selection.update(0, false); + selection = selection.update(2, true); + + expect(selection.ids.toSorted((a, b) => a - b)).toStrictEqual(all.slice(0, 3)); +}); + +test('selects multiple items (backwards)', () => { + let selection = setup(); + + selection = selection.update(2, false); + selection = selection.update(0, true); + + expect(selection.ids.toSorted((a, b) => a - b)).toStrictEqual(all.slice(0, 3)); +}); + +test('selects multiple items (only selectables)', () => { + let selection = setup(); + selection.selectable = (i) => i.selectable; + + selection = selection.update(0, false); + selection = selection.update(3, true); + + expect(selection.ids).toStrictEqual(selectable); +}); + +test('selects all', () => { + const selection = setup().all(); + + expect(selection.ids).toStrictEqual(all); +}); + +test('selects all selectables', () => { + let selection = setup(); + selection.selectable = (i) => i.selectable; + + selection = selection.all(); + + expect(selection.ids).toStrictEqual(selectable); +}); + +test('deselects all', () => { + let selection = setup().all(); + + selection = selection.none(); + + expect(selection.ids).empty; +}); + +test('deselects a single item', () => { + let selection = setup().all(); + + selection = selection.update(0, false); + + expect(selection.ids).toStrictEqual(all.slice(1)); +}); + +test('deselects multiple items', () => { + let selection = setup(); + + selection = selection.update(0, false); + selection = selection.update(2, true); + selection = selection.update(2, true); + + expect(selection.ids).empty; +}); + +test('retains selection', () => { + let selection = setup(); + + selection = selection.all(); + + selection.view = items.slice(0, 2); + expect(selection.ids).toStrictEqual(all.slice(0, 2)); + + selection.view = items; + expect(selection.ids).toStrictEqual(all); +}); + +test('is inactive by default', () => { + const selection = setup(); + expect(selection.active).toBe(false); +}); + +test('is inactive after clearing', () => { + let selection = setup(); + + selection.active = true; + + selection = selection.clear(); + expect(selection.active).false; +}); + +test('can be toggled', () => { + let selection = setup(); + + selection = selection.toggle(); + expect(selection.active).toBe(true); + + selection = selection.all(); + selection = selection.toggle(); + expect(selection.active).toBe(false); + expect(selection.ids).empty; +}); + +test('can be cleared', () => { + let selection = setup(); + + selection = selection.all(); + + selection = selection.clear(); + expect(selection.ids).empty; +}); + +test('reports selected items', () => { + let selection = setup(); + + selection = selection.update(0, false); + selection = selection.update(2, false); + + expect(selection.contains(all[0])).toBeTruthy(); + expect(selection.contains(all[1])).toBeFalsy(); + expect(selection.contains(all[2])).toBeTruthy(); + expect(selection.contains(all[3])).toBeFalsy(); +}); + +test('reports size', () => { + const selection = setup().all(); + + expect(selection.size).toBe(all.length); +}); + +test('reports size of visible items', () => { + const selection = setup().all(); + + selection.view = items.slice(0, 2); + expect(selection.size).toBe(2); + + selection.view = items; + expect(selection.size).toBe(all.length); +}); diff --git a/frontend/tsconfig.json b/frontend/tsconfig.json new file mode 100644 index 0000000..95c4753 --- /dev/null +++ b/frontend/tsconfig.json @@ -0,0 +1,19 @@ +{ + "extends": "./.svelte-kit/tsconfig.json", + "compilerOptions": { + "allowJs": true, + "checkJs": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true, + "skipLibCheck": true, + "sourceMap": true, + "strict": true, + "target": "ES2022", + "module": "ES2022" + } + // Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias + // + // If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes + // from the referenced tsconfig.json - TypeScript does not merge them in +} diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts new file mode 100644 index 0000000..145901f --- /dev/null +++ b/frontend/vite.config.ts @@ -0,0 +1,11 @@ +import { sveltekit } from '@sveltejs/kit/vite'; +import { defineConfig } from 'vite'; + +export default defineConfig({ + plugins: [sveltekit()], + server: { + fs: { + allow: ['objects'] + } + } +}); |