From 1827f20b2e44918fc3df7e3ff8943143e8464b9c Mon Sep 17 00:00:00 2001 From: Lucas Date: Thu, 29 May 2025 14:23:45 +1000 Subject: [PATCH 01/33] Delete old server --- server/.dockerignore | 9 - server/.env.example | 12 - server/.eslintrc.js | 25 - server/.gitignore | 56 - server/.prettierrc | 4 - server/Dockerfile | 30 - server/README.md | 90 - server/autotimetabler.proto | 26 - server/docker-compose.yaml | 40 - server/migrate.sh | 16 - server/nest-cli.json | 12 - server/package.json | 97 - server/pnpm-lock.yaml | 7113 ----------------- server/pnpm-workspace.yaml | 8 - .../20240713012659_init/migration.sql | 220 - .../migrations/20241003042905_/migration.sql | 40 - .../20241101072349_activity/migration.sql | 8 - .../migration.sql | 35 - .../migration.sql | 2 - .../migration.sql | 4 - .../migration.sql | 8 - .../migration.sql | 2 - .../migration.sql | 15 - server/prisma/migrations/migration_lock.toml | 3 - server/prisma/schema.prisma | 127 - server/proto-gen.sh | 14 - server/src/app.controller.ts | 7 - server/src/app.module.ts | 35 - server/src/app.service.ts | 24 - server/src/auth/auth.controller.spec.ts | 18 - server/src/auth/auth.controller.ts | 93 - server/src/auth/auth.module.ts | 34 - server/src/auth/auth.service.spec.ts | 18 - server/src/auth/auth.service.ts | 47 - server/src/auth/authenticated.guard.ts | 9 - server/src/auth/dtos/auth.dto.ts | 7 - server/src/auth/dtos/index.ts | 1 - server/src/auth/login.guard.ts | 12 - server/src/auth/oidc.strategy.ts | 72 - server/src/auth/session.serializer.ts | 14 - server/src/auto/auto.controller.ts | 21 - server/src/auto/auto.module.ts | 24 - server/src/auto/auto.service.ts | 68 - server/src/auto/dto/auto.dto.ts | 12 - server/src/config.ts | 11 - server/src/friend/dto/friend.dto.ts | 17 - server/src/friend/dto/index.ts | 1 - server/src/friend/friend.controller.spec.ts | 18 - server/src/friend/friend.controller.ts | 66 - server/src/friend/friend.module.ts | 10 - server/src/friend/friend.service.spec.ts | 18 - server/src/friend/friend.service.ts | 171 - server/src/graphql/graphql.module.ts | 7 - server/src/graphql/graphql.response.ts | 24 - server/src/graphql/graphql.service.spec.ts | 18 - server/src/graphql/graphql.service.ts | 67 - server/src/group/dto/group.dto.ts | 9 - server/src/group/dto/index.ts | 0 server/src/group/entities/group.entity.ts | 1 - server/src/group/group.controller.spec.ts | 20 - server/src/group/group.controller.ts | 99 - server/src/group/group.module.ts | 12 - server/src/group/group.service.spec.ts | 18 - server/src/group/group.service.ts | 157 - server/src/main.ts | 70 - server/src/prisma/prisma.module.ts | 7 - server/src/prisma/prisma.service.ts | 17 - server/src/proto/autotimetabler.proto | 26 - server/src/proto/autotimetabler_grpc_pb.d.ts | 98 - server/src/proto/autotimetabler_grpc_pb.js | 44 - server/src/proto/autotimetabler_pb.d.ts | 137 - server/src/proto/autotimetabler_pb.js | 827 -- server/src/user/dto/index.ts | 3 - server/src/user/dto/settings.dto.ts | 14 - server/src/user/dto/timetable.dto.ts | 84 - server/src/user/dto/user.dto.ts | 51 - server/src/user/user.controller.spec.ts | 18 - server/src/user/user.controller.ts | 229 - server/src/user/user.module.ts | 11 - server/src/user/user.service.spec.ts | 18 - server/src/user/user.service.ts | 465 -- server/test/app.e2e-spec.ts | 24 - server/test/db.spec.ts | 497 -- server/test/jest-e2e.json | 9 - server/test/mockData.ts | 143 - server/tsconfig.build.json | 4 - server/tsconfig.json | 21 - 87 files changed, 12093 deletions(-) delete mode 100644 server/.dockerignore delete mode 100644 server/.env.example delete mode 100644 server/.eslintrc.js delete mode 100644 server/.gitignore delete mode 100644 server/.prettierrc delete mode 100644 server/Dockerfile delete mode 100644 server/README.md delete mode 100644 server/autotimetabler.proto delete mode 100644 server/docker-compose.yaml delete mode 100644 server/migrate.sh delete mode 100644 server/nest-cli.json delete mode 100644 server/package.json delete mode 100644 server/pnpm-lock.yaml delete mode 100644 server/pnpm-workspace.yaml delete mode 100644 server/prisma/migrations/20240713012659_init/migration.sql delete mode 100644 server/prisma/migrations/20241003042905_/migration.sql delete mode 100644 server/prisma/migrations/20241101072349_activity/migration.sql delete mode 100644 server/prisma/migrations/20250322064905_upgrade_to_v6/migration.sql delete mode 100644 server/prisma/migrations/20250414034722_add_courseid_to_class/migration.sql delete mode 100644 server/prisma/migrations/20250424101523_fill_course_id/migration.sql delete mode 100644 server/prisma/migrations/20250424102004_require_course_id/migration.sql delete mode 100644 server/prisma/migrations/20250529041455_primary_timetable/migration.sql delete mode 100644 server/prisma/migrations/20250605081924_update_color_config/migration.sql delete mode 100644 server/prisma/migrations/migration_lock.toml delete mode 100644 server/prisma/schema.prisma delete mode 100755 server/proto-gen.sh delete mode 100644 server/src/app.controller.ts delete mode 100644 server/src/app.module.ts delete mode 100644 server/src/app.service.ts delete mode 100644 server/src/auth/auth.controller.spec.ts delete mode 100644 server/src/auth/auth.controller.ts delete mode 100644 server/src/auth/auth.module.ts delete mode 100644 server/src/auth/auth.service.spec.ts delete mode 100644 server/src/auth/auth.service.ts delete mode 100644 server/src/auth/authenticated.guard.ts delete mode 100644 server/src/auth/dtos/auth.dto.ts delete mode 100644 server/src/auth/dtos/index.ts delete mode 100644 server/src/auth/login.guard.ts delete mode 100644 server/src/auth/oidc.strategy.ts delete mode 100644 server/src/auth/session.serializer.ts delete mode 100644 server/src/auto/auto.controller.ts delete mode 100644 server/src/auto/auto.module.ts delete mode 100644 server/src/auto/auto.service.ts delete mode 100644 server/src/auto/dto/auto.dto.ts delete mode 100644 server/src/config.ts delete mode 100644 server/src/friend/dto/friend.dto.ts delete mode 100644 server/src/friend/dto/index.ts delete mode 100644 server/src/friend/friend.controller.spec.ts delete mode 100644 server/src/friend/friend.controller.ts delete mode 100644 server/src/friend/friend.module.ts delete mode 100644 server/src/friend/friend.service.spec.ts delete mode 100644 server/src/friend/friend.service.ts delete mode 100644 server/src/graphql/graphql.module.ts delete mode 100644 server/src/graphql/graphql.response.ts delete mode 100644 server/src/graphql/graphql.service.spec.ts delete mode 100644 server/src/graphql/graphql.service.ts delete mode 100644 server/src/group/dto/group.dto.ts delete mode 100644 server/src/group/dto/index.ts delete mode 100644 server/src/group/entities/group.entity.ts delete mode 100644 server/src/group/group.controller.spec.ts delete mode 100644 server/src/group/group.controller.ts delete mode 100644 server/src/group/group.module.ts delete mode 100644 server/src/group/group.service.spec.ts delete mode 100644 server/src/group/group.service.ts delete mode 100644 server/src/main.ts delete mode 100644 server/src/prisma/prisma.module.ts delete mode 100644 server/src/prisma/prisma.service.ts delete mode 100644 server/src/proto/autotimetabler.proto delete mode 100644 server/src/proto/autotimetabler_grpc_pb.d.ts delete mode 100644 server/src/proto/autotimetabler_grpc_pb.js delete mode 100644 server/src/proto/autotimetabler_pb.d.ts delete mode 100644 server/src/proto/autotimetabler_pb.js delete mode 100644 server/src/user/dto/index.ts delete mode 100644 server/src/user/dto/settings.dto.ts delete mode 100644 server/src/user/dto/timetable.dto.ts delete mode 100644 server/src/user/dto/user.dto.ts delete mode 100644 server/src/user/user.controller.spec.ts delete mode 100644 server/src/user/user.controller.ts delete mode 100644 server/src/user/user.module.ts delete mode 100644 server/src/user/user.service.spec.ts delete mode 100644 server/src/user/user.service.ts delete mode 100644 server/test/app.e2e-spec.ts delete mode 100644 server/test/db.spec.ts delete mode 100644 server/test/jest-e2e.json delete mode 100644 server/test/mockData.ts delete mode 100644 server/tsconfig.build.json delete mode 100644 server/tsconfig.json diff --git a/server/.dockerignore b/server/.dockerignore deleted file mode 100644 index 76762c498..000000000 --- a/server/.dockerignore +++ /dev/null @@ -1,9 +0,0 @@ -node_modules -npm-debug.log -test -.gitignore -.prettierrc -.git -Dockerfile -README.md -dist \ No newline at end of file diff --git a/server/.env.example b/server/.env.example deleted file mode 100644 index bb271ef1f..000000000 --- a/server/.env.example +++ /dev/null @@ -1,12 +0,0 @@ -POSTGRES_USER="postgres" -POSTGRES_DB="postgresdb" -POSTGRES_PASSWORD="verysneakypassword2022" -POSTGRES_PORT="5432" -DATABASE_URL="postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@localhost:${POSTGRES_PORT}/${POSTGRES_DB}?schema=public" -OAUTH2_CLIENT_PROVIDER_OIDC_ISSUER="https://id.notangles.com.au" -OAUTH2_CLIENT_REGISTRATION_LOGIN_CLIENT_ID="abcd1234" -OAUTH2_CLIENT_REGISTRATION_LOGIN_CLIENT_SECRET="abcd1234" -OAUTH2_CLIENT_REGISTRATION_LOGIN_SCOPE="openid" -OAUTH2_CLIENT_REGISTRATION_LOGIN_REDIRECT_URI="http://somehost:3001/api/auth/callback/your_org" -OAUTH2_CLIENT_REGISTRATION_LOGIN_POST_LOGOUT_REDIRECT_URI="http://somehost:3001/api/auth/callback/your_org" -SESSION_SECRET="abcd1234" \ No newline at end of file diff --git a/server/.eslintrc.js b/server/.eslintrc.js deleted file mode 100644 index 259de13c7..000000000 --- a/server/.eslintrc.js +++ /dev/null @@ -1,25 +0,0 @@ -module.exports = { - parser: '@typescript-eslint/parser', - parserOptions: { - project: 'tsconfig.json', - tsconfigRootDir: __dirname, - sourceType: 'module', - }, - plugins: ['@typescript-eslint/eslint-plugin'], - extends: [ - 'plugin:@typescript-eslint/recommended', - 'plugin:prettier/recommended', - ], - root: true, - env: { - node: true, - jest: true, - }, - ignorePatterns: ['.eslintrc.js'], - rules: { - '@typescript-eslint/interface-name-prefix': 'off', - '@typescript-eslint/explicit-function-return-type': 'off', - '@typescript-eslint/explicit-module-boundary-types': 'off', - '@typescript-eslint/no-explicit-any': 'off', - }, -}; diff --git a/server/.gitignore b/server/.gitignore deleted file mode 100644 index 4b56acfbe..000000000 --- a/server/.gitignore +++ /dev/null @@ -1,56 +0,0 @@ -# compiled output -/dist -/node_modules -/build - -# Logs -logs -*.log -npm-debug.log* -pnpm-debug.log* -yarn-debug.log* -yarn-error.log* -lerna-debug.log* - -# OS -.DS_Store - -# Tests -/coverage -/.nyc_output - -# IDEs and editors -/.idea -.project -.classpath -.c9/ -*.launch -.settings/ -*.sublime-workspace - -# IDE - VSCode -.vscode/* -!.vscode/settings.json -!.vscode/tasks.json -!.vscode/launch.json -!.vscode/extensions.json - -# dotenv environment variable files -.env -.env.development.local -.env.test.local -.env.production.local -.env.local - -# temp directory -.temp -.tmp - -# Runtime data -pids -*.pid -*.seed -*.pid.lock - -# Diagnostic reports (https://nodejs.org/api/report.html) -report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json diff --git a/server/.prettierrc b/server/.prettierrc deleted file mode 100644 index dcb72794f..000000000 --- a/server/.prettierrc +++ /dev/null @@ -1,4 +0,0 @@ -{ - "singleQuote": true, - "trailingComma": "all" -} \ No newline at end of file diff --git a/server/Dockerfile b/server/Dockerfile deleted file mode 100644 index 90a981e18..000000000 --- a/server/Dockerfile +++ /dev/null @@ -1,30 +0,0 @@ -# Dependency versions should be pinned -FROM node:22.16.0-alpine AS builder -RUN apk add --no-cache openssl - -RUN npm i -g pnpm -RUN pnpm install @nestjs/cli -WORKDIR /server - -COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./ -COPY prisma ./prisma/ - -RUN pnpm i --frozen-lockfile - -COPY . . -RUN pnpm run build - -FROM node:22.16.0-alpine -WORKDIR /server -RUN npm i -g pnpm - -ENV NODE_ENV=production -COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./ -RUN pnpm install --production --frozen-lockfile - -COPY --from=builder /server . -RUN npx prisma generate - -EXPOSE 3001 - -CMD ["pnpm", "run", "start:migrate:prod"] diff --git a/server/README.md b/server/README.md deleted file mode 100644 index 285e0fe0b..000000000 --- a/server/README.md +++ /dev/null @@ -1,90 +0,0 @@ -

- Nest Logo -

- -[circleci-image]: https://img.shields.io/circleci/build/github/nestjs/nest/master?token=abc123def456 -[circleci-url]: https://circleci.com/gh/nestjs/nest - -

A progressive Node.js framework for building efficient and scalable server-side applications.

-

-NPM Version -Package License -NPM Downloads -CircleCI -Coverage -Discord -Backers on Open Collective -Sponsors on Open Collective - - Support us - -

- - -## Description - -[Nest](https://github.com/nestjs/nest) framework TypeScript starter repository. - -## Installation - -```bash -# prerequisite -$ cd server - -# installation -$ pnpm install -$ pnpx prisma generate -``` - -## Running the app - -```bash -# development -$ pnpm run start - -# watch mode -$ pnpm run start:dev - -# production mode -$ pnpm run start:prod -``` - -The server will be hosted at `http://localhost:3001`. - -## Database - -```bash -# prerequisite -$ cd server - -# installation -$ docker compose up database -``` - -## Test - -```bash -# unit tests -$ pnpm run test - -# e2e tests -$ pnpm run test:e2e - -# test coverage -$ pnpm run test:cov -``` - -## Support - -Nest is an MIT-licensed open source project. It can grow thanks to the sponsors and support by the amazing backers. If you'd like to join them, please [read more here](https://docs.nestjs.com/support). - -## Stay in touch - -- Author - [Kamil Myƛliwiec](https://kamilmysliwiec.com) -- Website - [https://nestjs.com](https://nestjs.com/) -- Twitter - [@nestframework](https://twitter.com/nestframework) - -## License - -Nest is [MIT licensed](LICENSE). diff --git a/server/autotimetabler.proto b/server/autotimetabler.proto deleted file mode 100644 index 17c2bd84b..000000000 --- a/server/autotimetabler.proto +++ /dev/null @@ -1,26 +0,0 @@ -syntax = "proto3"; - - - -message TimetableConstraints { - message PeriodInfo { - int32 periodsPerClass = 1; - repeated float periodTimes = 2; - repeated float durations = 3; - } - int32 start = 1; - int32 end = 2; - string days = 3; - int32 gap = 4; - int32 maxdays = 5; - repeated PeriodInfo periodInfo = 6; -} - -message AutoTimetableResponse { - repeated float times = 1; - bool optimal = 2; -} - -service AutoTimetabler { - rpc FindBestTimetable (TimetableConstraints) returns (AutoTimetableResponse); -} diff --git a/server/docker-compose.yaml b/server/docker-compose.yaml deleted file mode 100644 index d8924da9b..000000000 --- a/server/docker-compose.yaml +++ /dev/null @@ -1,40 +0,0 @@ -version: '3.7' -services: - server: - container_name: notangles-server - image: notangles-server - restart: always - build: - context: . - dockerfile: Dockerfile - depends_on: - - database - ports: - - '3001:3001' - networks: - - notangles_network - environment: - - DATABASE_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@database:5432/${POSTGRES_DB}?schema=public - - database: - container_name: notangles-database - hostname: notangles_database - restart: always - image: postgres:17-alpine - ports: - - '5432:5432' - environment: - - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} - - POSTGRES_USER=${POSTGRES_USER} - - POSTGRES_DB=${POSTGRES_DB} - volumes: - - postgres:/var/lib/postgresql/data - networks: - - notangles_network - -volumes: - postgres: - name: server -networks: - notangles_network: - driver: bridge diff --git a/server/migrate.sh b/server/migrate.sh deleted file mode 100644 index 328ba5163..000000000 --- a/server/migrate.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/sh - -set -e - -cd /app/prisma - -# Check if there are any migrations -if [ -z "$(ls -A migrations)" ]; then - echo "No existing migrations found. Creating initial migration..." -else - echo "Existing migrations found. Deleting and reapplying..." - rm -rf migrations/* -fi - -npx prisma migrate dev --name init -npx prisma generate diff --git a/server/nest-cli.json b/server/nest-cli.json deleted file mode 100644 index 563742eca..000000000 --- a/server/nest-cli.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "$schema": "https://json.schemastore.org/nest-cli", - "collection": "@nestjs/schematics", - "sourceRoot": "src", - "compilerOptions": { - "deleteOutDir": true, - "assets": [ - "../prisma/*", - "./proto/*" - ] - } -} diff --git a/server/package.json b/server/package.json deleted file mode 100644 index b510db666..000000000 --- a/server/package.json +++ /dev/null @@ -1,97 +0,0 @@ -{ - "name": "server", - "version": "0.0.1", - "description": "", - "author": "", - "private": true, - "license": "UNLICENSED", - "scripts": { - "build": "nest build", - "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"", - "start": "nest start", - "start:dev": "nest start --watch", - "start:debug": "nest start --debug --watch", - "start:prod": "node dist/main", - "start:migrate:prod": "prisma migrate deploy && npm run start", - "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix", - "test": "jest", - "test:watch": "jest --watch", - "test:cov": "jest --coverage", - "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand", - "test:e2e": "jest --config ./test/jest-e2e.json", - "style": "prettier --write '{src,apps,libs,test}/**/*.ts' && eslint --fix '{src,apps,libs,test}/**/*.ts'" - }, - "dependencies": { - "@grpc/grpc-js": "1.13.4", - "@nestjs/common": "10.4.17", - "@nestjs/config": "3.3.0", - "@nestjs/core": "10.4.17", - "@nestjs/mapped-types": "2.1.0", - "@nestjs/microservices": "10.4.17", - "@nestjs/passport": "10.0.3", - "@nestjs/platform-express": "10.4.17", - "@nestjs/swagger": "7.4.2", - "@prisma/client": "6.9.0", - "@quixo3/prisma-session-store": "3.1.13", - "@types/express-session": "1.18.2", - "class-transformer": "0.5.1", - "class-validator": "0.14.1", - "dotenv": "16.5.0", - "express-session": "1.18.1", - "google-protobuf": "3.21.4", - "openid-client": "5.7.1", - "passport": "0.7.0", - "protobufjs": "5.0.3", - "reflect-metadata": "0.2.2", - "rxjs": "7.8.2", - "ts-protoc-gen": "0.15.0", - "uuid": "9.0.1" - }, - "devDependencies": { - "@nestjs/cli": "10.4.9", - "@nestjs/schematics": "10.2.3", - "@nestjs/testing": "10.4.17", - "@types/express": "4.17.21", - "@types/jest": "29.5.14", - "@types/node": "22.15.3", - "@types/supertest": "6.0.3", - "@typescript-eslint/eslint-plugin": "6.21.0", - "@typescript-eslint/parser": "6.21.0", - "eslint": "8.57.1", - "eslint-config-prettier": "9.1.0", - "eslint-plugin-prettier": "5.4.1", - "grpc-tools": "1.13.0", - "grpc_tools_node_protoc_ts": "5.3.3", - "jest": "29.7.0", - "prettier": "3.5.3", - "prisma": "6.9.0", - "source-map-support": "0.5.21", - "supertest": "6.3.4", - "ts-jest": "29.3.4", - "ts-loader": "9.5.2", - "ts-node": "10.9.2", - "tsconfig-paths": "4.2.0", - "typescript": "5.8.3" - }, - "jest": { - "moduleFileExtensions": [ - "js", - "json", - "ts" - ], - "rootDir": "./", - "testRegex": ".*\\.spec\\.ts$", - "transform": { - "^.+\\.(t|j)s$": "ts-jest" - }, - "collectCoverageFrom": [ - "**/*.(t|j)s" - ], - "coverageDirectory": "../coverage", - "testEnvironment": "node", - "modulePaths": [ - "" - ] - }, - "packageManager": "pnpm@10.12.1+sha512.f0dda8580f0ee9481c5c79a1d927b9164f2c478e90992ad268bbb2465a736984391d6333d2c327913578b2804af33474ca554ba29c04a8b13060a717675ae3ac" -} diff --git a/server/pnpm-lock.yaml b/server/pnpm-lock.yaml deleted file mode 100644 index c7463c340..000000000 --- a/server/pnpm-lock.yaml +++ /dev/null @@ -1,7113 +0,0 @@ -lockfileVersion: '9.0' - -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false - -importers: - - .: - dependencies: - '@grpc/grpc-js': - specifier: 1.13.4 - version: 1.13.4 - '@nestjs/common': - specifier: 10.4.17 - version: 10.4.17(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/config': - specifier: 3.3.0 - version: 3.3.0(@nestjs/common@10.4.17(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(rxjs@7.8.2) - '@nestjs/core': - specifier: 10.4.17 - version: 10.4.17(@nestjs/common@10.4.17(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/microservices@10.4.17)(@nestjs/platform-express@10.4.17)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/mapped-types': - specifier: 2.1.0 - version: 2.1.0(@nestjs/common@10.4.17(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2) - '@nestjs/microservices': - specifier: 10.4.17 - version: 10.4.17(@grpc/grpc-js@1.13.4)(@nestjs/common@10.4.17(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@10.4.17)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/passport': - specifier: 10.0.3 - version: 10.0.3(@nestjs/common@10.4.17(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(passport@0.7.0) - '@nestjs/platform-express': - specifier: 10.4.17 - version: 10.4.17(@nestjs/common@10.4.17(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@10.4.17) - '@nestjs/swagger': - specifier: 7.4.2 - version: 7.4.2(@nestjs/common@10.4.17(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@10.4.17)(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2) - '@prisma/client': - specifier: 6.9.0 - version: 6.9.0(prisma@6.9.0(typescript@5.8.3))(typescript@5.8.3) - '@quixo3/prisma-session-store': - specifier: 3.1.13 - version: 3.1.13(@prisma/client@6.9.0(prisma@6.9.0(typescript@5.8.3))(typescript@5.8.3))(express-session@1.18.1) - '@types/express-session': - specifier: 1.18.2 - version: 1.18.2 - class-transformer: - specifier: 0.5.1 - version: 0.5.1 - class-validator: - specifier: 0.14.1 - version: 0.14.1 - dotenv: - specifier: 16.5.0 - version: 16.5.0 - express-session: - specifier: 1.18.1 - version: 1.18.1 - google-protobuf: - specifier: 3.21.4 - version: 3.21.4 - openid-client: - specifier: 5.7.1 - version: 5.7.1 - passport: - specifier: 0.7.0 - version: 0.7.0 - protobufjs: - specifier: 5.0.3 - version: 5.0.3 - reflect-metadata: - specifier: 0.2.2 - version: 0.2.2 - rxjs: - specifier: 7.8.2 - version: 7.8.2 - ts-protoc-gen: - specifier: 0.15.0 - version: 0.15.0 - uuid: - specifier: 9.0.1 - version: 9.0.1 - devDependencies: - '@nestjs/cli': - specifier: 10.4.9 - version: 10.4.9 - '@nestjs/schematics': - specifier: 10.2.3 - version: 10.2.3(chokidar@3.6.0)(typescript@5.8.3) - '@nestjs/testing': - specifier: 10.4.17 - version: 10.4.17(@nestjs/common@10.4.17(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@10.4.17)(@nestjs/microservices@10.4.17)(@nestjs/platform-express@10.4.17) - '@types/express': - specifier: 4.17.21 - version: 4.17.21 - '@types/jest': - specifier: 29.5.14 - version: 29.5.14 - '@types/node': - specifier: 22.15.3 - version: 22.15.3 - '@types/supertest': - specifier: 6.0.3 - version: 6.0.3 - '@typescript-eslint/eslint-plugin': - specifier: 6.21.0 - version: 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1)(typescript@5.8.3) - '@typescript-eslint/parser': - specifier: 6.21.0 - version: 6.21.0(eslint@8.57.1)(typescript@5.8.3) - eslint: - specifier: 8.57.1 - version: 8.57.1 - eslint-config-prettier: - specifier: 9.1.0 - version: 9.1.0(eslint@8.57.1) - eslint-plugin-prettier: - specifier: 5.4.1 - version: 5.4.1(@types/eslint@9.6.1)(eslint-config-prettier@9.1.0(eslint@8.57.1))(eslint@8.57.1)(prettier@3.5.3) - grpc-tools: - specifier: 1.13.0 - version: 1.13.0 - grpc_tools_node_protoc_ts: - specifier: 5.3.3 - version: 5.3.3 - jest: - specifier: 29.7.0 - version: 29.7.0(@types/node@22.15.3)(ts-node@10.9.2(@types/node@22.15.3)(typescript@5.8.3)) - prettier: - specifier: 3.5.3 - version: 3.5.3 - prisma: - specifier: 6.9.0 - version: 6.9.0(typescript@5.8.3) - source-map-support: - specifier: 0.5.21 - version: 0.5.21 - supertest: - specifier: 6.3.4 - version: 6.3.4 - ts-jest: - specifier: 29.3.4 - version: 29.3.4(@babel/core@7.27.1)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.27.1))(jest@29.7.0(@types/node@22.15.3)(ts-node@10.9.2(@types/node@22.15.3)(typescript@5.8.3)))(typescript@5.8.3) - ts-loader: - specifier: 9.5.2 - version: 9.5.2(typescript@5.8.3)(webpack@5.97.1) - ts-node: - specifier: 10.9.2 - version: 10.9.2(@types/node@22.15.3)(typescript@5.8.3) - tsconfig-paths: - specifier: 4.2.0 - version: 4.2.0 - typescript: - specifier: 5.8.3 - version: 5.8.3 - -packages: - - '@ampproject/remapping@2.3.0': - resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} - engines: {node: '>=6.0.0'} - - '@angular-devkit/core@17.3.11': - resolution: {integrity: sha512-vTNDYNsLIWpYk2I969LMQFH29GTsLzxNk/0cLw5q56ARF0v5sIWfHYwGTS88jdDqIpuuettcSczbxeA7EuAmqQ==} - engines: {node: ^18.13.0 || >=20.9.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} - peerDependencies: - chokidar: ^3.5.2 - peerDependenciesMeta: - chokidar: - optional: true - - '@angular-devkit/schematics-cli@17.3.11': - resolution: {integrity: sha512-kcOMqp+PHAKkqRad7Zd7PbpqJ0LqLaNZdY1+k66lLWmkEBozgq8v4ASn/puPWf9Bo0HpCiK+EzLf0VHE8Z/y6Q==} - engines: {node: ^18.13.0 || >=20.9.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} - hasBin: true - - '@angular-devkit/schematics@17.3.11': - resolution: {integrity: sha512-I5wviiIqiFwar9Pdk30Lujk8FczEEc18i22A5c6Z9lbmhPQdTroDnEQdsfXjy404wPe8H62s0I15o4pmMGfTYQ==} - engines: {node: ^18.13.0 || >=20.9.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} - - '@babel/code-frame@7.27.1': - resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} - engines: {node: '>=6.9.0'} - - '@babel/compat-data@7.27.1': - resolution: {integrity: sha512-Q+E+rd/yBzNQhXkG+zQnF58e4zoZfBedaxwzPmicKsiK3nt8iJYrSrDbjwFFDGC4f+rPafqRaPH6TsDoSvMf7A==} - engines: {node: '>=6.9.0'} - - '@babel/core@7.27.1': - resolution: {integrity: sha512-IaaGWsQqfsQWVLqMn9OB92MNN7zukfVA4s7KKAI0KfrrDsZ0yhi5uV4baBuLuN7n3vsZpwP8asPPcVwApxvjBQ==} - engines: {node: '>=6.9.0'} - - '@babel/generator@7.27.1': - resolution: {integrity: sha512-UnJfnIpc/+JO0/+KRVQNGU+y5taA5vCbwN8+azkX6beii/ZF+enZJSOKo11ZSzGJjlNfJHfQtmQT8H+9TXPG2w==} - engines: {node: '>=6.9.0'} - - '@babel/helper-compilation-targets@7.27.1': - resolution: {integrity: sha512-2YaDd/Rd9E598B5+WIc8wJPmWETiiJXFYVE60oX8FDohv7rAUU3CQj+A1MgeEmcsk2+dQuEjIe/GDvig0SqL4g==} - engines: {node: '>=6.9.0'} - - '@babel/helper-module-imports@7.27.1': - resolution: {integrity: sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==} - engines: {node: '>=6.9.0'} - - '@babel/helper-module-transforms@7.27.1': - resolution: {integrity: sha512-9yHn519/8KvTU5BjTVEEeIM3w9/2yXNKoD82JifINImhpKkARMJKPP59kLo+BafpdN5zgNeIcS4jsGDmd3l58g==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - - '@babel/helper-plugin-utils@7.27.1': - resolution: {integrity: sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==} - engines: {node: '>=6.9.0'} - - '@babel/helper-string-parser@7.27.1': - resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} - engines: {node: '>=6.9.0'} - - '@babel/helper-validator-identifier@7.27.1': - resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==} - engines: {node: '>=6.9.0'} - - '@babel/helper-validator-option@7.27.1': - resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} - engines: {node: '>=6.9.0'} - - '@babel/helpers@7.27.1': - resolution: {integrity: sha512-FCvFTm0sWV8Fxhpp2McP5/W53GPllQ9QeQ7SiqGWjMf/LVG07lFa5+pgK05IRhVwtvafT22KF+ZSnM9I545CvQ==} - engines: {node: '>=6.9.0'} - - '@babel/parser@7.27.1': - resolution: {integrity: sha512-I0dZ3ZpCrJ1c04OqlNsQcKiZlsrXf/kkE4FXzID9rIOYICsAbA8mMDzhW/luRNAHdCNt7os/u8wenklZDlUVUQ==} - engines: {node: '>=6.0.0'} - hasBin: true - - '@babel/plugin-syntax-async-generators@7.8.4': - resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-bigint@7.8.3': - resolution: {integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-class-properties@7.12.13': - resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-class-static-block@7.14.5': - resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-import-attributes@7.27.1': - resolution: {integrity: sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-import-meta@7.10.4': - resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-json-strings@7.8.3': - resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-jsx@7.27.1': - resolution: {integrity: sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-logical-assignment-operators@7.10.4': - resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3': - resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-numeric-separator@7.10.4': - resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-object-rest-spread@7.8.3': - resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-optional-catch-binding@7.8.3': - resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-optional-chaining@7.8.3': - resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-private-property-in-object@7.14.5': - resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-top-level-await@7.14.5': - resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-typescript@7.27.1': - resolution: {integrity: sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/template@7.27.1': - resolution: {integrity: sha512-Fyo3ghWMqkHHpHQCoBs2VnYjR4iWFFjguTDEqA5WgZDOrFesVjMhMM2FSqTKSoUSDO1VQtavj8NFpdRBEvJTtg==} - engines: {node: '>=6.9.0'} - - '@babel/traverse@7.27.1': - resolution: {integrity: sha512-ZCYtZciz1IWJB4U61UPu4KEaqyfj+r5T1Q5mqPo+IBpcG9kHv30Z0aD8LXPgC1trYa6rK0orRyAhqUgk4MjmEg==} - engines: {node: '>=6.9.0'} - - '@babel/types@7.27.1': - resolution: {integrity: sha512-+EzkxvLNfiUeKMgy/3luqfsCWFRXLb7U6wNQTk60tovuckwB15B191tJWvpp4HjiQWdJkCxO3Wbvc6jlk3Xb2Q==} - engines: {node: '>=6.9.0'} - - '@bcoe/v8-coverage@0.2.3': - resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} - - '@colors/colors@1.5.0': - resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==} - engines: {node: '>=0.1.90'} - - '@cspotcode/source-map-support@0.8.1': - resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} - engines: {node: '>=12'} - - '@eslint-community/eslint-utils@4.6.1': - resolution: {integrity: sha512-KTsJMmobmbrFLe3LDh0PC2FXpcSYJt/MLjlkh/9LEnmKYLSYmT/0EW9JWANjeoemiuZrmogti0tW5Ch+qNUYDw==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - - '@eslint-community/regexpp@4.12.1': - resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} - engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - - '@eslint/eslintrc@2.1.4': - resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - - '@eslint/js@8.57.1': - resolution: {integrity: sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - - '@grpc/grpc-js@1.13.4': - resolution: {integrity: sha512-GsFaMXCkMqkKIvwCQjCrwH+GHbPKBjhwo/8ZuUkWHqbI73Kky9I+pQltrlT0+MWpedCoosda53lgjYfyEPgxBg==} - engines: {node: '>=12.10.0'} - - '@grpc/proto-loader@0.7.15': - resolution: {integrity: sha512-tMXdRCfYVixjuFK+Hk0Q1s38gV9zDiDJfWL3h1rv4Qc39oILCu1TRTDt7+fGUI8K4G1Fj125Hx/ru3azECWTyQ==} - engines: {node: '>=6'} - hasBin: true - - '@humanwhocodes/config-array@0.13.0': - resolution: {integrity: sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==} - engines: {node: '>=10.10.0'} - deprecated: Use @eslint/config-array instead - - '@humanwhocodes/module-importer@1.0.1': - resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} - engines: {node: '>=12.22'} - - '@humanwhocodes/object-schema@2.0.3': - resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==} - deprecated: Use @eslint/object-schema instead - - '@isaacs/cliui@8.0.2': - resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} - engines: {node: '>=12'} - - '@istanbuljs/load-nyc-config@1.1.0': - resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==} - engines: {node: '>=8'} - - '@istanbuljs/schema@0.1.3': - resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} - engines: {node: '>=8'} - - '@jest/console@29.7.0': - resolution: {integrity: sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jest/core@29.7.0': - resolution: {integrity: sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - - '@jest/environment@29.7.0': - resolution: {integrity: sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jest/expect-utils@29.7.0': - resolution: {integrity: sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jest/expect@29.7.0': - resolution: {integrity: sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jest/fake-timers@29.7.0': - resolution: {integrity: sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jest/globals@29.7.0': - resolution: {integrity: sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jest/reporters@29.7.0': - resolution: {integrity: sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - - '@jest/schemas@29.6.3': - resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jest/source-map@29.6.3': - resolution: {integrity: sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jest/test-result@29.7.0': - resolution: {integrity: sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jest/test-sequencer@29.7.0': - resolution: {integrity: sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jest/transform@29.7.0': - resolution: {integrity: sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jest/types@29.6.3': - resolution: {integrity: sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jridgewell/gen-mapping@0.3.8': - resolution: {integrity: sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==} - engines: {node: '>=6.0.0'} - - '@jridgewell/resolve-uri@3.1.2': - resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} - engines: {node: '>=6.0.0'} - - '@jridgewell/set-array@1.2.1': - resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} - engines: {node: '>=6.0.0'} - - '@jridgewell/source-map@0.3.6': - resolution: {integrity: sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==} - - '@jridgewell/sourcemap-codec@1.5.0': - resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} - - '@jridgewell/trace-mapping@0.3.25': - resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} - - '@jridgewell/trace-mapping@0.3.9': - resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} - - '@js-sdsl/ordered-map@4.4.2': - resolution: {integrity: sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==} - - '@ljharb/through@2.3.14': - resolution: {integrity: sha512-ajBvlKpWucBB17FuQYUShqpqy8GRgYEpJW0vWJbUu1CV9lWyrDCapy0lScU8T8Z6qn49sSwJB3+M+evYIdGg+A==} - engines: {node: '>= 0.4'} - - '@lukeed/csprng@1.1.0': - resolution: {integrity: sha512-Z7C/xXCiGWsg0KuKsHTKJxbWhpI3Vs5GwLfOean7MGyVFGqdRgBbAjOCh6u4bbjPc/8MJ2pZmK/0DLdCbivLDA==} - engines: {node: '>=8'} - - '@mapbox/node-pre-gyp@1.0.11': - resolution: {integrity: sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==} - hasBin: true - - '@microsoft/tsdoc@0.15.1': - resolution: {integrity: sha512-4aErSrCR/On/e5G2hDP0wjooqDdauzEbIq8hIkIe5pXV0rtWJZvdCEKL0ykZxex+IxIwBp0eGeV48hQN07dXtw==} - - '@nestjs/cli@10.4.9': - resolution: {integrity: sha512-s8qYd97bggqeK7Op3iD49X2MpFtW4LVNLAwXFkfbRxKME6IYT7X0muNTJ2+QfI8hpbNx9isWkrLWIp+g5FOhiA==} - engines: {node: '>= 16.14'} - hasBin: true - peerDependencies: - '@swc/cli': ^0.1.62 || ^0.3.0 || ^0.4.0 || ^0.5.0 - '@swc/core': ^1.3.62 - peerDependenciesMeta: - '@swc/cli': - optional: true - '@swc/core': - optional: true - - '@nestjs/common@10.4.17': - resolution: {integrity: sha512-NKzPA4Tb35XjlxizsT8KZb3CCX8tNKj5EnsXsTl/gZX//uAWccBsqB8BjU69x/u4/kQ0106/Kt6PP+yrHAez0w==} - peerDependencies: - class-transformer: '*' - class-validator: '*' - reflect-metadata: ^0.1.12 || ^0.2.0 - rxjs: ^7.1.0 - peerDependenciesMeta: - class-transformer: - optional: true - class-validator: - optional: true - - '@nestjs/config@3.3.0': - resolution: {integrity: sha512-pdGTp8m9d0ZCrjTpjkUbZx6gyf2IKf+7zlkrPNMsJzYZ4bFRRTpXrnj+556/5uiI6AfL5mMrJc2u7dB6bvM+VA==} - peerDependencies: - '@nestjs/common': ^8.0.0 || ^9.0.0 || ^10.0.0 - rxjs: ^7.1.0 - - '@nestjs/core@10.4.17': - resolution: {integrity: sha512-Tk4J5aS082NUYrsJEDLvGdU+kRnHAMdOvsA4j62fP5THO6fN6vqv6jWHfydhCiPGUCJWLT6m+mNIhETMhMAs+Q==} - peerDependencies: - '@nestjs/common': ^10.0.0 - '@nestjs/microservices': ^10.0.0 - '@nestjs/platform-express': ^10.0.0 - '@nestjs/websockets': ^10.0.0 - reflect-metadata: ^0.1.12 || ^0.2.0 - rxjs: ^7.1.0 - peerDependenciesMeta: - '@nestjs/microservices': - optional: true - '@nestjs/platform-express': - optional: true - '@nestjs/websockets': - optional: true - - '@nestjs/mapped-types@2.0.5': - resolution: {integrity: sha512-bSJv4pd6EY99NX9CjBIyn4TVDoSit82DUZlL4I3bqNfy5Gt+gXTa86i3I/i0iIV9P4hntcGM5GyO+FhZAhxtyg==} - peerDependencies: - '@nestjs/common': ^8.0.0 || ^9.0.0 || ^10.0.0 - class-transformer: ^0.4.0 || ^0.5.0 - class-validator: ^0.13.0 || ^0.14.0 - reflect-metadata: ^0.1.12 || ^0.2.0 - peerDependenciesMeta: - class-transformer: - optional: true - class-validator: - optional: true - - '@nestjs/mapped-types@2.1.0': - resolution: {integrity: sha512-W+n+rM69XsFdwORF11UqJahn4J3xi4g/ZEOlJNL6KoW5ygWSmBB2p0S2BZ4FQeS/NDH72e6xIcu35SfJnE8bXw==} - peerDependencies: - '@nestjs/common': ^10.0.0 || ^11.0.0 - class-transformer: ^0.4.0 || ^0.5.0 - class-validator: ^0.13.0 || ^0.14.0 - reflect-metadata: ^0.1.12 || ^0.2.0 - peerDependenciesMeta: - class-transformer: - optional: true - class-validator: - optional: true - - '@nestjs/microservices@10.4.17': - resolution: {integrity: sha512-12r7zFvh8q+u2Xi9CT6CjsPsBeJsM1u9Bk2ZSaign6W6lfqsIKtqC8dNxuggyCna8MftNo8uW3mhUG+9bW/tnw==} - peerDependencies: - '@grpc/grpc-js': '*' - '@nestjs/common': ^10.0.0 - '@nestjs/core': ^10.0.0 - '@nestjs/websockets': ^10.0.0 - amqp-connection-manager: '*' - amqplib: '*' - cache-manager: '*' - ioredis: '*' - kafkajs: '*' - mqtt: '*' - nats: '*' - reflect-metadata: ^0.1.12 || ^0.2.0 - rxjs: ^7.1.0 - peerDependenciesMeta: - '@grpc/grpc-js': - optional: true - '@nestjs/websockets': - optional: true - amqp-connection-manager: - optional: true - amqplib: - optional: true - cache-manager: - optional: true - ioredis: - optional: true - kafkajs: - optional: true - mqtt: - optional: true - nats: - optional: true - - '@nestjs/passport@10.0.3': - resolution: {integrity: sha512-znJ9Y4S8ZDVY+j4doWAJ8EuuVO7SkQN3yOBmzxbGaXbvcSwFDAdGJ+OMCg52NdzIO4tQoN4pYKx8W6M0ArfFRQ==} - peerDependencies: - '@nestjs/common': ^8.0.0 || ^9.0.0 || ^10.0.0 - passport: ^0.4.0 || ^0.5.0 || ^0.6.0 || ^0.7.0 - - '@nestjs/platform-express@10.4.17': - resolution: {integrity: sha512-ovn4Wxney3QGBrqNPv0QLcCuH5QoAi6pb/GNWAz6B/NmBjZbs9/zl4a2beGDA2SaYre9w43YbfmHTm17PneP9w==} - peerDependencies: - '@nestjs/common': ^10.0.0 - '@nestjs/core': ^10.0.0 - - '@nestjs/schematics@10.2.3': - resolution: {integrity: sha512-4e8gxaCk7DhBxVUly2PjYL4xC2ifDFexCqq1/u4TtivLGXotVk0wHdYuPYe1tHTHuR1lsOkRbfOCpkdTnigLVg==} - peerDependencies: - typescript: '>=4.8.2' - - '@nestjs/swagger@7.4.2': - resolution: {integrity: sha512-Mu6TEn1M/owIvAx2B4DUQObQXqo2028R2s9rSZ/hJEgBK95+doTwS0DjmVA2wTeZTyVtXOoN7CsoM5pONBzvKQ==} - peerDependencies: - '@fastify/static': ^6.0.0 || ^7.0.0 - '@nestjs/common': ^9.0.0 || ^10.0.0 - '@nestjs/core': ^9.0.0 || ^10.0.0 - class-transformer: '*' - class-validator: '*' - reflect-metadata: ^0.1.12 || ^0.2.0 - peerDependenciesMeta: - '@fastify/static': - optional: true - class-transformer: - optional: true - class-validator: - optional: true - - '@nestjs/testing@10.4.17': - resolution: {integrity: sha512-TV1fqSNqqXgp0W57jCAfhJRfsvpH+krd4RtYSa7Pu+aU9uB+xcMBn5M62G02aMU41DURVZXKNVbHsZb6meZqBQ==} - peerDependencies: - '@nestjs/common': ^10.0.0 - '@nestjs/core': ^10.0.0 - '@nestjs/microservices': ^10.0.0 - '@nestjs/platform-express': ^10.0.0 - peerDependenciesMeta: - '@nestjs/microservices': - optional: true - '@nestjs/platform-express': - optional: true - - '@noble/hashes@1.8.0': - resolution: {integrity: sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==} - engines: {node: ^14.21.3 || >=16} - - '@nodelib/fs.scandir@2.1.5': - resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} - engines: {node: '>= 8'} - - '@nodelib/fs.stat@2.0.5': - resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} - engines: {node: '>= 8'} - - '@nodelib/fs.walk@1.2.8': - resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} - engines: {node: '>= 8'} - - '@nuxtjs/opencollective@0.3.2': - resolution: {integrity: sha512-um0xL3fO7Mf4fDxcqx9KryrB7zgRM5JSlvGN5AGkP6JLM5XEKyjeAiPbNxdXVXQ16isuAhYpvP88NgL2BGd6aA==} - engines: {node: '>=8.0.0', npm: '>=5.0.0'} - hasBin: true - - '@paralleldrive/cuid2@2.2.2': - resolution: {integrity: sha512-ZOBkgDwEdoYVlSeRbYYXs0S9MejQofiVYoTbKzy/6GQa39/q5tQU2IX46+shYnUkpEl3wc+J6wRlar7r2EK2xA==} - - '@pkgjs/parseargs@0.11.0': - resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} - engines: {node: '>=14'} - - '@pkgr/core@0.2.4': - resolution: {integrity: sha512-ROFF39F6ZrnzSUEmQQZUar0Jt4xVoP9WnDRdWwF4NNcXs3xBTLgBUDoOwW141y1jP+S8nahIbdxbFC7IShw9Iw==} - engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} - - '@prisma/client@6.9.0': - resolution: {integrity: sha512-Gg7j1hwy3SgF1KHrh0PZsYvAaykeR0PaxusnLXydehS96voYCGt1U5zVR31NIouYc63hWzidcrir1a7AIyCsNQ==} - engines: {node: '>=18.18'} - peerDependencies: - prisma: '*' - typescript: '>=5.1.0' - peerDependenciesMeta: - prisma: - optional: true - typescript: - optional: true - - '@prisma/config@6.9.0': - resolution: {integrity: sha512-Wcfk8/lN3WRJd5w4jmNQkUwhUw0eksaU/+BlAJwPQKW10k0h0LC9PD/6TQFmqKVbHQL0vG2z266r0S1MPzzhbA==} - - '@prisma/debug@6.9.0': - resolution: {integrity: sha512-bFeur/qi/Q+Mqk4JdQ3R38upSYPebv5aOyD1RKywVD+rAMLtRkmTFn28ZuTtVOnZHEdtxnNOCH+bPIeSGz1+Fg==} - - '@prisma/engines-version@6.9.0-10.81e4af48011447c3cc503a190e86995b66d2a28e': - resolution: {integrity: sha512-Qp9gMoBHgqhKlrvumZWujmuD7q4DV/gooEyPCLtbkc13EZdSz2RsGUJ5mHb3RJgAbk+dm6XenqG7obJEhXcJ6Q==} - - '@prisma/engines@6.9.0': - resolution: {integrity: sha512-im0X0bwDLA0244CDf8fuvnLuCQcBBdAGgr+ByvGfQY9wWl6EA+kRGwVk8ZIpG65rnlOwtaWIr/ZcEU5pNVvq9g==} - - '@prisma/fetch-engine@6.9.0': - resolution: {integrity: sha512-PMKhJdl4fOdeE3J3NkcWZ+tf3W6rx3ht/rLU8w4SXFRcLhd5+3VcqY4Kslpdm8osca4ej3gTfB3+cSk5pGxgFg==} - - '@prisma/get-platform@6.9.0': - resolution: {integrity: sha512-/B4n+5V1LI/1JQcHp+sUpyRT1bBgZVPHbsC4lt4/19Xp4jvNIVcq5KYNtQDk5e/ukTSjo9PZVAxxy9ieFtlpTQ==} - - '@protobufjs/aspromise@1.1.2': - resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==} - - '@protobufjs/base64@1.1.2': - resolution: {integrity: sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==} - - '@protobufjs/codegen@2.0.4': - resolution: {integrity: sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==} - - '@protobufjs/eventemitter@1.1.0': - resolution: {integrity: sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==} - - '@protobufjs/fetch@1.1.0': - resolution: {integrity: sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==} - - '@protobufjs/float@1.0.2': - resolution: {integrity: sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==} - - '@protobufjs/inquire@1.1.0': - resolution: {integrity: sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==} - - '@protobufjs/path@1.1.2': - resolution: {integrity: sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==} - - '@protobufjs/pool@1.1.0': - resolution: {integrity: sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==} - - '@protobufjs/utf8@1.1.0': - resolution: {integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==} - - '@quixo3/prisma-session-store@3.1.13': - resolution: {integrity: sha512-EAuOvYAaAsQ0OqxkdJG/Qs3cxlT4VV8SFHjtsA3G01uB1b6r7xftX3oeg7mcG0HN/DI1qOqwvy3YFoJ38ls0iA==} - engines: {node: '>=12.0'} - peerDependencies: - '@prisma/client': '>=2.16.1' - express-session: '>=1.17.1' - - '@sinclair/typebox@0.27.8': - resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} - - '@sinonjs/commons@3.0.1': - resolution: {integrity: sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==} - - '@sinonjs/fake-timers@10.3.0': - resolution: {integrity: sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==} - - '@tokenizer/inflate@0.2.7': - resolution: {integrity: sha512-MADQgmZT1eKjp06jpI2yozxaU9uVs4GzzgSL+uEq7bVcJ9V1ZXQkeGNql1fsSI0gMy1vhvNTNbUqrx+pZfJVmg==} - engines: {node: '>=18'} - - '@tokenizer/token@0.3.0': - resolution: {integrity: sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==} - - '@tsconfig/node10@1.0.11': - resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==} - - '@tsconfig/node12@1.0.11': - resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} - - '@tsconfig/node14@1.0.3': - resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} - - '@tsconfig/node16@1.0.4': - resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} - - '@types/babel__core@7.20.5': - resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} - - '@types/babel__generator@7.27.0': - resolution: {integrity: sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==} - - '@types/babel__template@7.4.4': - resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} - - '@types/babel__traverse@7.20.7': - resolution: {integrity: sha512-dkO5fhS7+/oos4ciWxyEyjWe48zmG6wbCheo/G2ZnHx4fs3EU6YC6UM8rk56gAjNJ9P3MTH2jo5jb92/K6wbng==} - - '@types/body-parser@1.19.5': - resolution: {integrity: sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==} - - '@types/connect@3.4.38': - resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} - - '@types/cookiejar@2.1.5': - resolution: {integrity: sha512-he+DHOWReW0nghN24E1WUqM0efK4kI9oTqDm6XmK8ZPe2djZ90BSNdGnIyCLzCPw7/pogPlGbzI2wHGGmi4O/Q==} - - '@types/eslint-scope@3.7.7': - resolution: {integrity: sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==} - - '@types/eslint@9.6.1': - resolution: {integrity: sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==} - - '@types/estree@1.0.7': - resolution: {integrity: sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==} - - '@types/express-serve-static-core@4.19.6': - resolution: {integrity: sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==} - - '@types/express-session@1.18.2': - resolution: {integrity: sha512-k+I0BxwVXsnEU2hV77cCobC08kIsn4y44C3gC0b46uxZVMaXA04lSPgRLR/bSL2w0t0ShJiG8o4jPzRG/nscFg==} - - '@types/express@4.17.21': - resolution: {integrity: sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==} - - '@types/graceful-fs@4.1.9': - resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==} - - '@types/http-errors@2.0.4': - resolution: {integrity: sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==} - - '@types/istanbul-lib-coverage@2.0.6': - resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==} - - '@types/istanbul-lib-report@3.0.3': - resolution: {integrity: sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==} - - '@types/istanbul-reports@3.0.4': - resolution: {integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==} - - '@types/jest@29.5.14': - resolution: {integrity: sha512-ZN+4sdnLUbo8EVvVc2ao0GFW6oVrQRPn4K2lglySj7APvSrgzxHiNNK99us4WDMi57xxA2yggblIAMNhXOotLQ==} - - '@types/json-schema@7.0.15': - resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} - - '@types/methods@1.1.4': - resolution: {integrity: sha512-ymXWVrDiCxTBE3+RIrrP533E70eA+9qu7zdWoHuOmGujkYtzf4HQF96b8nwHLqhuf4ykX61IGRIB38CC6/sImQ==} - - '@types/mime@1.3.5': - resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==} - - '@types/node@22.15.3': - resolution: {integrity: sha512-lX7HFZeHf4QG/J7tBZqrCAXwz9J5RD56Y6MpP0eJkka8p+K0RY/yBTW7CYFJ4VGCclxqOLKmiGP5juQc6MKgcw==} - - '@types/qs@6.9.18': - resolution: {integrity: sha512-kK7dgTYDyGqS+e2Q4aK9X3D7q234CIZ1Bv0q/7Z5IwRDoADNU81xXJK/YVyLbLTZCoIwUoDoffFeF+p/eIklAA==} - - '@types/range-parser@1.2.7': - resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==} - - '@types/semver@7.7.0': - resolution: {integrity: sha512-k107IF4+Xr7UHjwDc7Cfd6PRQfbdkiRabXGRjo07b4WyPahFBZCZ1sE+BNxYIJPPg73UkfOsVOLwqVc/6ETrIA==} - - '@types/send@0.17.4': - resolution: {integrity: sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==} - - '@types/serve-static@1.15.7': - resolution: {integrity: sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==} - - '@types/stack-utils@2.0.3': - resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==} - - '@types/superagent@8.1.9': - resolution: {integrity: sha512-pTVjI73witn+9ILmoJdajHGW2jkSaOzhiFYF1Rd3EQ94kymLqB9PjD9ISg7WaALC7+dCHT0FGe9T2LktLq/3GQ==} - - '@types/supertest@6.0.3': - resolution: {integrity: sha512-8WzXq62EXFhJ7QsH3Ocb/iKQ/Ty9ZVWnVzoTKc9tyyFRRF3a74Tk2+TLFgaFFw364Ere+npzHKEJ6ga2LzIL7w==} - - '@types/validator@13.15.0': - resolution: {integrity: sha512-nh7nrWhLr6CBq9ldtw0wx+z9wKnnv/uTVLA9g/3/TcOYxbpOSZE+MhKPmWqU+K0NvThjhv12uD8MuqijB0WzEA==} - - '@types/yargs-parser@21.0.3': - resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} - - '@types/yargs@17.0.33': - resolution: {integrity: sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==} - - '@typescript-eslint/eslint-plugin@6.21.0': - resolution: {integrity: sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA==} - engines: {node: ^16.0.0 || >=18.0.0} - peerDependencies: - '@typescript-eslint/parser': ^6.0.0 || ^6.0.0-alpha - eslint: ^7.0.0 || ^8.0.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - - '@typescript-eslint/parser@6.21.0': - resolution: {integrity: sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==} - engines: {node: ^16.0.0 || >=18.0.0} - peerDependencies: - eslint: ^7.0.0 || ^8.0.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - - '@typescript-eslint/scope-manager@6.21.0': - resolution: {integrity: sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==} - engines: {node: ^16.0.0 || >=18.0.0} - - '@typescript-eslint/type-utils@6.21.0': - resolution: {integrity: sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag==} - engines: {node: ^16.0.0 || >=18.0.0} - peerDependencies: - eslint: ^7.0.0 || ^8.0.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - - '@typescript-eslint/types@6.21.0': - resolution: {integrity: sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==} - engines: {node: ^16.0.0 || >=18.0.0} - - '@typescript-eslint/typescript-estree@6.21.0': - resolution: {integrity: sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==} - engines: {node: ^16.0.0 || >=18.0.0} - peerDependencies: - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - - '@typescript-eslint/utils@6.21.0': - resolution: {integrity: sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==} - engines: {node: ^16.0.0 || >=18.0.0} - peerDependencies: - eslint: ^7.0.0 || ^8.0.0 - - '@typescript-eslint/visitor-keys@6.21.0': - resolution: {integrity: sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==} - engines: {node: ^16.0.0 || >=18.0.0} - - '@ungap/structured-clone@1.3.0': - resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} - - '@webassemblyjs/ast@1.14.1': - resolution: {integrity: sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==} - - '@webassemblyjs/floating-point-hex-parser@1.13.2': - resolution: {integrity: sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==} - - '@webassemblyjs/helper-api-error@1.13.2': - resolution: {integrity: sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==} - - '@webassemblyjs/helper-buffer@1.14.1': - resolution: {integrity: sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==} - - '@webassemblyjs/helper-numbers@1.13.2': - resolution: {integrity: sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==} - - '@webassemblyjs/helper-wasm-bytecode@1.13.2': - resolution: {integrity: sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==} - - '@webassemblyjs/helper-wasm-section@1.14.1': - resolution: {integrity: sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==} - - '@webassemblyjs/ieee754@1.13.2': - resolution: {integrity: sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==} - - '@webassemblyjs/leb128@1.13.2': - resolution: {integrity: sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==} - - '@webassemblyjs/utf8@1.13.2': - resolution: {integrity: sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==} - - '@webassemblyjs/wasm-edit@1.14.1': - resolution: {integrity: sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==} - - '@webassemblyjs/wasm-gen@1.14.1': - resolution: {integrity: sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==} - - '@webassemblyjs/wasm-opt@1.14.1': - resolution: {integrity: sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==} - - '@webassemblyjs/wasm-parser@1.14.1': - resolution: {integrity: sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==} - - '@webassemblyjs/wast-printer@1.14.1': - resolution: {integrity: sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==} - - '@xtuc/ieee754@1.2.0': - resolution: {integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==} - - '@xtuc/long@4.2.2': - resolution: {integrity: sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==} - - abbrev@1.1.1: - resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==} - - accepts@1.3.8: - resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} - engines: {node: '>= 0.6'} - - acorn-jsx@5.3.2: - resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} - peerDependencies: - acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - - acorn-walk@8.3.4: - resolution: {integrity: sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==} - engines: {node: '>=0.4.0'} - - acorn@8.14.1: - resolution: {integrity: sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==} - engines: {node: '>=0.4.0'} - hasBin: true - - agent-base@6.0.2: - resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} - engines: {node: '>= 6.0.0'} - - ajv-formats@2.1.1: - resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==} - peerDependencies: - ajv: ^8.0.0 - peerDependenciesMeta: - ajv: - optional: true - - ajv-keywords@3.5.2: - resolution: {integrity: sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==} - peerDependencies: - ajv: ^6.9.1 - - ajv-keywords@5.1.0: - resolution: {integrity: sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==} - peerDependencies: - ajv: ^8.8.2 - - ajv@6.12.6: - resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} - - ajv@8.12.0: - resolution: {integrity: sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==} - - ajv@8.17.1: - resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==} - - ansi-colors@4.1.3: - resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} - engines: {node: '>=6'} - - ansi-escapes@4.3.2: - resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} - engines: {node: '>=8'} - - ansi-regex@2.1.1: - resolution: {integrity: sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==} - engines: {node: '>=0.10.0'} - - ansi-regex@5.0.1: - resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} - engines: {node: '>=8'} - - ansi-regex@6.1.0: - resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==} - engines: {node: '>=12'} - - ansi-styles@4.3.0: - resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} - engines: {node: '>=8'} - - ansi-styles@5.2.0: - resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} - engines: {node: '>=10'} - - ansi-styles@6.2.1: - resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} - engines: {node: '>=12'} - - anymatch@3.1.3: - resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} - engines: {node: '>= 8'} - - append-field@1.0.0: - resolution: {integrity: sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==} - - aproba@2.0.0: - resolution: {integrity: sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==} - - are-we-there-yet@2.0.0: - resolution: {integrity: sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==} - engines: {node: '>=10'} - deprecated: This package is no longer supported. - - arg@4.1.3: - resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} - - argparse@1.0.10: - resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} - - argparse@2.0.1: - resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - - array-flatten@1.1.1: - resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} - - array-timsort@1.0.3: - resolution: {integrity: sha512-/+3GRL7dDAGEfM6TseQk/U+mi18TU2Ms9I3UlLdUMhz2hbvGNTKdj9xniwXfUqgYhHxRx0+8UnKkvlNwVU+cWQ==} - - array-union@2.1.0: - resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} - engines: {node: '>=8'} - - asap@2.0.6: - resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==} - - ascli@1.0.1: - resolution: {integrity: sha512-JGQaNxpaCJz9Bd1JvVaFIHuWn9S+l3xhN17R0V/vmUDiGE0QngNMXhjlqpwqV+91plWz9Fg+Lt28Lj7p5vjs8A==} - - async@3.2.6: - resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==} - - asynckit@0.4.0: - resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} - - babel-jest@29.7.0: - resolution: {integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - peerDependencies: - '@babel/core': ^7.8.0 - - babel-plugin-istanbul@6.1.1: - resolution: {integrity: sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==} - engines: {node: '>=8'} - - babel-plugin-jest-hoist@29.6.3: - resolution: {integrity: sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - babel-preset-current-node-syntax@1.1.0: - resolution: {integrity: sha512-ldYss8SbBlWva1bs28q78Ju5Zq1F+8BrqBZZ0VFhLBvhh6lCpC2o3gDJi/5DRLs9FgYZCnmPYIVFU4lRXCkyUw==} - peerDependencies: - '@babel/core': ^7.0.0 - - babel-preset-jest@29.6.3: - resolution: {integrity: sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - peerDependencies: - '@babel/core': ^7.0.0 - - balanced-match@1.0.2: - resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - - base64-js@1.5.1: - resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - - binary-extensions@2.3.0: - resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} - engines: {node: '>=8'} - - bl@4.1.0: - resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} - - body-parser@1.20.3: - resolution: {integrity: sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==} - engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} - - brace-expansion@1.1.11: - resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} - - brace-expansion@2.0.1: - resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} - - braces@3.0.3: - resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} - engines: {node: '>=8'} - - browserslist@4.24.4: - resolution: {integrity: sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==} - engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} - hasBin: true - - bs-logger@0.2.6: - resolution: {integrity: sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==} - engines: {node: '>= 6'} - - bser@2.1.1: - resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==} - - buffer-from@1.1.2: - resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} - - buffer@5.7.1: - resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} - - busboy@1.6.0: - resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} - engines: {node: '>=10.16.0'} - - bytebuffer@5.0.1: - resolution: {integrity: sha512-IuzSdmADppkZ6DlpycMkm8l9zeEq16fWtLvunEwFiYciR/BHo4E8/xs5piFquG+Za8OWmMqHF8zuRviz2LHvRQ==} - engines: {node: '>=0.8'} - - bytes@3.1.2: - resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} - engines: {node: '>= 0.8'} - - call-bind-apply-helpers@1.0.2: - resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} - engines: {node: '>= 0.4'} - - call-bind@1.0.8: - resolution: {integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==} - engines: {node: '>= 0.4'} - - call-bound@1.0.4: - resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} - engines: {node: '>= 0.4'} - - callsites@3.1.0: - resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} - engines: {node: '>=6'} - - camelcase@2.1.1: - resolution: {integrity: sha512-DLIsRzJVBQu72meAKPkWQOLcujdXT32hwdfnkI1frSiSRMK1MofjKHf+MEx0SB6fjEFXL8fBDv1dKymBlOp4Qw==} - engines: {node: '>=0.10.0'} - - camelcase@5.3.1: - resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} - engines: {node: '>=6'} - - camelcase@6.3.0: - resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} - engines: {node: '>=10'} - - caniuse-lite@1.0.30001716: - resolution: {integrity: sha512-49/c1+x3Kwz7ZIWt+4DvK3aMJy9oYXXG6/97JKsnjdCk/6n9vVyWL8NAwVt95Lwt9eigI10Hl782kDfZUUlRXw==} - - chalk@4.1.2: - resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} - engines: {node: '>=10'} - - chalk@5.4.1: - resolution: {integrity: sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==} - engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} - - char-regex@1.0.2: - resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} - engines: {node: '>=10'} - - chardet@0.7.0: - resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} - - chokidar@3.6.0: - resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} - engines: {node: '>= 8.10.0'} - - chownr@2.0.0: - resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} - engines: {node: '>=10'} - - chrome-trace-event@1.0.4: - resolution: {integrity: sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==} - engines: {node: '>=6.0'} - - ci-info@3.9.0: - resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} - engines: {node: '>=8'} - - cjs-module-lexer@1.4.3: - resolution: {integrity: sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==} - - class-transformer@0.5.1: - resolution: {integrity: sha512-SQa1Ws6hUbfC98vKGxZH3KFY0Y1lm5Zm0SY8XX9zbK7FJCyVEac3ATW0RIpwzW+oOfmHE5PMPufDG9hCfoEOMw==} - - class-validator@0.14.1: - resolution: {integrity: sha512-2VEG9JICxIqTpoK1eMzZqaV+u/EiwEJkMGzTrZf6sU/fwsnOITVgYJ8yojSy6CaXtO9V0Cc6ZQZ8h8m4UBuLwQ==} - - cli-cursor@3.1.0: - resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} - engines: {node: '>=8'} - - cli-spinners@2.9.2: - resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==} - engines: {node: '>=6'} - - cli-table3@0.6.5: - resolution: {integrity: sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==} - engines: {node: 10.* || >= 12.*} - - cli-width@3.0.0: - resolution: {integrity: sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==} - engines: {node: '>= 10'} - - cli-width@4.1.0: - resolution: {integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==} - engines: {node: '>= 12'} - - cliui@3.2.0: - resolution: {integrity: sha512-0yayqDxWQbqk3ojkYqUKqaAQ6AfNKeKWRNA8kR0WXzAsdHpP4BIaOmMAG87JGuO6qcobyW4GjxHd9PmhEd+T9w==} - - cliui@8.0.1: - resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} - engines: {node: '>=12'} - - clone@1.0.4: - resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} - engines: {node: '>=0.8'} - - co@4.6.0: - resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==} - engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} - - code-point-at@1.1.0: - resolution: {integrity: sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==} - engines: {node: '>=0.10.0'} - - collect-v8-coverage@1.0.2: - resolution: {integrity: sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==} - - color-convert@2.0.1: - resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} - engines: {node: '>=7.0.0'} - - color-name@1.1.4: - resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - - color-support@1.1.3: - resolution: {integrity: sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==} - hasBin: true - - colour@0.7.1: - resolution: {integrity: sha512-Rel466v0EnmKPcsxHo91L4kgPs/6XF7Pu2LJNszq9lXYwi5CFWEeIiRaTX5ym7PPMdj4udDHkLSVC1//JVkZQg==} - engines: {node: '>=0.8'} - - combined-stream@1.0.8: - resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} - engines: {node: '>= 0.8'} - - commander@2.20.3: - resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} - - commander@4.1.1: - resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} - engines: {node: '>= 6'} - - comment-json@4.2.5: - resolution: {integrity: sha512-bKw/r35jR3HGt5PEPm1ljsQQGyCrR8sFGNiN5L+ykDHdpO8Smxkrkla9Yi6NkQyUrb8V54PGhfMs6NrIwtxtdw==} - engines: {node: '>= 6'} - - component-emitter@1.3.1: - resolution: {integrity: sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==} - - concat-map@0.0.1: - resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - - concat-stream@1.6.2: - resolution: {integrity: sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==} - engines: {'0': node >= 0.8} - - consola@2.15.3: - resolution: {integrity: sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw==} - - console-control-strings@1.1.0: - resolution: {integrity: sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==} - - content-disposition@0.5.4: - resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} - engines: {node: '>= 0.6'} - - content-type@1.0.5: - resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} - engines: {node: '>= 0.6'} - - convert-source-map@2.0.0: - resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} - - cookie-signature@1.0.6: - resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} - - cookie-signature@1.0.7: - resolution: {integrity: sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==} - - cookie@0.7.1: - resolution: {integrity: sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==} - engines: {node: '>= 0.6'} - - cookie@0.7.2: - resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} - engines: {node: '>= 0.6'} - - cookiejar@2.1.4: - resolution: {integrity: sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==} - - core-util-is@1.0.3: - resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} - - cors@2.8.5: - resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==} - engines: {node: '>= 0.10'} - - cosmiconfig@8.3.6: - resolution: {integrity: sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==} - engines: {node: '>=14'} - peerDependencies: - typescript: '>=4.9.5' - peerDependenciesMeta: - typescript: - optional: true - - create-jest@29.7.0: - resolution: {integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - hasBin: true - - create-require@1.1.1: - resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} - - cross-spawn@7.0.6: - resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} - engines: {node: '>= 8'} - - debug@2.6.9: - resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - - debug@4.4.0: - resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - - decamelize@1.2.0: - resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} - engines: {node: '>=0.10.0'} - - dedent@1.5.3: - resolution: {integrity: sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==} - peerDependencies: - babel-plugin-macros: ^3.1.0 - peerDependenciesMeta: - babel-plugin-macros: - optional: true - - deep-is@0.1.4: - resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} - - deepmerge@4.3.1: - resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} - engines: {node: '>=0.10.0'} - - defaults@1.0.4: - resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} - - define-data-property@1.1.4: - resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} - engines: {node: '>= 0.4'} - - delayed-stream@1.0.0: - resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} - engines: {node: '>=0.4.0'} - - delegates@1.0.0: - resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==} - - depd@2.0.0: - resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} - engines: {node: '>= 0.8'} - - destroy@1.2.0: - resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} - engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} - - detect-libc@2.0.4: - resolution: {integrity: sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==} - engines: {node: '>=8'} - - detect-newline@3.1.0: - resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} - engines: {node: '>=8'} - - dezalgo@1.0.4: - resolution: {integrity: sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==} - - diff-sequences@29.6.3: - resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - diff@4.0.2: - resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} - engines: {node: '>=0.3.1'} - - dir-glob@3.0.1: - resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} - engines: {node: '>=8'} - - doctrine@3.0.0: - resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} - engines: {node: '>=6.0.0'} - - dotenv-expand@10.0.0: - resolution: {integrity: sha512-GopVGCpVS1UKH75VKHGuQFqS1Gusej0z4FyQkPdwjil2gNIv+LNsqBlboOzpJFZKVT95GkCyWJbBSdFEFUWI2A==} - engines: {node: '>=12'} - - dotenv@16.4.5: - resolution: {integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==} - engines: {node: '>=12'} - - dotenv@16.5.0: - resolution: {integrity: sha512-m/C+AwOAr9/W1UOIZUo232ejMNnJAJtYQjUbHoNTBNTJSvqzzDh7vnrei3o3r3m9blf6ZoDkvcw0VmozNRFJxg==} - engines: {node: '>=12'} - - dunder-proto@1.0.1: - resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} - engines: {node: '>= 0.4'} - - eastasianwidth@0.2.0: - resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} - - ee-first@1.1.1: - resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} - - ejs@3.1.10: - resolution: {integrity: sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==} - engines: {node: '>=0.10.0'} - hasBin: true - - electron-to-chromium@1.5.145: - resolution: {integrity: sha512-pZ5EcTWRq/055MvSBgoFEyKf2i4apwfoqJbK/ak2jnFq8oHjZ+vzc3AhRcz37Xn+ZJfL58R666FLJx0YOK9yTw==} - - emittery@0.13.1: - resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==} - engines: {node: '>=12'} - - emoji-regex@8.0.0: - resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} - - emoji-regex@9.2.2: - resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} - - encodeurl@1.0.2: - resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} - engines: {node: '>= 0.8'} - - encodeurl@2.0.0: - resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} - engines: {node: '>= 0.8'} - - enhanced-resolve@5.18.1: - resolution: {integrity: sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==} - engines: {node: '>=10.13.0'} - - error-ex@1.3.2: - resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} - - es-define-property@1.0.1: - resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} - engines: {node: '>= 0.4'} - - es-errors@1.3.0: - resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} - engines: {node: '>= 0.4'} - - es-module-lexer@1.7.0: - resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} - - es-object-atoms@1.1.1: - resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} - engines: {node: '>= 0.4'} - - es-set-tostringtag@2.1.0: - resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} - engines: {node: '>= 0.4'} - - escalade@3.2.0: - resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} - engines: {node: '>=6'} - - escape-html@1.0.3: - resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} - - escape-string-regexp@1.0.5: - resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} - engines: {node: '>=0.8.0'} - - escape-string-regexp@2.0.0: - resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} - engines: {node: '>=8'} - - escape-string-regexp@4.0.0: - resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} - engines: {node: '>=10'} - - eslint-config-prettier@9.1.0: - resolution: {integrity: sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==} - hasBin: true - peerDependencies: - eslint: '>=7.0.0' - - eslint-plugin-prettier@5.4.1: - resolution: {integrity: sha512-9dF+KuU/Ilkq27A8idRP7N2DH8iUR6qXcjF3FR2wETY21PZdBrIjwCau8oboyGj9b7etWmTGEeM8e7oOed6ZWg==} - engines: {node: ^14.18.0 || >=16.0.0} - peerDependencies: - '@types/eslint': '>=8.0.0' - eslint: '>=8.0.0' - eslint-config-prettier: '>= 7.0.0 <10.0.0 || >=10.1.0' - prettier: '>=3.0.0' - peerDependenciesMeta: - '@types/eslint': - optional: true - eslint-config-prettier: - optional: true - - eslint-scope@5.1.1: - resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} - engines: {node: '>=8.0.0'} - - eslint-scope@7.2.2: - resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - - eslint-visitor-keys@3.4.3: - resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - - eslint@8.57.1: - resolution: {integrity: sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options. - hasBin: true - - espree@9.6.1: - resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - - esprima@4.0.1: - resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} - engines: {node: '>=4'} - hasBin: true - - esquery@1.6.0: - resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} - engines: {node: '>=0.10'} - - esrecurse@4.3.0: - resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} - engines: {node: '>=4.0'} - - estraverse@4.3.0: - resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} - engines: {node: '>=4.0'} - - estraverse@5.3.0: - resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} - engines: {node: '>=4.0'} - - esutils@2.0.3: - resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} - engines: {node: '>=0.10.0'} - - etag@1.8.1: - resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} - engines: {node: '>= 0.6'} - - events@3.3.0: - resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} - engines: {node: '>=0.8.x'} - - execa@5.1.1: - resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} - engines: {node: '>=10'} - - exit@0.1.2: - resolution: {integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==} - engines: {node: '>= 0.8.0'} - - expect@29.7.0: - resolution: {integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - express-session@1.18.1: - resolution: {integrity: sha512-a5mtTqEaZvBCL9A9aqkrtfz+3SMDhOVUnjafjo+s7A9Txkq+SVX2DLvSp1Zrv4uCXa3lMSK3viWnh9Gg07PBUA==} - engines: {node: '>= 0.8.0'} - - express@4.21.2: - resolution: {integrity: sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==} - engines: {node: '>= 0.10.0'} - - external-editor@3.1.0: - resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==} - engines: {node: '>=4'} - - fast-deep-equal@3.1.3: - resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} - - fast-diff@1.3.0: - resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==} - - fast-glob@3.3.3: - resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} - engines: {node: '>=8.6.0'} - - fast-json-stable-stringify@2.1.0: - resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} - - fast-levenshtein@2.0.6: - resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} - - fast-safe-stringify@2.1.1: - resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==} - - fast-uri@3.0.6: - resolution: {integrity: sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==} - - fastq@1.19.1: - resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} - - fb-watchman@2.0.2: - resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==} - - fflate@0.8.2: - resolution: {integrity: sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==} - - figures@3.2.0: - resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==} - engines: {node: '>=8'} - - file-entry-cache@6.0.1: - resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} - engines: {node: ^10.12.0 || >=12.0.0} - - file-type@20.4.1: - resolution: {integrity: sha512-hw9gNZXUfZ02Jo0uafWLaFVPter5/k2rfcrjFJJHX/77xtSDOfJuEFb6oKlFV86FLP1SuyHMW1PSk0U9M5tKkQ==} - engines: {node: '>=18'} - - filelist@1.0.4: - resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==} - - fill-range@7.1.1: - resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} - engines: {node: '>=8'} - - finalhandler@1.3.1: - resolution: {integrity: sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==} - engines: {node: '>= 0.8'} - - find-up@4.1.0: - resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} - engines: {node: '>=8'} - - find-up@5.0.0: - resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} - engines: {node: '>=10'} - - flat-cache@3.2.0: - resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} - engines: {node: ^10.12.0 || >=12.0.0} - - flatted@3.3.3: - resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} - - foreground-child@3.3.1: - resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} - engines: {node: '>=14'} - - fork-ts-checker-webpack-plugin@9.0.2: - resolution: {integrity: sha512-Uochze2R8peoN1XqlSi/rGUkDQpRogtLFocP9+PGu68zk1BDAKXfdeCdyVZpgTk8V8WFVQXdEz426VKjXLO1Gg==} - engines: {node: '>=12.13.0', yarn: '>=1.0.0'} - peerDependencies: - typescript: '>3.6.0' - webpack: ^5.11.0 - - form-data@4.0.2: - resolution: {integrity: sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==} - engines: {node: '>= 6'} - - formidable@2.1.5: - resolution: {integrity: sha512-Oz5Hwvwak/DCaXVVUtPn4oLMLLy1CdclLKO1LFgU7XzDpVMUU5UjlSLpGMocyQNNk8F6IJW9M/YdooSn2MRI+Q==} - - forwarded@0.2.0: - resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} - engines: {node: '>= 0.6'} - - fresh@0.5.2: - resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} - engines: {node: '>= 0.6'} - - fs-extra@10.1.0: - resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} - engines: {node: '>=12'} - - fs-minipass@2.1.0: - resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} - engines: {node: '>= 8'} - - fs-monkey@1.0.6: - resolution: {integrity: sha512-b1FMfwetIKymC0eioW7mTywihSQE4oLzQn1dB6rZB5fx/3NpNEdAWeCSMB+60/AeT0TCXsxzAlcYVEFCTAksWg==} - - fs.realpath@1.0.0: - resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} - - fsevents@2.3.3: - resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} - os: [darwin] - - function-bind@1.1.2: - resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} - - gauge@3.0.2: - resolution: {integrity: sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==} - engines: {node: '>=10'} - deprecated: This package is no longer supported. - - gensync@1.0.0-beta.2: - resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} - engines: {node: '>=6.9.0'} - - get-caller-file@2.0.5: - resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} - engines: {node: 6.* || 8.* || >= 10.*} - - get-intrinsic@1.3.0: - resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} - engines: {node: '>= 0.4'} - - get-package-type@0.1.0: - resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} - engines: {node: '>=8.0.0'} - - get-proto@1.0.1: - resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} - engines: {node: '>= 0.4'} - - get-stream@6.0.1: - resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} - engines: {node: '>=10'} - - glob-parent@5.1.2: - resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} - engines: {node: '>= 6'} - - glob-parent@6.0.2: - resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} - engines: {node: '>=10.13.0'} - - glob-to-regexp@0.4.1: - resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} - - glob@10.4.5: - resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} - hasBin: true - - glob@7.2.3: - resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} - deprecated: Glob versions prior to v9 are no longer supported - - globals@11.12.0: - resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} - engines: {node: '>=4'} - - globals@13.24.0: - resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==} - engines: {node: '>=8'} - - globby@11.1.0: - resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} - engines: {node: '>=10'} - - google-protobuf@3.15.8: - resolution: {integrity: sha512-2jtfdqTaSxk0cuBJBtTTWsot4WtR9RVr2rXg7x7OoqiuOKopPrwXpM1G4dXIkLcUNRh3RKzz76C8IOkksZSeOw==} - - google-protobuf@3.21.4: - resolution: {integrity: sha512-MnG7N936zcKTco4Jd2PX2U96Kf9PxygAPKBug+74LHzmHXmceN16MmRcdgZv+DGef/S9YvQAfRsNCn4cjf9yyQ==} - - gopd@1.2.0: - resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} - engines: {node: '>= 0.4'} - - graceful-fs@4.2.11: - resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} - - graphemer@1.4.0: - resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} - - grpc-tools@1.13.0: - resolution: {integrity: sha512-7CbkJ1yWPfX0nHjbYG58BQThNhbICXBZynzCUxCb3LzX5X9B3hQbRY2STiRgIEiLILlK9fgl0z0QVGwPCdXf5g==} - hasBin: true - - grpc_tools_node_protoc_ts@5.3.3: - resolution: {integrity: sha512-M/YrklvVXMtuuj9kb42PxeouZhs7Ul+R4e/31XwrankUcKL8cQQP50Q9q+KEHGyHQaPt6VtKKsxMgLaKbCxeww==} - hasBin: true - - handlebars@4.7.7: - resolution: {integrity: sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==} - engines: {node: '>=0.4.7'} - hasBin: true - - has-flag@4.0.0: - resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} - engines: {node: '>=8'} - - has-own-prop@2.0.0: - resolution: {integrity: sha512-Pq0h+hvsVm6dDEa8x82GnLSYHOzNDt7f0ddFa3FqcQlgzEiptPqL+XrOJNavjOzSYiYWIrgeVYYgGlLmnxwilQ==} - engines: {node: '>=8'} - - has-property-descriptors@1.0.2: - resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} - - has-symbols@1.1.0: - resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} - engines: {node: '>= 0.4'} - - has-tostringtag@1.0.2: - resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} - engines: {node: '>= 0.4'} - - has-unicode@2.0.1: - resolution: {integrity: sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==} - - hasown@2.0.2: - resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} - engines: {node: '>= 0.4'} - - html-escaper@2.0.2: - resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} - - http-errors@2.0.0: - resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} - engines: {node: '>= 0.8'} - - https-proxy-agent@5.0.1: - resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} - engines: {node: '>= 6'} - - human-signals@2.1.0: - resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} - engines: {node: '>=10.17.0'} - - iconv-lite@0.4.24: - resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} - engines: {node: '>=0.10.0'} - - ieee754@1.2.1: - resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} - - ignore@5.3.2: - resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} - engines: {node: '>= 4'} - - import-fresh@3.3.1: - resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} - engines: {node: '>=6'} - - import-local@3.2.0: - resolution: {integrity: sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==} - engines: {node: '>=8'} - hasBin: true - - imurmurhash@0.1.4: - resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} - engines: {node: '>=0.8.19'} - - inflight@1.0.6: - resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} - deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. - - inherits@2.0.4: - resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - - inquirer@8.2.6: - resolution: {integrity: sha512-M1WuAmb7pn9zdFRtQYk26ZBoY043Sse0wVDdk4Bppr+JOXyQYybdtvK+l9wUibhtjdjvtoiNy8tk+EgsYIUqKg==} - engines: {node: '>=12.0.0'} - - inquirer@9.2.15: - resolution: {integrity: sha512-vI2w4zl/mDluHt9YEQ/543VTCwPKWiHzKtm9dM2V0NdFcqEexDAjUHzO1oA60HRNaVifGXXM1tRRNluLVHa0Kg==} - engines: {node: '>=18'} - - invert-kv@1.0.0: - resolution: {integrity: sha512-xgs2NH9AE66ucSq4cNG1nhSFghr5l6tdL15Pk+jl46bmmBapgoaY/AacXyaDznAqmGL99TiLSQgO/XazFSKYeQ==} - engines: {node: '>=0.10.0'} - - ipaddr.js@1.9.1: - resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} - engines: {node: '>= 0.10'} - - is-arrayish@0.2.1: - resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} - - is-binary-path@2.1.0: - resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} - engines: {node: '>=8'} - - is-core-module@2.16.1: - resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} - engines: {node: '>= 0.4'} - - is-extglob@2.1.1: - resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} - engines: {node: '>=0.10.0'} - - is-fullwidth-code-point@1.0.0: - resolution: {integrity: sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==} - engines: {node: '>=0.10.0'} - - is-fullwidth-code-point@3.0.0: - resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} - engines: {node: '>=8'} - - is-generator-fn@2.1.0: - resolution: {integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==} - engines: {node: '>=6'} - - is-glob@4.0.3: - resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} - engines: {node: '>=0.10.0'} - - is-interactive@1.0.0: - resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==} - engines: {node: '>=8'} - - is-number@7.0.0: - resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} - engines: {node: '>=0.12.0'} - - is-path-inside@3.0.3: - resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} - engines: {node: '>=8'} - - is-stream@2.0.1: - resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} - engines: {node: '>=8'} - - is-unicode-supported@0.1.0: - resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} - engines: {node: '>=10'} - - isarray@1.0.0: - resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} - - isexe@2.0.0: - resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - - istanbul-lib-coverage@3.2.2: - resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} - engines: {node: '>=8'} - - istanbul-lib-instrument@5.2.1: - resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==} - engines: {node: '>=8'} - - istanbul-lib-instrument@6.0.3: - resolution: {integrity: sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==} - engines: {node: '>=10'} - - istanbul-lib-report@3.0.1: - resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} - engines: {node: '>=10'} - - istanbul-lib-source-maps@4.0.1: - resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==} - engines: {node: '>=10'} - - istanbul-reports@3.1.7: - resolution: {integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==} - engines: {node: '>=8'} - - iterare@1.2.1: - resolution: {integrity: sha512-RKYVTCjAnRthyJes037NX/IiqeidgN1xc3j1RjFfECFp28A1GVwK9nA+i0rJPaHqSZwygLzRnFlzUuHFoWWy+Q==} - engines: {node: '>=6'} - - jackspeak@3.4.3: - resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} - - jake@10.9.2: - resolution: {integrity: sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==} - engines: {node: '>=10'} - hasBin: true - - jest-changed-files@29.7.0: - resolution: {integrity: sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-circus@29.7.0: - resolution: {integrity: sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-cli@29.7.0: - resolution: {integrity: sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - hasBin: true - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - - jest-config@29.7.0: - resolution: {integrity: sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - peerDependencies: - '@types/node': '*' - ts-node: '>=9.0.0' - peerDependenciesMeta: - '@types/node': - optional: true - ts-node: - optional: true - - jest-diff@29.7.0: - resolution: {integrity: sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-docblock@29.7.0: - resolution: {integrity: sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-each@29.7.0: - resolution: {integrity: sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-environment-node@29.7.0: - resolution: {integrity: sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-get-type@29.6.3: - resolution: {integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-haste-map@29.7.0: - resolution: {integrity: sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-leak-detector@29.7.0: - resolution: {integrity: sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-matcher-utils@29.7.0: - resolution: {integrity: sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-message-util@29.7.0: - resolution: {integrity: sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-mock@29.7.0: - resolution: {integrity: sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-pnp-resolver@1.2.3: - resolution: {integrity: sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==} - engines: {node: '>=6'} - peerDependencies: - jest-resolve: '*' - peerDependenciesMeta: - jest-resolve: - optional: true - - jest-regex-util@29.6.3: - resolution: {integrity: sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-resolve-dependencies@29.7.0: - resolution: {integrity: sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-resolve@29.7.0: - resolution: {integrity: sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-runner@29.7.0: - resolution: {integrity: sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-runtime@29.7.0: - resolution: {integrity: sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-snapshot@29.7.0: - resolution: {integrity: sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-util@29.7.0: - resolution: {integrity: sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-validate@29.7.0: - resolution: {integrity: sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-watcher@29.7.0: - resolution: {integrity: sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-worker@27.5.1: - resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==} - engines: {node: '>= 10.13.0'} - - jest-worker@29.7.0: - resolution: {integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest@29.7.0: - resolution: {integrity: sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - hasBin: true - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - - jiti@2.4.2: - resolution: {integrity: sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==} - hasBin: true - - jose@4.15.9: - resolution: {integrity: sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==} - - js-tokens@4.0.0: - resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - - js-yaml@3.14.1: - resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} - hasBin: true - - js-yaml@4.1.0: - resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} - hasBin: true - - jsesc@3.1.0: - resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} - engines: {node: '>=6'} - hasBin: true - - json-buffer@3.0.1: - resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} - - json-parse-even-better-errors@2.3.1: - resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} - - json-schema-traverse@0.4.1: - resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} - - json-schema-traverse@1.0.0: - resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} - - json-stable-stringify-without-jsonify@1.0.1: - resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} - - json5@2.2.3: - resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} - engines: {node: '>=6'} - hasBin: true - - jsonc-parser@3.2.1: - resolution: {integrity: sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==} - - jsonc-parser@3.3.1: - resolution: {integrity: sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==} - - jsonfile@6.1.0: - resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} - - keyv@4.5.4: - resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} - - kleur@3.0.3: - resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} - engines: {node: '>=6'} - - lcid@1.0.0: - resolution: {integrity: sha512-YiGkH6EnGrDGqLMITnGjXtGmNtjoXw9SVUzcaos8RBi7Ps0VBylkq+vOcY9QE5poLasPCR849ucFUkl0UzUyOw==} - engines: {node: '>=0.10.0'} - - leven@3.1.0: - resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} - engines: {node: '>=6'} - - levn@0.4.1: - resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} - engines: {node: '>= 0.8.0'} - - libphonenumber-js@1.12.7: - resolution: {integrity: sha512-0nYZSNj/QEikyhcM5RZFXGlCB/mr4PVamnT1C2sKBnDDTYndrvbybYjvg+PMqAndQHlLbwQ3socolnL3WWTUFA==} - - lines-and-columns@1.2.4: - resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} - - loader-runner@4.3.0: - resolution: {integrity: sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==} - engines: {node: '>=6.11.5'} - - locate-path@5.0.0: - resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} - engines: {node: '>=8'} - - locate-path@6.0.0: - resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} - engines: {node: '>=10'} - - lodash.camelcase@4.3.0: - resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} - - lodash.memoize@4.1.2: - resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==} - - lodash.merge@4.6.2: - resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} - - lodash@4.17.21: - resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} - - log-symbols@4.1.0: - resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} - engines: {node: '>=10'} - - long@3.2.0: - resolution: {integrity: sha512-ZYvPPOMqUwPoDsbJaR10iQJYnMuZhRTvHYl62ErLIEX7RgFlziSBUUvrt3OVfc47QlHHpzPZYP17g3Fv7oeJkg==} - engines: {node: '>=0.6'} - - long@5.3.2: - resolution: {integrity: sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==} - - lru-cache@10.4.3: - resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} - - lru-cache@5.1.1: - resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} - - lru-cache@6.0.0: - resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} - engines: {node: '>=10'} - - magic-string@0.30.8: - resolution: {integrity: sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==} - engines: {node: '>=12'} - - make-dir@3.1.0: - resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} - engines: {node: '>=8'} - - make-dir@4.0.0: - resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} - engines: {node: '>=10'} - - make-error@1.3.6: - resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} - - makeerror@1.0.12: - resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==} - - math-intrinsics@1.1.0: - resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} - engines: {node: '>= 0.4'} - - media-typer@0.3.0: - resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} - engines: {node: '>= 0.6'} - - memfs@3.5.3: - resolution: {integrity: sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==} - engines: {node: '>= 4.0.0'} - - merge-descriptors@1.0.3: - resolution: {integrity: sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==} - - merge-stream@2.0.0: - resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} - - merge2@1.4.1: - resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} - engines: {node: '>= 8'} - - methods@1.1.2: - resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} - engines: {node: '>= 0.6'} - - micromatch@4.0.8: - resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} - engines: {node: '>=8.6'} - - mime-db@1.52.0: - resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} - engines: {node: '>= 0.6'} - - mime-types@2.1.35: - resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} - engines: {node: '>= 0.6'} - - mime@1.6.0: - resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} - engines: {node: '>=4'} - hasBin: true - - mime@2.6.0: - resolution: {integrity: sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==} - engines: {node: '>=4.0.0'} - hasBin: true - - mimic-fn@2.1.0: - resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} - engines: {node: '>=6'} - - minimatch@3.1.2: - resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} - - minimatch@5.1.6: - resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} - engines: {node: '>=10'} - - minimatch@9.0.3: - resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==} - engines: {node: '>=16 || 14 >=14.17'} - - minimatch@9.0.5: - resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} - engines: {node: '>=16 || 14 >=14.17'} - - minimist@1.2.8: - resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - - minipass@3.3.6: - resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==} - engines: {node: '>=8'} - - minipass@5.0.0: - resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==} - engines: {node: '>=8'} - - minipass@7.1.2: - resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} - engines: {node: '>=16 || 14 >=14.17'} - - minizlib@2.1.2: - resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} - engines: {node: '>= 8'} - - mkdirp@0.5.6: - resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} - hasBin: true - - mkdirp@1.0.4: - resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} - engines: {node: '>=10'} - hasBin: true - - ms@2.0.0: - resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} - - ms@2.1.3: - resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - - multer@1.4.4-lts.1: - resolution: {integrity: sha512-WeSGziVj6+Z2/MwQo3GvqzgR+9Uc+qt8SwHKh3gvNPiISKfsMfG4SvCOFYlxxgkXt7yIV2i1yczehm0EOKIxIg==} - engines: {node: '>= 6.0.0'} - - mute-stream@0.0.8: - resolution: {integrity: sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==} - - mute-stream@1.0.0: - resolution: {integrity: sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - - natural-compare@1.4.0: - resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} - - negotiator@0.6.3: - resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} - engines: {node: '>= 0.6'} - - neo-async@2.6.2: - resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} - - node-abort-controller@3.1.1: - resolution: {integrity: sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==} - - node-emoji@1.11.0: - resolution: {integrity: sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==} - - node-fetch@2.7.0: - resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} - engines: {node: 4.x || >=6.0.0} - peerDependencies: - encoding: ^0.1.0 - peerDependenciesMeta: - encoding: - optional: true - - node-int64@0.4.0: - resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} - - node-releases@2.0.19: - resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==} - - nopt@5.0.0: - resolution: {integrity: sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==} - engines: {node: '>=6'} - hasBin: true - - normalize-path@3.0.0: - resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} - engines: {node: '>=0.10.0'} - - npm-run-path@4.0.1: - resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} - engines: {node: '>=8'} - - npmlog@5.0.1: - resolution: {integrity: sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==} - deprecated: This package is no longer supported. - - number-is-nan@1.0.1: - resolution: {integrity: sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==} - engines: {node: '>=0.10.0'} - - object-assign@4.1.1: - resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} - engines: {node: '>=0.10.0'} - - object-hash@2.2.0: - resolution: {integrity: sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==} - engines: {node: '>= 6'} - - object-inspect@1.13.4: - resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} - engines: {node: '>= 0.4'} - - oidc-token-hash@5.1.0: - resolution: {integrity: sha512-y0W+X7Ppo7oZX6eovsRkuzcSM40Bicg2JEJkDJ4irIt1wsYAP5MLSNv+QAogO8xivMffw/9OvV3um1pxXgt1uA==} - engines: {node: ^10.13.0 || >=12.0.0} - - on-finished@2.4.1: - resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} - engines: {node: '>= 0.8'} - - on-headers@1.0.2: - resolution: {integrity: sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==} - engines: {node: '>= 0.8'} - - once@1.4.0: - resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} - - onetime@5.1.2: - resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} - engines: {node: '>=6'} - - openid-client@5.7.1: - resolution: {integrity: sha512-jDBPgSVfTnkIh71Hg9pRvtJc6wTwqjRkN88+gCFtYWrlP4Yx2Dsrow8uPi3qLr/aeymPF3o2+dS+wOpglK04ew==} - - optionator@0.9.4: - resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} - engines: {node: '>= 0.8.0'} - - optjs@3.2.2: - resolution: {integrity: sha512-f8lTJm4LKirX+45xsFhuRNjA4f46QVLQKfGoNH7e2AEWS+24eM4XNH4pQ8Tw2LISCIvbST/wNcLdtgvgcqVaxA==} - - ora@5.4.1: - resolution: {integrity: sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==} - engines: {node: '>=10'} - - os-locale@1.4.0: - resolution: {integrity: sha512-PRT7ZORmwu2MEFt4/fv3Q+mEfN4zetKxufQrkShY2oGvUms9r8otu5HfdyIFHkYXjO7laNsoVGmM2MANfuTA8g==} - engines: {node: '>=0.10.0'} - - os-tmpdir@1.0.2: - resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} - engines: {node: '>=0.10.0'} - - p-limit@2.3.0: - resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} - engines: {node: '>=6'} - - p-limit@3.1.0: - resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} - engines: {node: '>=10'} - - p-locate@4.1.0: - resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} - engines: {node: '>=8'} - - p-locate@5.0.0: - resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} - engines: {node: '>=10'} - - p-try@2.2.0: - resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} - engines: {node: '>=6'} - - package-json-from-dist@1.0.1: - resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} - - parent-module@1.0.1: - resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} - engines: {node: '>=6'} - - parse-json@5.2.0: - resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} - engines: {node: '>=8'} - - parseurl@1.3.3: - resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} - engines: {node: '>= 0.8'} - - passport-strategy@1.0.0: - resolution: {integrity: sha512-CB97UUvDKJde2V0KDWWB3lyf6PC3FaZP7YxZ2G8OAtn9p4HI9j9JLP9qjOGZFvyl8uwNT8qM+hGnz/n16NI7oA==} - engines: {node: '>= 0.4.0'} - - passport@0.7.0: - resolution: {integrity: sha512-cPLl+qZpSc+ireUvt+IzqbED1cHHkDoVYMo30jbJIdOOjQ1MQYZBPiNvmi8UM6lJuOpTPXJGZQk0DtC4y61MYQ==} - engines: {node: '>= 0.4.0'} - - path-exists@4.0.0: - resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} - engines: {node: '>=8'} - - path-is-absolute@1.0.1: - resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} - engines: {node: '>=0.10.0'} - - path-key@3.1.1: - resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} - engines: {node: '>=8'} - - path-parse@1.0.7: - resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} - - path-scurry@1.11.1: - resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} - engines: {node: '>=16 || 14 >=14.18'} - - path-to-regexp@0.1.12: - resolution: {integrity: sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==} - - path-to-regexp@3.3.0: - resolution: {integrity: sha512-qyCH421YQPS2WFDxDjftfc1ZR5WKQzVzqsp4n9M2kQhVOo/ByahFoUNJfl58kOcEGfQ//7weFTDhm+ss8Ecxgw==} - - path-type@4.0.0: - resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} - engines: {node: '>=8'} - - pause@0.0.1: - resolution: {integrity: sha512-KG8UEiEVkR3wGEb4m5yZkVCzigAD+cVEJck2CzYZO37ZGJfctvVptVO192MwrtPhzONn6go8ylnOdMhKqi4nfg==} - - peek-readable@7.0.0: - resolution: {integrity: sha512-nri2TO5JE3/mRryik9LlHFT53cgHfRK0Lt0BAZQXku/AW3E6XLt2GaY8siWi7dvW/m1z0ecn+J+bpDa9ZN3IsQ==} - engines: {node: '>=18'} - - picocolors@1.1.1: - resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} - - picomatch@2.3.1: - resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} - engines: {node: '>=8.6'} - - picomatch@4.0.1: - resolution: {integrity: sha512-xUXwsxNjwTQ8K3GnT4pCJm+xq3RUPQbmkYJTP5aFIfNIvbcc/4MUxgBaaRSZJ6yGJZiGSyYlM6MzwTsRk8SYCg==} - engines: {node: '>=12'} - - pirates@4.0.7: - resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} - engines: {node: '>= 6'} - - pkg-dir@4.2.0: - resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} - engines: {node: '>=8'} - - pluralize@8.0.0: - resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} - engines: {node: '>=4'} - - prelude-ls@1.2.1: - resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} - engines: {node: '>= 0.8.0'} - - prettier-linter-helpers@1.0.0: - resolution: {integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==} - engines: {node: '>=6.0.0'} - - prettier@3.5.3: - resolution: {integrity: sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==} - engines: {node: '>=14'} - hasBin: true - - pretty-format@29.7.0: - resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - prisma@6.9.0: - resolution: {integrity: sha512-resJAwMyZREC/I40LF6FZ6rZTnlrlrYrb63oW37Gq+U+9xHwbyMSPJjKtM7VZf3gTO86t/Oyz+YeSXr3CmAY1Q==} - engines: {node: '>=18.18'} - hasBin: true - peerDependencies: - typescript: '>=5.1.0' - peerDependenciesMeta: - typescript: - optional: true - - process-nextick-args@2.0.1: - resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} - - prompts@2.4.2: - resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} - engines: {node: '>= 6'} - - protobufjs@5.0.3: - resolution: {integrity: sha512-55Kcx1MhPZX0zTbVosMQEO5R6/rikNXd9b6RQK4KSPcrSIIwoXTtebIczUrXlwaSrbz4x8XUVThGPob1n8I4QA==} - engines: {node: '>=0.8'} - hasBin: true - - protobufjs@7.5.0: - resolution: {integrity: sha512-Z2E/kOY1QjoMlCytmexzYfDm/w5fKAiRwpSzGtdnXW1zC88Z2yXazHHrOtwCzn+7wSxyE8PYM4rvVcMphF9sOA==} - engines: {node: '>=12.0.0'} - - proxy-addr@2.0.7: - resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} - engines: {node: '>= 0.10'} - - punycode@2.3.1: - resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} - engines: {node: '>=6'} - - pure-rand@6.1.0: - resolution: {integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==} - - qs@6.13.0: - resolution: {integrity: sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==} - engines: {node: '>=0.6'} - - qs@6.14.0: - resolution: {integrity: sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==} - engines: {node: '>=0.6'} - - queue-microtask@1.2.3: - resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} - - random-bytes@1.0.0: - resolution: {integrity: sha512-iv7LhNVO047HzYR3InF6pUcUsPQiHTM1Qal51DcGSuZFBil1aBBWG5eHPNek7bvILMaYJ/8RU1e8w1AMdHmLQQ==} - engines: {node: '>= 0.8'} - - randombytes@2.1.0: - resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} - - range-parser@1.2.1: - resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} - engines: {node: '>= 0.6'} - - raw-body@2.5.2: - resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==} - engines: {node: '>= 0.8'} - - react-is@18.3.1: - resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} - - readable-stream@2.3.8: - resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} - - readable-stream@3.6.2: - resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} - engines: {node: '>= 6'} - - readdirp@3.6.0: - resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} - engines: {node: '>=8.10.0'} - - reflect-metadata@0.2.2: - resolution: {integrity: sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==} - - repeat-string@1.6.1: - resolution: {integrity: sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==} - engines: {node: '>=0.10'} - - require-directory@2.1.1: - resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} - engines: {node: '>=0.10.0'} - - require-from-string@2.0.2: - resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} - engines: {node: '>=0.10.0'} - - resolve-cwd@3.0.0: - resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==} - engines: {node: '>=8'} - - resolve-from@4.0.0: - resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} - engines: {node: '>=4'} - - resolve-from@5.0.0: - resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} - engines: {node: '>=8'} - - resolve.exports@2.0.3: - resolution: {integrity: sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==} - engines: {node: '>=10'} - - resolve@1.22.10: - resolution: {integrity: sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==} - engines: {node: '>= 0.4'} - hasBin: true - - restore-cursor@3.1.0: - resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} - engines: {node: '>=8'} - - reusify@1.1.0: - resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} - engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - - rimraf@3.0.2: - resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} - deprecated: Rimraf versions prior to v4 are no longer supported - hasBin: true - - run-async@2.4.1: - resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==} - engines: {node: '>=0.12.0'} - - run-async@3.0.0: - resolution: {integrity: sha512-540WwVDOMxA6dN6We19EcT9sc3hkXPw5mzRNGM3FkdN/vtE9NFvj5lFAPNwUDmJjXidm3v7TC1cTE7t17Ulm1Q==} - engines: {node: '>=0.12.0'} - - run-parallel@1.2.0: - resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} - - rxjs@7.8.1: - resolution: {integrity: sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==} - - rxjs@7.8.2: - resolution: {integrity: sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==} - - safe-buffer@5.1.2: - resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} - - safe-buffer@5.2.1: - resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} - - safer-buffer@2.1.2: - resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - - schema-utils@3.3.0: - resolution: {integrity: sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==} - engines: {node: '>= 10.13.0'} - - schema-utils@4.3.2: - resolution: {integrity: sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ==} - engines: {node: '>= 10.13.0'} - - semver@6.3.1: - resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} - hasBin: true - - semver@7.7.1: - resolution: {integrity: sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==} - engines: {node: '>=10'} - hasBin: true - - semver@7.7.2: - resolution: {integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==} - engines: {node: '>=10'} - hasBin: true - - send@0.19.0: - resolution: {integrity: sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==} - engines: {node: '>= 0.8.0'} - - serialize-javascript@6.0.2: - resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} - - serve-static@1.16.2: - resolution: {integrity: sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==} - engines: {node: '>= 0.8.0'} - - set-blocking@2.0.0: - resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} - - set-function-length@1.2.2: - resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} - engines: {node: '>= 0.4'} - - setprototypeof@1.2.0: - resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} - - shebang-command@2.0.0: - resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} - engines: {node: '>=8'} - - shebang-regex@3.0.0: - resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} - engines: {node: '>=8'} - - side-channel-list@1.0.0: - resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} - engines: {node: '>= 0.4'} - - side-channel-map@1.0.1: - resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} - engines: {node: '>= 0.4'} - - side-channel-weakmap@1.0.2: - resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} - engines: {node: '>= 0.4'} - - side-channel@1.1.0: - resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} - engines: {node: '>= 0.4'} - - signal-exit@3.0.7: - resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} - - signal-exit@4.1.0: - resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} - engines: {node: '>=14'} - - sisteransi@1.0.5: - resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} - - slash@3.0.0: - resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} - engines: {node: '>=8'} - - source-map-support@0.5.13: - resolution: {integrity: sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==} - - source-map-support@0.5.21: - resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} - - source-map@0.6.1: - resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} - engines: {node: '>=0.10.0'} - - source-map@0.7.4: - resolution: {integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==} - engines: {node: '>= 8'} - - sprintf-js@1.0.3: - resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} - - stack-utils@2.0.6: - resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} - engines: {node: '>=10'} - - statuses@2.0.1: - resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} - engines: {node: '>= 0.8'} - - streamsearch@1.1.0: - resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} - engines: {node: '>=10.0.0'} - - string-length@4.0.2: - resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==} - engines: {node: '>=10'} - - string-width@1.0.2: - resolution: {integrity: sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==} - engines: {node: '>=0.10.0'} - - string-width@4.2.3: - resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} - engines: {node: '>=8'} - - string-width@5.1.2: - resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} - engines: {node: '>=12'} - - string_decoder@1.1.1: - resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} - - string_decoder@1.3.0: - resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} - - strip-ansi@3.0.1: - resolution: {integrity: sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==} - engines: {node: '>=0.10.0'} - - strip-ansi@6.0.1: - resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} - engines: {node: '>=8'} - - strip-ansi@7.1.0: - resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} - engines: {node: '>=12'} - - strip-bom@3.0.0: - resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} - engines: {node: '>=4'} - - strip-bom@4.0.0: - resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==} - engines: {node: '>=8'} - - strip-final-newline@2.0.0: - resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} - engines: {node: '>=6'} - - strip-json-comments@3.1.1: - resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} - engines: {node: '>=8'} - - strtok3@10.2.2: - resolution: {integrity: sha512-Xt18+h4s7Z8xyZ0tmBoRmzxcop97R4BAh+dXouUDCYn+Em+1P3qpkUfI5ueWLT8ynC5hZ+q4iPEmGG1urvQGBg==} - engines: {node: '>=18'} - - superagent@8.1.2: - resolution: {integrity: sha512-6WTxW1EB6yCxV5VFOIPQruWGHqc3yI7hEmZK6h+pyk69Lk/Ut7rLUY6W/ONF2MjBuGjvmMiIpsrVJ2vjrHlslA==} - engines: {node: '>=6.4.0 <13 || >=14'} - deprecated: Please upgrade to v9.0.0+ as we have fixed a public vulnerability with formidable dependency. Note that v9.0.0+ requires Node.js v14.18.0+. See https://github.com/ladjs/superagent/pull/1800 for insight. This project is supported and maintained by the team at Forward Email @ https://forwardemail.net - - supertest@6.3.4: - resolution: {integrity: sha512-erY3HFDG0dPnhw4U+udPfrzXa4xhSG+n4rxfRuZWCUvjFWwKl+OxWf/7zk50s84/fAAs7vf5QAb9uRa0cCykxw==} - engines: {node: '>=6.4.0'} - - supports-color@7.2.0: - resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} - engines: {node: '>=8'} - - supports-color@8.1.1: - resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} - engines: {node: '>=10'} - - supports-preserve-symlinks-flag@1.0.0: - resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} - engines: {node: '>= 0.4'} - - swagger-ui-dist@5.17.14: - resolution: {integrity: sha512-CVbSfaLpstV65OnSjbXfVd6Sta3q3F7Cj/yYuvHMp1P90LztOLs6PfUnKEVAeiIVQt9u2SaPwv0LiH/OyMjHRw==} - - symbol-observable@4.0.0: - resolution: {integrity: sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ==} - engines: {node: '>=0.10'} - - synckit@0.11.8: - resolution: {integrity: sha512-+XZ+r1XGIJGeQk3VvXhT6xx/VpbHsRzsTkGgF6E5RX9TTXD0118l87puaEBZ566FhqblC6U0d4XnubznJDm30A==} - engines: {node: ^14.18.0 || >=16.0.0} - - tapable@2.2.1: - resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} - engines: {node: '>=6'} - - tar@6.2.1: - resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==} - engines: {node: '>=10'} - - terser-webpack-plugin@5.3.14: - resolution: {integrity: sha512-vkZjpUjb6OMS7dhV+tILUW6BhpDR7P2L/aQSAv+Uwk+m8KATX9EccViHTJR2qDtACKPIYndLGCyl3FMo+r2LMw==} - engines: {node: '>= 10.13.0'} - peerDependencies: - '@swc/core': '*' - esbuild: '*' - uglify-js: '*' - webpack: ^5.1.0 - peerDependenciesMeta: - '@swc/core': - optional: true - esbuild: - optional: true - uglify-js: - optional: true - - terser@5.39.0: - resolution: {integrity: sha512-LBAhFyLho16harJoWMg/nZsQYgTrg5jXOn2nCYjRUcZZEdE3qa2zb8QEDRUGVZBW4rlazf2fxkg8tztybTaqWw==} - engines: {node: '>=10'} - hasBin: true - - test-exclude@6.0.0: - resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} - engines: {node: '>=8'} - - text-table@0.2.0: - resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} - - through@2.3.8: - resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} - - tmp@0.0.33: - resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} - engines: {node: '>=0.6.0'} - - tmpl@1.0.5: - resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} - - to-regex-range@5.0.1: - resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} - engines: {node: '>=8.0'} - - toidentifier@1.0.1: - resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} - engines: {node: '>=0.6'} - - token-types@6.0.0: - resolution: {integrity: sha512-lbDrTLVsHhOMljPscd0yitpozq7Ga2M5Cvez5AjGg8GASBjtt6iERCAJ93yommPmz62fb45oFIXHEZ3u9bfJEA==} - engines: {node: '>=14.16'} - - tr46@0.0.3: - resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} - - tree-kill@1.2.2: - resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} - hasBin: true - - ts-api-utils@1.4.3: - resolution: {integrity: sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw==} - engines: {node: '>=16'} - peerDependencies: - typescript: '>=4.2.0' - - ts-dedent@2.2.0: - resolution: {integrity: sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==} - engines: {node: '>=6.10'} - - ts-jest@29.3.4: - resolution: {integrity: sha512-Iqbrm8IXOmV+ggWHOTEbjwyCf2xZlUMv5npExksXohL+tk8va4Fjhb+X2+Rt9NBmgO7bJ8WpnMLOwih/DnMlFA==} - engines: {node: ^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0} - hasBin: true - peerDependencies: - '@babel/core': '>=7.0.0-beta.0 <8' - '@jest/transform': ^29.0.0 - '@jest/types': ^29.0.0 - babel-jest: ^29.0.0 - esbuild: '*' - jest: ^29.0.0 - typescript: '>=4.3 <6' - peerDependenciesMeta: - '@babel/core': - optional: true - '@jest/transform': - optional: true - '@jest/types': - optional: true - babel-jest: - optional: true - esbuild: - optional: true - - ts-loader@9.5.2: - resolution: {integrity: sha512-Qo4piXvOTWcMGIgRiuFa6nHNm+54HbYaZCKqc9eeZCLRy3XqafQgwX2F7mofrbJG3g7EEb+lkiR+z2Lic2s3Zw==} - engines: {node: '>=12.0.0'} - peerDependencies: - typescript: '*' - webpack: ^5.0.0 - - ts-node@10.9.2: - resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==} - hasBin: true - peerDependencies: - '@swc/core': '>=1.2.50' - '@swc/wasm': '>=1.2.50' - '@types/node': '*' - typescript: '>=2.7' - peerDependenciesMeta: - '@swc/core': - optional: true - '@swc/wasm': - optional: true - - ts-protoc-gen@0.15.0: - resolution: {integrity: sha512-TycnzEyrdVDlATJ3bWFTtra3SCiEP0W0vySXReAuEygXCUr1j2uaVyL0DhzjwuUdQoW5oXPwk6oZWeA0955V+g==} - hasBin: true - - tsconfig-paths-webpack-plugin@4.2.0: - resolution: {integrity: sha512-zbem3rfRS8BgeNK50Zz5SIQgXzLafiHjOwUAvk/38/o1jHn/V5QAgVUcz884or7WYcPaH3N2CIfUc2u0ul7UcA==} - engines: {node: '>=10.13.0'} - - tsconfig-paths@4.2.0: - resolution: {integrity: sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==} - engines: {node: '>=6'} - - tslib@2.8.1: - resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} - - type-check@0.4.0: - resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} - engines: {node: '>= 0.8.0'} - - type-detect@4.0.8: - resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} - engines: {node: '>=4'} - - type-fest@0.20.2: - resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} - engines: {node: '>=10'} - - type-fest@0.21.3: - resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} - engines: {node: '>=10'} - - type-fest@2.19.0: - resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==} - engines: {node: '>=12.20'} - - type-fest@4.41.0: - resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} - engines: {node: '>=16'} - - type-is@1.6.18: - resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} - engines: {node: '>= 0.6'} - - typedarray@0.0.6: - resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} - - typescript@5.7.2: - resolution: {integrity: sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==} - engines: {node: '>=14.17'} - hasBin: true - - typescript@5.8.3: - resolution: {integrity: sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==} - engines: {node: '>=14.17'} - hasBin: true - - uglify-js@3.19.3: - resolution: {integrity: sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==} - engines: {node: '>=0.8.0'} - hasBin: true - - uid-safe@2.1.5: - resolution: {integrity: sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==} - engines: {node: '>= 0.8'} - - uid@2.0.2: - resolution: {integrity: sha512-u3xV3X7uzvi5b1MncmZo3i2Aw222Zk1keqLA1YkHldREkAhAqi65wuPfe7lHx8H/Wzy+8CE7S7uS3jekIM5s8g==} - engines: {node: '>=8'} - - uint8array-extras@1.4.0: - resolution: {integrity: sha512-ZPtzy0hu4cZjv3z5NW9gfKnNLjoz4y6uv4HlelAjDK7sY/xOkKZv9xK/WQpcsBB3jEybChz9DPC2U/+cusjJVQ==} - engines: {node: '>=18'} - - undici-types@6.21.0: - resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} - - universalify@2.0.1: - resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} - engines: {node: '>= 10.0.0'} - - unpipe@1.0.0: - resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} - engines: {node: '>= 0.8'} - - update-browserslist-db@1.1.3: - resolution: {integrity: sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==} - hasBin: true - peerDependencies: - browserslist: '>= 4.21.0' - - uri-js@4.4.1: - resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} - - util-deprecate@1.0.2: - resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - - utils-merge@1.0.1: - resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} - engines: {node: '>= 0.4.0'} - - uuid@9.0.1: - resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} - hasBin: true - - v8-compile-cache-lib@3.0.1: - resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} - - v8-to-istanbul@9.3.0: - resolution: {integrity: sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==} - engines: {node: '>=10.12.0'} - - validator@13.15.0: - resolution: {integrity: sha512-36B2ryl4+oL5QxZ3AzD0t5SsMNGvTtQHpjgFO5tbNxfXbMFkY822ktCDe1MnlqV3301QQI9SLHDNJokDI+Z9pA==} - engines: {node: '>= 0.10'} - - vary@1.1.2: - resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} - engines: {node: '>= 0.8'} - - walker@1.0.8: - resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==} - - watchpack@2.4.2: - resolution: {integrity: sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==} - engines: {node: '>=10.13.0'} - - wcwidth@1.0.1: - resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} - - webidl-conversions@3.0.1: - resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} - - webpack-node-externals@3.0.0: - resolution: {integrity: sha512-LnL6Z3GGDPht/AigwRh2dvL9PQPFQ8skEpVrWZXLWBYmqcaojHNN0onvHzie6rq7EWKrrBfPYqNEzTJgiwEQDQ==} - engines: {node: '>=6'} - - webpack-sources@3.2.3: - resolution: {integrity: sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==} - engines: {node: '>=10.13.0'} - - webpack@5.97.1: - resolution: {integrity: sha512-EksG6gFY3L1eFMROS/7Wzgrii5mBAFe4rIr3r2BTfo7bcc+DWwFZ4OJ/miOuHJO/A85HwyI4eQ0F6IKXesO7Fg==} - engines: {node: '>=10.13.0'} - hasBin: true - peerDependencies: - webpack-cli: '*' - peerDependenciesMeta: - webpack-cli: - optional: true - - whatwg-url@5.0.0: - resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} - - which@2.0.2: - resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} - engines: {node: '>= 8'} - hasBin: true - - wide-align@1.1.5: - resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==} - - window-size@0.1.4: - resolution: {integrity: sha512-2thx4pB0cV3h+Bw7QmMXcEbdmOzv9t0HFplJH/Lz6yu60hXYy5RT8rUu+wlIreVxWsGN20mo+MHeCSfUpQBwPw==} - engines: {node: '>= 0.10.0'} - hasBin: true - - word-wrap@1.2.5: - resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} - engines: {node: '>=0.10.0'} - - wordwrap@1.0.0: - resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==} - - wrap-ansi@2.1.0: - resolution: {integrity: sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw==} - engines: {node: '>=0.10.0'} - - wrap-ansi@6.2.0: - resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} - engines: {node: '>=8'} - - wrap-ansi@7.0.0: - resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} - engines: {node: '>=10'} - - wrap-ansi@8.1.0: - resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} - engines: {node: '>=12'} - - wrappy@1.0.2: - resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} - - write-file-atomic@4.0.2: - resolution: {integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==} - engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} - - xtend@4.0.2: - resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} - engines: {node: '>=0.4'} - - y18n@3.2.2: - resolution: {integrity: sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==} - - y18n@5.0.8: - resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} - engines: {node: '>=10'} - - yallist@3.1.1: - resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} - - yallist@4.0.0: - resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} - - yargs-parser@21.1.1: - resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} - engines: {node: '>=12'} - - yargs@17.7.2: - resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} - engines: {node: '>=12'} - - yargs@3.32.0: - resolution: {integrity: sha512-ONJZiimStfZzhKamYvR/xvmgW3uEkAUFSP91y2caTEPhzF6uP2JfPiVZcq66b/YR0C3uitxSV7+T1x8p5bkmMg==} - - yn@3.1.1: - resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} - engines: {node: '>=6'} - - yocto-queue@0.1.0: - resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} - engines: {node: '>=10'} - -snapshots: - - '@ampproject/remapping@2.3.0': - dependencies: - '@jridgewell/gen-mapping': 0.3.8 - '@jridgewell/trace-mapping': 0.3.25 - - '@angular-devkit/core@17.3.11(chokidar@3.6.0)': - dependencies: - ajv: 8.12.0 - ajv-formats: 2.1.1(ajv@8.12.0) - jsonc-parser: 3.2.1 - picomatch: 4.0.1 - rxjs: 7.8.1 - source-map: 0.7.4 - optionalDependencies: - chokidar: 3.6.0 - - '@angular-devkit/schematics-cli@17.3.11(chokidar@3.6.0)': - dependencies: - '@angular-devkit/core': 17.3.11(chokidar@3.6.0) - '@angular-devkit/schematics': 17.3.11(chokidar@3.6.0) - ansi-colors: 4.1.3 - inquirer: 9.2.15 - symbol-observable: 4.0.0 - yargs-parser: 21.1.1 - transitivePeerDependencies: - - chokidar - - '@angular-devkit/schematics@17.3.11(chokidar@3.6.0)': - dependencies: - '@angular-devkit/core': 17.3.11(chokidar@3.6.0) - jsonc-parser: 3.2.1 - magic-string: 0.30.8 - ora: 5.4.1 - rxjs: 7.8.1 - transitivePeerDependencies: - - chokidar - - '@babel/code-frame@7.27.1': - dependencies: - '@babel/helper-validator-identifier': 7.27.1 - js-tokens: 4.0.0 - picocolors: 1.1.1 - - '@babel/compat-data@7.27.1': {} - - '@babel/core@7.27.1': - dependencies: - '@ampproject/remapping': 2.3.0 - '@babel/code-frame': 7.27.1 - '@babel/generator': 7.27.1 - '@babel/helper-compilation-targets': 7.27.1 - '@babel/helper-module-transforms': 7.27.1(@babel/core@7.27.1) - '@babel/helpers': 7.27.1 - '@babel/parser': 7.27.1 - '@babel/template': 7.27.1 - '@babel/traverse': 7.27.1 - '@babel/types': 7.27.1 - convert-source-map: 2.0.0 - debug: 4.4.0 - gensync: 1.0.0-beta.2 - json5: 2.2.3 - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - - '@babel/generator@7.27.1': - dependencies: - '@babel/parser': 7.27.1 - '@babel/types': 7.27.1 - '@jridgewell/gen-mapping': 0.3.8 - '@jridgewell/trace-mapping': 0.3.25 - jsesc: 3.1.0 - - '@babel/helper-compilation-targets@7.27.1': - dependencies: - '@babel/compat-data': 7.27.1 - '@babel/helper-validator-option': 7.27.1 - browserslist: 4.24.4 - lru-cache: 5.1.1 - semver: 6.3.1 - - '@babel/helper-module-imports@7.27.1': - dependencies: - '@babel/traverse': 7.27.1 - '@babel/types': 7.27.1 - transitivePeerDependencies: - - supports-color - - '@babel/helper-module-transforms@7.27.1(@babel/core@7.27.1)': - dependencies: - '@babel/core': 7.27.1 - '@babel/helper-module-imports': 7.27.1 - '@babel/helper-validator-identifier': 7.27.1 - '@babel/traverse': 7.27.1 - transitivePeerDependencies: - - supports-color - - '@babel/helper-plugin-utils@7.27.1': {} - - '@babel/helper-string-parser@7.27.1': {} - - '@babel/helper-validator-identifier@7.27.1': {} - - '@babel/helper-validator-option@7.27.1': {} - - '@babel/helpers@7.27.1': - dependencies: - '@babel/template': 7.27.1 - '@babel/types': 7.27.1 - - '@babel/parser@7.27.1': - dependencies: - '@babel/types': 7.27.1 - - '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.27.1)': - dependencies: - '@babel/core': 7.27.1 - '@babel/helper-plugin-utils': 7.27.1 - - '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.27.1)': - dependencies: - '@babel/core': 7.27.1 - '@babel/helper-plugin-utils': 7.27.1 - - '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.27.1)': - dependencies: - '@babel/core': 7.27.1 - '@babel/helper-plugin-utils': 7.27.1 - - '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.27.1)': - dependencies: - '@babel/core': 7.27.1 - '@babel/helper-plugin-utils': 7.27.1 - - '@babel/plugin-syntax-import-attributes@7.27.1(@babel/core@7.27.1)': - dependencies: - '@babel/core': 7.27.1 - '@babel/helper-plugin-utils': 7.27.1 - - '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.27.1)': - dependencies: - '@babel/core': 7.27.1 - '@babel/helper-plugin-utils': 7.27.1 - - '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.27.1)': - dependencies: - '@babel/core': 7.27.1 - '@babel/helper-plugin-utils': 7.27.1 - - '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.27.1)': - dependencies: - '@babel/core': 7.27.1 - '@babel/helper-plugin-utils': 7.27.1 - - '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.27.1)': - dependencies: - '@babel/core': 7.27.1 - '@babel/helper-plugin-utils': 7.27.1 - - '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.27.1)': - dependencies: - '@babel/core': 7.27.1 - '@babel/helper-plugin-utils': 7.27.1 - - '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.27.1)': - dependencies: - '@babel/core': 7.27.1 - '@babel/helper-plugin-utils': 7.27.1 - - '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.27.1)': - dependencies: - '@babel/core': 7.27.1 - '@babel/helper-plugin-utils': 7.27.1 - - '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.27.1)': - dependencies: - '@babel/core': 7.27.1 - '@babel/helper-plugin-utils': 7.27.1 - - '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.27.1)': - dependencies: - '@babel/core': 7.27.1 - '@babel/helper-plugin-utils': 7.27.1 - - '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.27.1)': - dependencies: - '@babel/core': 7.27.1 - '@babel/helper-plugin-utils': 7.27.1 - - '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.27.1)': - dependencies: - '@babel/core': 7.27.1 - '@babel/helper-plugin-utils': 7.27.1 - - '@babel/plugin-syntax-typescript@7.27.1(@babel/core@7.27.1)': - dependencies: - '@babel/core': 7.27.1 - '@babel/helper-plugin-utils': 7.27.1 - - '@babel/template@7.27.1': - dependencies: - '@babel/code-frame': 7.27.1 - '@babel/parser': 7.27.1 - '@babel/types': 7.27.1 - - '@babel/traverse@7.27.1': - dependencies: - '@babel/code-frame': 7.27.1 - '@babel/generator': 7.27.1 - '@babel/parser': 7.27.1 - '@babel/template': 7.27.1 - '@babel/types': 7.27.1 - debug: 4.4.0 - globals: 11.12.0 - transitivePeerDependencies: - - supports-color - - '@babel/types@7.27.1': - dependencies: - '@babel/helper-string-parser': 7.27.1 - '@babel/helper-validator-identifier': 7.27.1 - - '@bcoe/v8-coverage@0.2.3': {} - - '@colors/colors@1.5.0': - optional: true - - '@cspotcode/source-map-support@0.8.1': - dependencies: - '@jridgewell/trace-mapping': 0.3.9 - - '@eslint-community/eslint-utils@4.6.1(eslint@8.57.1)': - dependencies: - eslint: 8.57.1 - eslint-visitor-keys: 3.4.3 - - '@eslint-community/regexpp@4.12.1': {} - - '@eslint/eslintrc@2.1.4': - dependencies: - ajv: 6.12.6 - debug: 4.4.0 - espree: 9.6.1 - globals: 13.24.0 - ignore: 5.3.2 - import-fresh: 3.3.1 - js-yaml: 4.1.0 - minimatch: 3.1.2 - strip-json-comments: 3.1.1 - transitivePeerDependencies: - - supports-color - - '@eslint/js@8.57.1': {} - - '@grpc/grpc-js@1.13.4': - dependencies: - '@grpc/proto-loader': 0.7.15 - '@js-sdsl/ordered-map': 4.4.2 - - '@grpc/proto-loader@0.7.15': - dependencies: - lodash.camelcase: 4.3.0 - long: 5.3.2 - protobufjs: 7.5.0 - yargs: 17.7.2 - - '@humanwhocodes/config-array@0.13.0': - dependencies: - '@humanwhocodes/object-schema': 2.0.3 - debug: 4.4.0 - minimatch: 3.1.2 - transitivePeerDependencies: - - supports-color - - '@humanwhocodes/module-importer@1.0.1': {} - - '@humanwhocodes/object-schema@2.0.3': {} - - '@isaacs/cliui@8.0.2': - dependencies: - string-width: 5.1.2 - string-width-cjs: string-width@4.2.3 - strip-ansi: 7.1.0 - strip-ansi-cjs: strip-ansi@6.0.1 - wrap-ansi: 8.1.0 - wrap-ansi-cjs: wrap-ansi@7.0.0 - - '@istanbuljs/load-nyc-config@1.1.0': - dependencies: - camelcase: 5.3.1 - find-up: 4.1.0 - get-package-type: 0.1.0 - js-yaml: 3.14.1 - resolve-from: 5.0.0 - - '@istanbuljs/schema@0.1.3': {} - - '@jest/console@29.7.0': - dependencies: - '@jest/types': 29.6.3 - '@types/node': 22.15.3 - chalk: 4.1.2 - jest-message-util: 29.7.0 - jest-util: 29.7.0 - slash: 3.0.0 - - '@jest/core@29.7.0(ts-node@10.9.2(@types/node@22.15.3)(typescript@5.8.3))': - dependencies: - '@jest/console': 29.7.0 - '@jest/reporters': 29.7.0 - '@jest/test-result': 29.7.0 - '@jest/transform': 29.7.0 - '@jest/types': 29.6.3 - '@types/node': 22.15.3 - ansi-escapes: 4.3.2 - chalk: 4.1.2 - ci-info: 3.9.0 - exit: 0.1.2 - graceful-fs: 4.2.11 - jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@22.15.3)(ts-node@10.9.2(@types/node@22.15.3)(typescript@5.8.3)) - jest-haste-map: 29.7.0 - jest-message-util: 29.7.0 - jest-regex-util: 29.6.3 - jest-resolve: 29.7.0 - jest-resolve-dependencies: 29.7.0 - jest-runner: 29.7.0 - jest-runtime: 29.7.0 - jest-snapshot: 29.7.0 - jest-util: 29.7.0 - jest-validate: 29.7.0 - jest-watcher: 29.7.0 - micromatch: 4.0.8 - pretty-format: 29.7.0 - slash: 3.0.0 - strip-ansi: 6.0.1 - transitivePeerDependencies: - - babel-plugin-macros - - supports-color - - ts-node - - '@jest/environment@29.7.0': - dependencies: - '@jest/fake-timers': 29.7.0 - '@jest/types': 29.6.3 - '@types/node': 22.15.3 - jest-mock: 29.7.0 - - '@jest/expect-utils@29.7.0': - dependencies: - jest-get-type: 29.6.3 - - '@jest/expect@29.7.0': - dependencies: - expect: 29.7.0 - jest-snapshot: 29.7.0 - transitivePeerDependencies: - - supports-color - - '@jest/fake-timers@29.7.0': - dependencies: - '@jest/types': 29.6.3 - '@sinonjs/fake-timers': 10.3.0 - '@types/node': 22.15.3 - jest-message-util: 29.7.0 - jest-mock: 29.7.0 - jest-util: 29.7.0 - - '@jest/globals@29.7.0': - dependencies: - '@jest/environment': 29.7.0 - '@jest/expect': 29.7.0 - '@jest/types': 29.6.3 - jest-mock: 29.7.0 - transitivePeerDependencies: - - supports-color - - '@jest/reporters@29.7.0': - dependencies: - '@bcoe/v8-coverage': 0.2.3 - '@jest/console': 29.7.0 - '@jest/test-result': 29.7.0 - '@jest/transform': 29.7.0 - '@jest/types': 29.6.3 - '@jridgewell/trace-mapping': 0.3.25 - '@types/node': 22.15.3 - chalk: 4.1.2 - collect-v8-coverage: 1.0.2 - exit: 0.1.2 - glob: 7.2.3 - graceful-fs: 4.2.11 - istanbul-lib-coverage: 3.2.2 - istanbul-lib-instrument: 6.0.3 - istanbul-lib-report: 3.0.1 - istanbul-lib-source-maps: 4.0.1 - istanbul-reports: 3.1.7 - jest-message-util: 29.7.0 - jest-util: 29.7.0 - jest-worker: 29.7.0 - slash: 3.0.0 - string-length: 4.0.2 - strip-ansi: 6.0.1 - v8-to-istanbul: 9.3.0 - transitivePeerDependencies: - - supports-color - - '@jest/schemas@29.6.3': - dependencies: - '@sinclair/typebox': 0.27.8 - - '@jest/source-map@29.6.3': - dependencies: - '@jridgewell/trace-mapping': 0.3.25 - callsites: 3.1.0 - graceful-fs: 4.2.11 - - '@jest/test-result@29.7.0': - dependencies: - '@jest/console': 29.7.0 - '@jest/types': 29.6.3 - '@types/istanbul-lib-coverage': 2.0.6 - collect-v8-coverage: 1.0.2 - - '@jest/test-sequencer@29.7.0': - dependencies: - '@jest/test-result': 29.7.0 - graceful-fs: 4.2.11 - jest-haste-map: 29.7.0 - slash: 3.0.0 - - '@jest/transform@29.7.0': - dependencies: - '@babel/core': 7.27.1 - '@jest/types': 29.6.3 - '@jridgewell/trace-mapping': 0.3.25 - babel-plugin-istanbul: 6.1.1 - chalk: 4.1.2 - convert-source-map: 2.0.0 - fast-json-stable-stringify: 2.1.0 - graceful-fs: 4.2.11 - jest-haste-map: 29.7.0 - jest-regex-util: 29.6.3 - jest-util: 29.7.0 - micromatch: 4.0.8 - pirates: 4.0.7 - slash: 3.0.0 - write-file-atomic: 4.0.2 - transitivePeerDependencies: - - supports-color - - '@jest/types@29.6.3': - dependencies: - '@jest/schemas': 29.6.3 - '@types/istanbul-lib-coverage': 2.0.6 - '@types/istanbul-reports': 3.0.4 - '@types/node': 22.15.3 - '@types/yargs': 17.0.33 - chalk: 4.1.2 - - '@jridgewell/gen-mapping@0.3.8': - dependencies: - '@jridgewell/set-array': 1.2.1 - '@jridgewell/sourcemap-codec': 1.5.0 - '@jridgewell/trace-mapping': 0.3.25 - - '@jridgewell/resolve-uri@3.1.2': {} - - '@jridgewell/set-array@1.2.1': {} - - '@jridgewell/source-map@0.3.6': - dependencies: - '@jridgewell/gen-mapping': 0.3.8 - '@jridgewell/trace-mapping': 0.3.25 - - '@jridgewell/sourcemap-codec@1.5.0': {} - - '@jridgewell/trace-mapping@0.3.25': - dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.0 - - '@jridgewell/trace-mapping@0.3.9': - dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.0 - - '@js-sdsl/ordered-map@4.4.2': {} - - '@ljharb/through@2.3.14': - dependencies: - call-bind: 1.0.8 - - '@lukeed/csprng@1.1.0': {} - - '@mapbox/node-pre-gyp@1.0.11': - dependencies: - detect-libc: 2.0.4 - https-proxy-agent: 5.0.1 - make-dir: 3.1.0 - node-fetch: 2.7.0 - nopt: 5.0.0 - npmlog: 5.0.1 - rimraf: 3.0.2 - semver: 7.7.1 - tar: 6.2.1 - transitivePeerDependencies: - - encoding - - supports-color - - '@microsoft/tsdoc@0.15.1': {} - - '@nestjs/cli@10.4.9': - dependencies: - '@angular-devkit/core': 17.3.11(chokidar@3.6.0) - '@angular-devkit/schematics': 17.3.11(chokidar@3.6.0) - '@angular-devkit/schematics-cli': 17.3.11(chokidar@3.6.0) - '@nestjs/schematics': 10.2.3(chokidar@3.6.0)(typescript@5.7.2) - chalk: 4.1.2 - chokidar: 3.6.0 - cli-table3: 0.6.5 - commander: 4.1.1 - fork-ts-checker-webpack-plugin: 9.0.2(typescript@5.7.2)(webpack@5.97.1) - glob: 10.4.5 - inquirer: 8.2.6 - node-emoji: 1.11.0 - ora: 5.4.1 - tree-kill: 1.2.2 - tsconfig-paths: 4.2.0 - tsconfig-paths-webpack-plugin: 4.2.0 - typescript: 5.7.2 - webpack: 5.97.1 - webpack-node-externals: 3.0.0 - transitivePeerDependencies: - - esbuild - - uglify-js - - webpack-cli - - '@nestjs/common@10.4.17(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)': - dependencies: - file-type: 20.4.1 - iterare: 1.2.1 - reflect-metadata: 0.2.2 - rxjs: 7.8.2 - tslib: 2.8.1 - uid: 2.0.2 - optionalDependencies: - class-transformer: 0.5.1 - class-validator: 0.14.1 - transitivePeerDependencies: - - supports-color - - '@nestjs/config@3.3.0(@nestjs/common@10.4.17(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(rxjs@7.8.2)': - dependencies: - '@nestjs/common': 10.4.17(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) - dotenv: 16.4.5 - dotenv-expand: 10.0.0 - lodash: 4.17.21 - rxjs: 7.8.2 - - '@nestjs/core@10.4.17(@nestjs/common@10.4.17(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/microservices@10.4.17)(@nestjs/platform-express@10.4.17)(reflect-metadata@0.2.2)(rxjs@7.8.2)': - dependencies: - '@nestjs/common': 10.4.17(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nuxtjs/opencollective': 0.3.2 - fast-safe-stringify: 2.1.1 - iterare: 1.2.1 - path-to-regexp: 3.3.0 - reflect-metadata: 0.2.2 - rxjs: 7.8.2 - tslib: 2.8.1 - uid: 2.0.2 - optionalDependencies: - '@nestjs/microservices': 10.4.17(@grpc/grpc-js@1.13.4)(@nestjs/common@10.4.17(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@10.4.17)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/platform-express': 10.4.17(@nestjs/common@10.4.17(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@10.4.17) - transitivePeerDependencies: - - encoding - - '@nestjs/mapped-types@2.0.5(@nestjs/common@10.4.17(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)': - dependencies: - '@nestjs/common': 10.4.17(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) - reflect-metadata: 0.2.2 - optionalDependencies: - class-transformer: 0.5.1 - class-validator: 0.14.1 - - '@nestjs/mapped-types@2.1.0(@nestjs/common@10.4.17(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)': - dependencies: - '@nestjs/common': 10.4.17(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) - reflect-metadata: 0.2.2 - optionalDependencies: - class-transformer: 0.5.1 - class-validator: 0.14.1 - - '@nestjs/microservices@10.4.17(@grpc/grpc-js@1.13.4)(@nestjs/common@10.4.17(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@10.4.17)(reflect-metadata@0.2.2)(rxjs@7.8.2)': - dependencies: - '@nestjs/common': 10.4.17(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 10.4.17(@nestjs/common@10.4.17(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/microservices@10.4.17)(@nestjs/platform-express@10.4.17)(reflect-metadata@0.2.2)(rxjs@7.8.2) - iterare: 1.2.1 - reflect-metadata: 0.2.2 - rxjs: 7.8.2 - tslib: 2.8.1 - optionalDependencies: - '@grpc/grpc-js': 1.13.4 - - '@nestjs/passport@10.0.3(@nestjs/common@10.4.17(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(passport@0.7.0)': - dependencies: - '@nestjs/common': 10.4.17(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) - passport: 0.7.0 - - '@nestjs/platform-express@10.4.17(@nestjs/common@10.4.17(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@10.4.17)': - dependencies: - '@nestjs/common': 10.4.17(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 10.4.17(@nestjs/common@10.4.17(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/microservices@10.4.17)(@nestjs/platform-express@10.4.17)(reflect-metadata@0.2.2)(rxjs@7.8.2) - body-parser: 1.20.3 - cors: 2.8.5 - express: 4.21.2 - multer: 1.4.4-lts.1 - tslib: 2.8.1 - transitivePeerDependencies: - - supports-color - - '@nestjs/schematics@10.2.3(chokidar@3.6.0)(typescript@5.7.2)': - dependencies: - '@angular-devkit/core': 17.3.11(chokidar@3.6.0) - '@angular-devkit/schematics': 17.3.11(chokidar@3.6.0) - comment-json: 4.2.5 - jsonc-parser: 3.3.1 - pluralize: 8.0.0 - typescript: 5.7.2 - transitivePeerDependencies: - - chokidar - - '@nestjs/schematics@10.2.3(chokidar@3.6.0)(typescript@5.8.3)': - dependencies: - '@angular-devkit/core': 17.3.11(chokidar@3.6.0) - '@angular-devkit/schematics': 17.3.11(chokidar@3.6.0) - comment-json: 4.2.5 - jsonc-parser: 3.3.1 - pluralize: 8.0.0 - typescript: 5.8.3 - transitivePeerDependencies: - - chokidar - - '@nestjs/swagger@7.4.2(@nestjs/common@10.4.17(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@10.4.17)(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)': - dependencies: - '@microsoft/tsdoc': 0.15.1 - '@nestjs/common': 10.4.17(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 10.4.17(@nestjs/common@10.4.17(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/microservices@10.4.17)(@nestjs/platform-express@10.4.17)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/mapped-types': 2.0.5(@nestjs/common@10.4.17(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2) - js-yaml: 4.1.0 - lodash: 4.17.21 - path-to-regexp: 3.3.0 - reflect-metadata: 0.2.2 - swagger-ui-dist: 5.17.14 - optionalDependencies: - class-transformer: 0.5.1 - class-validator: 0.14.1 - - '@nestjs/testing@10.4.17(@nestjs/common@10.4.17(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@10.4.17)(@nestjs/microservices@10.4.17)(@nestjs/platform-express@10.4.17)': - dependencies: - '@nestjs/common': 10.4.17(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 10.4.17(@nestjs/common@10.4.17(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/microservices@10.4.17)(@nestjs/platform-express@10.4.17)(reflect-metadata@0.2.2)(rxjs@7.8.2) - tslib: 2.8.1 - optionalDependencies: - '@nestjs/microservices': 10.4.17(@grpc/grpc-js@1.13.4)(@nestjs/common@10.4.17(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@10.4.17)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/platform-express': 10.4.17(@nestjs/common@10.4.17(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@10.4.17) - - '@noble/hashes@1.8.0': {} - - '@nodelib/fs.scandir@2.1.5': - dependencies: - '@nodelib/fs.stat': 2.0.5 - run-parallel: 1.2.0 - - '@nodelib/fs.stat@2.0.5': {} - - '@nodelib/fs.walk@1.2.8': - dependencies: - '@nodelib/fs.scandir': 2.1.5 - fastq: 1.19.1 - - '@nuxtjs/opencollective@0.3.2': - dependencies: - chalk: 4.1.2 - consola: 2.15.3 - node-fetch: 2.7.0 - transitivePeerDependencies: - - encoding - - '@paralleldrive/cuid2@2.2.2': - dependencies: - '@noble/hashes': 1.8.0 - - '@pkgjs/parseargs@0.11.0': - optional: true - - '@pkgr/core@0.2.4': {} - - '@prisma/client@6.9.0(prisma@6.9.0(typescript@5.8.3))(typescript@5.8.3)': - optionalDependencies: - prisma: 6.9.0(typescript@5.8.3) - typescript: 5.8.3 - - '@prisma/config@6.9.0': - dependencies: - jiti: 2.4.2 - - '@prisma/debug@6.9.0': {} - - '@prisma/engines-version@6.9.0-10.81e4af48011447c3cc503a190e86995b66d2a28e': {} - - '@prisma/engines@6.9.0': - dependencies: - '@prisma/debug': 6.9.0 - '@prisma/engines-version': 6.9.0-10.81e4af48011447c3cc503a190e86995b66d2a28e - '@prisma/fetch-engine': 6.9.0 - '@prisma/get-platform': 6.9.0 - - '@prisma/fetch-engine@6.9.0': - dependencies: - '@prisma/debug': 6.9.0 - '@prisma/engines-version': 6.9.0-10.81e4af48011447c3cc503a190e86995b66d2a28e - '@prisma/get-platform': 6.9.0 - - '@prisma/get-platform@6.9.0': - dependencies: - '@prisma/debug': 6.9.0 - - '@protobufjs/aspromise@1.1.2': {} - - '@protobufjs/base64@1.1.2': {} - - '@protobufjs/codegen@2.0.4': {} - - '@protobufjs/eventemitter@1.1.0': {} - - '@protobufjs/fetch@1.1.0': - dependencies: - '@protobufjs/aspromise': 1.1.2 - '@protobufjs/inquire': 1.1.0 - - '@protobufjs/float@1.0.2': {} - - '@protobufjs/inquire@1.1.0': {} - - '@protobufjs/path@1.1.2': {} - - '@protobufjs/pool@1.1.0': {} - - '@protobufjs/utf8@1.1.0': {} - - '@quixo3/prisma-session-store@3.1.13(@prisma/client@6.9.0(prisma@6.9.0(typescript@5.8.3))(typescript@5.8.3))(express-session@1.18.1)': - dependencies: - '@paralleldrive/cuid2': 2.2.2 - '@prisma/client': 6.9.0(prisma@6.9.0(typescript@5.8.3))(typescript@5.8.3) - express-session: 1.18.1 - ts-dedent: 2.2.0 - type-fest: 2.19.0 - - '@sinclair/typebox@0.27.8': {} - - '@sinonjs/commons@3.0.1': - dependencies: - type-detect: 4.0.8 - - '@sinonjs/fake-timers@10.3.0': - dependencies: - '@sinonjs/commons': 3.0.1 - - '@tokenizer/inflate@0.2.7': - dependencies: - debug: 4.4.0 - fflate: 0.8.2 - token-types: 6.0.0 - transitivePeerDependencies: - - supports-color - - '@tokenizer/token@0.3.0': {} - - '@tsconfig/node10@1.0.11': {} - - '@tsconfig/node12@1.0.11': {} - - '@tsconfig/node14@1.0.3': {} - - '@tsconfig/node16@1.0.4': {} - - '@types/babel__core@7.20.5': - dependencies: - '@babel/parser': 7.27.1 - '@babel/types': 7.27.1 - '@types/babel__generator': 7.27.0 - '@types/babel__template': 7.4.4 - '@types/babel__traverse': 7.20.7 - - '@types/babel__generator@7.27.0': - dependencies: - '@babel/types': 7.27.1 - - '@types/babel__template@7.4.4': - dependencies: - '@babel/parser': 7.27.1 - '@babel/types': 7.27.1 - - '@types/babel__traverse@7.20.7': - dependencies: - '@babel/types': 7.27.1 - - '@types/body-parser@1.19.5': - dependencies: - '@types/connect': 3.4.38 - '@types/node': 22.15.3 - - '@types/connect@3.4.38': - dependencies: - '@types/node': 22.15.3 - - '@types/cookiejar@2.1.5': {} - - '@types/eslint-scope@3.7.7': - dependencies: - '@types/eslint': 9.6.1 - '@types/estree': 1.0.7 - - '@types/eslint@9.6.1': - dependencies: - '@types/estree': 1.0.7 - '@types/json-schema': 7.0.15 - - '@types/estree@1.0.7': {} - - '@types/express-serve-static-core@4.19.6': - dependencies: - '@types/node': 22.15.3 - '@types/qs': 6.9.18 - '@types/range-parser': 1.2.7 - '@types/send': 0.17.4 - - '@types/express-session@1.18.2': - dependencies: - '@types/express': 4.17.21 - - '@types/express@4.17.21': - dependencies: - '@types/body-parser': 1.19.5 - '@types/express-serve-static-core': 4.19.6 - '@types/qs': 6.9.18 - '@types/serve-static': 1.15.7 - - '@types/graceful-fs@4.1.9': - dependencies: - '@types/node': 22.15.3 - - '@types/http-errors@2.0.4': {} - - '@types/istanbul-lib-coverage@2.0.6': {} - - '@types/istanbul-lib-report@3.0.3': - dependencies: - '@types/istanbul-lib-coverage': 2.0.6 - - '@types/istanbul-reports@3.0.4': - dependencies: - '@types/istanbul-lib-report': 3.0.3 - - '@types/jest@29.5.14': - dependencies: - expect: 29.7.0 - pretty-format: 29.7.0 - - '@types/json-schema@7.0.15': {} - - '@types/methods@1.1.4': {} - - '@types/mime@1.3.5': {} - - '@types/node@22.15.3': - dependencies: - undici-types: 6.21.0 - - '@types/qs@6.9.18': {} - - '@types/range-parser@1.2.7': {} - - '@types/semver@7.7.0': {} - - '@types/send@0.17.4': - dependencies: - '@types/mime': 1.3.5 - '@types/node': 22.15.3 - - '@types/serve-static@1.15.7': - dependencies: - '@types/http-errors': 2.0.4 - '@types/node': 22.15.3 - '@types/send': 0.17.4 - - '@types/stack-utils@2.0.3': {} - - '@types/superagent@8.1.9': - dependencies: - '@types/cookiejar': 2.1.5 - '@types/methods': 1.1.4 - '@types/node': 22.15.3 - form-data: 4.0.2 - - '@types/supertest@6.0.3': - dependencies: - '@types/methods': 1.1.4 - '@types/superagent': 8.1.9 - - '@types/validator@13.15.0': {} - - '@types/yargs-parser@21.0.3': {} - - '@types/yargs@17.0.33': - dependencies: - '@types/yargs-parser': 21.0.3 - - '@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1)(typescript@5.8.3)': - dependencies: - '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 6.21.0(eslint@8.57.1)(typescript@5.8.3) - '@typescript-eslint/scope-manager': 6.21.0 - '@typescript-eslint/type-utils': 6.21.0(eslint@8.57.1)(typescript@5.8.3) - '@typescript-eslint/utils': 6.21.0(eslint@8.57.1)(typescript@5.8.3) - '@typescript-eslint/visitor-keys': 6.21.0 - debug: 4.4.0 - eslint: 8.57.1 - graphemer: 1.4.0 - ignore: 5.3.2 - natural-compare: 1.4.0 - semver: 7.7.1 - ts-api-utils: 1.4.3(typescript@5.8.3) - optionalDependencies: - typescript: 5.8.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.3)': - dependencies: - '@typescript-eslint/scope-manager': 6.21.0 - '@typescript-eslint/types': 6.21.0 - '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.8.3) - '@typescript-eslint/visitor-keys': 6.21.0 - debug: 4.4.0 - eslint: 8.57.1 - optionalDependencies: - typescript: 5.8.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/scope-manager@6.21.0': - dependencies: - '@typescript-eslint/types': 6.21.0 - '@typescript-eslint/visitor-keys': 6.21.0 - - '@typescript-eslint/type-utils@6.21.0(eslint@8.57.1)(typescript@5.8.3)': - dependencies: - '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.8.3) - '@typescript-eslint/utils': 6.21.0(eslint@8.57.1)(typescript@5.8.3) - debug: 4.4.0 - eslint: 8.57.1 - ts-api-utils: 1.4.3(typescript@5.8.3) - optionalDependencies: - typescript: 5.8.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/types@6.21.0': {} - - '@typescript-eslint/typescript-estree@6.21.0(typescript@5.8.3)': - dependencies: - '@typescript-eslint/types': 6.21.0 - '@typescript-eslint/visitor-keys': 6.21.0 - debug: 4.4.0 - globby: 11.1.0 - is-glob: 4.0.3 - minimatch: 9.0.3 - semver: 7.7.1 - ts-api-utils: 1.4.3(typescript@5.8.3) - optionalDependencies: - typescript: 5.8.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/utils@6.21.0(eslint@8.57.1)(typescript@5.8.3)': - dependencies: - '@eslint-community/eslint-utils': 4.6.1(eslint@8.57.1) - '@types/json-schema': 7.0.15 - '@types/semver': 7.7.0 - '@typescript-eslint/scope-manager': 6.21.0 - '@typescript-eslint/types': 6.21.0 - '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.8.3) - eslint: 8.57.1 - semver: 7.7.1 - transitivePeerDependencies: - - supports-color - - typescript - - '@typescript-eslint/visitor-keys@6.21.0': - dependencies: - '@typescript-eslint/types': 6.21.0 - eslint-visitor-keys: 3.4.3 - - '@ungap/structured-clone@1.3.0': {} - - '@webassemblyjs/ast@1.14.1': - dependencies: - '@webassemblyjs/helper-numbers': 1.13.2 - '@webassemblyjs/helper-wasm-bytecode': 1.13.2 - - '@webassemblyjs/floating-point-hex-parser@1.13.2': {} - - '@webassemblyjs/helper-api-error@1.13.2': {} - - '@webassemblyjs/helper-buffer@1.14.1': {} - - '@webassemblyjs/helper-numbers@1.13.2': - dependencies: - '@webassemblyjs/floating-point-hex-parser': 1.13.2 - '@webassemblyjs/helper-api-error': 1.13.2 - '@xtuc/long': 4.2.2 - - '@webassemblyjs/helper-wasm-bytecode@1.13.2': {} - - '@webassemblyjs/helper-wasm-section@1.14.1': - dependencies: - '@webassemblyjs/ast': 1.14.1 - '@webassemblyjs/helper-buffer': 1.14.1 - '@webassemblyjs/helper-wasm-bytecode': 1.13.2 - '@webassemblyjs/wasm-gen': 1.14.1 - - '@webassemblyjs/ieee754@1.13.2': - dependencies: - '@xtuc/ieee754': 1.2.0 - - '@webassemblyjs/leb128@1.13.2': - dependencies: - '@xtuc/long': 4.2.2 - - '@webassemblyjs/utf8@1.13.2': {} - - '@webassemblyjs/wasm-edit@1.14.1': - dependencies: - '@webassemblyjs/ast': 1.14.1 - '@webassemblyjs/helper-buffer': 1.14.1 - '@webassemblyjs/helper-wasm-bytecode': 1.13.2 - '@webassemblyjs/helper-wasm-section': 1.14.1 - '@webassemblyjs/wasm-gen': 1.14.1 - '@webassemblyjs/wasm-opt': 1.14.1 - '@webassemblyjs/wasm-parser': 1.14.1 - '@webassemblyjs/wast-printer': 1.14.1 - - '@webassemblyjs/wasm-gen@1.14.1': - dependencies: - '@webassemblyjs/ast': 1.14.1 - '@webassemblyjs/helper-wasm-bytecode': 1.13.2 - '@webassemblyjs/ieee754': 1.13.2 - '@webassemblyjs/leb128': 1.13.2 - '@webassemblyjs/utf8': 1.13.2 - - '@webassemblyjs/wasm-opt@1.14.1': - dependencies: - '@webassemblyjs/ast': 1.14.1 - '@webassemblyjs/helper-buffer': 1.14.1 - '@webassemblyjs/wasm-gen': 1.14.1 - '@webassemblyjs/wasm-parser': 1.14.1 - - '@webassemblyjs/wasm-parser@1.14.1': - dependencies: - '@webassemblyjs/ast': 1.14.1 - '@webassemblyjs/helper-api-error': 1.13.2 - '@webassemblyjs/helper-wasm-bytecode': 1.13.2 - '@webassemblyjs/ieee754': 1.13.2 - '@webassemblyjs/leb128': 1.13.2 - '@webassemblyjs/utf8': 1.13.2 - - '@webassemblyjs/wast-printer@1.14.1': - dependencies: - '@webassemblyjs/ast': 1.14.1 - '@xtuc/long': 4.2.2 - - '@xtuc/ieee754@1.2.0': {} - - '@xtuc/long@4.2.2': {} - - abbrev@1.1.1: {} - - accepts@1.3.8: - dependencies: - mime-types: 2.1.35 - negotiator: 0.6.3 - - acorn-jsx@5.3.2(acorn@8.14.1): - dependencies: - acorn: 8.14.1 - - acorn-walk@8.3.4: - dependencies: - acorn: 8.14.1 - - acorn@8.14.1: {} - - agent-base@6.0.2: - dependencies: - debug: 4.4.0 - transitivePeerDependencies: - - supports-color - - ajv-formats@2.1.1(ajv@8.12.0): - optionalDependencies: - ajv: 8.12.0 - - ajv-formats@2.1.1(ajv@8.17.1): - optionalDependencies: - ajv: 8.17.1 - - ajv-keywords@3.5.2(ajv@6.12.6): - dependencies: - ajv: 6.12.6 - - ajv-keywords@5.1.0(ajv@8.17.1): - dependencies: - ajv: 8.17.1 - fast-deep-equal: 3.1.3 - - ajv@6.12.6: - dependencies: - fast-deep-equal: 3.1.3 - fast-json-stable-stringify: 2.1.0 - json-schema-traverse: 0.4.1 - uri-js: 4.4.1 - - ajv@8.12.0: - dependencies: - fast-deep-equal: 3.1.3 - json-schema-traverse: 1.0.0 - require-from-string: 2.0.2 - uri-js: 4.4.1 - - ajv@8.17.1: - dependencies: - fast-deep-equal: 3.1.3 - fast-uri: 3.0.6 - json-schema-traverse: 1.0.0 - require-from-string: 2.0.2 - - ansi-colors@4.1.3: {} - - ansi-escapes@4.3.2: - dependencies: - type-fest: 0.21.3 - - ansi-regex@2.1.1: {} - - ansi-regex@5.0.1: {} - - ansi-regex@6.1.0: {} - - ansi-styles@4.3.0: - dependencies: - color-convert: 2.0.1 - - ansi-styles@5.2.0: {} - - ansi-styles@6.2.1: {} - - anymatch@3.1.3: - dependencies: - normalize-path: 3.0.0 - picomatch: 2.3.1 - - append-field@1.0.0: {} - - aproba@2.0.0: {} - - are-we-there-yet@2.0.0: - dependencies: - delegates: 1.0.0 - readable-stream: 3.6.2 - - arg@4.1.3: {} - - argparse@1.0.10: - dependencies: - sprintf-js: 1.0.3 - - argparse@2.0.1: {} - - array-flatten@1.1.1: {} - - array-timsort@1.0.3: {} - - array-union@2.1.0: {} - - asap@2.0.6: {} - - ascli@1.0.1: - dependencies: - colour: 0.7.1 - optjs: 3.2.2 - - async@3.2.6: {} - - asynckit@0.4.0: {} - - babel-jest@29.7.0(@babel/core@7.27.1): - dependencies: - '@babel/core': 7.27.1 - '@jest/transform': 29.7.0 - '@types/babel__core': 7.20.5 - babel-plugin-istanbul: 6.1.1 - babel-preset-jest: 29.6.3(@babel/core@7.27.1) - chalk: 4.1.2 - graceful-fs: 4.2.11 - slash: 3.0.0 - transitivePeerDependencies: - - supports-color - - babel-plugin-istanbul@6.1.1: - dependencies: - '@babel/helper-plugin-utils': 7.27.1 - '@istanbuljs/load-nyc-config': 1.1.0 - '@istanbuljs/schema': 0.1.3 - istanbul-lib-instrument: 5.2.1 - test-exclude: 6.0.0 - transitivePeerDependencies: - - supports-color - - babel-plugin-jest-hoist@29.6.3: - dependencies: - '@babel/template': 7.27.1 - '@babel/types': 7.27.1 - '@types/babel__core': 7.20.5 - '@types/babel__traverse': 7.20.7 - - babel-preset-current-node-syntax@1.1.0(@babel/core@7.27.1): - dependencies: - '@babel/core': 7.27.1 - '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.27.1) - '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.27.1) - '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.27.1) - '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.27.1) - '@babel/plugin-syntax-import-attributes': 7.27.1(@babel/core@7.27.1) - '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.27.1) - '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.27.1) - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.27.1) - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.27.1) - '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.27.1) - '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.27.1) - '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.27.1) - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.27.1) - '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.27.1) - '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.27.1) - - babel-preset-jest@29.6.3(@babel/core@7.27.1): - dependencies: - '@babel/core': 7.27.1 - babel-plugin-jest-hoist: 29.6.3 - babel-preset-current-node-syntax: 1.1.0(@babel/core@7.27.1) - - balanced-match@1.0.2: {} - - base64-js@1.5.1: {} - - binary-extensions@2.3.0: {} - - bl@4.1.0: - dependencies: - buffer: 5.7.1 - inherits: 2.0.4 - readable-stream: 3.6.2 - - body-parser@1.20.3: - dependencies: - bytes: 3.1.2 - content-type: 1.0.5 - debug: 2.6.9 - depd: 2.0.0 - destroy: 1.2.0 - http-errors: 2.0.0 - iconv-lite: 0.4.24 - on-finished: 2.4.1 - qs: 6.13.0 - raw-body: 2.5.2 - type-is: 1.6.18 - unpipe: 1.0.0 - transitivePeerDependencies: - - supports-color - - brace-expansion@1.1.11: - dependencies: - balanced-match: 1.0.2 - concat-map: 0.0.1 - - brace-expansion@2.0.1: - dependencies: - balanced-match: 1.0.2 - - braces@3.0.3: - dependencies: - fill-range: 7.1.1 - - browserslist@4.24.4: - dependencies: - caniuse-lite: 1.0.30001716 - electron-to-chromium: 1.5.145 - node-releases: 2.0.19 - update-browserslist-db: 1.1.3(browserslist@4.24.4) - - bs-logger@0.2.6: - dependencies: - fast-json-stable-stringify: 2.1.0 - - bser@2.1.1: - dependencies: - node-int64: 0.4.0 - - buffer-from@1.1.2: {} - - buffer@5.7.1: - dependencies: - base64-js: 1.5.1 - ieee754: 1.2.1 - - busboy@1.6.0: - dependencies: - streamsearch: 1.1.0 - - bytebuffer@5.0.1: - dependencies: - long: 3.2.0 - - bytes@3.1.2: {} - - call-bind-apply-helpers@1.0.2: - dependencies: - es-errors: 1.3.0 - function-bind: 1.1.2 - - call-bind@1.0.8: - dependencies: - call-bind-apply-helpers: 1.0.2 - es-define-property: 1.0.1 - get-intrinsic: 1.3.0 - set-function-length: 1.2.2 - - call-bound@1.0.4: - dependencies: - call-bind-apply-helpers: 1.0.2 - get-intrinsic: 1.3.0 - - callsites@3.1.0: {} - - camelcase@2.1.1: {} - - camelcase@5.3.1: {} - - camelcase@6.3.0: {} - - caniuse-lite@1.0.30001716: {} - - chalk@4.1.2: - dependencies: - ansi-styles: 4.3.0 - supports-color: 7.2.0 - - chalk@5.4.1: {} - - char-regex@1.0.2: {} - - chardet@0.7.0: {} - - chokidar@3.6.0: - dependencies: - anymatch: 3.1.3 - braces: 3.0.3 - glob-parent: 5.1.2 - is-binary-path: 2.1.0 - is-glob: 4.0.3 - normalize-path: 3.0.0 - readdirp: 3.6.0 - optionalDependencies: - fsevents: 2.3.3 - - chownr@2.0.0: {} - - chrome-trace-event@1.0.4: {} - - ci-info@3.9.0: {} - - cjs-module-lexer@1.4.3: {} - - class-transformer@0.5.1: {} - - class-validator@0.14.1: - dependencies: - '@types/validator': 13.15.0 - libphonenumber-js: 1.12.7 - validator: 13.15.0 - - cli-cursor@3.1.0: - dependencies: - restore-cursor: 3.1.0 - - cli-spinners@2.9.2: {} - - cli-table3@0.6.5: - dependencies: - string-width: 4.2.3 - optionalDependencies: - '@colors/colors': 1.5.0 - - cli-width@3.0.0: {} - - cli-width@4.1.0: {} - - cliui@3.2.0: - dependencies: - string-width: 1.0.2 - strip-ansi: 3.0.1 - wrap-ansi: 2.1.0 - - cliui@8.0.1: - dependencies: - string-width: 4.2.3 - strip-ansi: 6.0.1 - wrap-ansi: 7.0.0 - - clone@1.0.4: {} - - co@4.6.0: {} - - code-point-at@1.1.0: {} - - collect-v8-coverage@1.0.2: {} - - color-convert@2.0.1: - dependencies: - color-name: 1.1.4 - - color-name@1.1.4: {} - - color-support@1.1.3: {} - - colour@0.7.1: {} - - combined-stream@1.0.8: - dependencies: - delayed-stream: 1.0.0 - - commander@2.20.3: {} - - commander@4.1.1: {} - - comment-json@4.2.5: - dependencies: - array-timsort: 1.0.3 - core-util-is: 1.0.3 - esprima: 4.0.1 - has-own-prop: 2.0.0 - repeat-string: 1.6.1 - - component-emitter@1.3.1: {} - - concat-map@0.0.1: {} - - concat-stream@1.6.2: - dependencies: - buffer-from: 1.1.2 - inherits: 2.0.4 - readable-stream: 2.3.8 - typedarray: 0.0.6 - - consola@2.15.3: {} - - console-control-strings@1.1.0: {} - - content-disposition@0.5.4: - dependencies: - safe-buffer: 5.2.1 - - content-type@1.0.5: {} - - convert-source-map@2.0.0: {} - - cookie-signature@1.0.6: {} - - cookie-signature@1.0.7: {} - - cookie@0.7.1: {} - - cookie@0.7.2: {} - - cookiejar@2.1.4: {} - - core-util-is@1.0.3: {} - - cors@2.8.5: - dependencies: - object-assign: 4.1.1 - vary: 1.1.2 - - cosmiconfig@8.3.6(typescript@5.7.2): - dependencies: - import-fresh: 3.3.1 - js-yaml: 4.1.0 - parse-json: 5.2.0 - path-type: 4.0.0 - optionalDependencies: - typescript: 5.7.2 - - create-jest@29.7.0(@types/node@22.15.3)(ts-node@10.9.2(@types/node@22.15.3)(typescript@5.8.3)): - dependencies: - '@jest/types': 29.6.3 - chalk: 4.1.2 - exit: 0.1.2 - graceful-fs: 4.2.11 - jest-config: 29.7.0(@types/node@22.15.3)(ts-node@10.9.2(@types/node@22.15.3)(typescript@5.8.3)) - jest-util: 29.7.0 - prompts: 2.4.2 - transitivePeerDependencies: - - '@types/node' - - babel-plugin-macros - - supports-color - - ts-node - - create-require@1.1.1: {} - - cross-spawn@7.0.6: - dependencies: - path-key: 3.1.1 - shebang-command: 2.0.0 - which: 2.0.2 - - debug@2.6.9: - dependencies: - ms: 2.0.0 - - debug@4.4.0: - dependencies: - ms: 2.1.3 - - decamelize@1.2.0: {} - - dedent@1.5.3: {} - - deep-is@0.1.4: {} - - deepmerge@4.3.1: {} - - defaults@1.0.4: - dependencies: - clone: 1.0.4 - - define-data-property@1.1.4: - dependencies: - es-define-property: 1.0.1 - es-errors: 1.3.0 - gopd: 1.2.0 - - delayed-stream@1.0.0: {} - - delegates@1.0.0: {} - - depd@2.0.0: {} - - destroy@1.2.0: {} - - detect-libc@2.0.4: {} - - detect-newline@3.1.0: {} - - dezalgo@1.0.4: - dependencies: - asap: 2.0.6 - wrappy: 1.0.2 - - diff-sequences@29.6.3: {} - - diff@4.0.2: {} - - dir-glob@3.0.1: - dependencies: - path-type: 4.0.0 - - doctrine@3.0.0: - dependencies: - esutils: 2.0.3 - - dotenv-expand@10.0.0: {} - - dotenv@16.4.5: {} - - dotenv@16.5.0: {} - - dunder-proto@1.0.1: - dependencies: - call-bind-apply-helpers: 1.0.2 - es-errors: 1.3.0 - gopd: 1.2.0 - - eastasianwidth@0.2.0: {} - - ee-first@1.1.1: {} - - ejs@3.1.10: - dependencies: - jake: 10.9.2 - - electron-to-chromium@1.5.145: {} - - emittery@0.13.1: {} - - emoji-regex@8.0.0: {} - - emoji-regex@9.2.2: {} - - encodeurl@1.0.2: {} - - encodeurl@2.0.0: {} - - enhanced-resolve@5.18.1: - dependencies: - graceful-fs: 4.2.11 - tapable: 2.2.1 - - error-ex@1.3.2: - dependencies: - is-arrayish: 0.2.1 - - es-define-property@1.0.1: {} - - es-errors@1.3.0: {} - - es-module-lexer@1.7.0: {} - - es-object-atoms@1.1.1: - dependencies: - es-errors: 1.3.0 - - es-set-tostringtag@2.1.0: - dependencies: - es-errors: 1.3.0 - get-intrinsic: 1.3.0 - has-tostringtag: 1.0.2 - hasown: 2.0.2 - - escalade@3.2.0: {} - - escape-html@1.0.3: {} - - escape-string-regexp@1.0.5: {} - - escape-string-regexp@2.0.0: {} - - escape-string-regexp@4.0.0: {} - - eslint-config-prettier@9.1.0(eslint@8.57.1): - dependencies: - eslint: 8.57.1 - - eslint-plugin-prettier@5.4.1(@types/eslint@9.6.1)(eslint-config-prettier@9.1.0(eslint@8.57.1))(eslint@8.57.1)(prettier@3.5.3): - dependencies: - eslint: 8.57.1 - prettier: 3.5.3 - prettier-linter-helpers: 1.0.0 - synckit: 0.11.8 - optionalDependencies: - '@types/eslint': 9.6.1 - eslint-config-prettier: 9.1.0(eslint@8.57.1) - - eslint-scope@5.1.1: - dependencies: - esrecurse: 4.3.0 - estraverse: 4.3.0 - - eslint-scope@7.2.2: - dependencies: - esrecurse: 4.3.0 - estraverse: 5.3.0 - - eslint-visitor-keys@3.4.3: {} - - eslint@8.57.1: - dependencies: - '@eslint-community/eslint-utils': 4.6.1(eslint@8.57.1) - '@eslint-community/regexpp': 4.12.1 - '@eslint/eslintrc': 2.1.4 - '@eslint/js': 8.57.1 - '@humanwhocodes/config-array': 0.13.0 - '@humanwhocodes/module-importer': 1.0.1 - '@nodelib/fs.walk': 1.2.8 - '@ungap/structured-clone': 1.3.0 - ajv: 6.12.6 - chalk: 4.1.2 - cross-spawn: 7.0.6 - debug: 4.4.0 - 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.6.0 - esutils: 2.0.3 - fast-deep-equal: 3.1.3 - file-entry-cache: 6.0.1 - find-up: 5.0.0 - glob-parent: 6.0.2 - globals: 13.24.0 - graphemer: 1.4.0 - ignore: 5.3.2 - imurmurhash: 0.1.4 - is-glob: 4.0.3 - 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.4 - strip-ansi: 6.0.1 - text-table: 0.2.0 - transitivePeerDependencies: - - supports-color - - espree@9.6.1: - dependencies: - acorn: 8.14.1 - acorn-jsx: 5.3.2(acorn@8.14.1) - eslint-visitor-keys: 3.4.3 - - esprima@4.0.1: {} - - esquery@1.6.0: - dependencies: - estraverse: 5.3.0 - - esrecurse@4.3.0: - dependencies: - estraverse: 5.3.0 - - estraverse@4.3.0: {} - - estraverse@5.3.0: {} - - esutils@2.0.3: {} - - etag@1.8.1: {} - - events@3.3.0: {} - - execa@5.1.1: - dependencies: - cross-spawn: 7.0.6 - get-stream: 6.0.1 - human-signals: 2.1.0 - is-stream: 2.0.1 - merge-stream: 2.0.0 - npm-run-path: 4.0.1 - onetime: 5.1.2 - signal-exit: 3.0.7 - strip-final-newline: 2.0.0 - - exit@0.1.2: {} - - expect@29.7.0: - dependencies: - '@jest/expect-utils': 29.7.0 - jest-get-type: 29.6.3 - jest-matcher-utils: 29.7.0 - jest-message-util: 29.7.0 - jest-util: 29.7.0 - - express-session@1.18.1: - dependencies: - cookie: 0.7.2 - cookie-signature: 1.0.7 - debug: 2.6.9 - depd: 2.0.0 - on-headers: 1.0.2 - parseurl: 1.3.3 - safe-buffer: 5.2.1 - uid-safe: 2.1.5 - transitivePeerDependencies: - - supports-color - - express@4.21.2: - dependencies: - accepts: 1.3.8 - array-flatten: 1.1.1 - body-parser: 1.20.3 - content-disposition: 0.5.4 - content-type: 1.0.5 - cookie: 0.7.1 - cookie-signature: 1.0.6 - debug: 2.6.9 - depd: 2.0.0 - encodeurl: 2.0.0 - escape-html: 1.0.3 - etag: 1.8.1 - finalhandler: 1.3.1 - fresh: 0.5.2 - http-errors: 2.0.0 - merge-descriptors: 1.0.3 - methods: 1.1.2 - on-finished: 2.4.1 - parseurl: 1.3.3 - path-to-regexp: 0.1.12 - proxy-addr: 2.0.7 - qs: 6.13.0 - range-parser: 1.2.1 - safe-buffer: 5.2.1 - send: 0.19.0 - serve-static: 1.16.2 - setprototypeof: 1.2.0 - statuses: 2.0.1 - type-is: 1.6.18 - utils-merge: 1.0.1 - vary: 1.1.2 - transitivePeerDependencies: - - supports-color - - external-editor@3.1.0: - dependencies: - chardet: 0.7.0 - iconv-lite: 0.4.24 - tmp: 0.0.33 - - fast-deep-equal@3.1.3: {} - - fast-diff@1.3.0: {} - - fast-glob@3.3.3: - dependencies: - '@nodelib/fs.stat': 2.0.5 - '@nodelib/fs.walk': 1.2.8 - glob-parent: 5.1.2 - merge2: 1.4.1 - micromatch: 4.0.8 - - fast-json-stable-stringify@2.1.0: {} - - fast-levenshtein@2.0.6: {} - - fast-safe-stringify@2.1.1: {} - - fast-uri@3.0.6: {} - - fastq@1.19.1: - dependencies: - reusify: 1.1.0 - - fb-watchman@2.0.2: - dependencies: - bser: 2.1.1 - - fflate@0.8.2: {} - - figures@3.2.0: - dependencies: - escape-string-regexp: 1.0.5 - - file-entry-cache@6.0.1: - dependencies: - flat-cache: 3.2.0 - - file-type@20.4.1: - dependencies: - '@tokenizer/inflate': 0.2.7 - strtok3: 10.2.2 - token-types: 6.0.0 - uint8array-extras: 1.4.0 - transitivePeerDependencies: - - supports-color - - filelist@1.0.4: - dependencies: - minimatch: 5.1.6 - - fill-range@7.1.1: - dependencies: - to-regex-range: 5.0.1 - - finalhandler@1.3.1: - dependencies: - debug: 2.6.9 - encodeurl: 2.0.0 - escape-html: 1.0.3 - on-finished: 2.4.1 - parseurl: 1.3.3 - statuses: 2.0.1 - unpipe: 1.0.0 - transitivePeerDependencies: - - supports-color - - find-up@4.1.0: - dependencies: - locate-path: 5.0.0 - path-exists: 4.0.0 - - find-up@5.0.0: - dependencies: - locate-path: 6.0.0 - path-exists: 4.0.0 - - flat-cache@3.2.0: - dependencies: - flatted: 3.3.3 - keyv: 4.5.4 - rimraf: 3.0.2 - - flatted@3.3.3: {} - - foreground-child@3.3.1: - dependencies: - cross-spawn: 7.0.6 - signal-exit: 4.1.0 - - fork-ts-checker-webpack-plugin@9.0.2(typescript@5.7.2)(webpack@5.97.1): - dependencies: - '@babel/code-frame': 7.27.1 - chalk: 4.1.2 - chokidar: 3.6.0 - cosmiconfig: 8.3.6(typescript@5.7.2) - deepmerge: 4.3.1 - fs-extra: 10.1.0 - memfs: 3.5.3 - minimatch: 3.1.2 - node-abort-controller: 3.1.1 - schema-utils: 3.3.0 - semver: 7.7.1 - tapable: 2.2.1 - typescript: 5.7.2 - webpack: 5.97.1 - - form-data@4.0.2: - dependencies: - asynckit: 0.4.0 - combined-stream: 1.0.8 - es-set-tostringtag: 2.1.0 - mime-types: 2.1.35 - - formidable@2.1.5: - dependencies: - '@paralleldrive/cuid2': 2.2.2 - dezalgo: 1.0.4 - once: 1.4.0 - qs: 6.14.0 - - forwarded@0.2.0: {} - - fresh@0.5.2: {} - - fs-extra@10.1.0: - dependencies: - graceful-fs: 4.2.11 - jsonfile: 6.1.0 - universalify: 2.0.1 - - fs-minipass@2.1.0: - dependencies: - minipass: 3.3.6 - - fs-monkey@1.0.6: {} - - fs.realpath@1.0.0: {} - - fsevents@2.3.3: - optional: true - - function-bind@1.1.2: {} - - gauge@3.0.2: - dependencies: - aproba: 2.0.0 - color-support: 1.1.3 - console-control-strings: 1.1.0 - has-unicode: 2.0.1 - object-assign: 4.1.1 - signal-exit: 3.0.7 - string-width: 4.2.3 - strip-ansi: 6.0.1 - wide-align: 1.1.5 - - gensync@1.0.0-beta.2: {} - - get-caller-file@2.0.5: {} - - get-intrinsic@1.3.0: - dependencies: - call-bind-apply-helpers: 1.0.2 - es-define-property: 1.0.1 - es-errors: 1.3.0 - es-object-atoms: 1.1.1 - function-bind: 1.1.2 - get-proto: 1.0.1 - gopd: 1.2.0 - has-symbols: 1.1.0 - hasown: 2.0.2 - math-intrinsics: 1.1.0 - - get-package-type@0.1.0: {} - - get-proto@1.0.1: - dependencies: - dunder-proto: 1.0.1 - es-object-atoms: 1.1.1 - - get-stream@6.0.1: {} - - glob-parent@5.1.2: - dependencies: - is-glob: 4.0.3 - - glob-parent@6.0.2: - dependencies: - is-glob: 4.0.3 - - glob-to-regexp@0.4.1: {} - - glob@10.4.5: - dependencies: - foreground-child: 3.3.1 - jackspeak: 3.4.3 - minimatch: 9.0.5 - minipass: 7.1.2 - package-json-from-dist: 1.0.1 - path-scurry: 1.11.1 - - glob@7.2.3: - dependencies: - fs.realpath: 1.0.0 - inflight: 1.0.6 - inherits: 2.0.4 - minimatch: 3.1.2 - once: 1.4.0 - path-is-absolute: 1.0.1 - - globals@11.12.0: {} - - globals@13.24.0: - dependencies: - type-fest: 0.20.2 - - globby@11.1.0: - dependencies: - array-union: 2.1.0 - dir-glob: 3.0.1 - fast-glob: 3.3.3 - ignore: 5.3.2 - merge2: 1.4.1 - slash: 3.0.0 - - google-protobuf@3.15.8: {} - - google-protobuf@3.21.4: {} - - gopd@1.2.0: {} - - graceful-fs@4.2.11: {} - - graphemer@1.4.0: {} - - grpc-tools@1.13.0: - dependencies: - '@mapbox/node-pre-gyp': 1.0.11 - transitivePeerDependencies: - - encoding - - supports-color - - grpc_tools_node_protoc_ts@5.3.3: - dependencies: - google-protobuf: 3.15.8 - handlebars: 4.7.7 - - handlebars@4.7.7: - dependencies: - minimist: 1.2.8 - neo-async: 2.6.2 - source-map: 0.6.1 - wordwrap: 1.0.0 - optionalDependencies: - uglify-js: 3.19.3 - - has-flag@4.0.0: {} - - has-own-prop@2.0.0: {} - - has-property-descriptors@1.0.2: - dependencies: - es-define-property: 1.0.1 - - has-symbols@1.1.0: {} - - has-tostringtag@1.0.2: - dependencies: - has-symbols: 1.1.0 - - has-unicode@2.0.1: {} - - hasown@2.0.2: - dependencies: - function-bind: 1.1.2 - - html-escaper@2.0.2: {} - - http-errors@2.0.0: - dependencies: - depd: 2.0.0 - inherits: 2.0.4 - setprototypeof: 1.2.0 - statuses: 2.0.1 - toidentifier: 1.0.1 - - https-proxy-agent@5.0.1: - dependencies: - agent-base: 6.0.2 - debug: 4.4.0 - transitivePeerDependencies: - - supports-color - - human-signals@2.1.0: {} - - iconv-lite@0.4.24: - dependencies: - safer-buffer: 2.1.2 - - ieee754@1.2.1: {} - - ignore@5.3.2: {} - - import-fresh@3.3.1: - dependencies: - parent-module: 1.0.1 - resolve-from: 4.0.0 - - import-local@3.2.0: - dependencies: - pkg-dir: 4.2.0 - resolve-cwd: 3.0.0 - - imurmurhash@0.1.4: {} - - inflight@1.0.6: - dependencies: - once: 1.4.0 - wrappy: 1.0.2 - - inherits@2.0.4: {} - - inquirer@8.2.6: - dependencies: - ansi-escapes: 4.3.2 - chalk: 4.1.2 - cli-cursor: 3.1.0 - cli-width: 3.0.0 - external-editor: 3.1.0 - figures: 3.2.0 - lodash: 4.17.21 - mute-stream: 0.0.8 - ora: 5.4.1 - run-async: 2.4.1 - rxjs: 7.8.2 - string-width: 4.2.3 - strip-ansi: 6.0.1 - through: 2.3.8 - wrap-ansi: 6.2.0 - - inquirer@9.2.15: - dependencies: - '@ljharb/through': 2.3.14 - ansi-escapes: 4.3.2 - chalk: 5.4.1 - cli-cursor: 3.1.0 - cli-width: 4.1.0 - external-editor: 3.1.0 - figures: 3.2.0 - lodash: 4.17.21 - mute-stream: 1.0.0 - ora: 5.4.1 - run-async: 3.0.0 - rxjs: 7.8.2 - string-width: 4.2.3 - strip-ansi: 6.0.1 - wrap-ansi: 6.2.0 - - invert-kv@1.0.0: {} - - ipaddr.js@1.9.1: {} - - is-arrayish@0.2.1: {} - - is-binary-path@2.1.0: - dependencies: - binary-extensions: 2.3.0 - - is-core-module@2.16.1: - dependencies: - hasown: 2.0.2 - - is-extglob@2.1.1: {} - - is-fullwidth-code-point@1.0.0: - dependencies: - number-is-nan: 1.0.1 - - is-fullwidth-code-point@3.0.0: {} - - is-generator-fn@2.1.0: {} - - is-glob@4.0.3: - dependencies: - is-extglob: 2.1.1 - - is-interactive@1.0.0: {} - - is-number@7.0.0: {} - - is-path-inside@3.0.3: {} - - is-stream@2.0.1: {} - - is-unicode-supported@0.1.0: {} - - isarray@1.0.0: {} - - isexe@2.0.0: {} - - istanbul-lib-coverage@3.2.2: {} - - istanbul-lib-instrument@5.2.1: - dependencies: - '@babel/core': 7.27.1 - '@babel/parser': 7.27.1 - '@istanbuljs/schema': 0.1.3 - istanbul-lib-coverage: 3.2.2 - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - - istanbul-lib-instrument@6.0.3: - dependencies: - '@babel/core': 7.27.1 - '@babel/parser': 7.27.1 - '@istanbuljs/schema': 0.1.3 - istanbul-lib-coverage: 3.2.2 - semver: 7.7.1 - transitivePeerDependencies: - - supports-color - - istanbul-lib-report@3.0.1: - dependencies: - istanbul-lib-coverage: 3.2.2 - make-dir: 4.0.0 - supports-color: 7.2.0 - - istanbul-lib-source-maps@4.0.1: - dependencies: - debug: 4.4.0 - istanbul-lib-coverage: 3.2.2 - source-map: 0.6.1 - transitivePeerDependencies: - - supports-color - - istanbul-reports@3.1.7: - dependencies: - html-escaper: 2.0.2 - istanbul-lib-report: 3.0.1 - - iterare@1.2.1: {} - - jackspeak@3.4.3: - dependencies: - '@isaacs/cliui': 8.0.2 - optionalDependencies: - '@pkgjs/parseargs': 0.11.0 - - jake@10.9.2: - dependencies: - async: 3.2.6 - chalk: 4.1.2 - filelist: 1.0.4 - minimatch: 3.1.2 - - jest-changed-files@29.7.0: - dependencies: - execa: 5.1.1 - jest-util: 29.7.0 - p-limit: 3.1.0 - - jest-circus@29.7.0: - dependencies: - '@jest/environment': 29.7.0 - '@jest/expect': 29.7.0 - '@jest/test-result': 29.7.0 - '@jest/types': 29.6.3 - '@types/node': 22.15.3 - chalk: 4.1.2 - co: 4.6.0 - dedent: 1.5.3 - is-generator-fn: 2.1.0 - jest-each: 29.7.0 - jest-matcher-utils: 29.7.0 - jest-message-util: 29.7.0 - jest-runtime: 29.7.0 - jest-snapshot: 29.7.0 - jest-util: 29.7.0 - p-limit: 3.1.0 - pretty-format: 29.7.0 - pure-rand: 6.1.0 - slash: 3.0.0 - stack-utils: 2.0.6 - transitivePeerDependencies: - - babel-plugin-macros - - supports-color - - jest-cli@29.7.0(@types/node@22.15.3)(ts-node@10.9.2(@types/node@22.15.3)(typescript@5.8.3)): - dependencies: - '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@22.15.3)(typescript@5.8.3)) - '@jest/test-result': 29.7.0 - '@jest/types': 29.6.3 - chalk: 4.1.2 - create-jest: 29.7.0(@types/node@22.15.3)(ts-node@10.9.2(@types/node@22.15.3)(typescript@5.8.3)) - exit: 0.1.2 - import-local: 3.2.0 - jest-config: 29.7.0(@types/node@22.15.3)(ts-node@10.9.2(@types/node@22.15.3)(typescript@5.8.3)) - jest-util: 29.7.0 - jest-validate: 29.7.0 - yargs: 17.7.2 - transitivePeerDependencies: - - '@types/node' - - babel-plugin-macros - - supports-color - - ts-node - - jest-config@29.7.0(@types/node@22.15.3)(ts-node@10.9.2(@types/node@22.15.3)(typescript@5.8.3)): - dependencies: - '@babel/core': 7.27.1 - '@jest/test-sequencer': 29.7.0 - '@jest/types': 29.6.3 - babel-jest: 29.7.0(@babel/core@7.27.1) - chalk: 4.1.2 - ci-info: 3.9.0 - deepmerge: 4.3.1 - glob: 7.2.3 - graceful-fs: 4.2.11 - jest-circus: 29.7.0 - jest-environment-node: 29.7.0 - jest-get-type: 29.6.3 - jest-regex-util: 29.6.3 - jest-resolve: 29.7.0 - jest-runner: 29.7.0 - jest-util: 29.7.0 - jest-validate: 29.7.0 - micromatch: 4.0.8 - parse-json: 5.2.0 - pretty-format: 29.7.0 - slash: 3.0.0 - strip-json-comments: 3.1.1 - optionalDependencies: - '@types/node': 22.15.3 - ts-node: 10.9.2(@types/node@22.15.3)(typescript@5.8.3) - transitivePeerDependencies: - - babel-plugin-macros - - supports-color - - jest-diff@29.7.0: - dependencies: - chalk: 4.1.2 - diff-sequences: 29.6.3 - jest-get-type: 29.6.3 - pretty-format: 29.7.0 - - jest-docblock@29.7.0: - dependencies: - detect-newline: 3.1.0 - - jest-each@29.7.0: - dependencies: - '@jest/types': 29.6.3 - chalk: 4.1.2 - jest-get-type: 29.6.3 - jest-util: 29.7.0 - pretty-format: 29.7.0 - - jest-environment-node@29.7.0: - dependencies: - '@jest/environment': 29.7.0 - '@jest/fake-timers': 29.7.0 - '@jest/types': 29.6.3 - '@types/node': 22.15.3 - jest-mock: 29.7.0 - jest-util: 29.7.0 - - jest-get-type@29.6.3: {} - - jest-haste-map@29.7.0: - dependencies: - '@jest/types': 29.6.3 - '@types/graceful-fs': 4.1.9 - '@types/node': 22.15.3 - anymatch: 3.1.3 - fb-watchman: 2.0.2 - graceful-fs: 4.2.11 - jest-regex-util: 29.6.3 - jest-util: 29.7.0 - jest-worker: 29.7.0 - micromatch: 4.0.8 - walker: 1.0.8 - optionalDependencies: - fsevents: 2.3.3 - - jest-leak-detector@29.7.0: - dependencies: - jest-get-type: 29.6.3 - pretty-format: 29.7.0 - - jest-matcher-utils@29.7.0: - dependencies: - chalk: 4.1.2 - jest-diff: 29.7.0 - jest-get-type: 29.6.3 - pretty-format: 29.7.0 - - jest-message-util@29.7.0: - dependencies: - '@babel/code-frame': 7.27.1 - '@jest/types': 29.6.3 - '@types/stack-utils': 2.0.3 - chalk: 4.1.2 - graceful-fs: 4.2.11 - micromatch: 4.0.8 - pretty-format: 29.7.0 - slash: 3.0.0 - stack-utils: 2.0.6 - - jest-mock@29.7.0: - dependencies: - '@jest/types': 29.6.3 - '@types/node': 22.15.3 - jest-util: 29.7.0 - - jest-pnp-resolver@1.2.3(jest-resolve@29.7.0): - optionalDependencies: - jest-resolve: 29.7.0 - - jest-regex-util@29.6.3: {} - - jest-resolve-dependencies@29.7.0: - dependencies: - jest-regex-util: 29.6.3 - jest-snapshot: 29.7.0 - transitivePeerDependencies: - - supports-color - - jest-resolve@29.7.0: - dependencies: - chalk: 4.1.2 - graceful-fs: 4.2.11 - jest-haste-map: 29.7.0 - jest-pnp-resolver: 1.2.3(jest-resolve@29.7.0) - jest-util: 29.7.0 - jest-validate: 29.7.0 - resolve: 1.22.10 - resolve.exports: 2.0.3 - slash: 3.0.0 - - jest-runner@29.7.0: - dependencies: - '@jest/console': 29.7.0 - '@jest/environment': 29.7.0 - '@jest/test-result': 29.7.0 - '@jest/transform': 29.7.0 - '@jest/types': 29.6.3 - '@types/node': 22.15.3 - chalk: 4.1.2 - emittery: 0.13.1 - graceful-fs: 4.2.11 - jest-docblock: 29.7.0 - jest-environment-node: 29.7.0 - jest-haste-map: 29.7.0 - jest-leak-detector: 29.7.0 - jest-message-util: 29.7.0 - jest-resolve: 29.7.0 - jest-runtime: 29.7.0 - jest-util: 29.7.0 - jest-watcher: 29.7.0 - jest-worker: 29.7.0 - p-limit: 3.1.0 - source-map-support: 0.5.13 - transitivePeerDependencies: - - supports-color - - jest-runtime@29.7.0: - dependencies: - '@jest/environment': 29.7.0 - '@jest/fake-timers': 29.7.0 - '@jest/globals': 29.7.0 - '@jest/source-map': 29.6.3 - '@jest/test-result': 29.7.0 - '@jest/transform': 29.7.0 - '@jest/types': 29.6.3 - '@types/node': 22.15.3 - chalk: 4.1.2 - cjs-module-lexer: 1.4.3 - collect-v8-coverage: 1.0.2 - glob: 7.2.3 - graceful-fs: 4.2.11 - jest-haste-map: 29.7.0 - jest-message-util: 29.7.0 - jest-mock: 29.7.0 - jest-regex-util: 29.6.3 - jest-resolve: 29.7.0 - jest-snapshot: 29.7.0 - jest-util: 29.7.0 - slash: 3.0.0 - strip-bom: 4.0.0 - transitivePeerDependencies: - - supports-color - - jest-snapshot@29.7.0: - dependencies: - '@babel/core': 7.27.1 - '@babel/generator': 7.27.1 - '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.27.1) - '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.27.1) - '@babel/types': 7.27.1 - '@jest/expect-utils': 29.7.0 - '@jest/transform': 29.7.0 - '@jest/types': 29.6.3 - babel-preset-current-node-syntax: 1.1.0(@babel/core@7.27.1) - chalk: 4.1.2 - expect: 29.7.0 - graceful-fs: 4.2.11 - jest-diff: 29.7.0 - jest-get-type: 29.6.3 - jest-matcher-utils: 29.7.0 - jest-message-util: 29.7.0 - jest-util: 29.7.0 - natural-compare: 1.4.0 - pretty-format: 29.7.0 - semver: 7.7.1 - transitivePeerDependencies: - - supports-color - - jest-util@29.7.0: - dependencies: - '@jest/types': 29.6.3 - '@types/node': 22.15.3 - chalk: 4.1.2 - ci-info: 3.9.0 - graceful-fs: 4.2.11 - picomatch: 2.3.1 - - jest-validate@29.7.0: - dependencies: - '@jest/types': 29.6.3 - camelcase: 6.3.0 - chalk: 4.1.2 - jest-get-type: 29.6.3 - leven: 3.1.0 - pretty-format: 29.7.0 - - jest-watcher@29.7.0: - dependencies: - '@jest/test-result': 29.7.0 - '@jest/types': 29.6.3 - '@types/node': 22.15.3 - ansi-escapes: 4.3.2 - chalk: 4.1.2 - emittery: 0.13.1 - jest-util: 29.7.0 - string-length: 4.0.2 - - jest-worker@27.5.1: - dependencies: - '@types/node': 22.15.3 - merge-stream: 2.0.0 - supports-color: 8.1.1 - - jest-worker@29.7.0: - dependencies: - '@types/node': 22.15.3 - jest-util: 29.7.0 - merge-stream: 2.0.0 - supports-color: 8.1.1 - - jest@29.7.0(@types/node@22.15.3)(ts-node@10.9.2(@types/node@22.15.3)(typescript@5.8.3)): - dependencies: - '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@22.15.3)(typescript@5.8.3)) - '@jest/types': 29.6.3 - import-local: 3.2.0 - jest-cli: 29.7.0(@types/node@22.15.3)(ts-node@10.9.2(@types/node@22.15.3)(typescript@5.8.3)) - transitivePeerDependencies: - - '@types/node' - - babel-plugin-macros - - supports-color - - ts-node - - jiti@2.4.2: {} - - jose@4.15.9: {} - - js-tokens@4.0.0: {} - - js-yaml@3.14.1: - dependencies: - argparse: 1.0.10 - esprima: 4.0.1 - - js-yaml@4.1.0: - dependencies: - argparse: 2.0.1 - - jsesc@3.1.0: {} - - json-buffer@3.0.1: {} - - json-parse-even-better-errors@2.3.1: {} - - json-schema-traverse@0.4.1: {} - - json-schema-traverse@1.0.0: {} - - json-stable-stringify-without-jsonify@1.0.1: {} - - json5@2.2.3: {} - - jsonc-parser@3.2.1: {} - - jsonc-parser@3.3.1: {} - - jsonfile@6.1.0: - dependencies: - universalify: 2.0.1 - optionalDependencies: - graceful-fs: 4.2.11 - - keyv@4.5.4: - dependencies: - json-buffer: 3.0.1 - - kleur@3.0.3: {} - - lcid@1.0.0: - dependencies: - invert-kv: 1.0.0 - - leven@3.1.0: {} - - levn@0.4.1: - dependencies: - prelude-ls: 1.2.1 - type-check: 0.4.0 - - libphonenumber-js@1.12.7: {} - - lines-and-columns@1.2.4: {} - - loader-runner@4.3.0: {} - - locate-path@5.0.0: - dependencies: - p-locate: 4.1.0 - - locate-path@6.0.0: - dependencies: - p-locate: 5.0.0 - - lodash.camelcase@4.3.0: {} - - lodash.memoize@4.1.2: {} - - lodash.merge@4.6.2: {} - - lodash@4.17.21: {} - - log-symbols@4.1.0: - dependencies: - chalk: 4.1.2 - is-unicode-supported: 0.1.0 - - long@3.2.0: {} - - long@5.3.2: {} - - lru-cache@10.4.3: {} - - lru-cache@5.1.1: - dependencies: - yallist: 3.1.1 - - lru-cache@6.0.0: - dependencies: - yallist: 4.0.0 - - magic-string@0.30.8: - dependencies: - '@jridgewell/sourcemap-codec': 1.5.0 - - make-dir@3.1.0: - dependencies: - semver: 6.3.1 - - make-dir@4.0.0: - dependencies: - semver: 7.7.1 - - make-error@1.3.6: {} - - makeerror@1.0.12: - dependencies: - tmpl: 1.0.5 - - math-intrinsics@1.1.0: {} - - media-typer@0.3.0: {} - - memfs@3.5.3: - dependencies: - fs-monkey: 1.0.6 - - merge-descriptors@1.0.3: {} - - merge-stream@2.0.0: {} - - merge2@1.4.1: {} - - methods@1.1.2: {} - - micromatch@4.0.8: - dependencies: - braces: 3.0.3 - picomatch: 2.3.1 - - mime-db@1.52.0: {} - - mime-types@2.1.35: - dependencies: - mime-db: 1.52.0 - - mime@1.6.0: {} - - mime@2.6.0: {} - - mimic-fn@2.1.0: {} - - minimatch@3.1.2: - dependencies: - brace-expansion: 1.1.11 - - minimatch@5.1.6: - dependencies: - brace-expansion: 2.0.1 - - minimatch@9.0.3: - dependencies: - brace-expansion: 2.0.1 - - minimatch@9.0.5: - dependencies: - brace-expansion: 2.0.1 - - minimist@1.2.8: {} - - minipass@3.3.6: - dependencies: - yallist: 4.0.0 - - minipass@5.0.0: {} - - minipass@7.1.2: {} - - minizlib@2.1.2: - dependencies: - minipass: 3.3.6 - yallist: 4.0.0 - - mkdirp@0.5.6: - dependencies: - minimist: 1.2.8 - - mkdirp@1.0.4: {} - - ms@2.0.0: {} - - ms@2.1.3: {} - - multer@1.4.4-lts.1: - dependencies: - append-field: 1.0.0 - busboy: 1.6.0 - concat-stream: 1.6.2 - mkdirp: 0.5.6 - object-assign: 4.1.1 - type-is: 1.6.18 - xtend: 4.0.2 - - mute-stream@0.0.8: {} - - mute-stream@1.0.0: {} - - natural-compare@1.4.0: {} - - negotiator@0.6.3: {} - - neo-async@2.6.2: {} - - node-abort-controller@3.1.1: {} - - node-emoji@1.11.0: - dependencies: - lodash: 4.17.21 - - node-fetch@2.7.0: - dependencies: - whatwg-url: 5.0.0 - - node-int64@0.4.0: {} - - node-releases@2.0.19: {} - - nopt@5.0.0: - dependencies: - abbrev: 1.1.1 - - normalize-path@3.0.0: {} - - npm-run-path@4.0.1: - dependencies: - path-key: 3.1.1 - - npmlog@5.0.1: - dependencies: - are-we-there-yet: 2.0.0 - console-control-strings: 1.1.0 - gauge: 3.0.2 - set-blocking: 2.0.0 - - number-is-nan@1.0.1: {} - - object-assign@4.1.1: {} - - object-hash@2.2.0: {} - - object-inspect@1.13.4: {} - - oidc-token-hash@5.1.0: {} - - on-finished@2.4.1: - dependencies: - ee-first: 1.1.1 - - on-headers@1.0.2: {} - - once@1.4.0: - dependencies: - wrappy: 1.0.2 - - onetime@5.1.2: - dependencies: - mimic-fn: 2.1.0 - - openid-client@5.7.1: - dependencies: - jose: 4.15.9 - lru-cache: 6.0.0 - object-hash: 2.2.0 - oidc-token-hash: 5.1.0 - - optionator@0.9.4: - dependencies: - deep-is: 0.1.4 - fast-levenshtein: 2.0.6 - levn: 0.4.1 - prelude-ls: 1.2.1 - type-check: 0.4.0 - word-wrap: 1.2.5 - - optjs@3.2.2: {} - - ora@5.4.1: - dependencies: - bl: 4.1.0 - chalk: 4.1.2 - cli-cursor: 3.1.0 - cli-spinners: 2.9.2 - is-interactive: 1.0.0 - is-unicode-supported: 0.1.0 - log-symbols: 4.1.0 - strip-ansi: 6.0.1 - wcwidth: 1.0.1 - - os-locale@1.4.0: - dependencies: - lcid: 1.0.0 - - os-tmpdir@1.0.2: {} - - p-limit@2.3.0: - dependencies: - p-try: 2.2.0 - - p-limit@3.1.0: - dependencies: - yocto-queue: 0.1.0 - - p-locate@4.1.0: - dependencies: - p-limit: 2.3.0 - - p-locate@5.0.0: - dependencies: - p-limit: 3.1.0 - - p-try@2.2.0: {} - - package-json-from-dist@1.0.1: {} - - parent-module@1.0.1: - dependencies: - callsites: 3.1.0 - - parse-json@5.2.0: - dependencies: - '@babel/code-frame': 7.27.1 - error-ex: 1.3.2 - json-parse-even-better-errors: 2.3.1 - lines-and-columns: 1.2.4 - - parseurl@1.3.3: {} - - passport-strategy@1.0.0: {} - - passport@0.7.0: - dependencies: - passport-strategy: 1.0.0 - pause: 0.0.1 - utils-merge: 1.0.1 - - path-exists@4.0.0: {} - - path-is-absolute@1.0.1: {} - - path-key@3.1.1: {} - - path-parse@1.0.7: {} - - path-scurry@1.11.1: - dependencies: - lru-cache: 10.4.3 - minipass: 7.1.2 - - path-to-regexp@0.1.12: {} - - path-to-regexp@3.3.0: {} - - path-type@4.0.0: {} - - pause@0.0.1: {} - - peek-readable@7.0.0: {} - - picocolors@1.1.1: {} - - picomatch@2.3.1: {} - - picomatch@4.0.1: {} - - pirates@4.0.7: {} - - pkg-dir@4.2.0: - dependencies: - find-up: 4.1.0 - - pluralize@8.0.0: {} - - prelude-ls@1.2.1: {} - - prettier-linter-helpers@1.0.0: - dependencies: - fast-diff: 1.3.0 - - prettier@3.5.3: {} - - pretty-format@29.7.0: - dependencies: - '@jest/schemas': 29.6.3 - ansi-styles: 5.2.0 - react-is: 18.3.1 - - prisma@6.9.0(typescript@5.8.3): - dependencies: - '@prisma/config': 6.9.0 - '@prisma/engines': 6.9.0 - optionalDependencies: - typescript: 5.8.3 - - process-nextick-args@2.0.1: {} - - prompts@2.4.2: - dependencies: - kleur: 3.0.3 - sisteransi: 1.0.5 - - protobufjs@5.0.3: - dependencies: - ascli: 1.0.1 - bytebuffer: 5.0.1 - glob: 7.2.3 - yargs: 3.32.0 - - protobufjs@7.5.0: - dependencies: - '@protobufjs/aspromise': 1.1.2 - '@protobufjs/base64': 1.1.2 - '@protobufjs/codegen': 2.0.4 - '@protobufjs/eventemitter': 1.1.0 - '@protobufjs/fetch': 1.1.0 - '@protobufjs/float': 1.0.2 - '@protobufjs/inquire': 1.1.0 - '@protobufjs/path': 1.1.2 - '@protobufjs/pool': 1.1.0 - '@protobufjs/utf8': 1.1.0 - '@types/node': 22.15.3 - long: 5.3.2 - - proxy-addr@2.0.7: - dependencies: - forwarded: 0.2.0 - ipaddr.js: 1.9.1 - - punycode@2.3.1: {} - - pure-rand@6.1.0: {} - - qs@6.13.0: - dependencies: - side-channel: 1.1.0 - - qs@6.14.0: - dependencies: - side-channel: 1.1.0 - - queue-microtask@1.2.3: {} - - random-bytes@1.0.0: {} - - randombytes@2.1.0: - dependencies: - safe-buffer: 5.2.1 - - range-parser@1.2.1: {} - - raw-body@2.5.2: - dependencies: - bytes: 3.1.2 - http-errors: 2.0.0 - iconv-lite: 0.4.24 - unpipe: 1.0.0 - - react-is@18.3.1: {} - - readable-stream@2.3.8: - dependencies: - core-util-is: 1.0.3 - inherits: 2.0.4 - isarray: 1.0.0 - process-nextick-args: 2.0.1 - safe-buffer: 5.1.2 - string_decoder: 1.1.1 - util-deprecate: 1.0.2 - - readable-stream@3.6.2: - dependencies: - inherits: 2.0.4 - string_decoder: 1.3.0 - util-deprecate: 1.0.2 - - readdirp@3.6.0: - dependencies: - picomatch: 2.3.1 - - reflect-metadata@0.2.2: {} - - repeat-string@1.6.1: {} - - require-directory@2.1.1: {} - - require-from-string@2.0.2: {} - - resolve-cwd@3.0.0: - dependencies: - resolve-from: 5.0.0 - - resolve-from@4.0.0: {} - - resolve-from@5.0.0: {} - - resolve.exports@2.0.3: {} - - resolve@1.22.10: - dependencies: - is-core-module: 2.16.1 - path-parse: 1.0.7 - supports-preserve-symlinks-flag: 1.0.0 - - restore-cursor@3.1.0: - dependencies: - onetime: 5.1.2 - signal-exit: 3.0.7 - - reusify@1.1.0: {} - - rimraf@3.0.2: - dependencies: - glob: 7.2.3 - - run-async@2.4.1: {} - - run-async@3.0.0: {} - - run-parallel@1.2.0: - dependencies: - queue-microtask: 1.2.3 - - rxjs@7.8.1: - dependencies: - tslib: 2.8.1 - - rxjs@7.8.2: - dependencies: - tslib: 2.8.1 - - safe-buffer@5.1.2: {} - - safe-buffer@5.2.1: {} - - safer-buffer@2.1.2: {} - - schema-utils@3.3.0: - dependencies: - '@types/json-schema': 7.0.15 - ajv: 6.12.6 - ajv-keywords: 3.5.2(ajv@6.12.6) - - schema-utils@4.3.2: - dependencies: - '@types/json-schema': 7.0.15 - ajv: 8.17.1 - ajv-formats: 2.1.1(ajv@8.17.1) - ajv-keywords: 5.1.0(ajv@8.17.1) - - semver@6.3.1: {} - - semver@7.7.1: {} - - semver@7.7.2: {} - - send@0.19.0: - dependencies: - debug: 2.6.9 - depd: 2.0.0 - destroy: 1.2.0 - encodeurl: 1.0.2 - escape-html: 1.0.3 - etag: 1.8.1 - fresh: 0.5.2 - http-errors: 2.0.0 - mime: 1.6.0 - ms: 2.1.3 - on-finished: 2.4.1 - range-parser: 1.2.1 - statuses: 2.0.1 - transitivePeerDependencies: - - supports-color - - serialize-javascript@6.0.2: - dependencies: - randombytes: 2.1.0 - - serve-static@1.16.2: - dependencies: - encodeurl: 2.0.0 - escape-html: 1.0.3 - parseurl: 1.3.3 - send: 0.19.0 - transitivePeerDependencies: - - supports-color - - set-blocking@2.0.0: {} - - set-function-length@1.2.2: - dependencies: - define-data-property: 1.1.4 - es-errors: 1.3.0 - function-bind: 1.1.2 - get-intrinsic: 1.3.0 - gopd: 1.2.0 - has-property-descriptors: 1.0.2 - - setprototypeof@1.2.0: {} - - shebang-command@2.0.0: - dependencies: - shebang-regex: 3.0.0 - - shebang-regex@3.0.0: {} - - side-channel-list@1.0.0: - dependencies: - es-errors: 1.3.0 - object-inspect: 1.13.4 - - side-channel-map@1.0.1: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - get-intrinsic: 1.3.0 - object-inspect: 1.13.4 - - side-channel-weakmap@1.0.2: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - get-intrinsic: 1.3.0 - object-inspect: 1.13.4 - side-channel-map: 1.0.1 - - side-channel@1.1.0: - dependencies: - es-errors: 1.3.0 - object-inspect: 1.13.4 - side-channel-list: 1.0.0 - side-channel-map: 1.0.1 - side-channel-weakmap: 1.0.2 - - signal-exit@3.0.7: {} - - signal-exit@4.1.0: {} - - sisteransi@1.0.5: {} - - slash@3.0.0: {} - - source-map-support@0.5.13: - dependencies: - buffer-from: 1.1.2 - source-map: 0.6.1 - - source-map-support@0.5.21: - dependencies: - buffer-from: 1.1.2 - source-map: 0.6.1 - - source-map@0.6.1: {} - - source-map@0.7.4: {} - - sprintf-js@1.0.3: {} - - stack-utils@2.0.6: - dependencies: - escape-string-regexp: 2.0.0 - - statuses@2.0.1: {} - - streamsearch@1.1.0: {} - - string-length@4.0.2: - dependencies: - char-regex: 1.0.2 - strip-ansi: 6.0.1 - - string-width@1.0.2: - dependencies: - code-point-at: 1.1.0 - is-fullwidth-code-point: 1.0.0 - strip-ansi: 3.0.1 - - string-width@4.2.3: - dependencies: - emoji-regex: 8.0.0 - is-fullwidth-code-point: 3.0.0 - strip-ansi: 6.0.1 - - string-width@5.1.2: - dependencies: - eastasianwidth: 0.2.0 - emoji-regex: 9.2.2 - strip-ansi: 7.1.0 - - string_decoder@1.1.1: - dependencies: - safe-buffer: 5.1.2 - - string_decoder@1.3.0: - dependencies: - safe-buffer: 5.2.1 - - strip-ansi@3.0.1: - dependencies: - ansi-regex: 2.1.1 - - strip-ansi@6.0.1: - dependencies: - ansi-regex: 5.0.1 - - strip-ansi@7.1.0: - dependencies: - ansi-regex: 6.1.0 - - strip-bom@3.0.0: {} - - strip-bom@4.0.0: {} - - strip-final-newline@2.0.0: {} - - strip-json-comments@3.1.1: {} - - strtok3@10.2.2: - dependencies: - '@tokenizer/token': 0.3.0 - peek-readable: 7.0.0 - - superagent@8.1.2: - dependencies: - component-emitter: 1.3.1 - cookiejar: 2.1.4 - debug: 4.4.0 - fast-safe-stringify: 2.1.1 - form-data: 4.0.2 - formidable: 2.1.5 - methods: 1.1.2 - mime: 2.6.0 - qs: 6.14.0 - semver: 7.7.1 - transitivePeerDependencies: - - supports-color - - supertest@6.3.4: - dependencies: - methods: 1.1.2 - superagent: 8.1.2 - transitivePeerDependencies: - - supports-color - - supports-color@7.2.0: - dependencies: - has-flag: 4.0.0 - - supports-color@8.1.1: - dependencies: - has-flag: 4.0.0 - - supports-preserve-symlinks-flag@1.0.0: {} - - swagger-ui-dist@5.17.14: {} - - symbol-observable@4.0.0: {} - - synckit@0.11.8: - dependencies: - '@pkgr/core': 0.2.4 - - tapable@2.2.1: {} - - tar@6.2.1: - dependencies: - chownr: 2.0.0 - fs-minipass: 2.1.0 - minipass: 5.0.0 - minizlib: 2.1.2 - mkdirp: 1.0.4 - yallist: 4.0.0 - - terser-webpack-plugin@5.3.14(webpack@5.97.1): - dependencies: - '@jridgewell/trace-mapping': 0.3.25 - jest-worker: 27.5.1 - schema-utils: 4.3.2 - serialize-javascript: 6.0.2 - terser: 5.39.0 - webpack: 5.97.1 - - terser@5.39.0: - dependencies: - '@jridgewell/source-map': 0.3.6 - acorn: 8.14.1 - commander: 2.20.3 - source-map-support: 0.5.21 - - test-exclude@6.0.0: - dependencies: - '@istanbuljs/schema': 0.1.3 - glob: 7.2.3 - minimatch: 3.1.2 - - text-table@0.2.0: {} - - through@2.3.8: {} - - tmp@0.0.33: - dependencies: - os-tmpdir: 1.0.2 - - tmpl@1.0.5: {} - - to-regex-range@5.0.1: - dependencies: - is-number: 7.0.0 - - toidentifier@1.0.1: {} - - token-types@6.0.0: - dependencies: - '@tokenizer/token': 0.3.0 - ieee754: 1.2.1 - - tr46@0.0.3: {} - - tree-kill@1.2.2: {} - - ts-api-utils@1.4.3(typescript@5.8.3): - dependencies: - typescript: 5.8.3 - - ts-dedent@2.2.0: {} - - ts-jest@29.3.4(@babel/core@7.27.1)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.27.1))(jest@29.7.0(@types/node@22.15.3)(ts-node@10.9.2(@types/node@22.15.3)(typescript@5.8.3)))(typescript@5.8.3): - dependencies: - bs-logger: 0.2.6 - ejs: 3.1.10 - fast-json-stable-stringify: 2.1.0 - jest: 29.7.0(@types/node@22.15.3)(ts-node@10.9.2(@types/node@22.15.3)(typescript@5.8.3)) - jest-util: 29.7.0 - json5: 2.2.3 - lodash.memoize: 4.1.2 - make-error: 1.3.6 - semver: 7.7.2 - type-fest: 4.41.0 - typescript: 5.8.3 - yargs-parser: 21.1.1 - optionalDependencies: - '@babel/core': 7.27.1 - '@jest/transform': 29.7.0 - '@jest/types': 29.6.3 - babel-jest: 29.7.0(@babel/core@7.27.1) - - ts-loader@9.5.2(typescript@5.8.3)(webpack@5.97.1): - dependencies: - chalk: 4.1.2 - enhanced-resolve: 5.18.1 - micromatch: 4.0.8 - semver: 7.7.1 - source-map: 0.7.4 - typescript: 5.8.3 - webpack: 5.97.1 - - ts-node@10.9.2(@types/node@22.15.3)(typescript@5.8.3): - dependencies: - '@cspotcode/source-map-support': 0.8.1 - '@tsconfig/node10': 1.0.11 - '@tsconfig/node12': 1.0.11 - '@tsconfig/node14': 1.0.3 - '@tsconfig/node16': 1.0.4 - '@types/node': 22.15.3 - acorn: 8.14.1 - acorn-walk: 8.3.4 - arg: 4.1.3 - create-require: 1.1.1 - diff: 4.0.2 - make-error: 1.3.6 - typescript: 5.8.3 - v8-compile-cache-lib: 3.0.1 - yn: 3.1.1 - - ts-protoc-gen@0.15.0: - dependencies: - google-protobuf: 3.21.4 - - tsconfig-paths-webpack-plugin@4.2.0: - dependencies: - chalk: 4.1.2 - enhanced-resolve: 5.18.1 - tapable: 2.2.1 - tsconfig-paths: 4.2.0 - - tsconfig-paths@4.2.0: - dependencies: - json5: 2.2.3 - minimist: 1.2.8 - strip-bom: 3.0.0 - - tslib@2.8.1: {} - - type-check@0.4.0: - dependencies: - prelude-ls: 1.2.1 - - type-detect@4.0.8: {} - - type-fest@0.20.2: {} - - type-fest@0.21.3: {} - - type-fest@2.19.0: {} - - type-fest@4.41.0: {} - - type-is@1.6.18: - dependencies: - media-typer: 0.3.0 - mime-types: 2.1.35 - - typedarray@0.0.6: {} - - typescript@5.7.2: {} - - typescript@5.8.3: {} - - uglify-js@3.19.3: - optional: true - - uid-safe@2.1.5: - dependencies: - random-bytes: 1.0.0 - - uid@2.0.2: - dependencies: - '@lukeed/csprng': 1.1.0 - - uint8array-extras@1.4.0: {} - - undici-types@6.21.0: {} - - universalify@2.0.1: {} - - unpipe@1.0.0: {} - - update-browserslist-db@1.1.3(browserslist@4.24.4): - dependencies: - browserslist: 4.24.4 - escalade: 3.2.0 - picocolors: 1.1.1 - - uri-js@4.4.1: - dependencies: - punycode: 2.3.1 - - util-deprecate@1.0.2: {} - - utils-merge@1.0.1: {} - - uuid@9.0.1: {} - - v8-compile-cache-lib@3.0.1: {} - - v8-to-istanbul@9.3.0: - dependencies: - '@jridgewell/trace-mapping': 0.3.25 - '@types/istanbul-lib-coverage': 2.0.6 - convert-source-map: 2.0.0 - - validator@13.15.0: {} - - vary@1.1.2: {} - - walker@1.0.8: - dependencies: - makeerror: 1.0.12 - - watchpack@2.4.2: - dependencies: - glob-to-regexp: 0.4.1 - graceful-fs: 4.2.11 - - wcwidth@1.0.1: - dependencies: - defaults: 1.0.4 - - webidl-conversions@3.0.1: {} - - webpack-node-externals@3.0.0: {} - - webpack-sources@3.2.3: {} - - webpack@5.97.1: - dependencies: - '@types/eslint-scope': 3.7.7 - '@types/estree': 1.0.7 - '@webassemblyjs/ast': 1.14.1 - '@webassemblyjs/wasm-edit': 1.14.1 - '@webassemblyjs/wasm-parser': 1.14.1 - acorn: 8.14.1 - browserslist: 4.24.4 - chrome-trace-event: 1.0.4 - enhanced-resolve: 5.18.1 - es-module-lexer: 1.7.0 - eslint-scope: 5.1.1 - events: 3.3.0 - glob-to-regexp: 0.4.1 - graceful-fs: 4.2.11 - json-parse-even-better-errors: 2.3.1 - loader-runner: 4.3.0 - mime-types: 2.1.35 - neo-async: 2.6.2 - schema-utils: 3.3.0 - tapable: 2.2.1 - terser-webpack-plugin: 5.3.14(webpack@5.97.1) - watchpack: 2.4.2 - webpack-sources: 3.2.3 - transitivePeerDependencies: - - '@swc/core' - - esbuild - - uglify-js - - whatwg-url@5.0.0: - dependencies: - tr46: 0.0.3 - webidl-conversions: 3.0.1 - - which@2.0.2: - dependencies: - isexe: 2.0.0 - - wide-align@1.1.5: - dependencies: - string-width: 4.2.3 - - window-size@0.1.4: {} - - word-wrap@1.2.5: {} - - wordwrap@1.0.0: {} - - wrap-ansi@2.1.0: - dependencies: - string-width: 1.0.2 - strip-ansi: 3.0.1 - - wrap-ansi@6.2.0: - dependencies: - ansi-styles: 4.3.0 - string-width: 4.2.3 - strip-ansi: 6.0.1 - - wrap-ansi@7.0.0: - dependencies: - ansi-styles: 4.3.0 - string-width: 4.2.3 - strip-ansi: 6.0.1 - - wrap-ansi@8.1.0: - dependencies: - ansi-styles: 6.2.1 - string-width: 5.1.2 - strip-ansi: 7.1.0 - - wrappy@1.0.2: {} - - write-file-atomic@4.0.2: - dependencies: - imurmurhash: 0.1.4 - signal-exit: 3.0.7 - - xtend@4.0.2: {} - - y18n@3.2.2: {} - - y18n@5.0.8: {} - - yallist@3.1.1: {} - - yallist@4.0.0: {} - - yargs-parser@21.1.1: {} - - yargs@17.7.2: - dependencies: - cliui: 8.0.1 - escalade: 3.2.0 - get-caller-file: 2.0.5 - require-directory: 2.1.1 - string-width: 4.2.3 - y18n: 5.0.8 - yargs-parser: 21.1.1 - - yargs@3.32.0: - dependencies: - camelcase: 2.1.1 - cliui: 3.2.0 - decamelize: 1.2.0 - os-locale: 1.4.0 - string-width: 1.0.2 - window-size: 0.1.4 - y18n: 3.2.2 - - yn@3.1.1: {} - - yocto-queue@0.1.0: {} diff --git a/server/pnpm-workspace.yaml b/server/pnpm-workspace.yaml deleted file mode 100644 index afe6bcbda..000000000 --- a/server/pnpm-workspace.yaml +++ /dev/null @@ -1,8 +0,0 @@ -onlyBuiltDependencies: - - '@nestjs/core' - - '@prisma/client' - - '@prisma/engines' - - esbuild - - grpc-tools - - prisma - - protobufjs diff --git a/server/prisma/migrations/20240713012659_init/migration.sql b/server/prisma/migrations/20240713012659_init/migration.sql deleted file mode 100644 index caa7387b4..000000000 --- a/server/prisma/migrations/20240713012659_init/migration.sql +++ /dev/null @@ -1,220 +0,0 @@ --- CreateEnum -CREATE TYPE "group_visibility" AS ENUM ('PUBLIC', 'PRIVATE'); - --- CreateEnum -CREATE TYPE "ClassType" AS ENUM ('LECTURE', 'TUTORIAL', 'LAORATORY', 'OTHER'); - --- CreateTable -CREATE TABLE "users" ( - "userID" TEXT NOT NULL, - "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, - "lastLogin" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP, - "firstname" TEXT, - "lastname" TEXT, - "email" TEXT NOT NULL, - "profileURL" TEXT, - - CONSTRAINT "users_pkey" PRIMARY KEY ("userID") -); - --- CreateTable -CREATE TABLE "groups" ( - "id" TEXT NOT NULL, - "name" TEXT NOT NULL, - "description" TEXT, - "imageURL" TEXT, - "visibility" "group_visibility" NOT NULL DEFAULT 'PRIVATE', - - CONSTRAINT "groups_pkey" PRIMARY KEY ("id") -); - --- CreateTable -CREATE TABLE "events" ( - "id" TEXT NOT NULL, - "name" TEXT NOT NULL, - "location" TEXT, - "description" TEXT, - "colour" TEXT NOT NULL DEFAULT '#1F7E8C', - "day" TEXT NOT NULL, - "start" TIMESTAMP(3) NOT NULL, - "end" TIMESTAMP(3) NOT NULL, - "timetableId" TEXT, - "groupIds" TEXT[], - - CONSTRAINT "events_pkey" PRIMARY KEY ("id") -); - --- CreateTable -CREATE TABLE "classes" ( - "id" TEXT NOT NULL, - "classType" "ClassType" NOT NULL, - "courseName" TEXT, - "timetableId" TEXT -); - --- CreateTable -CREATE TABLE "timetables" ( - "id" TEXT NOT NULL, - "name" TEXT NOT NULL, - "selectedCourses" TEXT[], - "userID" TEXT NOT NULL, - - CONSTRAINT "timetables_pkey" PRIMARY KEY ("id") -); - --- CreateTable -CREATE TABLE "settings" ( - "userID" TEXT NOT NULL, - "is12HourMode" BOOLEAN NOT NULL, - "isDarkMode" BOOLEAN NOT NULL, - "isSquareEdges" BOOLEAN NOT NULL, - "isHideFullClasses" BOOLEAN NOT NULL, - "isDefaultUnscheduled" BOOLEAN NOT NULL, - "isHideClassInfo" BOOLEAN NOT NULL, - "isSortAlphabetic" BOOLEAN NOT NULL, - "isShowOnlyOpenClasses" BOOLEAN NOT NULL, - "isHideExamClasses" BOOLEAN NOT NULL, - "isConvertToLocalTimezone" BOOLEAN NOT NULL -); - --- CreateTable -CREATE TABLE "sessions" ( - "id" TEXT NOT NULL, - "sid" TEXT NOT NULL, - "data" TEXT NOT NULL, - "expiresAt" TIMESTAMP(3) NOT NULL, - - CONSTRAINT "sessions_pkey" PRIMARY KEY ("id") -); - --- CreateTable -CREATE TABLE "_user_friends" ( - "A" TEXT NOT NULL, - "B" TEXT NOT NULL -); - --- CreateTable -CREATE TABLE "_friend_requests" ( - "A" TEXT NOT NULL, - "B" TEXT NOT NULL -); - --- CreateTable -CREATE TABLE "_group_timetables" ( - "A" TEXT NOT NULL, - "B" TEXT NOT NULL -); - --- CreateTable -CREATE TABLE "_group_members" ( - "A" TEXT NOT NULL, - "B" TEXT NOT NULL -); - --- CreateTable -CREATE TABLE "_admins" ( - "A" TEXT NOT NULL, - "B" TEXT NOT NULL -); - --- CreateTable -CREATE TABLE "_TimetableToUser" ( - "A" TEXT NOT NULL, - "B" TEXT NOT NULL -); - --- CreateIndex -CREATE INDEX "users_userID_idx" ON "users"("userID"); - --- CreateIndex -CREATE UNIQUE INDEX "classes_id_key" ON "classes"("id"); - --- CreateIndex -CREATE UNIQUE INDEX "timetables_id_key" ON "timetables"("id"); - --- CreateIndex -CREATE UNIQUE INDEX "settings_userID_key" ON "settings"("userID"); - --- CreateIndex -CREATE UNIQUE INDEX "sessions_sid_key" ON "sessions"("sid"); - --- CreateIndex -CREATE UNIQUE INDEX "_user_friends_AB_unique" ON "_user_friends"("A", "B"); - --- CreateIndex -CREATE INDEX "_user_friends_B_index" ON "_user_friends"("B"); - --- CreateIndex -CREATE UNIQUE INDEX "_friend_requests_AB_unique" ON "_friend_requests"("A", "B"); - --- CreateIndex -CREATE INDEX "_friend_requests_B_index" ON "_friend_requests"("B"); - --- CreateIndex -CREATE UNIQUE INDEX "_group_timetables_AB_unique" ON "_group_timetables"("A", "B"); - --- CreateIndex -CREATE INDEX "_group_timetables_B_index" ON "_group_timetables"("B"); - --- CreateIndex -CREATE UNIQUE INDEX "_group_members_AB_unique" ON "_group_members"("A", "B"); - --- CreateIndex -CREATE INDEX "_group_members_B_index" ON "_group_members"("B"); - --- CreateIndex -CREATE UNIQUE INDEX "_admins_AB_unique" ON "_admins"("A", "B"); - --- CreateIndex -CREATE INDEX "_admins_B_index" ON "_admins"("B"); - --- CreateIndex -CREATE UNIQUE INDEX "_TimetableToUser_AB_unique" ON "_TimetableToUser"("A", "B"); - --- CreateIndex -CREATE INDEX "_TimetableToUser_B_index" ON "_TimetableToUser"("B"); - --- AddForeignKey -ALTER TABLE "events" ADD CONSTRAINT "events_timetableId_fkey" FOREIGN KEY ("timetableId") REFERENCES "timetables"("id") ON DELETE CASCADE ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "classes" ADD CONSTRAINT "classes_timetableId_fkey" FOREIGN KEY ("timetableId") REFERENCES "timetables"("id") ON DELETE CASCADE ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "settings" ADD CONSTRAINT "settings_userID_fkey" FOREIGN KEY ("userID") REFERENCES "users"("userID") ON DELETE RESTRICT ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "_user_friends" ADD CONSTRAINT "_user_friends_A_fkey" FOREIGN KEY ("A") REFERENCES "users"("userID") ON DELETE CASCADE ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "_user_friends" ADD CONSTRAINT "_user_friends_B_fkey" FOREIGN KEY ("B") REFERENCES "users"("userID") ON DELETE CASCADE ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "_friend_requests" ADD CONSTRAINT "_friend_requests_A_fkey" FOREIGN KEY ("A") REFERENCES "users"("userID") ON DELETE CASCADE ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "_friend_requests" ADD CONSTRAINT "_friend_requests_B_fkey" FOREIGN KEY ("B") REFERENCES "users"("userID") ON DELETE CASCADE ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "_group_timetables" ADD CONSTRAINT "_group_timetables_A_fkey" FOREIGN KEY ("A") REFERENCES "groups"("id") ON DELETE CASCADE ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "_group_timetables" ADD CONSTRAINT "_group_timetables_B_fkey" FOREIGN KEY ("B") REFERENCES "timetables"("id") ON DELETE CASCADE ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "_group_members" ADD CONSTRAINT "_group_members_A_fkey" FOREIGN KEY ("A") REFERENCES "groups"("id") ON DELETE CASCADE ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "_group_members" ADD CONSTRAINT "_group_members_B_fkey" FOREIGN KEY ("B") REFERENCES "users"("userID") ON DELETE CASCADE ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "_admins" ADD CONSTRAINT "_admins_A_fkey" FOREIGN KEY ("A") REFERENCES "groups"("id") ON DELETE CASCADE ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "_admins" ADD CONSTRAINT "_admins_B_fkey" FOREIGN KEY ("B") REFERENCES "users"("userID") ON DELETE CASCADE ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "_TimetableToUser" ADD CONSTRAINT "_TimetableToUser_A_fkey" FOREIGN KEY ("A") REFERENCES "timetables"("id") ON DELETE CASCADE ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "_TimetableToUser" ADD CONSTRAINT "_TimetableToUser_B_fkey" FOREIGN KEY ("B") REFERENCES "users"("userID") ON DELETE CASCADE ON UPDATE CASCADE; \ No newline at end of file diff --git a/server/prisma/migrations/20241003042905_/migration.sql b/server/prisma/migrations/20241003042905_/migration.sql deleted file mode 100644 index 4c9b2fbac..000000000 --- a/server/prisma/migrations/20241003042905_/migration.sql +++ /dev/null @@ -1,40 +0,0 @@ -/* - Warnings: - - - You are about to drop the column `classType` on the `classes` table. All the data in the column will be lost. - - You are about to drop the column `courseName` on the `classes` table. All the data in the column will be lost. - - You are about to drop the column `userID` on the `timetables` table. All the data in the column will be lost. - - Added the required column `classNo` to the `classes` table without a default value. This is not possible if the table is not empty. - - Added the required column `courseCode` to the `classes` table without a default value. This is not possible if the table is not empty. - - Added the required column `term` to the `classes` table without a default value. This is not possible if the table is not empty. - - Added the required column `year` to the `classes` table without a default value. This is not possible if the table is not empty. - - Added the required column `subtype` to the `events` table without a default value. This is not possible if the table is not empty. - - Changed the type of `day` on the `events` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required. - - Changed the type of `start` on the `events` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required. - - Changed the type of `end` on the `events` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required. - - Added the required column `mapKey` to the `timetables` table without a default value. This is not possible if the table is not empty. - -*/ --- AlterTable -ALTER TABLE "classes" DROP COLUMN "classType", -DROP COLUMN "courseName", -ADD COLUMN "classNo" TEXT NOT NULL, -ADD COLUMN "courseCode" TEXT NOT NULL, -ADD COLUMN "term" TEXT NOT NULL, -ADD COLUMN "year" TEXT NOT NULL; - --- AlterTable -ALTER TABLE "events" ADD COLUMN "subtype" TEXT NOT NULL, -DROP COLUMN "day", -ADD COLUMN "day" INTEGER NOT NULL, -DROP COLUMN "start", -ADD COLUMN "start" INTEGER NOT NULL, -DROP COLUMN "end", -ADD COLUMN "end" INTEGER NOT NULL; - --- AlterTable -ALTER TABLE "timetables" DROP COLUMN "userID", -ADD COLUMN "mapKey" TEXT NOT NULL; - --- DropEnum -DROP TYPE "ClassType"; diff --git a/server/prisma/migrations/20241101072349_activity/migration.sql b/server/prisma/migrations/20241101072349_activity/migration.sql deleted file mode 100644 index b85d4f6d3..000000000 --- a/server/prisma/migrations/20241101072349_activity/migration.sql +++ /dev/null @@ -1,8 +0,0 @@ -/* - Warnings: - - - Added the required column `activity` to the `classes` table without a default value. This is not possible if the table is not empty. - -*/ --- AlterTable -ALTER TABLE "classes" ADD COLUMN "activity" TEXT NOT NULL; diff --git a/server/prisma/migrations/20250322064905_upgrade_to_v6/migration.sql b/server/prisma/migrations/20250322064905_upgrade_to_v6/migration.sql deleted file mode 100644 index 5240dac0b..000000000 --- a/server/prisma/migrations/20250322064905_upgrade_to_v6/migration.sql +++ /dev/null @@ -1,35 +0,0 @@ --- AlterTable -ALTER TABLE "_TimetableToUser" ADD CONSTRAINT "_TimetableToUser_AB_pkey" PRIMARY KEY ("A", "B"); - --- DropIndex -DROP INDEX "_TimetableToUser_AB_unique"; - --- AlterTable -ALTER TABLE "_admins" ADD CONSTRAINT "_admins_AB_pkey" PRIMARY KEY ("A", "B"); - --- DropIndex -DROP INDEX "_admins_AB_unique"; - --- AlterTable -ALTER TABLE "_friend_requests" ADD CONSTRAINT "_friend_requests_AB_pkey" PRIMARY KEY ("A", "B"); - --- DropIndex -DROP INDEX "_friend_requests_AB_unique"; - --- AlterTable -ALTER TABLE "_group_members" ADD CONSTRAINT "_group_members_AB_pkey" PRIMARY KEY ("A", "B"); - --- DropIndex -DROP INDEX "_group_members_AB_unique"; - --- AlterTable -ALTER TABLE "_group_timetables" ADD CONSTRAINT "_group_timetables_AB_pkey" PRIMARY KEY ("A", "B"); - --- DropIndex -DROP INDEX "_group_timetables_AB_unique"; - --- AlterTable -ALTER TABLE "_user_friends" ADD CONSTRAINT "_user_friends_AB_pkey" PRIMARY KEY ("A", "B"); - --- DropIndex -DROP INDEX "_user_friends_AB_unique"; diff --git a/server/prisma/migrations/20250414034722_add_courseid_to_class/migration.sql b/server/prisma/migrations/20250414034722_add_courseid_to_class/migration.sql deleted file mode 100644 index a7e60c24e..000000000 --- a/server/prisma/migrations/20250414034722_add_courseid_to_class/migration.sql +++ /dev/null @@ -1,2 +0,0 @@ --- AlterTable -ALTER TABLE "classes" ADD COLUMN "courseId" TEXT; diff --git a/server/prisma/migrations/20250424101523_fill_course_id/migration.sql b/server/prisma/migrations/20250424101523_fill_course_id/migration.sql deleted file mode 100644 index 2e1b3e77f..000000000 --- a/server/prisma/migrations/20250424101523_fill_course_id/migration.sql +++ /dev/null @@ -1,4 +0,0 @@ --- classNo is currently a string such as COMP6420Undergraduate-11965-T1-2025 --- courseId should be a string such as COMP6420Undergraduate -UPDATE "classes" -SET "courseId" = split_part("classNo", '-', 1); diff --git a/server/prisma/migrations/20250424102004_require_course_id/migration.sql b/server/prisma/migrations/20250424102004_require_course_id/migration.sql deleted file mode 100644 index 6737de306..000000000 --- a/server/prisma/migrations/20250424102004_require_course_id/migration.sql +++ /dev/null @@ -1,8 +0,0 @@ -/* - Warnings: - - - Made the column `courseId` on table `classes` required. This step will fail if there are existing NULL values in that column. - -*/ --- AlterTable -ALTER TABLE "classes" ALTER COLUMN "courseId" SET NOT NULL; diff --git a/server/prisma/migrations/20250529041455_primary_timetable/migration.sql b/server/prisma/migrations/20250529041455_primary_timetable/migration.sql deleted file mode 100644 index 29adde5e7..000000000 --- a/server/prisma/migrations/20250529041455_primary_timetable/migration.sql +++ /dev/null @@ -1,2 +0,0 @@ --- AlterTable -ALTER TABLE "timetables" ADD COLUMN "isPrimary" BOOLEAN NOT NULL DEFAULT false; diff --git a/server/prisma/migrations/20250605081924_update_color_config/migration.sql b/server/prisma/migrations/20250605081924_update_color_config/migration.sql deleted file mode 100644 index 355adfe88..000000000 --- a/server/prisma/migrations/20250605081924_update_color_config/migration.sql +++ /dev/null @@ -1,15 +0,0 @@ --- Update the colour column in the events table based on the MIGRATE_COLOR_MAP - -UPDATE "events" -SET "colour" = CASE - WHEN "colour" = '#137786' THEN 'default-1' - WHEN "colour" = '#a843a4' THEN 'default-2' - WHEN "colour" = '#134e86' THEN 'default-3' - WHEN "colour" = '#138652' THEN 'default-4' - WHEN "colour" = '#861313' THEN 'default-5' - WHEN "colour" = '#868413' THEN 'default-6' - WHEN "colour" = '#2e89ff' THEN 'default-7' - WHEN "colour" = '#3323ad' THEN 'default-8' - ELSE "colour" -END -WHERE "colour" IN ('#137786', '#a843a4', '#134e86', '#138652', '#861313', '#868413', '#2e89ff', '#3323ad'); diff --git a/server/prisma/migrations/migration_lock.toml b/server/prisma/migrations/migration_lock.toml deleted file mode 100644 index 044d57cdb..000000000 --- a/server/prisma/migrations/migration_lock.toml +++ /dev/null @@ -1,3 +0,0 @@ -# Please do not edit this file manually -# It should be added in your version-control system (e.g., Git) -provider = "postgresql" diff --git a/server/prisma/schema.prisma b/server/prisma/schema.prisma deleted file mode 100644 index ca598e058..000000000 --- a/server/prisma/schema.prisma +++ /dev/null @@ -1,127 +0,0 @@ -generator client { - provider = "prisma-client-js" -} - -datasource db { - provider = "postgresql" - url = env("DATABASE_URL") -} - -model User { - userID String @id // same as zid - createdAt DateTime @default(now()) - lastLogin DateTime? @default(now()) - firstname String? - lastname String? - email String - profileURL String? - timetables Timetable[] - settings Settings? - friends User[] @relation(name: "user_friends") - friendOf User[] @relation(name: "user_friends") - outgoing User[] @relation(name: "friend_requests") - incoming User[] @relation(name: "friend_requests") - adminGroups Group[] @relation(name: "admins") - memberGroups Group[] @relation(name: "group_members") - - @@index([userID]) - @@map("users") -} - -model Group { - id String @id @default(uuid()) - name String - description String? - imageURL String? - visibility GroupVisibility @default(PRIVATE) - timetables Timetable[] @relation("group_timetables") - members User[] @relation("group_members") - groupAdmins User[] @relation("admins") - - @@map("groups") -} - -model Event { - id String @id @default(uuid()) - name String - location String? - description String? - colour String @default("#1F7E8C") // Notangles Blue - - // Event Time - // TODO: revert this change after custom event dates are added - day Int - start Int - end Int - subtype String - // day String - // start DateTime - // end DateTime - - timetable Timetable? @relation(fields: [timetableId], references: [id], onDelete: Cascade) // TODO: was there a reason this wasn't cascaded on delete? - timetableId String? - groupIds String[] // Added to link an event to a group - - @@map("events") -} - -model Class { - id String @unique - classNo String // From scraper (not unique in db, but between classes) - term String - year String - courseCode String - courseId String - Timetable Timetable? @relation(fields: [timetableId], references: [id], onDelete: Cascade) - timetableId String? - activity String - - @@map("classes") -} - -model Timetable { - id String @id @unique @default(uuid()) - name String - isPrimary Boolean @default(false) - selectedCourses String[] - selectedClasses Class[] - createdEvents Event[] - user User[] - groups Group[] @relation("group_timetables") - mapKey String // Key for timetable map - - @@map("timetables") -} - -model Settings { - userID String @unique - user User @relation(fields: [userID], references: [userID]) - is12HourMode Boolean - isDarkMode Boolean - isSquareEdges Boolean - isHideFullClasses Boolean - isDefaultUnscheduled Boolean - isHideClassInfo Boolean - isSortAlphabetic Boolean - isShowOnlyOpenClasses Boolean - isHideExamClasses Boolean - isConvertToLocalTimezone Boolean - - @@map("settings") -} - -model Session { - id String @id - sid String @unique - data String @db.Text // MediumText may be needed for MySql - expiresAt DateTime - - @@map("sessions") -} - -enum GroupVisibility { - PUBLIC - PRIVATE - - @@map("group_visibility") -} diff --git a/server/proto-gen.sh b/server/proto-gen.sh deleted file mode 100755 index 747e96bdc..000000000 --- a/server/proto-gen.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/bash - -PROTO_DEST=./src/proto - -FINAL_TS=$PROTO_DEST/autotimetabler_grpc_pb.d.ts -FINAL_JS=$PROTO_DEST/autotimetabler_grpc_pb.js - -npx grpc_tools_node_protoc --js_out=import_style=commonjs,binary:./src/proto --grpc_out=./src/proto -I ./ ./autotimetabler.proto -npx grpc_tools_node_protoc --plugin=protoc-gen-ts=./node_modules/.bin/protoc-gen-ts --ts_out=./src/proto -I ./ ./autotimetabler.proto - -sed -i -r 's/(import.*")grpc/\1@grpc\/grpc-js/' $FINAL_TS # replaces grpc import with @grpc/grpc-js -sed -i -r 's/(require.*'')grpc/\1@grpc\/grpc-js/' $FINAL_JS # replaces grpc import with @grpc/grpc-js - -python3 -m grpc_tools.protoc -I./ --python_out=../auto_server --grpc_python_out=../auto_server ./autotimetabler.proto \ No newline at end of file diff --git a/server/src/app.controller.ts b/server/src/app.controller.ts deleted file mode 100644 index c73d6d8de..000000000 --- a/server/src/app.controller.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { Controller } from '@nestjs/common'; -import { AppService } from './app.service'; - -@Controller() -export class AppController { - constructor(private readonly appService: AppService) {} -} diff --git a/server/src/app.module.ts b/server/src/app.module.ts deleted file mode 100644 index e56e37e59..000000000 --- a/server/src/app.module.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { Module } from '@nestjs/common'; -import { ConfigModule } from '@nestjs/config'; -import { AppController } from './app.controller'; -import { AppService } from './app.service'; -import { AuthModule } from './auth/auth.module'; -import { AutoModule } from './auto/auto.module'; -import config from './config'; -// import { FriendModule } from './friend/friend.module'; -// import { GroupModule } from './group/group.module'; -import { PrismaModule } from './prisma/prisma.module'; -import { UserModule } from './user/user.module'; -import { GraphqlService } from './graphql/graphql.service'; -import { GraphqlModule } from './graphql/graphql.module'; - -// TOOD: Re-enable FriendModule and GroupModule when ready -// Need to be locked down better, and FE supported -@Module({ - imports: [ - ConfigModule.forRoot({ - load: [config], - isGlobal: true, - envFilePath: '../.env', - }), - AuthModule, - AutoModule, - UserModule, - // FriendModule, - PrismaModule, - GraphqlModule, - // GroupModule, - ], - controllers: [AppController], - providers: [AppService, GraphqlService], -}) -export class AppModule {} diff --git a/server/src/app.service.ts b/server/src/app.service.ts deleted file mode 100644 index 3969f5261..000000000 --- a/server/src/app.service.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { Injectable } from '@nestjs/common'; -import { ConfigService } from '@nestjs/config'; - -@Injectable() -export class AppService { - constructor(private configService: ConfigService) {} - - getServerConfig() { - const env = this.configService.get('NODE_ENV'); - const port = this.configService.get('PORT'); - - const auto = `${this.configService.get('AUTO_SERVER_HOST_NAME')}:${this.configService.get('AUTO_SERVER_HOST_PORT')}`; - const client = `${this.configService.get('CLIENT_HOST_NAME')}:${this.configService.get('CLIENT_HOST_PORT')}`; - const redirectLink = `https://${this.configService.get('CLIENT_HOST_NAME')}:${this.configService.get('CLIENT_HOST_PORT')}`; - - return { - env, - port, - auto, - client, - redirectLink, - }; - } -} diff --git a/server/src/auth/auth.controller.spec.ts b/server/src/auth/auth.controller.spec.ts deleted file mode 100644 index 27a31e618..000000000 --- a/server/src/auth/auth.controller.spec.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { AuthController } from './auth.controller'; - -describe('AuthController', () => { - let controller: AuthController; - - beforeEach(async () => { - const module: TestingModule = await Test.createTestingModule({ - controllers: [AuthController], - }).compile(); - - controller = module.get(AuthController); - }); - - it('should be defined', () => { - expect(controller).toBeDefined(); - }); -}); diff --git a/server/src/auth/auth.controller.ts b/server/src/auth/auth.controller.ts deleted file mode 100644 index ddc3d2d92..000000000 --- a/server/src/auth/auth.controller.ts +++ /dev/null @@ -1,93 +0,0 @@ -import { Controller, Get, Request, Res, UseGuards } from '@nestjs/common'; -import { Response } from 'express'; - -import { AuthService } from './auth.service'; -import { LoginGuard } from './login.guard'; -import { UserService } from 'src/user/user.service'; -import { ConfigService } from '@nestjs/config'; -import { InitUserDTO, UserDTO } from 'src/user/dto'; - -@Controller('auth') -export class AuthController { - constructor( - private authService: AuthService, - private userService: UserService, - private configService: ConfigService, - ) {} - - @UseGuards(LoginGuard) - @Get('/login') - login() {} - - checkUserDataUpdatedBeforeLogin = ( - userData: UserDTO, - updatedUserData: InitUserDTO, - ) => { - if ( - userData.firstname !== updatedUserData.firstname || - userData.lastname !== updatedUserData.lastname || - userData.email !== updatedUserData.email - ) { - return true; - } - - return false; - }; - @Get('/user') - async user(@Request() req, @Res() res: Response) { - if (req.user) { - const userID = req.user.userinfo.sub; - const updateUserData = async () => { - const userData = req.user.userinfo.userData ?? { - firstName: `No First (${userID})`, - lastName: 'No Last', - }; - await this.userService.setUserProfile({ - userID: userID, - email: '', - firstname: userData.firstName, - lastname: userData.lastName, - }); - }; - try { - const userData = await this.userService.getUserInfo(userID); - const reqUserData = req.user.userinfo.userData ?? { - firstName: `No First (${userID})`, - lastName: 'No Last', - email: '', - userID: userID, - }; - if (this.checkUserDataUpdatedBeforeLogin(userData, reqUserData)) { - console.debug( - 'The user ' + - userID + - ' has their profiles updated! Updating now :)', - ); - updateUserData(); - } - } catch (e) { - console.debug(`User ${userID} does not exist in db, adding them now!`); - updateUserData(); - } - return res.json(req.user.userinfo.sub); - } - - return res.json(req.user); - } - - @UseGuards(LoginGuard) - @Get('/callback/csesoc') - loginCallback(@Res() res: Response) { - res.redirect( - this.configService.get( - 'app.redirectLink', - 'https://notangles.devsoc.app/api/auth/callback/csesoc', - ), - ); - } - - @Get('/logout') - async logout(@Request() req, @Res() res: Response) { - await this.authService.logout(req, res); - } -} diff --git a/server/src/auth/auth.module.ts b/server/src/auth/auth.module.ts deleted file mode 100644 index 023a37a54..000000000 --- a/server/src/auth/auth.module.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { Module } from '@nestjs/common'; -import { PassportModule } from '@nestjs/passport'; -import { OidcStrategy, buildOpenIdClient } from './oidc.strategy'; -import { SessionSerializer } from './session.serializer'; -import { AuthService } from './auth.service'; -import { AuthController } from './auth.controller'; -import { UserService } from 'src/user/user.service'; -import { PrismaService } from 'src/prisma/prisma.service'; -import { GraphqlService } from 'src/graphql/graphql.service'; - -const OidcStrategyFactory = { - provide: 'OidcStrategy', - useFactory: async (authService: AuthService) => { - const client = await buildOpenIdClient(); - return new OidcStrategy(authService, client); - }, - inject: [AuthService], -}; - -@Module({ - imports: [ - PassportModule.register({ session: true, defaultStrategy: 'oidc' }), - ], - controllers: [AuthController], - providers: [ - OidcStrategyFactory, - SessionSerializer, - AuthService, - UserService, - PrismaService, - GraphqlService, - ], -}) -export class AuthModule {} diff --git a/server/src/auth/auth.service.spec.ts b/server/src/auth/auth.service.spec.ts deleted file mode 100644 index 800ab6626..000000000 --- a/server/src/auth/auth.service.spec.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { AuthService } from './auth.service'; - -describe('AuthService', () => { - let service: AuthService; - - beforeEach(async () => { - const module: TestingModule = await Test.createTestingModule({ - providers: [AuthService], - }).compile(); - - service = module.get(AuthService); - }); - - it('should be defined', () => { - expect(service).toBeDefined(); - }); -}); diff --git a/server/src/auth/auth.service.ts b/server/src/auth/auth.service.ts deleted file mode 100644 index 07b653ad4..000000000 --- a/server/src/auth/auth.service.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { Injectable, Request, Res } from '@nestjs/common'; -import { Response } from 'express'; -import { Issuer } from 'openid-client'; -import { ConfigService } from '@nestjs/config'; - -@Injectable() -export class AuthService { - constructor(private configService: ConfigService) {} - async logout(@Request() req, @Res() res: Response): Promise { - const id_token = req.user ? req.user.id_token : undefined; - - const TrustIssuer = await Issuer.discover( - `${process.env.OAUTH2_CLIENT_PROVIDER_OIDC_ISSUER}/.well-known/openid-configuration`, - ); - - const postLogoutRedirect = this.configService.get( - 'app.redirectLink', - process.env.OAUTH2_CLIENT_REGISTRATION_LOGIN_POST_LOGOUT_REDIRECT_URI, - ); - - if (!id_token || !TrustIssuer) { - return res.redirect(postLogoutRedirect); - } - - const endSessionEndpoint = TrustIssuer.metadata.end_session_endpoint; - - return new Promise((resolve, reject) => { - req.logout((err) => { - if (err) return reject(err); - - req.session.destroy((error) => { - if (error) return reject(error); - - if (endSessionEndpoint && id_token) { - res.redirect( - `${endSessionEndpoint}?post_logout_redirect_uri=${postLogoutRedirect}&id_token_hint=${id_token}`, - ); - } else { - res.redirect(postLogoutRedirect); - } - - resolve(); - }); - }); - }); - } -} diff --git a/server/src/auth/authenticated.guard.ts b/server/src/auth/authenticated.guard.ts deleted file mode 100644 index 0d9bd6bc6..000000000 --- a/server/src/auth/authenticated.guard.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { ExecutionContext, Injectable, CanActivate } from '@nestjs/common'; - -@Injectable() -export class AuthenticatedGuard implements CanActivate { - async canActivate(context: ExecutionContext) { - const request = context.switchToHttp().getRequest(); - return request.isAuthenticated(); - } -} diff --git a/server/src/auth/dtos/auth.dto.ts b/server/src/auth/dtos/auth.dto.ts deleted file mode 100644 index fb4ce9096..000000000 --- a/server/src/auth/dtos/auth.dto.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { IsNotEmpty, IsString } from 'class-validator'; - -export class AuthDto { - @IsString() @IsNotEmpty() code: string; - - @IsString() @IsNotEmpty() state: string; -} diff --git a/server/src/auth/dtos/index.ts b/server/src/auth/dtos/index.ts deleted file mode 100644 index 0ee0429bc..000000000 --- a/server/src/auth/dtos/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './auth.dto'; diff --git a/server/src/auth/login.guard.ts b/server/src/auth/login.guard.ts deleted file mode 100644 index c16b6042b..000000000 --- a/server/src/auth/login.guard.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { ExecutionContext, Injectable } from '@nestjs/common'; -import { AuthGuard } from '@nestjs/passport'; - -@Injectable() -export class LoginGuard extends AuthGuard('oidc') { - async canActivate(context: ExecutionContext) { - const result = (await super.canActivate(context)) as boolean; - const request = context.switchToHttp().getRequest(); - await super.logIn(request); - return result; - } -} diff --git a/server/src/auth/oidc.strategy.ts b/server/src/auth/oidc.strategy.ts deleted file mode 100644 index 8c2d5d515..000000000 --- a/server/src/auth/oidc.strategy.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { Request } from 'express'; -import { UnauthorizedException } from '@nestjs/common'; -import { PassportStrategy } from '@nestjs/passport'; -import { - Strategy, - Client, - UserinfoResponse, - TokenSet, - Issuer, -} from 'openid-client'; -import { AuthService } from './auth.service'; - -export const buildOpenIdClient = async () => { - const TrustIssuer = await Issuer.discover( - `${process.env.OAUTH2_CLIENT_PROVIDER_OIDC_ISSUER}/.well-known/openid-configuration`, - ); - const client = new TrustIssuer.Client({ - client_id: process.env.OAUTH2_CLIENT_REGISTRATION_LOGIN_CLIENT_ID, - client_secret: process.env.OAUTH2_CLIENT_REGISTRATION_LOGIN_CLIENT_SECRET, - }); - return client; -}; - -export class OidcStrategy extends PassportStrategy(Strategy, 'oidc') { - client: Client; - - constructor( - private readonly authService: AuthService, - client: Client, - ) { - super({ - client: client, - params: { - redirect_uri: process.env.OAUTH2_CLIENT_REGISTRATION_LOGIN_REDIRECT_URI, - scope: process.env.OAUTH2_CLIENT_REGISTRATION_LOGIN_SCOPE, - }, - passReqToCallback: true, - usePKCE: false, - }); - - this.client = client; - } - - async validate( - req: Request & { login: any }, - tokenset: TokenSet, - ): Promise { - const userinfo: UserinfoResponse = await this.client.userinfo(tokenset); - try { - const id_token = tokenset.id_token; - const access_token = tokenset.access_token; - const refresh_token = tokenset.refresh_token; - const user = { - id_token, - access_token, - refresh_token, - userinfo, - }; - - return new Promise((resolve, reject) => { - req.login(user, (err) => { - if (err) { - return reject(new UnauthorizedException('Login failed')); - } - resolve(user); - }); - }); - } catch (err) { - throw new UnauthorizedException(); - } - } -} diff --git a/server/src/auth/session.serializer.ts b/server/src/auth/session.serializer.ts deleted file mode 100644 index 664f77777..000000000 --- a/server/src/auth/session.serializer.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { PassportSerializer } from '@nestjs/passport'; -import { Injectable } from '@nestjs/common'; -@Injectable() -export class SessionSerializer extends PassportSerializer { - serializeUser(user: any, done: (err: Error, user: any) => void): any { - done(null, user); - } - deserializeUser( - payload: any, - done: (err: Error, payload: string) => void, - ): any { - done(null, payload); - } -} diff --git a/server/src/auto/auto.controller.ts b/server/src/auto/auto.controller.ts deleted file mode 100644 index 784d3c9cd..000000000 --- a/server/src/auto/auto.controller.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { - Controller, - Get, - Post, - Body, - Patch, - Param, - Delete, -} from '@nestjs/common'; -import { AutoService } from './auto.service'; -import { autoDTO } from './dto/auto.dto'; - -@Controller('auto') -export class AutoController { - constructor(private readonly autoService: AutoService) {} - - @Post() - async create(@Body() userRequestConstraints: autoDTO) { - return await this.autoService.getAutoTimetable(userRequestConstraints); - } -} diff --git a/server/src/auto/auto.module.ts b/server/src/auto/auto.module.ts deleted file mode 100644 index 11351beed..000000000 --- a/server/src/auto/auto.module.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { Module } from '@nestjs/common'; -import { AutoService } from './auto.service'; -import { AutoController } from './auto.controller'; -import { ClientsModule, Transport } from '@nestjs/microservices'; -import { join } from 'path'; - -@Module({ - imports: [ - ClientsModule.register([ - { - name: 'autotimetabler', - transport: Transport.GRPC, - options: { - package: 'autotimetabler', - protoPath: join(__dirname, '../proto/autotimetabler.proto'), - url: `${process.env.AUTO_SERVER_HOST_NAME}:${process.env.AUTO_SERVER_HOST_PORT}`, - }, - }, - ]), - ], - controllers: [AutoController], - providers: [AutoService], -}) -export class AutoModule {} diff --git a/server/src/auto/auto.service.ts b/server/src/auto/auto.service.ts deleted file mode 100644 index d50f3da38..000000000 --- a/server/src/auto/auto.service.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { Body, HttpException, HttpStatus, Injectable } from '@nestjs/common'; - -import * as grpc from '@grpc/grpc-js'; -import { TimetableConstraints } from '../proto/autotimetabler_pb'; -import { AutoTimetablerClient } from '../proto/autotimetabler_grpc_pb'; -import { autoDTO } from './dto/auto.dto'; -import { ConfigService } from '@nestjs/config'; - -@Injectable() -export class AutoService { - constructor(private configService: ConfigService) {} - async getAutoTimetable(@Body() autoService: autoDTO): Promise { - const AUTO_SERVER_HOST = `${this.configService.get( - 'AUTO_SERVER_HOST_NAME', - )}:${this.configService.get('AUTO_SERVER_HOST_PORT')}`; - return await getAuto(autoService, AUTO_SERVER_HOST); - } -} - -interface getAutoParameter { - (data: autoDTO, grpc_client_conn: string): Promise; -} - -export const getAuto: getAutoParameter = async ( - data: autoDTO, - grpc_client_conn: string, -) => { - const client = new AutoTimetablerClient( - grpc_client_conn, - grpc.credentials.createInsecure(), - ); - const constraints = new TimetableConstraints(); - - constraints.setStart(data.start); - constraints.setEnd(data.end); - constraints.setDays(data.days); - constraints.setGap(data.gap); - constraints.setMaxdays(data.maxdays); - data.periodInfoList.forEach((thisPeriod) => { - const thisPeriodInfo = new TimetableConstraints.PeriodInfo(); - - thisPeriodInfo.setPeriodsperclass(thisPeriod.periodsPerClass); - thisPeriodInfo.setPeriodtimesList(thisPeriod.periodTimes); - thisPeriodInfo.setDurationsList(thisPeriod.durations); - - constraints.addPeriodinfo(thisPeriodInfo); - }); - return new Promise((resolve, reject) => { - client.findBestTimetable(constraints, (err, response) => { - if (err) { - console.error('error was found: ' + err); - reject( - new HttpException( - 'An error occurred when handling the request.', - HttpStatus.BAD_GATEWAY, - ), - ); - } else { - resolve( - JSON.stringify({ - given: response.getTimesList(), - optimal: response.getOptimal(), - }), - ); - } - }); - }); -}; diff --git a/server/src/auto/dto/auto.dto.ts b/server/src/auto/dto/auto.dto.ts deleted file mode 100644 index 12e529fb8..000000000 --- a/server/src/auto/dto/auto.dto.ts +++ /dev/null @@ -1,12 +0,0 @@ -export class autoDTO { - start: number; - end: number; - days: string; - gap: number; - maxdays: number; - periodInfoList: { - periodsPerClass: number; - periodTimes: Array; - durations: Array; - }[]; -} diff --git a/server/src/config.ts b/server/src/config.ts deleted file mode 100644 index b2e17fcff..000000000 --- a/server/src/config.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { registerAs } from '@nestjs/config'; - -export default registerAs('app', () => ({ - env: process.env.NODE_ENV || 'dev', - port: parseInt(process.env.PORT, 10) || 3000, - auto: `${process.env.AUTO_SERVER_HOST_NAME}:${process.env.AUTO_SERVER_HOST_PORT}`, - client: `${process.env.CLIENT_HOST_NAME}:${process.env.CLIENT_HOST_PORT}`, - redirectLink: - (process.env.NODE_ENV === 'dev' ? `http://` : `https://`) + - `${process.env.CLIENT_HOST_NAME}:${process.env.CLIENT_HOST_PORT}`, -})); diff --git a/server/src/friend/dto/friend.dto.ts b/server/src/friend/dto/friend.dto.ts deleted file mode 100644 index 448776946..000000000 --- a/server/src/friend/dto/friend.dto.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { IsNotEmpty, IsString } from 'class-validator'; - -export class friendDto { - @IsString() - @IsNotEmpty() - senderId: string; - - @IsString() - @IsNotEmpty() - sendeeId: string; -} - -// export class friendRequestDto { -// @IsString() -// @IsNotEmpty() -// requestId: string; -// } diff --git a/server/src/friend/dto/index.ts b/server/src/friend/dto/index.ts deleted file mode 100644 index 1392bb23e..000000000 --- a/server/src/friend/dto/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './friend.dto'; diff --git a/server/src/friend/friend.controller.spec.ts b/server/src/friend/friend.controller.spec.ts deleted file mode 100644 index 33542ffe8..000000000 --- a/server/src/friend/friend.controller.spec.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { FriendController } from './friend.controller'; - -describe('FriendController', () => { - let controller: FriendController; - - beforeEach(async () => { - const module: TestingModule = await Test.createTestingModule({ - controllers: [FriendController], - }).compile(); - - controller = module.get(FriendController); - }); - - it('should be defined', () => { - expect(controller).toBeDefined(); - }); -}); diff --git a/server/src/friend/friend.controller.ts b/server/src/friend/friend.controller.ts deleted file mode 100644 index f221bd667..000000000 --- a/server/src/friend/friend.controller.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { Body, Controller, Delete, Get, Param, Post } from '@nestjs/common'; -import { friendDto } from './dto'; -import { FriendService } from './friend.service'; -@Controller('friend') -export class FriendController { - constructor(private friendService: FriendService) {} - @Get(':userId') - findAllFriends(@Param('userId') userId: string) { - return this.friendService.findAllFriends(userId).then((data) => { - return { - status: "Found user's friends", - data, - }; - }); - } - - @Post() - friendUsers(@Body() friendDTO: friendDto) { - return this.friendService - .friendUsers(friendDTO.senderId, friendDTO.sendeeId) - .then((id) => { - return { - status: 'Successfully added users as friends!', - data: { - id, - }, - }; - }); - } - - @Delete() - unfriendUsers(@Body() friendDTO: friendDto) { - return this.friendService - .unfriendUsers(friendDTO.senderId, friendDTO.sendeeId) - .then((id) => { - return { - status: 'Successfully removed users as friends!', - data: { - id, - }, - }; - }); - } - - @Post('request') - sendFriendRequest(@Body() friendDTO: friendDto) { - return this.friendService.sendFriendRequest( - friendDTO.senderId, - friendDTO.sendeeId, - ); - } - - @Delete('request') - deleteFriendRequest(@Body() friendDTO: friendDto) { - return this.friendService - .deleteFriendRequest(friendDTO.senderId, friendDTO.sendeeId) - .then((id) => { - return { - status: 'Successfully rejected friend request!', - data: { - senderId: id, - }, - }; - }); - } -} diff --git a/server/src/friend/friend.module.ts b/server/src/friend/friend.module.ts deleted file mode 100644 index 349cf389d..000000000 --- a/server/src/friend/friend.module.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Module } from '@nestjs/common'; -import { FriendService } from './friend.service'; -import { FriendController } from './friend.controller'; -import { PrismaService } from 'src/prisma/prisma.service'; - -@Module({ - providers: [FriendService, PrismaService], - controllers: [FriendController], -}) -export class FriendModule {} diff --git a/server/src/friend/friend.service.spec.ts b/server/src/friend/friend.service.spec.ts deleted file mode 100644 index 7ed4fd654..000000000 --- a/server/src/friend/friend.service.spec.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { FriendService } from './friend.service'; - -describe('FriendService', () => { - let service: FriendService; - - beforeEach(async () => { - const module: TestingModule = await Test.createTestingModule({ - providers: [FriendService], - }).compile(); - - service = module.get(FriendService); - }); - - it('should be defined', () => { - expect(service).toBeDefined(); - }); -}); diff --git a/server/src/friend/friend.service.ts b/server/src/friend/friend.service.ts deleted file mode 100644 index 449219254..000000000 --- a/server/src/friend/friend.service.ts +++ /dev/null @@ -1,171 +0,0 @@ -import { Injectable } from '@nestjs/common'; -import { PrismaService } from 'src/prisma/prisma.service'; - -@Injectable({}) -export class FriendService { - constructor(private readonly prisma: PrismaService) {} - async findAllFriends(userID: string) { - try { - const res = await this.prisma.user.findUniqueOrThrow({ - where: { userID }, - select: { - friends: true, - }, - }); - - return res.friends; - } catch (e) { - throw new Error(e); - } - } - - async friendUsers(senderId: string, sendeeId: string): Promise { - try { - if (senderId === sendeeId) { - throw new Error('Cannot friend yourself'); - } - - await this.prisma.$transaction([ - this.prisma.user.update({ - where: { - userID: senderId, - }, - data: { - friends: { - connect: { - userID: sendeeId, - }, - }, - }, - }), - this.prisma.user.update({ - where: { - userID: sendeeId, - }, - data: { - friends: { - connect: { - userID: senderId, - }, - }, - }, - }), - ]); - - // Need to delete friend request - this.deleteFriendRequest(sendeeId, senderId); - - return Promise.resolve(sendeeId); - } catch (e) { - throw new Error(e); - } - } - - async unfriendUsers(senderId: string, sendeeId: string): Promise { - try { - await this.prisma.$transaction([ - this.prisma.user.update({ - where: { - userID: senderId, - }, - data: { - friends: { - disconnect: { - userID: sendeeId, - }, - }, - }, - }), - this.prisma.user.update({ - where: { - userID: sendeeId, - }, - data: { - friends: { - disconnect: { - userID: senderId, - }, - }, - }, - }), - ]); - - return Promise.resolve(sendeeId); - } catch (e) { - throw new Error(e); - } - } - - // Note: This can also serve as accepting a friend req (lmk if we should decouple these functions) - async sendFriendRequest(senderId: string, sendeeId: string) { - try { - if (senderId === sendeeId) { - throw new Error('Cannot friend yourself'); - } - - // Check if there's corresponding incoming request first - const isIncoming = await this.prisma.user.findFirst({ - where: { - userID: senderId, - incoming: { - some: { - userID: sendeeId, - }, - }, - }, - }); - - let status; - // If so, we can just friend them - if (isIncoming) { - // Reversed order because the current sender has an incoming req, so they are the "sendee" of that transaction - await this.deleteFriendRequest(sendeeId, senderId); - await this.friendUsers(senderId, sendeeId); - status = 'Successfully accepted friend request'; - } else { - // Else, send outgoing friend request - await this.prisma.user.update({ - where: { - userID: senderId, - }, - data: { - outgoing: { - connect: { - userID: sendeeId, - }, - }, - }, - }); - status = 'Successfully sent friend request'; - } - - return Promise.resolve({ - status, - data: { id: sendeeId }, - }); - } catch (e) { - throw new Error(e); - } - } - - // sendee = receiver = incoming (f-req is coming into the sendee, so sendee is the id of user who made this api req) - async deleteFriendRequest(senderId: string, sendeeId: string) { - try { - await this.prisma.user.update({ - where: { - userID: sendeeId, - }, - data: { - incoming: { - disconnect: { - userID: senderId, - }, - }, - }, - }); - return Promise.resolve(senderId); - } catch (e) { - throw new Error(e); - } - } -} diff --git a/server/src/graphql/graphql.module.ts b/server/src/graphql/graphql.module.ts deleted file mode 100644 index 19b41c5b5..000000000 --- a/server/src/graphql/graphql.module.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { Module } from '@nestjs/common'; -import { GraphqlService } from './graphql.service'; - -@Module({ - providers: [GraphqlService], -}) -export class GraphqlModule {} diff --git a/server/src/graphql/graphql.response.ts b/server/src/graphql/graphql.response.ts deleted file mode 100644 index f47b7d774..000000000 --- a/server/src/graphql/graphql.response.ts +++ /dev/null @@ -1,24 +0,0 @@ -export interface GQLCourseInfo { - course_code: string; - course_name: string; - classes: { - activity: string; - status: string; - course_enrolment: string; - class_id: string; - term: string; - section: string; - times: { - day: string; - time: string; - weeks: string; - location: string; - }[]; - }[]; -} - -export type GQLCourseData = { - data: { - courses: GQLCourseInfo[]; - }; -}; diff --git a/server/src/graphql/graphql.service.spec.ts b/server/src/graphql/graphql.service.spec.ts deleted file mode 100644 index b390186b5..000000000 --- a/server/src/graphql/graphql.service.spec.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { GraphqlService } from './graphql.service'; - -describe('GraphqlService', () => { - let service: GraphqlService; - - beforeEach(async () => { - const module: TestingModule = await Test.createTestingModule({ - providers: [GraphqlService], - }).compile(); - - service = module.get(GraphqlService); - }); - - it('should be defined', () => { - expect(service).toBeDefined(); - }); -}); diff --git a/server/src/graphql/graphql.service.ts b/server/src/graphql/graphql.service.ts deleted file mode 100644 index b52c78e15..000000000 --- a/server/src/graphql/graphql.service.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { Injectable } from '@nestjs/common'; -import { GQLCourseData } from './graphql.response'; -const HASURAGRES_GRAPHQL_API = 'https://graphql.csesoc.app/v1/graphql'; - -export const GET_COURSE_INFO = ` - query GetCourseInfo($courseCode: String!, $term: String!, $year: String!) { - courses(where: { course_code: { _eq: $courseCode } }) { - course_code - course_name - classes( - where: { - term: { _eq: $term } - year: { _eq: $year } - activity: { _neq: "Course Enrolment" } - } - ) { - activity - status - course_enrolment - class_id - term - section - times { - day - time - weeks - location - } - consent - mode - class_notes - } - } - } -`; - -@Injectable() -export class GraphqlService { - async fetchData( - query: string, - variables?: Record, - ): Promise { - try { - const data = await fetch(HASURAGRES_GRAPHQL_API, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - query, - variables, - }), - }); - return data.json(); - } catch (error) { - console.error('GraphQL Request Error:', error); - throw error; - } - } - async fetchCourseData( - courseCode: string, - term: string, - year: string, - ): Promise { - return this.fetchData(GET_COURSE_INFO, { courseCode, term, year }); - } -} diff --git a/server/src/group/dto/group.dto.ts b/server/src/group/dto/group.dto.ts deleted file mode 100644 index b6c5475b1..000000000 --- a/server/src/group/dto/group.dto.ts +++ /dev/null @@ -1,9 +0,0 @@ -export class GroupDto { - name: string; - description: string; - imageURL: string; - visibility: string; - timetableIDs: string[]; - memberIDs: string[]; - groupAdminIDs: string[]; -} diff --git a/server/src/group/dto/index.ts b/server/src/group/dto/index.ts deleted file mode 100644 index e69de29bb..000000000 diff --git a/server/src/group/entities/group.entity.ts b/server/src/group/entities/group.entity.ts deleted file mode 100644 index f08776497..000000000 --- a/server/src/group/entities/group.entity.ts +++ /dev/null @@ -1 +0,0 @@ -export class Group {} diff --git a/server/src/group/group.controller.spec.ts b/server/src/group/group.controller.spec.ts deleted file mode 100644 index 9988380e7..000000000 --- a/server/src/group/group.controller.spec.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { GroupController } from './group.controller'; -import { GroupService } from './group.service'; - -describe('GroupController', () => { - let controller: GroupController; - - beforeEach(async () => { - const module: TestingModule = await Test.createTestingModule({ - controllers: [GroupController], - providers: [GroupService], - }).compile(); - - controller = module.get(GroupController); - }); - - it('should be defined', () => { - expect(controller).toBeDefined(); - }); -}); diff --git a/server/src/group/group.controller.ts b/server/src/group/group.controller.ts deleted file mode 100644 index 0e9b19312..000000000 --- a/server/src/group/group.controller.ts +++ /dev/null @@ -1,99 +0,0 @@ -import { - Controller, - Get, - Post, - Put, - Delete, - Body, - Param, - NotFoundException, - ConflictException, - BadRequestException, -} from '@nestjs/common'; -import { GroupService } from './group.service'; -import { GroupDto } from './dto/group.dto'; - -@Controller('group') -export class GroupController { - constructor(private readonly groupService: GroupService) {} - - @Get(':id') - async findOne(@Param('id') id: string) { - const group = await this.groupService.findOne(id); - if (!group) { - throw new NotFoundException({ - timestamp: new Date().toISOString(), - path: `/api/group/${id}`, - data: "Can't find group!", - }); - } - return { - status: 'Success message for fetching group.', - data: group, - }; - } - - @Post() - async create(@Body() createGroupDto: GroupDto) { - try { - const group = await this.groupService.create(createGroupDto); - return { - status: 'Success message for creation of group.', - data: group, - }; - } catch (error) { - throw new BadRequestException({ - timestamp: new Date().toISOString(), - path: `/api/group`, - data: `There was an error creating the group, the error: ${error}`, - }); - } - } - - @Put(':id') - async update(@Param('id') id: string, @Body() updateGroupDto: GroupDto) { - try { - const group = await this.groupService.update(id, updateGroupDto); - return { - status: 'Success message for updating of group.', - data: group, - }; - } catch (error) { - if (error.message === 'Group not found') { - throw new NotFoundException({ - timestamp: new Date().toISOString(), - path: `/api/group/${id}`, - data: "Can't find group!", - }); - } else if (error.message === 'Group already exists') { - throw new ConflictException({ - timestamp: new Date().toISOString(), - path: `/api/group/${id}`, - data: 'Message detailing what went wrong. ie already exists', - }); - } - throw new BadRequestException({ - timestamp: new Date().toISOString(), - path: `/api/group/${id}`, - data: 'Message detailing what went wrong.', - }); - } - } - - @Delete(':id') - async remove(@Param('id') id: string) { - try { - await this.groupService.remove(id); - return { - status: 'Success message for deletion of group.', - data: {}, - }; - } catch (error) { - throw new NotFoundException({ - timestamp: new Date().toISOString(), - path: `/api/group/${id}`, - data: error.message || 'Message detailing what went wrong.', - }); - } - } -} diff --git a/server/src/group/group.module.ts b/server/src/group/group.module.ts deleted file mode 100644 index bdf62e060..000000000 --- a/server/src/group/group.module.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Module } from '@nestjs/common'; -import { GroupService } from './group.service'; -import { GroupController } from './group.controller'; -import { PrismaService } from 'src/prisma/prisma.service'; -import { UserService } from 'src/user/user.service'; -import { GraphqlService } from 'src/graphql/graphql.service'; - -@Module({ - controllers: [GroupController], - providers: [GroupService, PrismaService, UserService, GraphqlService], -}) -export class GroupModule {} diff --git a/server/src/group/group.service.spec.ts b/server/src/group/group.service.spec.ts deleted file mode 100644 index 495dd7969..000000000 --- a/server/src/group/group.service.spec.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { GroupService } from './group.service'; - -describe('GroupService', () => { - let service: GroupService; - - beforeEach(async () => { - const module: TestingModule = await Test.createTestingModule({ - providers: [GroupService], - }).compile(); - - service = module.get(GroupService); - }); - - it('should be defined', () => { - expect(service).toBeDefined(); - }); -}); diff --git a/server/src/group/group.service.ts b/server/src/group/group.service.ts deleted file mode 100644 index 339dd3bdd..000000000 --- a/server/src/group/group.service.ts +++ /dev/null @@ -1,157 +0,0 @@ -import { - Injectable, - NotFoundException, - ConflictException, - HttpException, -} from '@nestjs/common'; -import { PrismaService } from '../prisma/prisma.service'; -import { GroupDto } from './dto/group.dto'; -import { UserService } from 'src/user/user.service'; - -export enum PrismaErrorCode { - UNIQUE_CONSTRAINT_FAILED = 'P2002', - RECORD_NOT_FOUND = 'P2025', -} - -@Injectable() -export class GroupService { - constructor( - private readonly prisma: PrismaService, - private readonly user: UserService, - ) {} - - async prepareGroupData(data: GroupDto) { - const { - name, - visibility, - timetableIDs, - memberIDs, - groupAdminIDs, - description = '', - imageURL = '', - } = data; - - // Prepare the base data - const resData = { - name, - visibility, - description, - imageURL, - timetables: { connect: [] }, - members: { connect: [] }, - groupAdmins: { connect: [] }, - }; - - // Fetch related entities - const [timetables, memberUsers, admins] = await Promise.all([ - this.user.getTimetablesByIDs(timetableIDs), - this.user.getUsersByIDs(memberIDs), - this.user.getUsersByIDs(groupAdminIDs), - ]); - - // Populate the connect arrays - if (timetables.length > 0) { - resData.timetables.connect = timetables.map((timetable) => ({ - id: timetable.id, - })); - } - - if (memberUsers.length > 0) { - resData.members.connect = memberUsers.map((member) => ({ - userID: member.userID, - })); - } - - if (admins.length > 0) { - resData.groupAdmins.connect = admins.map((admin) => ({ - userID: admin.userID, - })); - } - - return resData; - } - - async create(createGroupDto: GroupDto) { - try { - const data = await this.prepareGroupData(createGroupDto); - const group = await this.prisma.group.create({ data }); - return group; - } catch (error) { - if (error.code === PrismaErrorCode.UNIQUE_CONSTRAINT_FAILED) { - throw new ConflictException('Group already exists'); - } - throw new HttpException( - `There was an error: ${error.message}`, - error.status || 500, - ); - } - } - - async findOne(id: string) { - const group = await this.prisma.group.findUnique({ - where: { id }, - include: { - timetables: true, - members: true, - groupAdmins: true, - }, - }); - if (!group) { - throw new NotFoundException('Group not found'); - } - return group; - } - - async update(id: string, updateGroupDto: GroupDto) { - try { - const data = await this.prepareGroupData(updateGroupDto); - - // Prepare relational fields - const updateData = { - name: data.name, - visibility: data.visibility, - description: data.description, - imageURL: data.imageURL, - timetables: { - set: data.timetables.connect.map((item) => ({ id: item.id })), - }, - members: { - set: data.members.connect.map((item) => ({ userID: item.userID })), - }, - groupAdmins: { - set: data.groupAdmins.connect.map((item) => ({ - userID: item.userID, - })), - }, - }; - - const group = await this.prisma.group.update({ - where: { id }, - data: updateData, - include: { - timetables: true, - members: true, - groupAdmins: true, - }, - }); - - return group; - } catch (error) { - if (error.code === PrismaErrorCode.RECORD_NOT_FOUND) { - throw new NotFoundException('Group not found'); - } - throw error; - } - } - - async remove(id: string) { - try { - await this.prisma.group.delete({ where: { id } }); - } catch (error) { - if (error.code === PrismaErrorCode.RECORD_NOT_FOUND) { - throw new NotFoundException('Group not found'); - } - throw error; - } - } -} diff --git a/server/src/main.ts b/server/src/main.ts deleted file mode 100644 index 34238fe87..000000000 --- a/server/src/main.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { ValidationPipe } from '@nestjs/common'; -import { NestFactory } from '@nestjs/core'; -import { MicroserviceOptions, Transport } from '@nestjs/microservices'; -import { PrismaSessionStore } from '@quixo3/prisma-session-store'; -import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger'; -import * as dotenv from 'dotenv'; -import * as session from 'express-session'; -import * as passport from 'passport'; -import * as path from 'path'; -import { AppModule } from './app.module'; -const { PrismaClient } = require('@prisma/client'); // pnpm breaks in production if require is not used. - -async function bootstrap() { - const app = await NestFactory.create(AppModule); - app.setGlobalPrefix('api'); - const config = new DocumentBuilder() - .setTitle('Notangles Backend') - .setDescription('Notangles Backend configuration file') - .setVersion('1.0') - // .addTag('Notangle Server') - .build(); - - const document = SwaggerModule.createDocument(app, config); - SwaggerModule.setup('swagger', app, document); - dotenv.config({ - path: path.resolve(__dirname, '../.env'), - }); - - app.enableCors({ - origin: [ - 'http://localhost:5173', - 'https://notanglesstaging.devsoc.app/', - 'https://notangles.devsoc.app/', - ], - credentials: true, // Allow credentials (e.g., cookies) to be sent with the request - }); - app.useGlobalPipes(new ValidationPipe()); - app.use( - session({ - store: new PrismaSessionStore(new PrismaClient(), { - checkPeriod: 2 * 60 * 1000, //ms - dbRecordIdIsSessionId: true, - dbRecordIdFunction: undefined, - }), // where session will be stored - secret: process.env.SESSION_SECRET, // to sign session id - resave: false, - saveUninitialized: false, - - rolling: true, // keep session alive - cookie: { - secure: false, - maxAge: 30 * 60 * 1000, // session expires in 1hr, refreshed by `rolling: true` option. - httpOnly: true, // so that cookie can't be accessed via client-side script - }, - }), - ); - app.connectMicroservice({ - transport: Transport.GRPC, // Use Transport.GRPC for gRPC - options: { - url: `${process.env.AUTO_SERVER_HOST_NAME}:${process.env.AUTO_SERVER_HOST_PORT}`, - protoPath: path.join(__dirname, '../proto/autotimetabler.proto'), - package: 'autotimetabler', - }, - }); - app.use(passport.initialize()); - app.use(passport.session()); - await app.listen(3001); -} - -bootstrap(); diff --git a/server/src/prisma/prisma.module.ts b/server/src/prisma/prisma.module.ts deleted file mode 100644 index f9deb7f60..000000000 --- a/server/src/prisma/prisma.module.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { Module } from '@nestjs/common'; -import { PrismaService } from './prisma.service'; - -@Module({ - providers: [PrismaService], -}) -export class PrismaModule {} diff --git a/server/src/prisma/prisma.service.ts b/server/src/prisma/prisma.service.ts deleted file mode 100644 index e576e1326..000000000 --- a/server/src/prisma/prisma.service.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { Injectable } from '@nestjs/common'; -// import { PrismaClient } from '@prisma/client'; -const { PrismaClient } = require('@prisma/client'); -import 'dotenv/config'; - -@Injectable() -export class PrismaService extends PrismaClient { - constructor() { - super({ - datasources: { - db: { - url: process.env.DATABASE_URL, - }, - }, - }); - } -} diff --git a/server/src/proto/autotimetabler.proto b/server/src/proto/autotimetabler.proto deleted file mode 100644 index 6c1baf720..000000000 --- a/server/src/proto/autotimetabler.proto +++ /dev/null @@ -1,26 +0,0 @@ -syntax = "proto3"; - -package autotimetabler; - -message TimetableConstraints { - message PeriodInfo { - int32 periodsPerClass = 1; - repeated float periodTimes = 2; - repeated float durations = 3; - } - int32 start = 1; - int32 end = 2; - string days = 3; - int32 gap = 4; - int32 maxdays = 5; - repeated PeriodInfo periodInfo = 6; -} - -message AutoTimetableResponse { - repeated float times = 1; - bool optimal = 2; -} - -service AutoTimetabler { - rpc FindBestTimetable (TimetableConstraints) returns (AutoTimetableResponse); -} \ No newline at end of file diff --git a/server/src/proto/autotimetabler_grpc_pb.d.ts b/server/src/proto/autotimetabler_grpc_pb.d.ts deleted file mode 100644 index 02fc10520..000000000 --- a/server/src/proto/autotimetabler_grpc_pb.d.ts +++ /dev/null @@ -1,98 +0,0 @@ -// package: -// file: autotimetabler.proto - -/* tslint:disable */ -/* eslint-disable */ - -import * as grpc from '@grpc/grpc-js'; -import * as autotimetabler_pb from './autotimetabler_pb'; - -interface IAutoTimetablerService - extends grpc.ServiceDefinition { - findBestTimetable: IAutoTimetablerService_IFindBestTimetable; -} - -interface IAutoTimetablerService_IFindBestTimetable - extends grpc.MethodDefinition< - autotimetabler_pb.TimetableConstraints, - autotimetabler_pb.AutoTimetableResponse - > { - path: '/AutoTimetabler/FindBestTimetable'; - requestStream: false; - responseStream: false; - requestSerialize: grpc.serialize; - requestDeserialize: grpc.deserialize; - responseSerialize: grpc.serialize; - responseDeserialize: grpc.deserialize; -} - -export const AutoTimetablerService: IAutoTimetablerService; - -export interface IAutoTimetablerServer { - findBestTimetable: grpc.handleUnaryCall< - autotimetabler_pb.TimetableConstraints, - autotimetabler_pb.AutoTimetableResponse - >; -} - -export interface IAutoTimetablerClient { - findBestTimetable( - request: autotimetabler_pb.TimetableConstraints, - callback: ( - error: grpc.ServiceError | null, - response: autotimetabler_pb.AutoTimetableResponse, - ) => void, - ): grpc.ClientUnaryCall; - findBestTimetable( - request: autotimetabler_pb.TimetableConstraints, - metadata: grpc.Metadata, - callback: ( - error: grpc.ServiceError | null, - response: autotimetabler_pb.AutoTimetableResponse, - ) => void, - ): grpc.ClientUnaryCall; - findBestTimetable( - request: autotimetabler_pb.TimetableConstraints, - metadata: grpc.Metadata, - options: Partial, - callback: ( - error: grpc.ServiceError | null, - response: autotimetabler_pb.AutoTimetableResponse, - ) => void, - ): grpc.ClientUnaryCall; -} - -export class AutoTimetablerClient - extends grpc.Client - implements IAutoTimetablerClient -{ - constructor( - address: string, - credentials: grpc.ChannelCredentials, - options?: object, - ); - public findBestTimetable( - request: autotimetabler_pb.TimetableConstraints, - callback: ( - error: grpc.ServiceError | null, - response: autotimetabler_pb.AutoTimetableResponse, - ) => void, - ): grpc.ClientUnaryCall; - public findBestTimetable( - request: autotimetabler_pb.TimetableConstraints, - metadata: grpc.Metadata, - callback: ( - error: grpc.ServiceError | null, - response: autotimetabler_pb.AutoTimetableResponse, - ) => void, - ): grpc.ClientUnaryCall; - public findBestTimetable( - request: autotimetabler_pb.TimetableConstraints, - metadata: grpc.Metadata, - options: Partial, - callback: ( - error: grpc.ServiceError | null, - response: autotimetabler_pb.AutoTimetableResponse, - ) => void, - ): grpc.ClientUnaryCall; -} diff --git a/server/src/proto/autotimetabler_grpc_pb.js b/server/src/proto/autotimetabler_grpc_pb.js deleted file mode 100644 index c50634f58..000000000 --- a/server/src/proto/autotimetabler_grpc_pb.js +++ /dev/null @@ -1,44 +0,0 @@ -// GENERATED CODE -- DO NOT EDIT! - -'use strict'; -var grpc = require('@grpc/grpc-js'); -var autotimetabler_pb = require('./autotimetabler_pb.js'); - -function serialize_AutoTimetableResponse(arg) { - if (!(arg instanceof autotimetabler_pb.AutoTimetableResponse)) { - throw new Error('Expected argument of type AutoTimetableResponse'); - } - return Buffer.from(arg.serializeBinary()); -} - -function deserialize_AutoTimetableResponse(buffer_arg) { - return autotimetabler_pb.AutoTimetableResponse.deserializeBinary(new Uint8Array(buffer_arg)); -} - -function serialize_TimetableConstraints(arg) { - if (!(arg instanceof autotimetabler_pb.TimetableConstraints)) { - throw new Error('Expected argument of type TimetableConstraints'); - } - return Buffer.from(arg.serializeBinary()); -} - -function deserialize_TimetableConstraints(buffer_arg) { - return autotimetabler_pb.TimetableConstraints.deserializeBinary(new Uint8Array(buffer_arg)); -} - - -var AutoTimetablerService = exports.AutoTimetablerService = { - findBestTimetable: { - path: '/AutoTimetabler/FindBestTimetable', - requestStream: false, - responseStream: false, - requestType: autotimetabler_pb.TimetableConstraints, - responseType: autotimetabler_pb.AutoTimetableResponse, - requestSerialize: serialize_TimetableConstraints, - requestDeserialize: deserialize_TimetableConstraints, - responseSerialize: serialize_AutoTimetableResponse, - responseDeserialize: deserialize_AutoTimetableResponse, - }, -}; - -exports.AutoTimetablerClient = grpc.makeGenericClientConstructor(AutoTimetablerService); diff --git a/server/src/proto/autotimetabler_pb.d.ts b/server/src/proto/autotimetabler_pb.d.ts deleted file mode 100644 index 7e775b720..000000000 --- a/server/src/proto/autotimetabler_pb.d.ts +++ /dev/null @@ -1,137 +0,0 @@ -// package: -// file: autotimetabler.proto - -/* tslint:disable */ -/* eslint-disable */ - -import * as jspb from 'google-protobuf'; - -export class TimetableConstraints extends jspb.Message { - getStart(): number; - setStart(value: number): TimetableConstraints; - getEnd(): number; - setEnd(value: number): TimetableConstraints; - getDays(): string; - setDays(value: string): TimetableConstraints; - getGap(): number; - setGap(value: number): TimetableConstraints; - getMaxdays(): number; - setMaxdays(value: number): TimetableConstraints; - clearPeriodinfoList(): void; - getPeriodinfoList(): Array; - setPeriodinfoList( - value: Array, - ): TimetableConstraints; - addPeriodinfo( - value?: TimetableConstraints.PeriodInfo, - index?: number, - ): TimetableConstraints.PeriodInfo; - - serializeBinary(): Uint8Array; - toObject(includeInstance?: boolean): TimetableConstraints.AsObject; - static toObject( - includeInstance: boolean, - msg: TimetableConstraints, - ): TimetableConstraints.AsObject; - static extensions: { [key: number]: jspb.ExtensionFieldInfo }; - static extensionsBinary: { - [key: number]: jspb.ExtensionFieldBinaryInfo; - }; - static serializeBinaryToWriter( - message: TimetableConstraints, - writer: jspb.BinaryWriter, - ): void; - static deserializeBinary(bytes: Uint8Array): TimetableConstraints; - static deserializeBinaryFromReader( - message: TimetableConstraints, - reader: jspb.BinaryReader, - ): TimetableConstraints; -} - -export namespace TimetableConstraints { - export type AsObject = { - start: number; - end: number; - days: string; - gap: number; - maxdays: number; - periodinfoList: Array; - }; - - export class PeriodInfo extends jspb.Message { - getPeriodsperclass(): number; - setPeriodsperclass(value: number): PeriodInfo; - clearPeriodtimesList(): void; - getPeriodtimesList(): Array; - setPeriodtimesList(value: Array): PeriodInfo; - addPeriodtimes(value: number, index?: number): number; - clearDurationsList(): void; - getDurationsList(): Array; - setDurationsList(value: Array): PeriodInfo; - addDurations(value: number, index?: number): number; - - serializeBinary(): Uint8Array; - toObject(includeInstance?: boolean): PeriodInfo.AsObject; - static toObject( - includeInstance: boolean, - msg: PeriodInfo, - ): PeriodInfo.AsObject; - static extensions: { [key: number]: jspb.ExtensionFieldInfo }; - static extensionsBinary: { - [key: number]: jspb.ExtensionFieldBinaryInfo; - }; - static serializeBinaryToWriter( - message: PeriodInfo, - writer: jspb.BinaryWriter, - ): void; - static deserializeBinary(bytes: Uint8Array): PeriodInfo; - static deserializeBinaryFromReader( - message: PeriodInfo, - reader: jspb.BinaryReader, - ): PeriodInfo; - } - - export namespace PeriodInfo { - export type AsObject = { - periodsperclass: number; - periodtimesList: Array; - durationsList: Array; - }; - } -} - -export class AutoTimetableResponse extends jspb.Message { - clearTimesList(): void; - getTimesList(): Array; - setTimesList(value: Array): AutoTimetableResponse; - addTimes(value: number, index?: number): number; - getOptimal(): boolean; - setOptimal(value: boolean): AutoTimetableResponse; - - serializeBinary(): Uint8Array; - toObject(includeInstance?: boolean): AutoTimetableResponse.AsObject; - static toObject( - includeInstance: boolean, - msg: AutoTimetableResponse, - ): AutoTimetableResponse.AsObject; - static extensions: { [key: number]: jspb.ExtensionFieldInfo }; - static extensionsBinary: { - [key: number]: jspb.ExtensionFieldBinaryInfo; - }; - static serializeBinaryToWriter( - message: AutoTimetableResponse, - writer: jspb.BinaryWriter, - ): void; - static deserializeBinary(bytes: Uint8Array): AutoTimetableResponse; - static deserializeBinaryFromReader( - message: AutoTimetableResponse, - reader: jspb.BinaryReader, - ): AutoTimetableResponse; -} - -export namespace AutoTimetableResponse { - export type AsObject = { - timesList: Array; - optimal: boolean; - }; -} diff --git a/server/src/proto/autotimetabler_pb.js b/server/src/proto/autotimetabler_pb.js deleted file mode 100644 index e20444439..000000000 --- a/server/src/proto/autotimetabler_pb.js +++ /dev/null @@ -1,827 +0,0 @@ -// source: autotimetabler.proto -/** - * @fileoverview - * @enhanceable - * @suppress {missingRequire} reports error on implicit type usages. - * @suppress {messageConventions} JS Compiler reports an error if a variable or - * field starts with 'MSG_' and isn't a translatable message. - * @public - */ -// GENERATED CODE -- DO NOT EDIT! -/* eslint-disable */ -// @ts-nocheck - -var jspb = require('google-protobuf'); -var goog = jspb; -var global = (function() { - if (this) { return this; } - if (typeof window !== 'undefined') { return window; } - if (typeof global !== 'undefined') { return global; } - if (typeof self !== 'undefined') { return self; } - return Function('return this')(); -}.call(null)); - -goog.exportSymbol('proto.AutoTimetableResponse', null, global); -goog.exportSymbol('proto.TimetableConstraints', null, global); -goog.exportSymbol('proto.TimetableConstraints.PeriodInfo', null, global); -/** - * Generated by JsPbCodeGenerator. - * @param {Array=} opt_data Optional initial data array, typically from a - * server response, or constructed directly in Javascript. The array is used - * in place and becomes part of the constructed object. It is not cloned. - * If no data is provided, the constructed object will be empty, but still - * valid. - * @extends {jspb.Message} - * @constructor - */ -proto.TimetableConstraints = function(opt_data) { - jspb.Message.initialize(this, opt_data, 0, -1, proto.TimetableConstraints.repeatedFields_, null); -}; -goog.inherits(proto.TimetableConstraints, jspb.Message); -if (goog.DEBUG && !COMPILED) { - /** - * @public - * @override - */ - proto.TimetableConstraints.displayName = 'proto.TimetableConstraints'; -} -/** - * Generated by JsPbCodeGenerator. - * @param {Array=} opt_data Optional initial data array, typically from a - * server response, or constructed directly in Javascript. The array is used - * in place and becomes part of the constructed object. It is not cloned. - * If no data is provided, the constructed object will be empty, but still - * valid. - * @extends {jspb.Message} - * @constructor - */ -proto.TimetableConstraints.PeriodInfo = function(opt_data) { - jspb.Message.initialize(this, opt_data, 0, -1, proto.TimetableConstraints.PeriodInfo.repeatedFields_, null); -}; -goog.inherits(proto.TimetableConstraints.PeriodInfo, jspb.Message); -if (goog.DEBUG && !COMPILED) { - /** - * @public - * @override - */ - proto.TimetableConstraints.PeriodInfo.displayName = 'proto.TimetableConstraints.PeriodInfo'; -} -/** - * Generated by JsPbCodeGenerator. - * @param {Array=} opt_data Optional initial data array, typically from a - * server response, or constructed directly in Javascript. The array is used - * in place and becomes part of the constructed object. It is not cloned. - * If no data is provided, the constructed object will be empty, but still - * valid. - * @extends {jspb.Message} - * @constructor - */ -proto.AutoTimetableResponse = function(opt_data) { - jspb.Message.initialize(this, opt_data, 0, -1, proto.AutoTimetableResponse.repeatedFields_, null); -}; -goog.inherits(proto.AutoTimetableResponse, jspb.Message); -if (goog.DEBUG && !COMPILED) { - /** - * @public - * @override - */ - proto.AutoTimetableResponse.displayName = 'proto.AutoTimetableResponse'; -} - -/** - * List of repeated fields within this message type. - * @private {!Array} - * @const - */ -proto.TimetableConstraints.repeatedFields_ = [6]; - - - -if (jspb.Message.GENERATE_TO_OBJECT) { -/** - * Creates an object representation of this proto. - * Field names that are reserved in JavaScript and will be renamed to pb_name. - * Optional fields that are not set will be set to undefined. - * To access a reserved field use, foo.pb_, eg, foo.pb_default. - * For the list of reserved names please see: - * net/proto2/compiler/js/internal/generator.cc#kKeyword. - * @param {boolean=} opt_includeInstance Deprecated. whether to include the - * JSPB instance for transitional soy proto support: - * http://goto/soy-param-migration - * @return {!Object} - */ -proto.TimetableConstraints.prototype.toObject = function(opt_includeInstance) { - return proto.TimetableConstraints.toObject(opt_includeInstance, this); -}; - - -/** - * Static version of the {@see toObject} method. - * @param {boolean|undefined} includeInstance Deprecated. Whether to include - * the JSPB instance for transitional soy proto support: - * http://goto/soy-param-migration - * @param {!proto.TimetableConstraints} msg The msg instance to transform. - * @return {!Object} - * @suppress {unusedLocalVariables} f is only used for nested messages - */ -proto.TimetableConstraints.toObject = function(includeInstance, msg) { - var f, obj = { - start: jspb.Message.getFieldWithDefault(msg, 1, 0), - end: jspb.Message.getFieldWithDefault(msg, 2, 0), - days: jspb.Message.getFieldWithDefault(msg, 3, ""), - gap: jspb.Message.getFieldWithDefault(msg, 4, 0), - maxdays: jspb.Message.getFieldWithDefault(msg, 5, 0), - periodinfoList: jspb.Message.toObjectList(msg.getPeriodinfoList(), - proto.TimetableConstraints.PeriodInfo.toObject, includeInstance) - }; - - if (includeInstance) { - obj.$jspbMessageInstance = msg; - } - return obj; -}; -} - - -/** - * Deserializes binary data (in protobuf wire format). - * @param {jspb.ByteSource} bytes The bytes to deserialize. - * @return {!proto.TimetableConstraints} - */ -proto.TimetableConstraints.deserializeBinary = function(bytes) { - var reader = new jspb.BinaryReader(bytes); - var msg = new proto.TimetableConstraints; - return proto.TimetableConstraints.deserializeBinaryFromReader(msg, reader); -}; - - -/** - * Deserializes binary data (in protobuf wire format) from the - * given reader into the given message object. - * @param {!proto.TimetableConstraints} msg The message object to deserialize into. - * @param {!jspb.BinaryReader} reader The BinaryReader to use. - * @return {!proto.TimetableConstraints} - */ -proto.TimetableConstraints.deserializeBinaryFromReader = function(msg, reader) { - while (reader.nextField()) { - if (reader.isEndGroup()) { - break; - } - var field = reader.getFieldNumber(); - switch (field) { - case 1: - var value = /** @type {number} */ (reader.readInt32()); - msg.setStart(value); - break; - case 2: - var value = /** @type {number} */ (reader.readInt32()); - msg.setEnd(value); - break; - case 3: - var value = /** @type {string} */ (reader.readString()); - msg.setDays(value); - break; - case 4: - var value = /** @type {number} */ (reader.readInt32()); - msg.setGap(value); - break; - case 5: - var value = /** @type {number} */ (reader.readInt32()); - msg.setMaxdays(value); - break; - case 6: - var value = new proto.TimetableConstraints.PeriodInfo; - reader.readMessage(value,proto.TimetableConstraints.PeriodInfo.deserializeBinaryFromReader); - msg.addPeriodinfo(value); - break; - default: - reader.skipField(); - break; - } - } - return msg; -}; - - -/** - * Serializes the message to binary data (in protobuf wire format). - * @return {!Uint8Array} - */ -proto.TimetableConstraints.prototype.serializeBinary = function() { - var writer = new jspb.BinaryWriter(); - proto.TimetableConstraints.serializeBinaryToWriter(this, writer); - return writer.getResultBuffer(); -}; - - -/** - * Serializes the given message to binary data (in protobuf wire - * format), writing to the given BinaryWriter. - * @param {!proto.TimetableConstraints} message - * @param {!jspb.BinaryWriter} writer - * @suppress {unusedLocalVariables} f is only used for nested messages - */ -proto.TimetableConstraints.serializeBinaryToWriter = function(message, writer) { - var f = undefined; - f = message.getStart(); - if (f !== 0) { - writer.writeInt32( - 1, - f - ); - } - f = message.getEnd(); - if (f !== 0) { - writer.writeInt32( - 2, - f - ); - } - f = message.getDays(); - if (f.length > 0) { - writer.writeString( - 3, - f - ); - } - f = message.getGap(); - if (f !== 0) { - writer.writeInt32( - 4, - f - ); - } - f = message.getMaxdays(); - if (f !== 0) { - writer.writeInt32( - 5, - f - ); - } - f = message.getPeriodinfoList(); - if (f.length > 0) { - writer.writeRepeatedMessage( - 6, - f, - proto.TimetableConstraints.PeriodInfo.serializeBinaryToWriter - ); - } -}; - - - -/** - * List of repeated fields within this message type. - * @private {!Array} - * @const - */ -proto.TimetableConstraints.PeriodInfo.repeatedFields_ = [2,3]; - - - -if (jspb.Message.GENERATE_TO_OBJECT) { -/** - * Creates an object representation of this proto. - * Field names that are reserved in JavaScript and will be renamed to pb_name. - * Optional fields that are not set will be set to undefined. - * To access a reserved field use, foo.pb_, eg, foo.pb_default. - * For the list of reserved names please see: - * net/proto2/compiler/js/internal/generator.cc#kKeyword. - * @param {boolean=} opt_includeInstance Deprecated. whether to include the - * JSPB instance for transitional soy proto support: - * http://goto/soy-param-migration - * @return {!Object} - */ -proto.TimetableConstraints.PeriodInfo.prototype.toObject = function(opt_includeInstance) { - return proto.TimetableConstraints.PeriodInfo.toObject(opt_includeInstance, this); -}; - - -/** - * Static version of the {@see toObject} method. - * @param {boolean|undefined} includeInstance Deprecated. Whether to include - * the JSPB instance for transitional soy proto support: - * http://goto/soy-param-migration - * @param {!proto.TimetableConstraints.PeriodInfo} msg The msg instance to transform. - * @return {!Object} - * @suppress {unusedLocalVariables} f is only used for nested messages - */ -proto.TimetableConstraints.PeriodInfo.toObject = function(includeInstance, msg) { - var f, obj = { - periodsperclass: jspb.Message.getFieldWithDefault(msg, 1, 0), - periodtimesList: (f = jspb.Message.getRepeatedFloatingPointField(msg, 2)) == null ? undefined : f, - durationsList: (f = jspb.Message.getRepeatedFloatingPointField(msg, 3)) == null ? undefined : f - }; - - if (includeInstance) { - obj.$jspbMessageInstance = msg; - } - return obj; -}; -} - - -/** - * Deserializes binary data (in protobuf wire format). - * @param {jspb.ByteSource} bytes The bytes to deserialize. - * @return {!proto.TimetableConstraints.PeriodInfo} - */ -proto.TimetableConstraints.PeriodInfo.deserializeBinary = function(bytes) { - var reader = new jspb.BinaryReader(bytes); - var msg = new proto.TimetableConstraints.PeriodInfo; - return proto.TimetableConstraints.PeriodInfo.deserializeBinaryFromReader(msg, reader); -}; - - -/** - * Deserializes binary data (in protobuf wire format) from the - * given reader into the given message object. - * @param {!proto.TimetableConstraints.PeriodInfo} msg The message object to deserialize into. - * @param {!jspb.BinaryReader} reader The BinaryReader to use. - * @return {!proto.TimetableConstraints.PeriodInfo} - */ -proto.TimetableConstraints.PeriodInfo.deserializeBinaryFromReader = function(msg, reader) { - while (reader.nextField()) { - if (reader.isEndGroup()) { - break; - } - var field = reader.getFieldNumber(); - switch (field) { - case 1: - var value = /** @type {number} */ (reader.readInt32()); - msg.setPeriodsperclass(value); - break; - case 2: - var values = /** @type {!Array} */ (reader.isDelimited() ? reader.readPackedFloat() : [reader.readFloat()]); - for (var i = 0; i < values.length; i++) { - msg.addPeriodtimes(values[i]); - } - break; - case 3: - var values = /** @type {!Array} */ (reader.isDelimited() ? reader.readPackedFloat() : [reader.readFloat()]); - for (var i = 0; i < values.length; i++) { - msg.addDurations(values[i]); - } - break; - default: - reader.skipField(); - break; - } - } - return msg; -}; - - -/** - * Serializes the message to binary data (in protobuf wire format). - * @return {!Uint8Array} - */ -proto.TimetableConstraints.PeriodInfo.prototype.serializeBinary = function() { - var writer = new jspb.BinaryWriter(); - proto.TimetableConstraints.PeriodInfo.serializeBinaryToWriter(this, writer); - return writer.getResultBuffer(); -}; - - -/** - * Serializes the given message to binary data (in protobuf wire - * format), writing to the given BinaryWriter. - * @param {!proto.TimetableConstraints.PeriodInfo} message - * @param {!jspb.BinaryWriter} writer - * @suppress {unusedLocalVariables} f is only used for nested messages - */ -proto.TimetableConstraints.PeriodInfo.serializeBinaryToWriter = function(message, writer) { - var f = undefined; - f = message.getPeriodsperclass(); - if (f !== 0) { - writer.writeInt32( - 1, - f - ); - } - f = message.getPeriodtimesList(); - if (f.length > 0) { - writer.writePackedFloat( - 2, - f - ); - } - f = message.getDurationsList(); - if (f.length > 0) { - writer.writePackedFloat( - 3, - f - ); - } -}; - - -/** - * optional int32 periodsPerClass = 1; - * @return {number} - */ -proto.TimetableConstraints.PeriodInfo.prototype.getPeriodsperclass = function() { - return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0)); -}; - - -/** - * @param {number} value - * @return {!proto.TimetableConstraints.PeriodInfo} returns this - */ -proto.TimetableConstraints.PeriodInfo.prototype.setPeriodsperclass = function(value) { - return jspb.Message.setProto3IntField(this, 1, value); -}; - - -/** - * repeated float periodTimes = 2; - * @return {!Array} - */ -proto.TimetableConstraints.PeriodInfo.prototype.getPeriodtimesList = function() { - return /** @type {!Array} */ (jspb.Message.getRepeatedFloatingPointField(this, 2)); -}; - - -/** - * @param {!Array} value - * @return {!proto.TimetableConstraints.PeriodInfo} returns this - */ -proto.TimetableConstraints.PeriodInfo.prototype.setPeriodtimesList = function(value) { - return jspb.Message.setField(this, 2, value || []); -}; - - -/** - * @param {number} value - * @param {number=} opt_index - * @return {!proto.TimetableConstraints.PeriodInfo} returns this - */ -proto.TimetableConstraints.PeriodInfo.prototype.addPeriodtimes = function(value, opt_index) { - return jspb.Message.addToRepeatedField(this, 2, value, opt_index); -}; - - -/** - * Clears the list making it empty but non-null. - * @return {!proto.TimetableConstraints.PeriodInfo} returns this - */ -proto.TimetableConstraints.PeriodInfo.prototype.clearPeriodtimesList = function() { - return this.setPeriodtimesList([]); -}; - - -/** - * repeated float durations = 3; - * @return {!Array} - */ -proto.TimetableConstraints.PeriodInfo.prototype.getDurationsList = function() { - return /** @type {!Array} */ (jspb.Message.getRepeatedFloatingPointField(this, 3)); -}; - - -/** - * @param {!Array} value - * @return {!proto.TimetableConstraints.PeriodInfo} returns this - */ -proto.TimetableConstraints.PeriodInfo.prototype.setDurationsList = function(value) { - return jspb.Message.setField(this, 3, value || []); -}; - - -/** - * @param {number} value - * @param {number=} opt_index - * @return {!proto.TimetableConstraints.PeriodInfo} returns this - */ -proto.TimetableConstraints.PeriodInfo.prototype.addDurations = function(value, opt_index) { - return jspb.Message.addToRepeatedField(this, 3, value, opt_index); -}; - - -/** - * Clears the list making it empty but non-null. - * @return {!proto.TimetableConstraints.PeriodInfo} returns this - */ -proto.TimetableConstraints.PeriodInfo.prototype.clearDurationsList = function() { - return this.setDurationsList([]); -}; - - -/** - * optional int32 start = 1; - * @return {number} - */ -proto.TimetableConstraints.prototype.getStart = function() { - return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0)); -}; - - -/** - * @param {number} value - * @return {!proto.TimetableConstraints} returns this - */ -proto.TimetableConstraints.prototype.setStart = function(value) { - return jspb.Message.setProto3IntField(this, 1, value); -}; - - -/** - * optional int32 end = 2; - * @return {number} - */ -proto.TimetableConstraints.prototype.getEnd = function() { - return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0)); -}; - - -/** - * @param {number} value - * @return {!proto.TimetableConstraints} returns this - */ -proto.TimetableConstraints.prototype.setEnd = function(value) { - return jspb.Message.setProto3IntField(this, 2, value); -}; - - -/** - * optional string days = 3; - * @return {string} - */ -proto.TimetableConstraints.prototype.getDays = function() { - return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, "")); -}; - - -/** - * @param {string} value - * @return {!proto.TimetableConstraints} returns this - */ -proto.TimetableConstraints.prototype.setDays = function(value) { - return jspb.Message.setProto3StringField(this, 3, value); -}; - - -/** - * optional int32 gap = 4; - * @return {number} - */ -proto.TimetableConstraints.prototype.getGap = function() { - return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 4, 0)); -}; - - -/** - * @param {number} value - * @return {!proto.TimetableConstraints} returns this - */ -proto.TimetableConstraints.prototype.setGap = function(value) { - return jspb.Message.setProto3IntField(this, 4, value); -}; - - -/** - * optional int32 maxdays = 5; - * @return {number} - */ -proto.TimetableConstraints.prototype.getMaxdays = function() { - return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 5, 0)); -}; - - -/** - * @param {number} value - * @return {!proto.TimetableConstraints} returns this - */ -proto.TimetableConstraints.prototype.setMaxdays = function(value) { - return jspb.Message.setProto3IntField(this, 5, value); -}; - - -/** - * repeated PeriodInfo periodInfo = 6; - * @return {!Array} - */ -proto.TimetableConstraints.prototype.getPeriodinfoList = function() { - return /** @type{!Array} */ ( - jspb.Message.getRepeatedWrapperField(this, proto.TimetableConstraints.PeriodInfo, 6)); -}; - - -/** - * @param {!Array} value - * @return {!proto.TimetableConstraints} returns this -*/ -proto.TimetableConstraints.prototype.setPeriodinfoList = function(value) { - return jspb.Message.setRepeatedWrapperField(this, 6, value); -}; - - -/** - * @param {!proto.TimetableConstraints.PeriodInfo=} opt_value - * @param {number=} opt_index - * @return {!proto.TimetableConstraints.PeriodInfo} - */ -proto.TimetableConstraints.prototype.addPeriodinfo = function(opt_value, opt_index) { - return jspb.Message.addToRepeatedWrapperField(this, 6, opt_value, proto.TimetableConstraints.PeriodInfo, opt_index); -}; - - -/** - * Clears the list making it empty but non-null. - * @return {!proto.TimetableConstraints} returns this - */ -proto.TimetableConstraints.prototype.clearPeriodinfoList = function() { - return this.setPeriodinfoList([]); -}; - - - -/** - * List of repeated fields within this message type. - * @private {!Array} - * @const - */ -proto.AutoTimetableResponse.repeatedFields_ = [1]; - - - -if (jspb.Message.GENERATE_TO_OBJECT) { -/** - * Creates an object representation of this proto. - * Field names that are reserved in JavaScript and will be renamed to pb_name. - * Optional fields that are not set will be set to undefined. - * To access a reserved field use, foo.pb_, eg, foo.pb_default. - * For the list of reserved names please see: - * net/proto2/compiler/js/internal/generator.cc#kKeyword. - * @param {boolean=} opt_includeInstance Deprecated. whether to include the - * JSPB instance for transitional soy proto support: - * http://goto/soy-param-migration - * @return {!Object} - */ -proto.AutoTimetableResponse.prototype.toObject = function(opt_includeInstance) { - return proto.AutoTimetableResponse.toObject(opt_includeInstance, this); -}; - - -/** - * Static version of the {@see toObject} method. - * @param {boolean|undefined} includeInstance Deprecated. Whether to include - * the JSPB instance for transitional soy proto support: - * http://goto/soy-param-migration - * @param {!proto.AutoTimetableResponse} msg The msg instance to transform. - * @return {!Object} - * @suppress {unusedLocalVariables} f is only used for nested messages - */ -proto.AutoTimetableResponse.toObject = function(includeInstance, msg) { - var f, obj = { - timesList: (f = jspb.Message.getRepeatedFloatingPointField(msg, 1)) == null ? undefined : f, - optimal: jspb.Message.getBooleanFieldWithDefault(msg, 2, false) - }; - - if (includeInstance) { - obj.$jspbMessageInstance = msg; - } - return obj; -}; -} - - -/** - * Deserializes binary data (in protobuf wire format). - * @param {jspb.ByteSource} bytes The bytes to deserialize. - * @return {!proto.AutoTimetableResponse} - */ -proto.AutoTimetableResponse.deserializeBinary = function(bytes) { - var reader = new jspb.BinaryReader(bytes); - var msg = new proto.AutoTimetableResponse; - return proto.AutoTimetableResponse.deserializeBinaryFromReader(msg, reader); -}; - - -/** - * Deserializes binary data (in protobuf wire format) from the - * given reader into the given message object. - * @param {!proto.AutoTimetableResponse} msg The message object to deserialize into. - * @param {!jspb.BinaryReader} reader The BinaryReader to use. - * @return {!proto.AutoTimetableResponse} - */ -proto.AutoTimetableResponse.deserializeBinaryFromReader = function(msg, reader) { - while (reader.nextField()) { - if (reader.isEndGroup()) { - break; - } - var field = reader.getFieldNumber(); - switch (field) { - case 1: - var values = /** @type {!Array} */ (reader.isDelimited() ? reader.readPackedFloat() : [reader.readFloat()]); - for (var i = 0; i < values.length; i++) { - msg.addTimes(values[i]); - } - break; - case 2: - var value = /** @type {boolean} */ (reader.readBool()); - msg.setOptimal(value); - break; - default: - reader.skipField(); - break; - } - } - return msg; -}; - - -/** - * Serializes the message to binary data (in protobuf wire format). - * @return {!Uint8Array} - */ -proto.AutoTimetableResponse.prototype.serializeBinary = function() { - var writer = new jspb.BinaryWriter(); - proto.AutoTimetableResponse.serializeBinaryToWriter(this, writer); - return writer.getResultBuffer(); -}; - - -/** - * Serializes the given message to binary data (in protobuf wire - * format), writing to the given BinaryWriter. - * @param {!proto.AutoTimetableResponse} message - * @param {!jspb.BinaryWriter} writer - * @suppress {unusedLocalVariables} f is only used for nested messages - */ -proto.AutoTimetableResponse.serializeBinaryToWriter = function(message, writer) { - var f = undefined; - f = message.getTimesList(); - if (f.length > 0) { - writer.writePackedFloat( - 1, - f - ); - } - f = message.getOptimal(); - if (f) { - writer.writeBool( - 2, - f - ); - } -}; - - -/** - * repeated float times = 1; - * @return {!Array} - */ -proto.AutoTimetableResponse.prototype.getTimesList = function() { - return /** @type {!Array} */ (jspb.Message.getRepeatedFloatingPointField(this, 1)); -}; - - -/** - * @param {!Array} value - * @return {!proto.AutoTimetableResponse} returns this - */ -proto.AutoTimetableResponse.prototype.setTimesList = function(value) { - return jspb.Message.setField(this, 1, value || []); -}; - - -/** - * @param {number} value - * @param {number=} opt_index - * @return {!proto.AutoTimetableResponse} returns this - */ -proto.AutoTimetableResponse.prototype.addTimes = function(value, opt_index) { - return jspb.Message.addToRepeatedField(this, 1, value, opt_index); -}; - - -/** - * Clears the list making it empty but non-null. - * @return {!proto.AutoTimetableResponse} returns this - */ -proto.AutoTimetableResponse.prototype.clearTimesList = function() { - return this.setTimesList([]); -}; - - -/** - * optional bool optimal = 2; - * @return {boolean} - */ -proto.AutoTimetableResponse.prototype.getOptimal = function() { - return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 2, false)); -}; - - -/** - * @param {boolean} value - * @return {!proto.AutoTimetableResponse} returns this - */ -proto.AutoTimetableResponse.prototype.setOptimal = function(value) { - return jspb.Message.setProto3BooleanField(this, 2, value); -}; - - -goog.object.extend(exports, proto); diff --git a/server/src/user/dto/index.ts b/server/src/user/dto/index.ts deleted file mode 100644 index db9f6913c..000000000 --- a/server/src/user/dto/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './settings.dto'; -export * from './user.dto'; -export * from './timetable.dto'; diff --git a/server/src/user/dto/settings.dto.ts b/server/src/user/dto/settings.dto.ts deleted file mode 100644 index 9c25d9cd8..000000000 --- a/server/src/user/dto/settings.dto.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { IsBoolean } from 'class-validator'; - -export class SettingsDto { - @IsBoolean() is12HourMode: boolean; - @IsBoolean() isDarkMode: boolean; - @IsBoolean() isSquareEdges: boolean; - @IsBoolean() isHideFullClasses: boolean; - @IsBoolean() isDefaultUnscheduled: boolean; - @IsBoolean() isHideClassInfo: boolean; - @IsBoolean() isSortAlphabetic: boolean; - @IsBoolean() isShowOnlyOpenClasses: boolean; - @IsBoolean() isHideExamClasses: boolean; - @IsBoolean() isConvertToLocalTimezone: boolean; -} diff --git a/server/src/user/dto/timetable.dto.ts b/server/src/user/dto/timetable.dto.ts deleted file mode 100644 index 0f31e8070..000000000 --- a/server/src/user/dto/timetable.dto.ts +++ /dev/null @@ -1,84 +0,0 @@ -import { IsArray, IsBoolean, IsString } from 'class-validator'; - -export class TimetableDto { - @IsString() - id: string; // Randomly generated on the backend - @IsBoolean() - isPrimary: boolean; - - @IsArray() - @IsString({ each: true }) - selectedCourses: string[]; - selectedClasses: ClassDto[]; - createdEvents: EventDto[]; - name?: string; - mapKey: string; -} - -export class ReconstructedTimetableDto { - @IsString() - id: string; // Randomly generated on the backend - @IsBoolean() - isPrimary: boolean; - - @IsArray() - @IsString({ each: true }) - selectedCourses: string[]; - selectedClasses: ScrapedClassDto[]; - createdEvents: EventDto[]; - name?: string; - mapKey: string; -} - -export class ClassDto { - id: string; - classNo: string; // From scraper - year: string; - term: string; - courseCode: string; - timetableId?: string; - activity: string; -} - -export class ClassTimeDto { - day: string; - time: { - start: string; - end: string; - }; - weeks: string; - location: string; -} - -// Get class from scraper -export class ScrapedClassDto { - classID: string; - section: string; - term: string; - activity: string; - status: string; - courseEnrolment: { - enrolments: number; - capacity: number; - }; - termDates: { - start: string; - end: string; - }; - needsConsent: boolean; - mode: string; - times: ClassTimeDto[]; - courseCode: string; - notes: []; -} - -export class EventDto { - id: string; // Frontend generated event id - name: string; - location: string; - description: string; - colour: string; - day: string; - start: Date; - end: Date; -} diff --git a/server/src/user/dto/user.dto.ts b/server/src/user/dto/user.dto.ts deleted file mode 100644 index f92d03514..000000000 --- a/server/src/user/dto/user.dto.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { - IsString, - IsEmail, - IsBoolean, - IsArray, - IsISO8601, - IsOptional, -} from 'class-validator'; -import { SettingsDto } from './settings.dto'; -import { TimetableDto } from './timetable.dto'; - -export class InitUserDTO { - @IsString() - userID: string; - - @IsString() - @IsOptional() - firstname?: string; - - @IsString() - @IsOptional() - lastname?: string; - - @IsEmail() - email: string; - - @IsString() - @IsOptional() - profileURL?: string; -} -export class UserDTO extends InitUserDTO { - @IsISO8601() - @IsOptional() - createdAt?: string; - - @IsISO8601() - @IsOptional() - lastLogin?: string; - - @IsBoolean() - loggedIn: boolean; - - @IsArray() - friends: string[]; - - @IsOptional() - settings?: SettingsDto; - - @IsArray() - timetables: TimetableDto[]; -} diff --git a/server/src/user/user.controller.spec.ts b/server/src/user/user.controller.spec.ts deleted file mode 100644 index 7057a1a89..000000000 --- a/server/src/user/user.controller.spec.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { UserController } from './user.controller'; - -describe('UserController', () => { - let controller: UserController; - - beforeEach(async () => { - const module: TestingModule = await Test.createTestingModule({ - controllers: [UserController], - }).compile(); - - controller = module.get(UserController); - }); - - it('should be defined', () => { - expect(controller).toBeDefined(); - }); -}); diff --git a/server/src/user/user.controller.ts b/server/src/user/user.controller.ts deleted file mode 100644 index f749242c2..000000000 --- a/server/src/user/user.controller.ts +++ /dev/null @@ -1,229 +0,0 @@ -import { - Body, - Controller, - Delete, - Get, - Param, - Post, - Put, - UseGuards, - Request, - HttpException, - HttpStatus, -} from '@nestjs/common'; -import { ClassDto, EventDto, InitUserDTO, TimetableDto } from './dto'; -import { UserService } from './user.service'; -import { AuthenticatedGuard } from 'src/auth/authenticated.guard'; - -@Controller('user') -export class UserController { - constructor(private userService: UserService) {} - - @UseGuards(AuthenticatedGuard) - @Get('profile/:userId') - getUserInfo(@Request() req, @Param('userId') userId: string) { - if (!req.user || userId !== req.user.userinfo.sub) { - throw new HttpException( - 'You can only access your own profile information.', - HttpStatus.FORBIDDEN, - ); - } - - return this.userService.getUserInfo(userId).then((data) => { - return { - status: 'Successsfully returned user profile', - data: { ...data, userID: userId }, - }; - }); - } - - @UseGuards(AuthenticatedGuard) - @Put('profile') - setUserInfo(@Request() req, @Body('data') data: InitUserDTO) { - if (!req.user || data.userID !== req.user.userinfo.sub) { - throw new HttpException( - 'You can only edit your own profile information.', - HttpStatus.FORBIDDEN, - ); - } - - return this.userService.setUserProfile(data).then((res) => { - return { - status: 'Successfully created user!', - data: res, - }; - }); - } - - @UseGuards(AuthenticatedGuard) - @Get('settings/:userId') - getUserSettings(@Request() req, @Param('userId') userId: string) { - if (!req.user || userId !== req.user.userinfo.sub) { - throw new HttpException( - 'You can only access your own settings.', - HttpStatus.FORBIDDEN, - ); - } - - return this.userService.getUserSettings(userId).then((data) => { - return { - status: 'Successfully found user and their settings!', - data, - }; - }); - } - - @UseGuards(AuthenticatedGuard) - @Put('settings') - // @UsePipes(new ValidationPipe({ transform: true })) - setUserSettings( - @Request() req, - @Body('userId') userId: string, - @Body('setting') setting: any, //SettingsDto - ) { - if (!req.user || userId !== req.user.userinfo.sub) { - throw new HttpException( - 'You can only edit your own settings.', - HttpStatus.FORBIDDEN, - ); - } - - return this.userService.setUserSettings(userId, setting).then((data) => { - return { - status: 'Successfully edited user settings!', - data, - }; - }); - } - - @UseGuards(AuthenticatedGuard) - @Get('timetable/:userId') - getUserTimetables(@Request() req, @Param('userId') userId: string) { - if (!req.user || userId !== req.user.userinfo.sub) { - throw new HttpException( - 'You can only access your own timetables.', - HttpStatus.FORBIDDEN, - ); - } - - return this.userService.getUserTimetables(userId).then((data) => { - return { status: `Successfully found user's timetables`, data }; - }); - } - - @UseGuards(AuthenticatedGuard) - @Post('timetable') - createUserTimetable( - @Request() req, - @Body('userId') userId: string, - @Body('isPrimary') isPrimary: boolean, - @Body('selectedCourses') selectedCourses: string[], - @Body('selectedClasses') selectedClasses: ClassDto[], - @Body('createdEvents') createdEvents: EventDto[], - @Body('mapKey') mapKey: string, - @Body('name') timetableName?: string, - ) { - if (!req.user || userId !== req.user.userinfo.sub) { - throw new HttpException( - 'You can only create timetables for your own user.', - HttpStatus.FORBIDDEN, - ); - } - - return this.userService - .createUserTimetable( - userId, - isPrimary, - selectedCourses, - selectedClasses, - createdEvents, - mapKey, - timetableName, - ) - .then((res) => { - return { - status: 'Successfully found user and created their new timetable!', - data: res, - }; - }); - } - - @UseGuards(AuthenticatedGuard) - @Put('timetable') - async editUserTimetable( - @Request() req, - @Body('userId') userId: string, - @Body('timetable') timetable: TimetableDto, - ) { - if (!req.user || userId !== req.user.userinfo.sub) { - // This is not really doing anything if the underlying function doesn't make use of the provided userId. - throw new HttpException( - 'You can only edit timetables for your own user.', - HttpStatus.FORBIDDEN, - ); - } - - return this.userService.editUserTimetable(userId, timetable).then((id) => { - return { - status: 'Successfully edited timetable', - data: { id }, - }; - }); - } - - @UseGuards(AuthenticatedGuard) - @Delete('timetable/:timetableId') - deleteUserTimetable( - @Request() req, - @Param('timetableId') timetableId: string, - ) { - return this.userService - .deleteUserTimetable(req.user.userinfo.sub, timetableId) - .then((id) => { - return { - status: 'Successfully deleted timetable', - data: { timetableId: id }, - }; - }); - } - - @UseGuards(AuthenticatedGuard) - @Get('group/:userId') - getUserGroups(@Request() req, @Param('userId') userId: string) { - if (!req.user || userId !== req.user.userinfo.sub) { - throw new HttpException( - 'You can only access your own groups.', - HttpStatus.FORBIDDEN, - ); - } - - try { - return this.userService.getGroups(userId).then((groups) => { - return { - status: `Successsfully returned groups ${userId} is apart of`, - data: { groups }, - }; - }); - } catch (e) { - return e; - } - } - - // Uncomment this and fix perms when adding groups and friends - @Get('all') - getAllUsers() { - return { status: 'This endpoint is not implemented yet.', data: [] }; - /* - try { - return this.userService.getAllUsers().then((data) => { - return { - status: 'Successsfully returned user profile', - data, - }; - }); - } catch (e) { - return e; - } - */ - } -} diff --git a/server/src/user/user.module.ts b/server/src/user/user.module.ts deleted file mode 100644 index 9c2545efd..000000000 --- a/server/src/user/user.module.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Module } from '@nestjs/common'; -import { UserService } from './user.service'; -import { UserController } from './user.controller'; -import { PrismaService } from 'src/prisma/prisma.service'; -import { GraphqlService } from 'src/graphql/graphql.service'; - -@Module({ - providers: [UserService, PrismaService, GraphqlService], - controllers: [UserController], -}) -export class UserModule {} diff --git a/server/src/user/user.service.spec.ts b/server/src/user/user.service.spec.ts deleted file mode 100644 index 873de8ac4..000000000 --- a/server/src/user/user.service.spec.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { UserService } from './user.service'; - -describe('UserService', () => { - let service: UserService; - - beforeEach(async () => { - const module: TestingModule = await Test.createTestingModule({ - providers: [UserService], - }).compile(); - - service = module.get(UserService); - }); - - it('should be defined', () => { - expect(service).toBeDefined(); - }); -}); diff --git a/server/src/user/user.service.ts b/server/src/user/user.service.ts deleted file mode 100644 index 133196213..000000000 --- a/server/src/user/user.service.ts +++ /dev/null @@ -1,465 +0,0 @@ -import { HttpException, HttpStatus, Injectable } from '@nestjs/common'; -import { - SettingsDto, - UserDTO, - EventDto, - TimetableDto, - ClassDto, - InitUserDTO, - ScrapedClassDto, - ReconstructedTimetableDto, -} from './dto'; -import { PrismaService } from 'src/prisma/prisma.service'; -import { v4 as uuidv4 } from 'uuid'; -import { User } from '@prisma/client'; -import { GroupDto } from 'src/group/dto/group.dto'; -import { GraphqlService } from 'src/graphql/graphql.service'; - -@Injectable({}) -export class UserService { - constructor( - private readonly prisma: PrismaService, - private readonly gql: GraphqlService, - ) {} - - private async convertClasses( - classes: ClassDto[], - ): Promise { - try { - // For each class in class DTO, we need to fetch information - const cache = {}; - for (const clz of classes) { - const k = `${clz.year}-${clz.term}/courses/${clz.courseCode}`; - - if (!(k in cache) && clz.classNo !== '') { - const courseInfoFetchPromise = await this.gql.fetchCourseData( - clz.courseCode, - clz.term, - clz.year, - ); - const courseInfoFetch = courseInfoFetchPromise.data.courses; - cache[k] = courseInfoFetch[0].classes; - } - } - - const res = classes.map((clz) => { - if (clz.classNo === '') - return { - classID: '', - courseCode: clz.courseCode, - activity: clz.activity, - }; - const k = `${clz.year}-${clz.term}/courses/${clz.courseCode}`; - const { - class_id, - course_enrolment, - consent, - times, - class_notes, - ...data - } = cache[k].find((c) => c.class_id === clz.classNo); - - const [enrolments, capacity] = course_enrolment.split('/'); - const [start, end] = times[0].time.replace(/\s/g, '').split('-'); - return { - ...data, - classID: class_id, - courseEnrolment: { - enrolments: Number(enrolments), - capacity: Number(capacity), - }, - termDates: { - start: '', - end: '', - }, - times: { ...times[0], time: { start, end } }, - needsConsent: consent == 'Consent not required', - courseCode: clz.courseCode, - notes: [class_notes], - }; - }); - - return res; - } catch (e) { - throw new Error(e); - } - } - - private async convertTimetable(timetable: TimetableDto): Promise { - try { - const c = await this.convertClasses(timetable.selectedClasses); - - return { - ...timetable, - selectedClasses: c, - }; - } catch (e) { - throw new Error(e); - } - } - async getUserInfo(_userID: string): Promise { - const { userID, timetables, ...userData } = - await this.prisma.user.findUniqueOrThrow({ - where: { userID: _userID }, - include: { - timetables: { - include: { - createdEvents: true, - selectedClasses: true, - }, - }, - friends: true, - outgoing: true, - incoming: true, - }, - }); - - const reconstructedTables = await Promise.all( - timetables.map(async (t) => { - return this.convertTimetable(t); - }), - ); - - const data = { - userID, - ...userData, - createdAt: userData.createdAt.toISOString(), - lastLogin: userData.lastLogin.toISOString(), - timetables: reconstructedTables, - }; - - return Promise.resolve(data); - } - - async setUserProfile(data: InitUserDTO): Promise { - try { - return Promise.resolve( - this.prisma.user.upsert({ - where: { - userID: data.userID, - }, - create: data, - update: data, - }), - ); - } catch (e) { - throw new Error(e); - } - } - - async getUserSettings(_userID: string): Promise { - try { - const { userID, ...settings } = - await this.prisma.settings.findUniqueOrThrow({ - where: { userID: _userID }, - }); - - return Promise.resolve(settings); - } catch (e) { - throw new Error(e); - } - } - - async setUserSettings( - _userID: string, - setting: SettingsDto, - ): Promise { - try { - return Promise.resolve( - this.prisma.settings.upsert({ - where: { - userID: _userID, - }, - create: { userID: _userID, ...setting }, - update: setting, - }), - ); - } catch (e) { - throw new Error(e); - } - } - - async getUserTimetables( - _userID: string, - ): Promise { - try { - const res = await this.prisma.user.findUniqueOrThrow({ - where: { userID: _userID }, - select: { - timetables: { - include: { - createdEvents: true, - selectedClasses: true, - isPrimary: true, - }, - }, - }, - }); - - const timetables = await Promise.all( - res.timetables.map(async (t) => { - return this.convertTimetable(t); - }), - ); - - return Promise.resolve(timetables); - } catch (e) { - throw new Error(e); - } - } - - async createUserTimetable( - _userID: string, - _isPrimary: boolean, - _selectedCourses: string[], - _selectedClasses: ClassDto[], - _createdEvents: EventDto[], - _mapKey: string, - _timetableName?: string, - ): Promise { - try { - // Generate random timetable id - const _timetableId = uuidv4(); - - await this.prisma.timetable.create({ - data: { - id: _timetableId, - name: _timetableName, - isPrimary: _isPrimary, - selectedCourses: _selectedCourses, - mapKey: _mapKey, - selectedClasses: { - create: _selectedClasses, - }, - createdEvents: { - create: _createdEvents, - }, - user: { - connect: { - userID: _userID, - }, - }, - }, - }); - - return Promise.resolve(_timetableId); - } catch (e) { - throw new Error(e); - } - } - - async editUserTimetable( - _userID: string, - _timetable: TimetableDto, - ): Promise { - const _timetableId = _timetable.id; - const eventIds = _timetable.createdEvents.map((event) => event.id); - const classIds = _timetable.createdEvents.map((c) => c.id); - - const timetable = await this.prisma.timetable.findFirst({ - where: { - id: _timetableId, - user: { - some: { - userID: _userID, - }, - }, - }, - }); - - if (!timetable) { - throw new HttpException( - 'Not allowed to edit this timetable', - HttpStatus.FORBIDDEN, - ); - } - - const update_timetable = this.prisma.timetable.update({ - where: { - id: _timetableId, - }, - data: { - name: _timetable.name, - isPrimary: _timetable.isPrimary, - selectedCourses: _timetable.selectedCourses, - mapKey: _timetable.mapKey, - }, - }); - - const delete_events = this.prisma.event.deleteMany({ - where: { - timetableId: _timetableId, - NOT: { - id: { in: eventIds }, - }, - }, - }); - - const update_events = _timetable.createdEvents.map((e) => - this.prisma.event.upsert({ - where: { id: e.id }, - update: e, - create: { ...e, timetableId: _timetableId }, - }), - ); - - const delete_classes = this.prisma.class.deleteMany({ - where: { - timetableId: _timetableId, - NOT: { - id: { in: classIds }, - }, - }, - }); - - const update_classes = _timetable.selectedClasses.map((c) => { - // TODO: Get the actual field instead of computing it - // classNo is currently a string such as COMP6420Undergraduate-11965-T1-2025 - // courseId should be a string such as COMP6420Undergraduate - const selectedClass = { - courseId: c.classNo.split('-')[0], - ...c, - }; - return this.prisma.class.upsert({ - where: { id: selectedClass.id }, - update: selectedClass, - create: { - ...selectedClass, - timetableId: _timetableId, - }, - }); - }); - - await this.prisma.$transaction([ - update_timetable, - delete_events, - delete_classes, - ...update_events, - ...update_classes, - ]); - - return Promise.resolve(_timetableId); - } - - async getTimetablesByIDs( - timetableIDs: string[], - ): Promise { - try { - const timetables = await this.prisma.timetable.findMany({ - where: { - id: { - in: timetableIDs, - }, - }, - include: { - createdEvents: true, - selectedClasses: true, - }, - }); - - return Promise.all( - timetables.map(async (t) => { - return this.convertTimetable(t); - }), - ); - } catch (error) { - console.error('Error retrieving timetables:', error); - } - } - - async getUsersByIDs(userIDs: string[]): Promise { - try { - const users = await this.prisma.user.findMany({ - where: { - userID: { - in: userIDs, - }, - }, - }); - return users; - } catch (error) { - console.error('Error retrieving users:', error); - } - } - - async deleteUserTimetable( - userID: string, - _timetableId: string, - ): Promise { - const timetable = await this.prisma.timetable.findFirst({ - where: { - id: _timetableId, - user: { - some: { - userID: userID, - }, - }, - }, - }); - - if (!timetable) { - throw new HttpException( - 'Not allowed to delete this timetable', - HttpStatus.FORBIDDEN, - ); - } - - try { - await this.prisma.timetable.delete({ - where: { - id: _timetableId, - }, - }); - - return Promise.resolve(_timetableId); - } catch (e) { - throw new Error(_timetableId); - } - } - - async getGroups(_userId: string) { - try { - const user = await this.prisma.user.findUniqueOrThrow({ - where: { userID: _userId }, - include: { - memberGroups: true, - adminGroups: true, - }, - }); - - const groupIds = user.adminGroups - .concat(user.memberGroups) - .map((group) => group.id); - - const res: GroupDto[] = []; - for (const groupId of groupIds) { - const group = await this.prisma.group.findUniqueOrThrow({ - where: { id: groupId }, - include: { - members: true, - groupAdmins: true, - timetables: true, - }, - }); - - res.push(group); - } - - return res; - } catch (error) { - console.error('Error retrieving users:', error); - } - } - - async getAllUsers() { - try { - const users = await this.prisma.user.findMany(); - const res = await Promise.all( - users.map((user) => this.getUserInfo(user.userID)), - ); - return res; - } catch (error) { - console.error('Error retrieving all users:', error); - } - } -} diff --git a/server/test/app.e2e-spec.ts b/server/test/app.e2e-spec.ts deleted file mode 100644 index 50cda6233..000000000 --- a/server/test/app.e2e-spec.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { INestApplication } from '@nestjs/common'; -import * as request from 'supertest'; -import { AppModule } from './../src/app.module'; - -describe('AppController (e2e)', () => { - let app: INestApplication; - - beforeEach(async () => { - const moduleFixture: TestingModule = await Test.createTestingModule({ - imports: [AppModule], - }).compile(); - - app = moduleFixture.createNestApplication(); - await app.init(); - }); - - it('/ (GET)', () => { - return request(app.getHttpServer()) - .get('/') - .expect(200) - .expect('Hello World!'); - }); -}); diff --git a/server/test/db.spec.ts b/server/test/db.spec.ts deleted file mode 100644 index ad3dd28a4..000000000 --- a/server/test/db.spec.ts +++ /dev/null @@ -1,497 +0,0 @@ -import { INestApplication } from '@nestjs/common'; -import { Test, TestingModule } from '@nestjs/testing'; -import * as request from 'supertest'; -import { AppModule } from '../src/app.module'; -import { PrismaService } from '../src/prisma/prisma.service'; -import mockData from './mockData'; - -// !! WARNING: these tests will ruin your local db container -// Before running these integration tests, spin up the DB first -describe('Integration testing for user/friend db endpoints', () => { - let app: INestApplication; - let module: TestingModule; - - beforeAll(async () => { - // To connect testing module to db container, need to change hostname to localhost. There's probably a better way to do this, but ¯\_(ツ)_/¯ idk - const prev = process.env.DATABASE_URL; - - process.env.DATABASE_URL = `postgresql://${process.env.POSTGRES_USER}:${process.env.POSTGRES_PASSWORD}@localhost:${process.env.POSTGRES_PORT}/${process.env.POSTGRES_DB}?schema=public`; - module = await Test.createTestingModule({ - imports: [AppModule], - }).compile(); - - app = module.createNestApplication(); - await app.init(); - // Change it back after we're done - process.env.DATABASE_URL = prev; - }); - - // Reset the DB before the tests - beforeEach(async () => { - const prisma = module.get(PrismaService); - await prisma.$transaction([ - prisma.settings.deleteMany(), - prisma.user.deleteMany(), - prisma.timetable.deleteMany(), - prisma.event.deleteMany(), - prisma.class.deleteMany(), - ]); - }); - - test('Basic create, read, and update tests for user and settings', async () => { - const user = mockData.users[0]; - - const setting = mockData.setting; - // Create new user - let res = await request(app.getHttpServer()) - .put('/user/profile') - .send({ data: user }); - - expect(res.status).toEqual(200); - expect(res.body.status).toEqual('Successfully created user!'); - expect(res.body.data).toMatchObject(user); - - // Fetch user profile - no friends etc - res = await request(app.getHttpServer()).get( - `/user/profile/${user.userID}`, - ); - expect(res.status).toEqual(200); - expect(res.body.status).toEqual('Successsfully returned user profile'); - expect(res.body.data).toMatchObject(user); - expect(res.body.data).toMatchObject({ - friends: [], - incoming: [], - outgoing: [], - timetables: [], - }); - - // Set settings - res = await request(app.getHttpServer()).put('/user/settings').send({ - userId: user.userID, - setting, - }); - expect(res.status).toEqual(200); - expect(res.body.data).toMatchObject(setting); - expect(res.body.status).toEqual('Successfully edited user settings!'); - - // Fetch settings - res = await request(app.getHttpServer()).get( - `/user/settings/${user.userID}`, - ); - expect(res.status).toEqual(200); - expect(res.body.data).toEqual(setting); - expect(res.body.status).toEqual( - 'Successfully found user and their settings!', - ); - - // Update user information - const modifiedUser = { - ...user, - email: 'new@outlook.com', - firstname: 'new', - profileURL: 'test', - }; - - res = await request(app.getHttpServer()) - .put('/user/profile') - .send({ data: modifiedUser }); - - expect(res.status).toEqual(200); - expect(res.body.status).toEqual('Successfully created user!'); // A bit misleading honestly, but whatever - expect(res.body.data).toMatchObject(modifiedUser); - - // Update settings - const modifiedSetting = { - ...setting, - isDarkMode: !setting.isDarkMode, - isSquareEdges: !setting.isSquareEdges, - isHideClassInfo: !setting.isHideClassInfo, - }; - - res = await request(app.getHttpServer()).put('/user/settings').send({ - userId: user.userID, - setting: modifiedSetting, - }); - expect(res.status).toEqual(200); - expect(res.body.data).toMatchObject(modifiedSetting); - expect(res.body.status).toEqual('Successfully edited user settings!'); - }); - - test('Add fetch and delete multiple timetables', async () => { - // Create user - const user = mockData.users[0]; - let res = await request(app.getHttpServer()) - .put('/user/profile') - .send({ data: user }); - expect(res.status).toEqual(200); - - // Create first timetable - (empty timetable) - const firstTimetable = mockData.timetables[0]; - - res = await request(app.getHttpServer()) - .post('/user/timetable') - .send({ userId: user.userID, ...firstTimetable }); - - expect(res.status).toEqual(201); - expect(res.body.status).toEqual( - 'Successfully found user and created their new timetable!', - ); - const firstTimetableId = res.body.data; - - // Create second timetable (filled timetable) - const secondTimetable = mockData.timetables[1]; - - res = await request(app.getHttpServer()) - .post('/user/timetable') - .send({ userId: user.userID, ...secondTimetable }); - - expect(res.status).toEqual(201); - expect(res.body.status).toEqual( - 'Successfully found user and created their new timetable!', - ); - const secondTimetableId = res.body.data; - - // Retrieve timetables - res = await request(app.getHttpServer()).get( - `/user/timetable/${user.userID}`, - ); - - expect(res.status).toEqual(200); - expect(res.body.status).toEqual(`Successfully found user's timetables`); - expect(res.body.data).toHaveLength(2); - expect(res.body.data[1]).toMatchObject({ - selectedCourses: secondTimetable.selectedCourses, - id: secondTimetableId, - name: secondTimetable.name, - }); - expect(res.body.data[1].selectedClasses).toHaveLength(2); - expect(res.body.data[1].createdEvents).toHaveLength(2); - - // Fetch user data (check if timetables are there) - res = await request(app.getHttpServer()).get( - `/user/profile/${user.userID}`, - ); - expect(res.status).toEqual(200); - expect(res.body.data).toMatchObject(user); - expect(res.body.data.timetables).toHaveLength(2); - expect(res.body.data.timetables[1]).toMatchObject({ - selectedCourses: secondTimetable.selectedCourses, - id: secondTimetableId, - name: secondTimetable.name, - }); - expect( - res.body.data.timetables[1].selectedClasses.map((c) => c.classID), - ).toEqual(secondTimetable.selectedClasses.map((c) => Number(c.classNo))); - expect(res.body.data.timetables[1].createdEvents.map((c) => c.id)).toEqual( - secondTimetable.createdEvents.map((c) => c.id), - ); - - // Delete both timetables - one at a time, and check that they're gone - res = await request(app.getHttpServer()).delete( - `/user/timetable/${firstTimetableId}`, - ); - expect(res.status).toEqual(200); - expect(res.body.status).toEqual('Successfully deleted timetable'); - expect(res.body.data).toEqual({ timetableId: firstTimetableId }); - - res = await request(app.getHttpServer()).get( - `/user/timetable/${user.userID}`, - ); - expect(res.body.data.length).toEqual(1); - - res = await request(app.getHttpServer()).delete( - `/user/timetable/${secondTimetableId}`, - ); - expect(res.status).toEqual(200); - - res = await request(app.getHttpServer()).get( - `/user/timetable/${user.userID}`, - ); - expect(res.body.data.length).toEqual(0); - }); - - test('Update timetables', async () => { - const timetable = mockData.timetables[2]; - - // Create user and timetable - const user = mockData.users[0]; - let res = await request(app.getHttpServer()) - .put('/user/profile') - .send({ data: user }); - expect(res.status).toEqual(200); - - res = await request(app.getHttpServer()) - .post('/user/timetable') - .send({ userId: user.userID, ...timetable }); - - expect(res.status).toEqual(201); - expect(res.body.status).toEqual( - 'Successfully found user and created their new timetable!', - ); - - const timetableId = res.body.data; - - // Edit timetable (remove one class/event, add one new one, edit one, and leave one the same) - const editedTimetable = { - name: 'updated timetable', - selectedCourses: ['COMP2511', 'COMP2521'], - selectedClasses: [ - timetable.selectedClasses[1], - { ...timetable.selectedClasses[2], term: 'T1', classNo: '8839' }, - { - id: 'c4', - classNo: '8930', - year: '2024', - term: 'T2', - courseCode: 'COMP2521', - }, - ], - createdEvents: [ - timetable.createdEvents[1], - { - ...timetable.createdEvents[2], - name: 'update', - location: 'Underground bunker #12', - colour: '111111', - end: '2018-11-22T13:28:06.419Z', - }, - { - id: 'e4', - name: 'New event', - location: 'Outer space', - colour: '123456', - day: 'Thursday', - start: '2013-10-21T13:28:06.419Z', - end: '2013-10-21T13:28:06.419Z', - }, - ], - }; - res = await request(app.getHttpServer()) - .put('/user/timetable') - .send({ - userId: user.userID, - timetable: { id: timetableId, ...editedTimetable }, - }); - - expect(res.status).toEqual(200); - expect(res.body.status).toEqual('Successfully edited timetable'); - expect(res.body.data).toEqual({ id: timetableId }); - - // Finally, check if timetable is correctly updated - res = await request(app.getHttpServer()).get( - `/user/timetable/${user.userID}`, - ); - expect(res.body.data.length).toEqual(1); - expect(res.body.data[0].selectedClasses.map((c) => c.classID)).toEqual( - editedTimetable.selectedClasses.map((c) => Number(c.classNo)), - ); - expect(res.body.data[0].createdEvents.map((c) => c.id)).toEqual( - editedTimetable.createdEvents.map((c) => c.id), - ); - }); - - describe('User error tests', () => { - let res; - test(`User profile doesn't exist`, async () => { - res = await request(app.getHttpServer()).get('/user/profile/1'); - expect(res.status); - }); - - test(`Settings don't exist`, async () => { - res = await request(app.getHttpServer()).get(`/user/settings/1`); - expect(res.status).not.toEqual(200); - expect(res.status).not.toEqual(201); - // Create user without settings - const user = mockData.users[0]; - res = await request(app.getHttpServer()) - .put('/user/profile') - .send({ data: user }); - - res = await request(app.getHttpServer()).get( - `/user/settings/${user.userID}`, - ); - expect(res.status).not.toEqual(200); - expect(res.status).not.toEqual(201); - }); - - test(`Edit timetable`, async () => { - res = await request(app.getHttpServer()) - .put('/user/timetable') - .send({ timetable: mockData.timetables[0] }); - expect(res.status).not.toEqual(200); - expect(res.status).not.toEqual(201); - }); - - test(`Delete timetable`, async () => { - res = await request(app.getHttpServer()).delete('/user/timetable/1'); - expect(res.status).not.toEqual(200); - expect(res.status).not.toEqual(201); - }); - }); - - describe('Friends tests', () => { - const [user1, user2, user3] = mockData.users; - beforeEach(async () => { - for (const user of [user1, user2, user3]) { - const res = await request(app.getHttpServer()) - .put('/user/profile') - .send({ data: user }); - - if (res.status !== 200) { - throw new Error('Failed to populate users'); - } - } - }); - - test('User1 and user2 - rejected friend request', async () => { - // User1 sends request to user2 - let res = await request(app.getHttpServer()) - .post('/friend/request') - .send({ senderId: user1.userID, sendeeId: user2.userID }); - expect(res.status).toEqual(201); - expect(res.body.status).toEqual('Successfully sent friend request'); - expect(res.body.data).toEqual({ id: user2.userID }); - - // Check user profiles are valid - res = await request(app.getHttpServer()).get( - `/user/profile/${user1.userID}`, - ); - expect(res.status).toEqual(200); - expect(res.body.data).toMatchObject({ - friends: [], - incoming: [], - }); - expect(res.body.data.outgoing).toHaveLength(1); - expect(res.body.data.outgoing[0]).toMatchObject(user2); - - res = await request(app.getHttpServer()).get( - `/user/profile/${user2.userID}`, - ); - expect(res.status).toEqual(200); - expect(res.body.data).toMatchObject({ - friends: [], - outgoing: [], - }); - expect(res.body.data.incoming).toHaveLength(1); - expect(res.body.data.incoming[0]).toMatchObject(user1); - - // User 2 rejects friend request/user 1 revokes friend request - res = await request(app.getHttpServer()).delete(`/friend/request`).send({ - senderId: user1.userID, - sendeeId: user2.userID, - }); - expect(res.status).toEqual(200); - expect(res.body.status).toEqual('Successfully rejected friend request!'); - expect(res.body.data).toEqual({ senderId: user1.userID }); - - res = await request(app.getHttpServer()).get( - `/user/profile/${user1.userID}`, - ); - expect(res.status).toEqual(200); - expect(res.body.data).toMatchObject({ - friends: [], - incoming: [], - outgoing: [], - }); - }); - - test('User 1 sends req to 2, accepts req from 1, then removes both (both sides of transaction). Tests getFriends to confirm', async () => { - // User 1 sends friend request to 2 - let res = await request(app.getHttpServer()) - .post('/friend/request') - .send({ senderId: user1.userID, sendeeId: user2.userID }); - expect(res.status).toEqual(201); - - // User 3 sends friend request to user 1 - res = await request(app.getHttpServer()) - .post('/friend/request') - .send({ senderId: user3.userID, sendeeId: user1.userID }); - expect(res.status).toEqual(201); - - // Confirm that user1 is not friends with anyone currently - res = await request(app.getHttpServer()).get(`/friend/${user1.userID}`); - expect(res.status).toEqual(200); - expect(res.body.status).toEqual("Found user's friends"); - expect(res.body.data).toHaveLength(0); - - // User 1 accepts friend request from 3 - res = await request(app.getHttpServer()) - .post('/friend/request') - .send({ senderId: user1.userID, sendeeId: user3.userID }); - expect(res.status).toEqual(201); - - // User 2 confirms friend request from 1 - res = await request(app.getHttpServer()) - .post('/friend/request') - .send({ senderId: user2.userID, sendeeId: user1.userID }); - expect(res.status).toEqual(201); - - // Confirm user 1 is friends with both now - res = await request(app.getHttpServer()).get(`/friend/${user1.userID}`); - expect(res.status).toEqual(200); - expect(res.body.data).toHaveLength(2); - expect(res.body.data.map((u) => u.userID)).toEqual( - expect.arrayContaining([user2.userID, user3.userID]), - ); - - // User 1 unfriends user 3 - res = await request(app.getHttpServer()) - .delete('/friend') - .send({ senderId: user1.userID, sendeeId: user3.userID }); - expect(res.status).toEqual(200); - - // User 2 unfriends user 1 - res = await request(app.getHttpServer()) - .delete('/friend') - .send({ senderId: user2.userID, sendeeId: user1.userID }); - expect(res.status).toEqual(200); - - // Check that user has no friends again :( - res = await request(app.getHttpServer()).get(`/friend/${user1.userID}`); - expect(res.status).toEqual(200); - expect(res.body.data).toHaveLength(0); - }); - - test('Basic friend errors', async () => { - // Friend request to someone that doesn't exist - let res = await request(app.getHttpServer()) - .post('/friend/request') - .send({ senderId: user1.userID, sendeeId: 'INVALID' }); - expect(res.status).not.toEqual(200); - expect(res.status).not.toEqual(201); - - // Friend request by person that doesn't exist - res = await request(app.getHttpServer()) - .post('/friend/request') - .send({ senderId: 'INVALID', sendeeId: user1.userID }); - expect(res.status).not.toEqual(200); - expect(res.status).not.toEqual(201); - }); - - // These tests below commented out, because updating object to disconnect a relation that doesn't exist - // actually does not throw an error. - // To cover these errors, we would have to send another query beforehand - this can be done, but introduces - // more overhead. Whether we should depends on frontend implementation - - // test('Friend errors - edge cases', async () => { - // // Unfriend request to someone with no outstanding friend request - // let res = await request(app.getHttpServer()) - // .delete('/friend') - // .send({ senderId: user1.userID, sendeeId: user3.userID }); - // expect(res.status).not.toEqual(200); - // expect(res.status).not.toEqual(201); - - // // Friend requesting someone who is already a friend - // res = await request(app.getHttpServer()) - // .post('/friend') - // .send({ senderId: user1.userID, sendeeId: user2.userID }); - // expect(res.status).toEqual(201); - - // res = await request(app.getHttpServer()) - // .post('/friend/request') - // .send({ senderId: user1.userID, sendeeId: user2.userID }); - // expect(res.status).not.toEqual(200); - // expect(res.status).not.toEqual(201); - // }); - }); -}); diff --git a/server/test/jest-e2e.json b/server/test/jest-e2e.json deleted file mode 100644 index e9d912f3e..000000000 --- a/server/test/jest-e2e.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "moduleFileExtensions": ["js", "json", "ts"], - "rootDir": ".", - "testEnvironment": "node", - "testRegex": ".e2e-spec.ts$", - "transform": { - "^.+\\.(t|j)s$": "ts-jest" - } -} diff --git a/server/test/mockData.ts b/server/test/mockData.ts deleted file mode 100644 index 310e31baf..000000000 --- a/server/test/mockData.ts +++ /dev/null @@ -1,143 +0,0 @@ -const mockData = { - users: [ - { - userID: 'z55555555', - firstname: 'First', - lastname: 'Last', - email: 'test@gmail.com', - profileURL: 'images.google.com/blahblah', - }, - { - userID: 'z66666666', - firstname: 'B', - lastname: '', - email: 'second@gmail.com', - profileURL: '', - }, - { - userID: 'z77777777', - firstname: 'C', - lastname: '', - email: 'third@gmail.com', - profileURL: '', - }, - ], - setting: { - is12HourMode: true, - isDarkMode: true, - isSquareEdges: true, - isHideFullClasses: true, - isDefaultUnscheduled: true, - isHideClassInfo: true, - isSortAlphabetic: true, - isShowOnlyOpenClasses: true, - isHideExamClasses: false, - isConvertToLocalTimezone: true, - }, - timetables: [ - { - selectedCourses: [], - selectedClasses: [], - createdEvents: [], - name: 'timetable1', - }, - { - selectedCourses: ['COMP1511', 'COMP2511'], - selectedClasses: [ - { - id: 'c1', - classNo: '8713', - year: '2024', - term: 'T1', - courseCode: 'COMP1511', - }, - { - id: 'c2', - classNo: '8714', - year: '2024', - term: 'T1', - courseCode: 'COMP1511', - }, - ], - createdEvents: [ - { - id: 'e1', - name: 'event1', - location: 'UNSW', - colour: 'FFFFFF', - day: 'Monday', - start: '2013-10-21T13:28:06.419Z', - end: '2013-10-21T13:28:06.419Z', - }, - { - id: 'e2', - name: 'event2', - location: 'Online', - colour: '000000', - day: 'Tuesday', - start: '2013-10-21T13:28:06.419Z', - end: '2013-10-21T13:28:06.419Z', - }, - ], - name: 'timetable2', - }, - { - selectedCourses: ['COMP1511', 'COMP2511'], - selectedClasses: [ - { - id: 'c1', - classNo: '8713', - year: '2024', - term: 'T1', - courseCode: 'COMP1511', - }, - { - id: 'c2', - classNo: '8714', - year: '2024', - term: 'T1', - courseCode: 'COMP1511', - }, - { - id: 'c3', - classNo: '8890', - year: '2024', - term: 'T2', - courseCode: 'COMP2511', - }, - ], - createdEvents: [ - { - id: 'e1', - name: 'event1', - location: 'UNSW', - colour: 'FFFFFF', - day: 'Monday', - start: '2013-10-21T13:28:06.419Z', - end: '2013-10-21T13:28:06.419Z', - }, - { - id: 'e2', - name: 'event2', - location: 'Online', - colour: '000000', - day: 'Tuesday', - start: '2013-10-21T13:28:06.419Z', - end: '2013-10-21T13:28:06.419Z', - }, - { - id: 'e3', - name: 'event3', - location: 'CBD', - colour: '000000', - day: 'Friday', - start: '2013-10-21T13:28:06.419Z', - end: '2013-10-21T13:28:06.419Z', - }, - ], - name: 'my timetable', - }, - ], -}; - -export default mockData; diff --git a/server/tsconfig.build.json b/server/tsconfig.build.json deleted file mode 100644 index 64f86c6bd..000000000 --- a/server/tsconfig.build.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "extends": "./tsconfig.json", - "exclude": ["node_modules", "test", "dist", "**/*spec.ts"] -} diff --git a/server/tsconfig.json b/server/tsconfig.json deleted file mode 100644 index 95f5641cf..000000000 --- a/server/tsconfig.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "compilerOptions": { - "module": "commonjs", - "declaration": true, - "removeComments": true, - "emitDecoratorMetadata": true, - "experimentalDecorators": true, - "allowSyntheticDefaultImports": true, - "target": "ES2021", - "sourceMap": true, - "outDir": "./dist", - "baseUrl": "./", - "incremental": true, - "skipLibCheck": true, - "strictNullChecks": false, - "noImplicitAny": false, - "strictBindCallApply": false, - "forceConsistentCasingInFileNames": false, - "noFallthroughCasesInSwitch": false - } -} From 348aa1b0b2ff40e516045a95637964b65ba1cfb1 Mon Sep 17 00:00:00 2001 From: Lucas Date: Thu, 29 May 2025 14:25:52 +1000 Subject: [PATCH 02/33] Add new server --- server/.gitignore | 58 + server/.prettierrc | 4 + server/eslint.config.mjs | 34 + server/nest-cli.json | 8 + server/package.json | 82 + server/pnpm-lock.yaml | 7245 +++++++++++++++++ server/pnpm-workspace.yaml | 6 + .../20250523064317_inital/migration.sql | 83 + server/prisma/migrations/migration_lock.toml | 3 + server/prisma/schema.prisma | 113 + server/src/app.controller.spec.ts | 22 + server/src/app.controller.ts | 12 + server/src/app.module.ts | 20 + server/src/app.service.ts | 8 + server/src/auth/authenticated.guard.ts | 11 + server/src/config.ts | 4 + server/src/main.ts | 35 + server/src/prisma/prisma.service.ts | 9 + server/src/types/express.d.ts | 9 + server/src/user/types.ts | 17 + server/src/user/user.controller.ts | 38 + server/src/user/user.module.ts | 10 + server/src/user/user.service.ts | 67 + server/test/app.e2e-spec.ts | 25 + server/test/jest-e2e.json | 9 + server/tsconfig.build.json | 4 + server/tsconfig.json | 21 + 27 files changed, 7957 insertions(+) create mode 100644 server/.gitignore create mode 100644 server/.prettierrc create mode 100644 server/eslint.config.mjs create mode 100644 server/nest-cli.json create mode 100644 server/package.json create mode 100644 server/pnpm-lock.yaml create mode 100644 server/pnpm-workspace.yaml create mode 100644 server/prisma/migrations/20250523064317_inital/migration.sql create mode 100644 server/prisma/migrations/migration_lock.toml create mode 100644 server/prisma/schema.prisma create mode 100644 server/src/app.controller.spec.ts create mode 100644 server/src/app.controller.ts create mode 100644 server/src/app.module.ts create mode 100644 server/src/app.service.ts create mode 100644 server/src/auth/authenticated.guard.ts create mode 100644 server/src/config.ts create mode 100644 server/src/main.ts create mode 100644 server/src/prisma/prisma.service.ts create mode 100644 server/src/types/express.d.ts create mode 100644 server/src/user/types.ts create mode 100644 server/src/user/user.controller.ts create mode 100644 server/src/user/user.module.ts create mode 100644 server/src/user/user.service.ts create mode 100644 server/test/app.e2e-spec.ts create mode 100644 server/test/jest-e2e.json create mode 100644 server/tsconfig.build.json create mode 100644 server/tsconfig.json diff --git a/server/.gitignore b/server/.gitignore new file mode 100644 index 000000000..f4e217f77 --- /dev/null +++ b/server/.gitignore @@ -0,0 +1,58 @@ +# compiled output +/dist +/node_modules +/build + +# Logs +logs +*.log +npm-debug.log* +pnpm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* + +# OS +.DS_Store + +# Tests +/coverage +/.nyc_output + +# IDEs and editors +/.idea +.project +.classpath +.c9/ +*.launch +.settings/ +*.sublime-workspace + +# IDE - VSCode +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json + +# dotenv environment variable files +.env +.env.development.local +.env.test.local +.env.production.local +.env.local + +# temp directory +.temp +.tmp + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +src/generated/* diff --git a/server/.prettierrc b/server/.prettierrc new file mode 100644 index 000000000..dcb72794f --- /dev/null +++ b/server/.prettierrc @@ -0,0 +1,4 @@ +{ + "singleQuote": true, + "trailingComma": "all" +} \ No newline at end of file diff --git a/server/eslint.config.mjs b/server/eslint.config.mjs new file mode 100644 index 000000000..caebf6e70 --- /dev/null +++ b/server/eslint.config.mjs @@ -0,0 +1,34 @@ +// @ts-check +import eslint from '@eslint/js'; +import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended'; +import globals from 'globals'; +import tseslint from 'typescript-eslint'; + +export default tseslint.config( + { + ignores: ['eslint.config.mjs'], + }, + eslint.configs.recommended, + ...tseslint.configs.recommendedTypeChecked, + eslintPluginPrettierRecommended, + { + languageOptions: { + globals: { + ...globals.node, + ...globals.jest, + }, + sourceType: 'commonjs', + parserOptions: { + projectService: true, + tsconfigRootDir: import.meta.dirname, + }, + }, + }, + { + rules: { + '@typescript-eslint/no-explicit-any': 'off', + '@typescript-eslint/no-floating-promises': 'warn', + '@typescript-eslint/no-unsafe-argument': 'warn' + }, + }, +); \ No newline at end of file diff --git a/server/nest-cli.json b/server/nest-cli.json new file mode 100644 index 000000000..f9aa683b1 --- /dev/null +++ b/server/nest-cli.json @@ -0,0 +1,8 @@ +{ + "$schema": "https://json.schemastore.org/nest-cli", + "collection": "@nestjs/schematics", + "sourceRoot": "src", + "compilerOptions": { + "deleteOutDir": true + } +} diff --git a/server/package.json b/server/package.json new file mode 100644 index 000000000..81fd31ffc --- /dev/null +++ b/server/package.json @@ -0,0 +1,82 @@ +{ + "name": "server", + "version": "0.0.1", + "description": "", + "author": "", + "private": true, + "license": "UNLICENSED", + "scripts": { + "build": "nest build", + "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"", + "start": "nest start", + "start:dev": "nest start --watch", + "start:debug": "nest start --debug --watch", + "start:prod": "node dist/main", + "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix", + "test": "jest", + "test:watch": "jest --watch", + "test:cov": "jest --coverage", + "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand", + "test:e2e": "jest --config ./test/jest-e2e.json" + }, + "dependencies": { + "@nestjs/common": "11.1.1", + "@nestjs/config": "4.0.2", + "@nestjs/core": "11.1.1", + "@nestjs/passport": "11.0.5", + "@nestjs/platform-express": "11.1.1", + "@prisma/client": "6.8.2", + "express-session": "1.18.1", + "passport": "0.7.0", + "reflect-metadata": "0.2.2", + "rxjs": "7.8.2" + }, + "devDependencies": { + "@eslint/eslintrc": "3.3.1", + "@eslint/js": "9.27.0", + "@nestjs/cli": "11.0.7", + "@nestjs/schematics": "11.0.5", + "@nestjs/testing": "11.1.1", + "@swc/cli": "0.6.0", + "@swc/core": "1.11.29", + "@types/express": "5.0.2", + "@types/express-session": "1.18.1", + "@types/jest": "29.5.14", + "@types/node": "22.15.21", + "@types/passport": "1.0.17", + "@types/supertest": "6.0.3", + "eslint": "9.27.0", + "eslint-config-prettier": "10.1.5", + "eslint-plugin-prettier": "5.4.0", + "globals": "16.1.0", + "jest": "29.7.0", + "prettier": "3.5.3", + "prisma": "6.8.2", + "source-map-support": "0.5.21", + "supertest": "7.1.1", + "ts-jest": "29.3.4", + "ts-loader": "9.5.2", + "ts-node": "10.9.2", + "tsconfig-paths": "4.2.0", + "typescript": "5.8.3", + "typescript-eslint": "8.32.1" + }, + "jest": { + "moduleFileExtensions": [ + "js", + "json", + "ts" + ], + "rootDir": "src", + "testRegex": ".*\\.spec\\.ts$", + "transform": { + "^.+\\.(t|j)s$": "ts-jest" + }, + "collectCoverageFrom": [ + "**/*.(t|j)s" + ], + "coverageDirectory": "../coverage", + "testEnvironment": "node" + }, + "packageManager": "pnpm@10.11.0+sha512.6540583f41cc5f628eb3d9773ecee802f4f9ef9923cc45b69890fb47991d4b092964694ec3a4f738a420c918a333062c8b925d312f42e4f0c263eb603551f977" +} diff --git a/server/pnpm-lock.yaml b/server/pnpm-lock.yaml new file mode 100644 index 000000000..ccd99eec1 --- /dev/null +++ b/server/pnpm-lock.yaml @@ -0,0 +1,7245 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@nestjs/common': + specifier: 11.1.1 + version: 11.1.1(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/config': + specifier: 4.0.2 + version: 4.0.2(@nestjs/common@11.1.1(reflect-metadata@0.2.2)(rxjs@7.8.2))(rxjs@7.8.2) + '@nestjs/core': + specifier: 11.1.1 + version: 11.1.1(@nestjs/common@11.1.1(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/passport': + specifier: 11.0.5 + version: 11.0.5(@nestjs/common@11.1.1(reflect-metadata@0.2.2)(rxjs@7.8.2))(passport@0.7.0) + '@nestjs/platform-express': + specifier: 11.1.1 + version: 11.1.1(@nestjs/common@11.1.1(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.1) + '@prisma/client': + specifier: 6.8.2 + version: 6.8.2(prisma@6.8.2(typescript@5.8.3))(typescript@5.8.3) + express-session: + specifier: 1.18.1 + version: 1.18.1 + passport: + specifier: 0.7.0 + version: 0.7.0 + reflect-metadata: + specifier: 0.2.2 + version: 0.2.2 + rxjs: + specifier: 7.8.2 + version: 7.8.2 + devDependencies: + '@eslint/eslintrc': + specifier: 3.3.1 + version: 3.3.1 + '@eslint/js': + specifier: 9.27.0 + version: 9.27.0 + '@nestjs/cli': + specifier: 11.0.7 + version: 11.0.7(@swc/cli@0.6.0(@swc/core@1.11.29)(chokidar@4.0.3))(@swc/core@1.11.29)(@types/node@22.15.21) + '@nestjs/schematics': + specifier: 11.0.5 + version: 11.0.5(chokidar@4.0.3)(typescript@5.8.3) + '@nestjs/testing': + specifier: 11.1.1 + version: 11.1.1(@nestjs/common@11.1.1(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.1)(@nestjs/platform-express@11.1.1) + '@swc/cli': + specifier: 0.6.0 + version: 0.6.0(@swc/core@1.11.29)(chokidar@4.0.3) + '@swc/core': + specifier: 1.11.29 + version: 1.11.29 + '@types/express': + specifier: 5.0.2 + version: 5.0.2 + '@types/express-session': + specifier: 1.18.1 + version: 1.18.1 + '@types/jest': + specifier: 29.5.14 + version: 29.5.14 + '@types/node': + specifier: 22.15.21 + version: 22.15.21 + '@types/passport': + specifier: 1.0.17 + version: 1.0.17 + '@types/supertest': + specifier: 6.0.3 + version: 6.0.3 + eslint: + specifier: 9.27.0 + version: 9.27.0(jiti@2.4.2) + eslint-config-prettier: + specifier: 10.1.5 + version: 10.1.5(eslint@9.27.0(jiti@2.4.2)) + eslint-plugin-prettier: + specifier: 5.4.0 + version: 5.4.0(@types/eslint@9.6.1)(eslint-config-prettier@10.1.5(eslint@9.27.0(jiti@2.4.2)))(eslint@9.27.0(jiti@2.4.2))(prettier@3.5.3) + globals: + specifier: 16.1.0 + version: 16.1.0 + jest: + specifier: 29.7.0 + version: 29.7.0(@types/node@22.15.21)(ts-node@10.9.2(@swc/core@1.11.29)(@types/node@22.15.21)(typescript@5.8.3)) + prettier: + specifier: 3.5.3 + version: 3.5.3 + prisma: + specifier: 6.8.2 + version: 6.8.2(typescript@5.8.3) + source-map-support: + specifier: 0.5.21 + version: 0.5.21 + supertest: + specifier: 7.1.1 + version: 7.1.1 + ts-jest: + specifier: 29.3.4 + version: 29.3.4(@babel/core@7.27.1)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.27.1))(jest@29.7.0(@types/node@22.15.21)(ts-node@10.9.2(@swc/core@1.11.29)(@types/node@22.15.21)(typescript@5.8.3)))(typescript@5.8.3) + ts-loader: + specifier: 9.5.2 + version: 9.5.2(typescript@5.8.3)(webpack@5.99.6(@swc/core@1.11.29)) + ts-node: + specifier: 10.9.2 + version: 10.9.2(@swc/core@1.11.29)(@types/node@22.15.21)(typescript@5.8.3) + tsconfig-paths: + specifier: 4.2.0 + version: 4.2.0 + typescript: + specifier: 5.8.3 + version: 5.8.3 + typescript-eslint: + specifier: 8.32.1 + version: 8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3) + +packages: + + '@ampproject/remapping@2.3.0': + resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} + engines: {node: '>=6.0.0'} + + '@angular-devkit/core@19.2.6': + resolution: {integrity: sha512-WFgiYhrDMq83UNaGRAneIM7CYYdBozD+yYA9BjoU8AgBLKtrvn6S8ZcjKAk5heoHtY/u8pEb0mwDTz9gxFmJZQ==} + engines: {node: ^18.19.1 || ^20.11.1 || >=22.0.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} + peerDependencies: + chokidar: ^4.0.0 + peerDependenciesMeta: + chokidar: + optional: true + + '@angular-devkit/core@19.2.8': + resolution: {integrity: sha512-kcxUHKf5Hi98r4gAvMP3ntJV8wuQ3/i6wuU9RcMP0UKUt2Rer5Ryis3MPqT92jvVVwg6lhrLIhXsFuWJMiYjXQ==} + engines: {node: ^18.19.1 || ^20.11.1 || >=22.0.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} + peerDependencies: + chokidar: ^4.0.0 + peerDependenciesMeta: + chokidar: + optional: true + + '@angular-devkit/schematics-cli@19.2.8': + resolution: {integrity: sha512-RFnlyu4Ld8I4xvu/eqrhjbQ6kQTr27w79omMiTbQcQZvP3E6oUyZdBjobyih4Np+1VVQrbdEeNz76daP2iUDig==} + engines: {node: ^18.19.1 || ^20.11.1 || >=22.0.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} + hasBin: true + + '@angular-devkit/schematics@19.2.6': + resolution: {integrity: sha512-YTAxNnT++5eflx19OUHmOWu597/TbTel+QARiZCv1xQw99+X8DCKKOUXtqBRd53CAHlREDI33Rn/JLY3NYgMLQ==} + engines: {node: ^18.19.1 || ^20.11.1 || >=22.0.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} + + '@angular-devkit/schematics@19.2.8': + resolution: {integrity: sha512-QsmFuYdAyeCyg9WF/AJBhFXDUfCwmDFTEbsv5t5KPSP6slhk0GoLNZApniiFytU2siRlSxVNpve2uATyYuAYkQ==} + engines: {node: ^18.19.1 || ^20.11.1 || >=22.0.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} + + '@babel/code-frame@7.27.1': + resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} + engines: {node: '>=6.9.0'} + + '@babel/compat-data@7.27.2': + resolution: {integrity: sha512-TUtMJYRPyUb/9aU8f3K0mjmjf6M9N5Woshn2CS6nqJSeJtTtQcpLUXjGt9vbF8ZGff0El99sWkLgzwW3VXnxZQ==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.27.1': + resolution: {integrity: sha512-IaaGWsQqfsQWVLqMn9OB92MNN7zukfVA4s7KKAI0KfrrDsZ0yhi5uV4baBuLuN7n3vsZpwP8asPPcVwApxvjBQ==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.27.1': + resolution: {integrity: sha512-UnJfnIpc/+JO0/+KRVQNGU+y5taA5vCbwN8+azkX6beii/ZF+enZJSOKo11ZSzGJjlNfJHfQtmQT8H+9TXPG2w==} + engines: {node: '>=6.9.0'} + + '@babel/helper-compilation-targets@7.27.2': + resolution: {integrity: sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-imports@7.27.1': + resolution: {integrity: sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-transforms@7.27.1': + resolution: {integrity: sha512-9yHn519/8KvTU5BjTVEEeIM3w9/2yXNKoD82JifINImhpKkARMJKPP59kLo+BafpdN5zgNeIcS4jsGDmd3l58g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-plugin-utils@7.27.1': + resolution: {integrity: sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-string-parser@7.27.1': + resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.27.1': + resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-option@7.27.1': + resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} + engines: {node: '>=6.9.0'} + + '@babel/helpers@7.27.1': + resolution: {integrity: sha512-FCvFTm0sWV8Fxhpp2McP5/W53GPllQ9QeQ7SiqGWjMf/LVG07lFa5+pgK05IRhVwtvafT22KF+ZSnM9I545CvQ==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.27.2': + resolution: {integrity: sha512-QYLs8299NA7WM/bZAdp+CviYYkVoYXlDW2rzliy3chxd1PQjej7JORuMJDJXJUb9g0TT+B99EwaVLKmX+sPXWw==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/plugin-syntax-async-generators@7.8.4': + resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-bigint@7.8.3': + resolution: {integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-class-properties@7.12.13': + resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-class-static-block@7.14.5': + resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-import-attributes@7.27.1': + resolution: {integrity: sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-import-meta@7.10.4': + resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-json-strings@7.8.3': + resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-jsx@7.27.1': + resolution: {integrity: sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-logical-assignment-operators@7.10.4': + resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3': + resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-numeric-separator@7.10.4': + resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-object-rest-spread@7.8.3': + resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-optional-catch-binding@7.8.3': + resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-optional-chaining@7.8.3': + resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-private-property-in-object@7.14.5': + resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-top-level-await@7.14.5': + resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-typescript@7.27.1': + resolution: {integrity: sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/template@7.27.2': + resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==} + engines: {node: '>=6.9.0'} + + '@babel/traverse@7.27.1': + resolution: {integrity: sha512-ZCYtZciz1IWJB4U61UPu4KEaqyfj+r5T1Q5mqPo+IBpcG9kHv30Z0aD8LXPgC1trYa6rK0orRyAhqUgk4MjmEg==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.27.1': + resolution: {integrity: sha512-+EzkxvLNfiUeKMgy/3luqfsCWFRXLb7U6wNQTk60tovuckwB15B191tJWvpp4HjiQWdJkCxO3Wbvc6jlk3Xb2Q==} + engines: {node: '>=6.9.0'} + + '@bcoe/v8-coverage@0.2.3': + resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} + + '@colors/colors@1.5.0': + resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==} + engines: {node: '>=0.1.90'} + + '@cspotcode/source-map-support@0.8.1': + resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} + engines: {node: '>=12'} + + '@eslint-community/eslint-utils@4.7.0': + resolution: {integrity: sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + + '@eslint-community/regexpp@4.12.1': + resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + + '@eslint/config-array@0.20.0': + resolution: {integrity: sha512-fxlS1kkIjx8+vy2SjuCB94q3htSNrufYTXubwiBFeaQHbH6Ipi43gFJq2zCMt6PHhImH3Xmr0NksKDvchWlpQQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/config-helpers@0.2.2': + resolution: {integrity: sha512-+GPzk8PlG0sPpzdU5ZvIRMPidzAnZDl/s9L+y13iodqvb8leL53bTannOrQ/Im7UkpsmFU5Ily5U60LWixnmLg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/core@0.14.0': + resolution: {integrity: sha512-qIbV0/JZr7iSDjqAc60IqbLdsj9GDt16xQtWD+B78d/HAlvysGdZZ6rpJHGAc2T0FQx1X6thsSPdnoiGKdNtdg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/eslintrc@3.3.1': + resolution: {integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/js@9.27.0': + resolution: {integrity: sha512-G5JD9Tu5HJEu4z2Uo4aHY2sLV64B7CDMXxFzqzjl3NKd6RVzSXNoE80jk7Y0lJkTTkjiIhBAqmlYwjuBY3tvpA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/object-schema@2.1.6': + resolution: {integrity: sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/plugin-kit@0.3.1': + resolution: {integrity: sha512-0J+zgWxHN+xXONWIyPWKFMgVuJoZuGiIFu8yxk7RJjxkzpGmyja5wRFqZIVtjDVOQpV+Rw0iOAjYPE2eQyjr0w==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@humanfs/core@0.19.1': + resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} + engines: {node: '>=18.18.0'} + + '@humanfs/node@0.16.6': + resolution: {integrity: sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==} + engines: {node: '>=18.18.0'} + + '@humanwhocodes/module-importer@1.0.1': + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + + '@humanwhocodes/retry@0.3.1': + resolution: {integrity: sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==} + engines: {node: '>=18.18'} + + '@humanwhocodes/retry@0.4.3': + resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} + engines: {node: '>=18.18'} + + '@inquirer/checkbox@4.1.6': + resolution: {integrity: sha512-62u896rWCtKKE43soodq5e/QcRsA22I+7/4Ov7LESWnKRO6BVo2A1DFLDmXL9e28TB0CfHc3YtkbPm7iwajqkg==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/confirm@5.1.10': + resolution: {integrity: sha512-FxbQ9giWxUWKUk2O5XZ6PduVnH2CZ/fmMKMBkH71MHJvWr7WL5AHKevhzF1L5uYWB2P548o1RzVxrNd3dpmk6g==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/core@10.1.11': + resolution: {integrity: sha512-BXwI/MCqdtAhzNQlBEFE7CEflhPkl/BqvAuV/aK6lW3DClIfYVDWPP/kXuXHtBWC7/EEbNqd/1BGq2BGBBnuxw==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/editor@4.2.11': + resolution: {integrity: sha512-YoZr0lBnnLFPpfPSNsQ8IZyKxU47zPyVi9NLjCWtna52//M/xuL0PGPAxHxxYhdOhnvY2oBafoM+BI5w/JK7jw==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/expand@4.0.13': + resolution: {integrity: sha512-HgYNWuZLHX6q5y4hqKhwyytqAghmx35xikOGY3TcgNiElqXGPas24+UzNPOwGUZa5Dn32y25xJqVeUcGlTv+QQ==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/figures@1.0.11': + resolution: {integrity: sha512-eOg92lvrn/aRUqbxRyvpEWnrvRuTYRifixHkYVpJiygTgVSBIHDqLh0SrMQXkafvULg3ck11V7xvR+zcgvpHFw==} + engines: {node: '>=18'} + + '@inquirer/input@4.1.10': + resolution: {integrity: sha512-kV3BVne3wJ+j6reYQUZi/UN9NZGZLxgc/tfyjeK3mrx1QI7RXPxGp21IUTv+iVHcbP4ytZALF8vCHoxyNSC6qg==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/number@3.0.13': + resolution: {integrity: sha512-IrLezcg/GWKS8zpKDvnJ/YTflNJdG0qSFlUM/zNFsdi4UKW/CO+gaJpbMgQ20Q58vNKDJbEzC6IebdkprwL6ew==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/password@4.0.13': + resolution: {integrity: sha512-NN0S/SmdhakqOTJhDwOpeBEEr8VdcYsjmZHDb0rblSh2FcbXQOr+2IApP7JG4WE3sxIdKytDn4ed3XYwtHxmJQ==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/prompts@7.3.2': + resolution: {integrity: sha512-G1ytyOoHh5BphmEBxSwALin3n1KGNYB6yImbICcRQdzXfOGbuJ9Jske/Of5Sebk339NSGGNfUshnzK8YWkTPsQ==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/prompts@7.4.1': + resolution: {integrity: sha512-UlmM5FVOZF0gpoe1PT/jN4vk8JmpIWBlMvTL8M+hlvPmzN89K6z03+IFmyeu/oFCenwdwHDr2gky7nIGSEVvlA==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/rawlist@4.1.1': + resolution: {integrity: sha512-VBUC0jPN2oaOq8+krwpo/mf3n/UryDUkKog3zi+oIi8/e5hykvdntgHUB9nhDM78RubiyR1ldIOfm5ue+2DeaQ==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/search@3.0.13': + resolution: {integrity: sha512-9g89d2c5Izok/Gw/U7KPC3f9kfe5rA1AJ24xxNZG0st+vWekSk7tB9oE+dJv5JXd0ZSijomvW0KPMoBd8qbN4g==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/select@4.2.1': + resolution: {integrity: sha512-gt1Kd5XZm+/ddemcT3m23IP8aD8rC9drRckWoP/1f7OL46Yy2FGi8DSmNjEjQKtPl6SV96Kmjbl6p713KXJ/Jg==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/type@3.0.6': + resolution: {integrity: sha512-/mKVCtVpyBu3IDarv0G+59KC4stsD5mDsGpYh+GKs1NZT88Jh52+cuoA1AtLk2Q0r/quNl+1cSUyLRHBFeD0XA==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + + '@istanbuljs/load-nyc-config@1.1.0': + resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==} + engines: {node: '>=8'} + + '@istanbuljs/schema@0.1.3': + resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} + engines: {node: '>=8'} + + '@jest/console@29.7.0': + resolution: {integrity: sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/core@29.7.0': + resolution: {integrity: sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + + '@jest/environment@29.7.0': + resolution: {integrity: sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/expect-utils@29.7.0': + resolution: {integrity: sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/expect@29.7.0': + resolution: {integrity: sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/fake-timers@29.7.0': + resolution: {integrity: sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/globals@29.7.0': + resolution: {integrity: sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/reporters@29.7.0': + resolution: {integrity: sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + + '@jest/schemas@29.6.3': + resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/source-map@29.6.3': + resolution: {integrity: sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/test-result@29.7.0': + resolution: {integrity: sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/test-sequencer@29.7.0': + resolution: {integrity: sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/transform@29.7.0': + resolution: {integrity: sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/types@29.6.3': + resolution: {integrity: sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jridgewell/gen-mapping@0.3.8': + resolution: {integrity: sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==} + engines: {node: '>=6.0.0'} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/set-array@1.2.1': + resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} + engines: {node: '>=6.0.0'} + + '@jridgewell/source-map@0.3.6': + resolution: {integrity: sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==} + + '@jridgewell/sourcemap-codec@1.5.0': + resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + + '@jridgewell/trace-mapping@0.3.25': + resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + + '@jridgewell/trace-mapping@0.3.9': + resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + + '@lukeed/csprng@1.1.0': + resolution: {integrity: sha512-Z7C/xXCiGWsg0KuKsHTKJxbWhpI3Vs5GwLfOean7MGyVFGqdRgBbAjOCh6u4bbjPc/8MJ2pZmK/0DLdCbivLDA==} + engines: {node: '>=8'} + + '@napi-rs/nice-android-arm-eabi@1.0.1': + resolution: {integrity: sha512-5qpvOu5IGwDo7MEKVqqyAxF90I6aLj4n07OzpARdgDRfz8UbBztTByBp0RC59r3J1Ij8uzYi6jI7r5Lws7nn6w==} + engines: {node: '>= 10'} + cpu: [arm] + os: [android] + + '@napi-rs/nice-android-arm64@1.0.1': + resolution: {integrity: sha512-GqvXL0P8fZ+mQqG1g0o4AO9hJjQaeYG84FRfZaYjyJtZZZcMjXW5TwkL8Y8UApheJgyE13TQ4YNUssQaTgTyvA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [android] + + '@napi-rs/nice-darwin-arm64@1.0.1': + resolution: {integrity: sha512-91k3HEqUl2fsrz/sKkuEkscj6EAj3/eZNCLqzD2AA0TtVbkQi8nqxZCZDMkfklULmxLkMxuUdKe7RvG/T6s2AA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + + '@napi-rs/nice-darwin-x64@1.0.1': + resolution: {integrity: sha512-jXnMleYSIR/+TAN/p5u+NkCA7yidgswx5ftqzXdD5wgy/hNR92oerTXHc0jrlBisbd7DpzoaGY4cFD7Sm5GlgQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + + '@napi-rs/nice-freebsd-x64@1.0.1': + resolution: {integrity: sha512-j+iJ/ezONXRQsVIB/FJfwjeQXX7A2tf3gEXs4WUGFrJjpe/z2KB7sOv6zpkm08PofF36C9S7wTNuzHZ/Iiccfw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [freebsd] + + '@napi-rs/nice-linux-arm-gnueabihf@1.0.1': + resolution: {integrity: sha512-G8RgJ8FYXYkkSGQwywAUh84m946UTn6l03/vmEXBYNJxQJcD+I3B3k5jmjFG/OPiU8DfvxutOP8bi+F89MCV7Q==} + engines: {node: '>= 10'} + cpu: [arm] + os: [linux] + + '@napi-rs/nice-linux-arm64-gnu@1.0.1': + resolution: {integrity: sha512-IMDak59/W5JSab1oZvmNbrms3mHqcreaCeClUjwlwDr0m3BoR09ZiN8cKFBzuSlXgRdZ4PNqCYNeGQv7YMTjuA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@napi-rs/nice-linux-arm64-musl@1.0.1': + resolution: {integrity: sha512-wG8fa2VKuWM4CfjOjjRX9YLIbysSVV1S3Kgm2Fnc67ap/soHBeYZa6AGMeR5BJAylYRjnoVOzV19Cmkco3QEPw==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@napi-rs/nice-linux-ppc64-gnu@1.0.1': + resolution: {integrity: sha512-lxQ9WrBf0IlNTCA9oS2jg/iAjQyTI6JHzABV664LLrLA/SIdD+I1i3Mjf7TsnoUbgopBcCuDztVLfJ0q9ubf6Q==} + engines: {node: '>= 10'} + cpu: [ppc64] + os: [linux] + + '@napi-rs/nice-linux-riscv64-gnu@1.0.1': + resolution: {integrity: sha512-3xs69dO8WSWBb13KBVex+yvxmUeEsdWexxibqskzoKaWx9AIqkMbWmE2npkazJoopPKX2ULKd8Fm9veEn0g4Ig==} + engines: {node: '>= 10'} + cpu: [riscv64] + os: [linux] + + '@napi-rs/nice-linux-s390x-gnu@1.0.1': + resolution: {integrity: sha512-lMFI3i9rlW7hgToyAzTaEybQYGbQHDrpRkg+1gJWEpH0PLAQoZ8jiY0IzakLfNWnVda1eTYYlxxFYzW8Rqczkg==} + engines: {node: '>= 10'} + cpu: [s390x] + os: [linux] + + '@napi-rs/nice-linux-x64-gnu@1.0.1': + resolution: {integrity: sha512-XQAJs7DRN2GpLN6Fb+ZdGFeYZDdGl2Fn3TmFlqEL5JorgWKrQGRUrpGKbgZ25UeZPILuTKJ+OowG2avN8mThBA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@napi-rs/nice-linux-x64-musl@1.0.1': + resolution: {integrity: sha512-/rodHpRSgiI9o1faq9SZOp/o2QkKQg7T+DK0R5AkbnI/YxvAIEHf2cngjYzLMQSQgUhxym+LFr+UGZx4vK4QdQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@napi-rs/nice-win32-arm64-msvc@1.0.1': + resolution: {integrity: sha512-rEcz9vZymaCB3OqEXoHnp9YViLct8ugF+6uO5McifTedjq4QMQs3DHz35xBEGhH3gJWEsXMUbzazkz5KNM5YUg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + + '@napi-rs/nice-win32-ia32-msvc@1.0.1': + resolution: {integrity: sha512-t7eBAyPUrWL8su3gDxw9xxxqNwZzAqKo0Szv3IjVQd1GpXXVkb6vBBQUuxfIYaXMzZLwlxRQ7uzM2vdUE9ULGw==} + engines: {node: '>= 10'} + cpu: [ia32] + os: [win32] + + '@napi-rs/nice-win32-x64-msvc@1.0.1': + resolution: {integrity: sha512-JlF+uDcatt3St2ntBG8H02F1mM45i5SF9W+bIKiReVE6wiy3o16oBP/yxt+RZ+N6LbCImJXJ6bXNO2kn9AXicg==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + + '@napi-rs/nice@1.0.1': + resolution: {integrity: sha512-zM0mVWSXE0a0h9aKACLwKmD6nHcRiKrPpCfvaKqG1CqDEyjEawId0ocXxVzPMCAm6kkWr2P025msfxXEnt8UGQ==} + engines: {node: '>= 10'} + + '@nestjs/cli@11.0.7': + resolution: {integrity: sha512-svrP8j1R0/lQVJ8ZI3BlDtuZxmkvVJokUJSB04sr6uibunk2wHeVDDVLZvYBUorCdGU/RHJl1IufhqUBM91vAQ==} + engines: {node: '>= 20.11'} + hasBin: true + peerDependencies: + '@swc/cli': ^0.1.62 || ^0.3.0 || ^0.4.0 || ^0.5.0 || ^0.6.0 || ^0.7.0 + '@swc/core': ^1.3.62 + peerDependenciesMeta: + '@swc/cli': + optional: true + '@swc/core': + optional: true + + '@nestjs/common@11.1.1': + resolution: {integrity: sha512-crzp+1qeZ5EGL0nFTPy9NrVMAaUWewV5AwtQyv6SQ9yQPXwRl9W9hm1pt0nAtUu5QbYMbSuo7lYcF81EjM+nCA==} + peerDependencies: + class-transformer: '>=0.4.1' + class-validator: '>=0.13.2' + reflect-metadata: ^0.1.12 || ^0.2.0 + rxjs: ^7.1.0 + peerDependenciesMeta: + class-transformer: + optional: true + class-validator: + optional: true + + '@nestjs/config@4.0.2': + resolution: {integrity: sha512-McMW6EXtpc8+CwTUwFdg6h7dYcBUpH5iUILCclAsa+MbCEvC9ZKu4dCHRlJqALuhjLw97pbQu62l4+wRwGeZqA==} + peerDependencies: + '@nestjs/common': ^10.0.0 || ^11.0.0 + rxjs: ^7.1.0 + + '@nestjs/core@11.1.1': + resolution: {integrity: sha512-UFoUAgLKFT+RwHTANJdr0dF7p0qS9QjkaUPjg8aafnjM/qxxxrUVDB49nVvyMlk+Hr1+vvcNaOHbWWQBxoZcHA==} + engines: {node: '>= 20'} + peerDependencies: + '@nestjs/common': ^11.0.0 + '@nestjs/microservices': ^11.0.0 + '@nestjs/platform-express': ^11.0.0 + '@nestjs/websockets': ^11.0.0 + reflect-metadata: ^0.1.12 || ^0.2.0 + rxjs: ^7.1.0 + peerDependenciesMeta: + '@nestjs/microservices': + optional: true + '@nestjs/platform-express': + optional: true + '@nestjs/websockets': + optional: true + + '@nestjs/passport@11.0.5': + resolution: {integrity: sha512-ulQX6mbjlws92PIM15Naes4F4p2JoxGnIJuUsdXQPT+Oo2sqQmENEZXM7eYuimocfHnKlcfZOuyzbA33LwUlOQ==} + peerDependencies: + '@nestjs/common': ^10.0.0 || ^11.0.0 + passport: ^0.5.0 || ^0.6.0 || ^0.7.0 + + '@nestjs/platform-express@11.1.1': + resolution: {integrity: sha512-IUxk380qnUtz0PCRQ5i+o9UHlGMrFzGPIJxDwyt3JZZwx2AngOlcEcm5e+7YeJQEr2QYX2QyC4tUQg0zde+D7A==} + peerDependencies: + '@nestjs/common': ^11.0.0 + '@nestjs/core': ^11.0.0 + + '@nestjs/schematics@11.0.5': + resolution: {integrity: sha512-T50SCNyqCZ/fDssaOD7meBKLZ87ebRLaJqZTJPvJKjlib1VYhMOCwXYsr7bjMPmuPgiQHOwvppz77xN/m6GM7A==} + peerDependencies: + typescript: '>=4.8.2' + + '@nestjs/testing@11.1.1': + resolution: {integrity: sha512-stzm8YrLDGAijHYQw+8Z9dD6lGdvahL0hIjGVZ/0KBxLZht0/rvRjgV31UK+DUqXaF7yhJTw9ryrPaITxI1J6A==} + peerDependencies: + '@nestjs/common': ^11.0.0 + '@nestjs/core': ^11.0.0 + '@nestjs/microservices': ^11.0.0 + '@nestjs/platform-express': ^11.0.0 + peerDependenciesMeta: + '@nestjs/microservices': + optional: true + '@nestjs/platform-express': + optional: true + + '@noble/hashes@1.8.0': + resolution: {integrity: sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==} + engines: {node: ^14.21.3 || >=16} + + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + + '@nuxt/opencollective@0.4.1': + resolution: {integrity: sha512-GXD3wy50qYbxCJ652bDrDzgMr3NFEkIS374+IgFQKkCvk9yiYcLvX2XDYr7UyQxf4wK0e+yqDYRubZ0DtOxnmQ==} + engines: {node: ^14.18.0 || >=16.10.0, npm: '>=5.10.0'} + hasBin: true + + '@paralleldrive/cuid2@2.2.2': + resolution: {integrity: sha512-ZOBkgDwEdoYVlSeRbYYXs0S9MejQofiVYoTbKzy/6GQa39/q5tQU2IX46+shYnUkpEl3wc+J6wRlar7r2EK2xA==} + + '@pkgr/core@0.2.4': + resolution: {integrity: sha512-ROFF39F6ZrnzSUEmQQZUar0Jt4xVoP9WnDRdWwF4NNcXs3xBTLgBUDoOwW141y1jP+S8nahIbdxbFC7IShw9Iw==} + engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + + '@prisma/client@6.8.2': + resolution: {integrity: sha512-5II+vbyzv4si6Yunwgkj0qT/iY0zyspttoDrL3R4BYgLdp42/d2C8xdi9vqkrYtKt9H32oFIukvyw3Koz5JoDg==} + engines: {node: '>=18.18'} + peerDependencies: + prisma: '*' + typescript: '>=5.1.0' + peerDependenciesMeta: + prisma: + optional: true + typescript: + optional: true + + '@prisma/config@6.8.2': + resolution: {integrity: sha512-ZJY1fF4qRBPdLQ/60wxNtX+eu89c3AkYEcP7L3jkp0IPXCNphCYxikTg55kPJLDOG6P0X+QG5tCv6CmsBRZWFQ==} + + '@prisma/debug@6.8.2': + resolution: {integrity: sha512-4muBSSUwJJ9BYth5N8tqts8JtiLT8QI/RSAzEogwEfpbYGFo9mYsInsVo8dqXdPO2+Rm5OG5q0qWDDE3nyUbVg==} + + '@prisma/engines-version@6.8.0-43.2060c79ba17c6bb9f5823312b6f6b7f4a845738e': + resolution: {integrity: sha512-Rkik9lMyHpFNGaLpPF3H5q5TQTkm/aE7DsGM5m92FZTvWQsvmi6Va8On3pWvqLHOt5aPUvFb/FeZTmphI4CPiQ==} + + '@prisma/engines@6.8.2': + resolution: {integrity: sha512-XqAJ//LXjqYRQ1RRabs79KOY4+v6gZOGzbcwDQl0D6n9WBKjV7qdrbd042CwSK0v0lM9MSHsbcFnU2Yn7z8Zlw==} + + '@prisma/fetch-engine@6.8.2': + resolution: {integrity: sha512-lCvikWOgaLOfqXGacEKSNeenvj0n3qR5QvZUOmPE2e1Eh8cMYSobxonCg9rqM6FSdTfbpqp9xwhSAOYfNqSW0g==} + + '@prisma/get-platform@6.8.2': + resolution: {integrity: sha512-vXSxyUgX3vm1Q70QwzwkjeYfRryIvKno1SXbIqwSptKwqKzskINnDUcx85oX+ys6ooN2ATGSD0xN2UTfg6Zcow==} + + '@sec-ant/readable-stream@0.4.1': + resolution: {integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==} + + '@sinclair/typebox@0.27.8': + resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} + + '@sindresorhus/is@5.6.0': + resolution: {integrity: sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==} + engines: {node: '>=14.16'} + + '@sinonjs/commons@3.0.1': + resolution: {integrity: sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==} + + '@sinonjs/fake-timers@10.3.0': + resolution: {integrity: sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==} + + '@swc/cli@0.6.0': + resolution: {integrity: sha512-Q5FsI3Cw0fGMXhmsg7c08i4EmXCrcl+WnAxb6LYOLHw4JFFC3yzmx9LaXZ7QMbA+JZXbigU2TirI7RAfO0Qlnw==} + engines: {node: '>= 16.14.0'} + hasBin: true + peerDependencies: + '@swc/core': ^1.2.66 + chokidar: ^4.0.1 + peerDependenciesMeta: + chokidar: + optional: true + + '@swc/core-darwin-arm64@1.11.29': + resolution: {integrity: sha512-whsCX7URzbuS5aET58c75Dloby3Gtj/ITk2vc4WW6pSDQKSPDuONsIcZ7B2ng8oz0K6ttbi4p3H/PNPQLJ4maQ==} + engines: {node: '>=10'} + cpu: [arm64] + os: [darwin] + + '@swc/core-darwin-x64@1.11.29': + resolution: {integrity: sha512-S3eTo/KYFk+76cWJRgX30hylN5XkSmjYtCBnM4jPLYn7L6zWYEPajsFLmruQEiTEDUg0gBEWLMNyUeghtswouw==} + engines: {node: '>=10'} + cpu: [x64] + os: [darwin] + + '@swc/core-linux-arm-gnueabihf@1.11.29': + resolution: {integrity: sha512-o9gdshbzkUMG6azldHdmKklcfrcMx+a23d/2qHQHPDLUPAN+Trd+sDQUYArK5Fcm7TlpG4sczz95ghN0DMkM7g==} + engines: {node: '>=10'} + cpu: [arm] + os: [linux] + + '@swc/core-linux-arm64-gnu@1.11.29': + resolution: {integrity: sha512-sLoaciOgUKQF1KX9T6hPGzvhOQaJn+3DHy4LOHeXhQqvBgr+7QcZ+hl4uixPKTzxk6hy6Hb0QOvQEdBAAR1gXw==} + engines: {node: '>=10'} + cpu: [arm64] + os: [linux] + + '@swc/core-linux-arm64-musl@1.11.29': + resolution: {integrity: sha512-PwjB10BC0N+Ce7RU/L23eYch6lXFHz7r3NFavIcwDNa/AAqywfxyxh13OeRy+P0cg7NDpWEETWspXeI4Ek8otw==} + engines: {node: '>=10'} + cpu: [arm64] + os: [linux] + + '@swc/core-linux-x64-gnu@1.11.29': + resolution: {integrity: sha512-i62vBVoPaVe9A3mc6gJG07n0/e7FVeAvdD9uzZTtGLiuIfVfIBta8EMquzvf+POLycSk79Z6lRhGPZPJPYiQaA==} + engines: {node: '>=10'} + cpu: [x64] + os: [linux] + + '@swc/core-linux-x64-musl@1.11.29': + resolution: {integrity: sha512-YER0XU1xqFdK0hKkfSVX1YIyCvMDI7K07GIpefPvcfyNGs38AXKhb2byySDjbVxkdl4dycaxxhRyhQ2gKSlsFQ==} + engines: {node: '>=10'} + cpu: [x64] + os: [linux] + + '@swc/core-win32-arm64-msvc@1.11.29': + resolution: {integrity: sha512-po+WHw+k9g6FAg5IJ+sMwtA/fIUL3zPQ4m/uJgONBATCVnDDkyW6dBA49uHNVtSEvjvhuD8DVWdFP847YTcITw==} + engines: {node: '>=10'} + cpu: [arm64] + os: [win32] + + '@swc/core-win32-ia32-msvc@1.11.29': + resolution: {integrity: sha512-h+NjOrbqdRBYr5ItmStmQt6x3tnhqgwbj9YxdGPepbTDamFv7vFnhZR0YfB3jz3UKJ8H3uGJ65Zw1VsC+xpFkg==} + engines: {node: '>=10'} + cpu: [ia32] + os: [win32] + + '@swc/core-win32-x64-msvc@1.11.29': + resolution: {integrity: sha512-Q8cs2BDV9wqDvqobkXOYdC+pLUSEpX/KvI0Dgfun1F+LzuLotRFuDhrvkU9ETJA6OnD2+Fn/ieHgloiKA/Mn/g==} + engines: {node: '>=10'} + cpu: [x64] + os: [win32] + + '@swc/core@1.11.29': + resolution: {integrity: sha512-g4mThMIpWbNhV8G2rWp5a5/Igv8/2UFRJx2yImrLGMgrDDYZIopqZ/z0jZxDgqNA1QDx93rpwNF7jGsxVWcMlA==} + engines: {node: '>=10'} + peerDependencies: + '@swc/helpers': '>=0.5.17' + peerDependenciesMeta: + '@swc/helpers': + optional: true + + '@swc/counter@0.1.3': + resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} + + '@swc/types@0.1.21': + resolution: {integrity: sha512-2YEtj5HJVbKivud9N4bpPBAyZhj4S2Ipe5LkUG94alTpr7in/GU/EARgPAd3BwU+YOmFVJC2+kjqhGRi3r0ZpQ==} + + '@szmarczak/http-timer@5.0.1': + resolution: {integrity: sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==} + engines: {node: '>=14.16'} + + '@tokenizer/inflate@0.2.7': + resolution: {integrity: sha512-MADQgmZT1eKjp06jpI2yozxaU9uVs4GzzgSL+uEq7bVcJ9V1ZXQkeGNql1fsSI0gMy1vhvNTNbUqrx+pZfJVmg==} + engines: {node: '>=18'} + + '@tokenizer/token@0.3.0': + resolution: {integrity: sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==} + + '@tsconfig/node10@1.0.11': + resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==} + + '@tsconfig/node12@1.0.11': + resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} + + '@tsconfig/node14@1.0.3': + resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} + + '@tsconfig/node16@1.0.4': + resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} + + '@types/babel__core@7.20.5': + resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} + + '@types/babel__generator@7.27.0': + resolution: {integrity: sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==} + + '@types/babel__template@7.4.4': + resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} + + '@types/babel__traverse@7.20.7': + resolution: {integrity: sha512-dkO5fhS7+/oos4ciWxyEyjWe48zmG6wbCheo/G2ZnHx4fs3EU6YC6UM8rk56gAjNJ9P3MTH2jo5jb92/K6wbng==} + + '@types/body-parser@1.19.5': + resolution: {integrity: sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==} + + '@types/connect@3.4.38': + resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} + + '@types/cookiejar@2.1.5': + resolution: {integrity: sha512-he+DHOWReW0nghN24E1WUqM0efK4kI9oTqDm6XmK8ZPe2djZ90BSNdGnIyCLzCPw7/pogPlGbzI2wHGGmi4O/Q==} + + '@types/eslint-scope@3.7.7': + resolution: {integrity: sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==} + + '@types/eslint@9.6.1': + resolution: {integrity: sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==} + + '@types/estree@1.0.7': + resolution: {integrity: sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==} + + '@types/express-serve-static-core@5.0.6': + resolution: {integrity: sha512-3xhRnjJPkULekpSzgtoNYYcTWgEZkp4myc+Saevii5JPnHNvHMRlBSHDbs7Bh1iPPoVTERHEZXyhyLbMEsExsA==} + + '@types/express-session@1.18.1': + resolution: {integrity: sha512-S6TkD/lljxDlQ2u/4A70luD8/ZxZcrU5pQwI1rVXCiaVIywoFgbA+PIUNDjPhQpPdK0dGleLtYc/y7XWBfclBg==} + + '@types/express@5.0.2': + resolution: {integrity: sha512-BtjL3ZwbCQriyb0DGw+Rt12qAXPiBTPs815lsUvtt1Grk0vLRMZNMUZ741d5rjk+UQOxfDiBZ3dxpX00vSkK3g==} + + '@types/graceful-fs@4.1.9': + resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==} + + '@types/http-cache-semantics@4.0.4': + resolution: {integrity: sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==} + + '@types/http-errors@2.0.4': + resolution: {integrity: sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==} + + '@types/istanbul-lib-coverage@2.0.6': + resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==} + + '@types/istanbul-lib-report@3.0.3': + resolution: {integrity: sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==} + + '@types/istanbul-reports@3.0.4': + resolution: {integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==} + + '@types/jest@29.5.14': + resolution: {integrity: sha512-ZN+4sdnLUbo8EVvVc2ao0GFW6oVrQRPn4K2lglySj7APvSrgzxHiNNK99us4WDMi57xxA2yggblIAMNhXOotLQ==} + + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + '@types/methods@1.1.4': + resolution: {integrity: sha512-ymXWVrDiCxTBE3+RIrrP533E70eA+9qu7zdWoHuOmGujkYtzf4HQF96b8nwHLqhuf4ykX61IGRIB38CC6/sImQ==} + + '@types/mime@1.3.5': + resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==} + + '@types/node@22.15.21': + resolution: {integrity: sha512-EV/37Td6c+MgKAbkcLG6vqZ2zEYHD7bvSrzqqs2RIhbA6w3x+Dqz8MZM3sP6kGTeLrdoOgKZe+Xja7tUB2DNkQ==} + + '@types/passport@1.0.17': + resolution: {integrity: sha512-aciLyx+wDwT2t2/kJGJR2AEeBz0nJU4WuRX04Wu9Dqc5lSUtwu0WERPHYsLhF9PtseiAMPBGNUOtFjxZ56prsg==} + + '@types/qs@6.14.0': + resolution: {integrity: sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==} + + '@types/range-parser@1.2.7': + resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==} + + '@types/send@0.17.4': + resolution: {integrity: sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==} + + '@types/serve-static@1.15.7': + resolution: {integrity: sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==} + + '@types/stack-utils@2.0.3': + resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==} + + '@types/superagent@8.1.9': + resolution: {integrity: sha512-pTVjI73witn+9ILmoJdajHGW2jkSaOzhiFYF1Rd3EQ94kymLqB9PjD9ISg7WaALC7+dCHT0FGe9T2LktLq/3GQ==} + + '@types/supertest@6.0.3': + resolution: {integrity: sha512-8WzXq62EXFhJ7QsH3Ocb/iKQ/Ty9ZVWnVzoTKc9tyyFRRF3a74Tk2+TLFgaFFw364Ere+npzHKEJ6ga2LzIL7w==} + + '@types/yargs-parser@21.0.3': + resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} + + '@types/yargs@17.0.33': + resolution: {integrity: sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==} + + '@typescript-eslint/eslint-plugin@8.32.1': + resolution: {integrity: sha512-6u6Plg9nP/J1GRpe/vcjjabo6Uc5YQPAMxsgQyGC/I0RuukiG1wIe3+Vtg3IrSCVJDmqK3j8adrtzXSENRtFgg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + '@typescript-eslint/parser': ^8.0.0 || ^8.0.0-alpha.0 + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <5.9.0' + + '@typescript-eslint/parser@8.32.1': + resolution: {integrity: sha512-LKMrmwCPoLhM45Z00O1ulb6jwyVr2kr3XJp+G+tSEZcbauNnScewcQwtJqXDhXeYPDEjZ8C1SjXm015CirEmGg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <5.9.0' + + '@typescript-eslint/scope-manager@8.32.1': + resolution: {integrity: sha512-7IsIaIDeZn7kffk7qXC3o6Z4UblZJKV3UBpkvRNpr5NSyLji7tvTcvmnMNYuYLyh26mN8W723xpo3i4MlD33vA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/type-utils@8.32.1': + resolution: {integrity: sha512-mv9YpQGA8iIsl5KyUPi+FGLm7+bA4fgXaeRcFKRDRwDMu4iwrSHeDPipwueNXhdIIZltwCJv+NkxftECbIZWfA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <5.9.0' + + '@typescript-eslint/types@8.32.1': + resolution: {integrity: sha512-YmybwXUJcgGqgAp6bEsgpPXEg6dcCyPyCSr0CAAueacR/CCBi25G3V8gGQ2kRzQRBNol7VQknxMs9HvVa9Rvfg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/typescript-estree@8.32.1': + resolution: {integrity: sha512-Y3AP9EIfYwBb4kWGb+simvPaqQoT5oJuzzj9m0i6FCY6SPvlomY2Ei4UEMm7+FXtlNJbor80ximyslzaQF6xhg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <5.9.0' + + '@typescript-eslint/utils@8.32.1': + resolution: {integrity: sha512-DsSFNIgLSrc89gpq1LJB7Hm1YpuhK086DRDJSNrewcGvYloWW1vZLHBTIvarKZDcAORIy/uWNx8Gad+4oMpkSA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <5.9.0' + + '@typescript-eslint/visitor-keys@8.32.1': + resolution: {integrity: sha512-ar0tjQfObzhSaW3C3QNmTc5ofj0hDoNQ5XWrCy6zDyabdr0TWhCkClp+rywGNj/odAFBVzzJrK4tEq5M4Hmu4w==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@webassemblyjs/ast@1.14.1': + resolution: {integrity: sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==} + + '@webassemblyjs/floating-point-hex-parser@1.13.2': + resolution: {integrity: sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==} + + '@webassemblyjs/helper-api-error@1.13.2': + resolution: {integrity: sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==} + + '@webassemblyjs/helper-buffer@1.14.1': + resolution: {integrity: sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==} + + '@webassemblyjs/helper-numbers@1.13.2': + resolution: {integrity: sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==} + + '@webassemblyjs/helper-wasm-bytecode@1.13.2': + resolution: {integrity: sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==} + + '@webassemblyjs/helper-wasm-section@1.14.1': + resolution: {integrity: sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==} + + '@webassemblyjs/ieee754@1.13.2': + resolution: {integrity: sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==} + + '@webassemblyjs/leb128@1.13.2': + resolution: {integrity: sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==} + + '@webassemblyjs/utf8@1.13.2': + resolution: {integrity: sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==} + + '@webassemblyjs/wasm-edit@1.14.1': + resolution: {integrity: sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==} + + '@webassemblyjs/wasm-gen@1.14.1': + resolution: {integrity: sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==} + + '@webassemblyjs/wasm-opt@1.14.1': + resolution: {integrity: sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==} + + '@webassemblyjs/wasm-parser@1.14.1': + resolution: {integrity: sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==} + + '@webassemblyjs/wast-printer@1.14.1': + resolution: {integrity: sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==} + + '@xhmikosr/archive-type@7.0.0': + resolution: {integrity: sha512-sIm84ZneCOJuiy3PpWR5bxkx3HaNt1pqaN+vncUBZIlPZCq8ASZH+hBVdu5H8znR7qYC6sKwx+ie2Q7qztJTxA==} + engines: {node: ^14.14.0 || >=16.0.0} + + '@xhmikosr/bin-check@7.0.3': + resolution: {integrity: sha512-4UnCLCs8DB+itHJVkqFp9Zjg+w/205/J2j2wNBsCEAm/BuBmtua2hhUOdAMQE47b1c7P9Xmddj0p+X1XVsfHsA==} + engines: {node: '>=18'} + + '@xhmikosr/bin-wrapper@13.0.5': + resolution: {integrity: sha512-DT2SAuHDeOw0G5bs7wZbQTbf4hd8pJ14tO0i4cWhRkIJfgRdKmMfkDilpaJ8uZyPA0NVRwasCNAmMJcWA67osw==} + engines: {node: '>=18'} + + '@xhmikosr/decompress-tar@8.0.1': + resolution: {integrity: sha512-dpEgs0cQKJ2xpIaGSO0hrzz3Kt8TQHYdizHsgDtLorWajuHJqxzot9Hbi0huRxJuAGG2qiHSQkwyvHHQtlE+fg==} + engines: {node: '>=18'} + + '@xhmikosr/decompress-tarbz2@8.0.2': + resolution: {integrity: sha512-p5A2r/AVynTQSsF34Pig6olt9CvRj6J5ikIhzUd3b57pUXyFDGtmBstcw+xXza0QFUh93zJsmY3zGeNDlR2AQQ==} + engines: {node: '>=18'} + + '@xhmikosr/decompress-targz@8.0.1': + resolution: {integrity: sha512-mvy5AIDIZjQ2IagMI/wvauEiSNHhu/g65qpdM4EVoYHUJBAmkQWqcPJa8Xzi1aKVTmOA5xLJeDk7dqSjlHq8Mg==} + engines: {node: '>=18'} + + '@xhmikosr/decompress-unzip@7.0.0': + resolution: {integrity: sha512-GQMpzIpWTsNr6UZbISawsGI0hJ4KA/mz5nFq+cEoPs12UybAqZWKbyIaZZyLbJebKl5FkLpsGBkrplJdjvUoSQ==} + engines: {node: '>=18'} + + '@xhmikosr/decompress@10.0.1': + resolution: {integrity: sha512-6uHnEEt5jv9ro0CDzqWlFgPycdE+H+kbJnwyxgZregIMLQ7unQSCNVsYG255FoqU8cP46DyggI7F7LohzEl8Ag==} + engines: {node: '>=18'} + + '@xhmikosr/downloader@15.0.1': + resolution: {integrity: sha512-fiuFHf3Dt6pkX8HQrVBsK0uXtkgkVlhrZEh8b7VgoDqFf+zrgFBPyrwCqE/3nDwn3hLeNz+BsrS7q3mu13Lp1g==} + engines: {node: '>=18'} + + '@xhmikosr/os-filter-obj@3.0.0': + resolution: {integrity: sha512-siPY6BD5dQ2SZPl3I0OZBHL27ZqZvLEosObsZRQ1NUB8qcxegwt0T9eKtV96JMFQpIz1elhkzqOg4c/Ri6Dp9A==} + engines: {node: ^14.14.0 || >=16.0.0} + + '@xtuc/ieee754@1.2.0': + resolution: {integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==} + + '@xtuc/long@4.2.2': + resolution: {integrity: sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==} + + accepts@2.0.0: + resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==} + engines: {node: '>= 0.6'} + + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn-walk@8.3.4: + resolution: {integrity: sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==} + engines: {node: '>=0.4.0'} + + acorn@8.14.1: + resolution: {integrity: sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==} + engines: {node: '>=0.4.0'} + hasBin: true + + ajv-formats@2.1.1: + resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==} + peerDependencies: + ajv: ^8.0.0 + peerDependenciesMeta: + ajv: + optional: true + + ajv-formats@3.0.1: + resolution: {integrity: sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==} + peerDependencies: + ajv: ^8.0.0 + peerDependenciesMeta: + ajv: + optional: true + + ajv-keywords@3.5.2: + resolution: {integrity: sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==} + peerDependencies: + ajv: ^6.9.1 + + ajv-keywords@5.1.0: + resolution: {integrity: sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==} + peerDependencies: + ajv: ^8.8.2 + + ajv@6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + + ajv@8.17.1: + resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==} + + ansi-colors@4.1.3: + resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} + engines: {node: '>=6'} + + ansi-escapes@4.3.2: + resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} + engines: {node: '>=8'} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-regex@6.1.0: + resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==} + engines: {node: '>=12'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansi-styles@5.2.0: + resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} + engines: {node: '>=10'} + + ansi-styles@6.2.1: + resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + engines: {node: '>=12'} + + ansis@3.17.0: + resolution: {integrity: sha512-0qWUglt9JEqLFr3w1I1pbrChn1grhaiAR2ocX1PP/flRmxgtwTzPFFFnfIlD6aMOLQZgSuCRlidD70lvx8yhzg==} + engines: {node: '>=14'} + + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + + append-field@1.0.0: + resolution: {integrity: sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==} + + arch@3.0.0: + resolution: {integrity: sha512-AmIAC+Wtm2AU8lGfTtHsw0Y9Qtftx2YXEEtiBP10xFUtMOA+sHHx6OAddyL52mUKh1vsXQ6/w1mVDptZCyUt4Q==} + + arg@4.1.3: + resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} + + argparse@1.0.10: + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + array-timsort@1.0.3: + resolution: {integrity: sha512-/+3GRL7dDAGEfM6TseQk/U+mi18TU2Ms9I3UlLdUMhz2hbvGNTKdj9xniwXfUqgYhHxRx0+8UnKkvlNwVU+cWQ==} + + asap@2.0.6: + resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==} + + async@3.2.6: + resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==} + + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + + b4a@1.6.7: + resolution: {integrity: sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg==} + + babel-jest@29.7.0: + resolution: {integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@babel/core': ^7.8.0 + + babel-plugin-istanbul@6.1.1: + resolution: {integrity: sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==} + engines: {node: '>=8'} + + babel-plugin-jest-hoist@29.6.3: + resolution: {integrity: sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + babel-preset-current-node-syntax@1.1.0: + resolution: {integrity: sha512-ldYss8SbBlWva1bs28q78Ju5Zq1F+8BrqBZZ0VFhLBvhh6lCpC2o3gDJi/5DRLs9FgYZCnmPYIVFU4lRXCkyUw==} + peerDependencies: + '@babel/core': ^7.0.0 + + babel-preset-jest@29.6.3: + resolution: {integrity: sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@babel/core': ^7.0.0 + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + bare-events@2.5.4: + resolution: {integrity: sha512-+gFfDkR8pj4/TrWCGUGWmJIkBwuxPS5F+a5yWjOHQt2hHvNZd5YLzadjmDUtFmMM4y429bnKLa8bYBMHcYdnQA==} + + base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + + bin-version-check@5.1.0: + resolution: {integrity: sha512-bYsvMqJ8yNGILLz1KP9zKLzQ6YpljV3ln1gqhuLkUtyfGi3qXKGuK2p+U4NAvjVFzDFiBBtOpCOSFNuYYEGZ5g==} + engines: {node: '>=12'} + + bin-version@6.0.0: + resolution: {integrity: sha512-nk5wEsP4RiKjG+vF+uG8lFsEn4d7Y6FVDamzzftSunXOoOcOOkzcWdKVlGgFFwlUQCj63SgnUkLLGF8v7lufhw==} + engines: {node: '>=12'} + + bl@4.1.0: + resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} + + body-parser@2.2.0: + resolution: {integrity: sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==} + engines: {node: '>=18'} + + brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + + brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + browserslist@4.24.5: + resolution: {integrity: sha512-FDToo4Wo82hIdgc1CQ+NQD0hEhmpPjrZ3hiUgwgOG6IuTdlpr8jdjyG24P6cNP1yJpTLzS5OcGgSw0xmDU1/Tw==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + bs-logger@0.2.6: + resolution: {integrity: sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==} + engines: {node: '>= 6'} + + bser@2.1.1: + resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==} + + buffer-crc32@0.2.13: + resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} + + buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + + buffer@5.7.1: + resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + + busboy@1.6.0: + resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} + engines: {node: '>=10.16.0'} + + bytes@3.1.2: + resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} + engines: {node: '>= 0.8'} + + cacheable-lookup@7.0.0: + resolution: {integrity: sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==} + engines: {node: '>=14.16'} + + cacheable-request@10.2.14: + resolution: {integrity: sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==} + engines: {node: '>=14.16'} + + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + + call-bound@1.0.4: + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} + engines: {node: '>= 0.4'} + + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + + camelcase@5.3.1: + resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} + engines: {node: '>=6'} + + camelcase@6.3.0: + resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} + engines: {node: '>=10'} + + caniuse-lite@1.0.30001718: + resolution: {integrity: sha512-AflseV1ahcSunK53NfEs9gFWgOEmzr0f+kaMFA4xiLZlr9Hzt7HxcSpIFcnNCUkz6R6dWKa54rUz3HUmI3nVcw==} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + char-regex@1.0.2: + resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} + engines: {node: '>=10'} + + chardet@0.7.0: + resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} + + chokidar@4.0.3: + resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} + engines: {node: '>= 14.16.0'} + + chrome-trace-event@1.0.4: + resolution: {integrity: sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==} + engines: {node: '>=6.0'} + + ci-info@3.9.0: + resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} + engines: {node: '>=8'} + + cjs-module-lexer@1.4.3: + resolution: {integrity: sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==} + + cli-cursor@3.1.0: + resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} + engines: {node: '>=8'} + + cli-spinners@2.9.2: + resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==} + engines: {node: '>=6'} + + cli-table3@0.6.5: + resolution: {integrity: sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==} + engines: {node: 10.* || >= 12.*} + + cli-width@4.1.0: + resolution: {integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==} + engines: {node: '>= 12'} + + cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + + clone@1.0.4: + resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} + engines: {node: '>=0.8'} + + co@4.6.0: + resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==} + engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} + + collect-v8-coverage@1.0.2: + resolution: {integrity: sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + + commander@2.20.3: + resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + + commander@4.1.1: + resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} + engines: {node: '>= 6'} + + commander@6.2.1: + resolution: {integrity: sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==} + engines: {node: '>= 6'} + + commander@8.3.0: + resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} + engines: {node: '>= 12'} + + comment-json@4.2.5: + resolution: {integrity: sha512-bKw/r35jR3HGt5PEPm1ljsQQGyCrR8sFGNiN5L+ykDHdpO8Smxkrkla9Yi6NkQyUrb8V54PGhfMs6NrIwtxtdw==} + engines: {node: '>= 6'} + + component-emitter@1.3.1: + resolution: {integrity: sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + concat-stream@1.6.2: + resolution: {integrity: sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==} + engines: {'0': node >= 0.8} + + consola@3.4.2: + resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} + engines: {node: ^14.18.0 || >=16.10.0} + + content-disposition@0.5.4: + resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} + engines: {node: '>= 0.6'} + + content-disposition@1.0.0: + resolution: {integrity: sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==} + engines: {node: '>= 0.6'} + + content-type@1.0.5: + resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} + engines: {node: '>= 0.6'} + + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + + cookie-signature@1.0.7: + resolution: {integrity: sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==} + + cookie-signature@1.2.2: + resolution: {integrity: sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==} + engines: {node: '>=6.6.0'} + + cookie@0.7.1: + resolution: {integrity: sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==} + engines: {node: '>= 0.6'} + + cookie@0.7.2: + resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} + engines: {node: '>= 0.6'} + + cookiejar@2.1.4: + resolution: {integrity: sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==} + + core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + + cors@2.8.5: + resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==} + engines: {node: '>= 0.10'} + + cosmiconfig@8.3.6: + resolution: {integrity: sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==} + engines: {node: '>=14'} + peerDependencies: + typescript: '>=4.9.5' + peerDependenciesMeta: + typescript: + optional: true + + create-jest@29.7.0: + resolution: {integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + hasBin: true + + create-require@1.1.1: + resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + + debug@2.6.9: + resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@4.4.1: + resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + decompress-response@6.0.0: + resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} + engines: {node: '>=10'} + + dedent@1.6.0: + resolution: {integrity: sha512-F1Z+5UCFpmQUzJa11agbyPVMbpgT/qA3/SKyJ1jyBgm7dUcUEa8v9JwDkerSQXfakBwFljIxhOJqGkjUwZ9FSA==} + peerDependencies: + babel-plugin-macros: ^3.1.0 + peerDependenciesMeta: + babel-plugin-macros: + optional: true + + deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + + deepmerge@4.3.1: + resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} + engines: {node: '>=0.10.0'} + + defaults@1.0.4: + resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} + + defaults@3.0.0: + resolution: {integrity: sha512-RsqXDEAALjfRTro+IFNKpcPCt0/Cy2FqHSIlnomiJp9YGadpQnrtbRpSgN2+np21qHcIKiva4fiOQGjS9/qR/A==} + engines: {node: '>=18'} + + defer-to-connect@2.0.1: + resolution: {integrity: sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==} + engines: {node: '>=10'} + + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + + depd@2.0.0: + resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} + engines: {node: '>= 0.8'} + + detect-newline@3.1.0: + resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} + engines: {node: '>=8'} + + dezalgo@1.0.4: + resolution: {integrity: sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==} + + diff-sequences@29.6.3: + resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + diff@4.0.2: + resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} + engines: {node: '>=0.3.1'} + + dotenv-expand@12.0.1: + resolution: {integrity: sha512-LaKRbou8gt0RNID/9RoI+J2rvXsBRPMV7p+ElHlPhcSARbCPDYcYG2s1TIzAfWv4YSgyY5taidWzzs31lNV3yQ==} + engines: {node: '>=12'} + + dotenv@16.4.7: + resolution: {integrity: sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==} + engines: {node: '>=12'} + + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + + eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + + ee-first@1.1.1: + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + + ejs@3.1.10: + resolution: {integrity: sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==} + engines: {node: '>=0.10.0'} + hasBin: true + + electron-to-chromium@1.5.155: + resolution: {integrity: sha512-ps5KcGGmwL8VaeJlvlDlu4fORQpv3+GIcF5I3f9tUKUlJ/wsysh6HU8P5L1XWRYeXfA0oJd4PyM8ds8zTFf6Ng==} + + emittery@0.13.1: + resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==} + engines: {node: '>=12'} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + + encodeurl@2.0.0: + resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} + engines: {node: '>= 0.8'} + + enhanced-resolve@5.18.1: + resolution: {integrity: sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==} + engines: {node: '>=10.13.0'} + + error-ex@1.3.2: + resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-module-lexer@1.7.0: + resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} + + es-object-atoms@1.1.1: + resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} + engines: {node: '>= 0.4'} + + es-set-tostringtag@2.1.0: + resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} + engines: {node: '>= 0.4'} + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + + escape-string-regexp@2.0.0: + resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} + engines: {node: '>=8'} + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + eslint-config-prettier@10.1.5: + resolution: {integrity: sha512-zc1UmCpNltmVY34vuLRV61r1K27sWuX39E+uyUnY8xS2Bex88VV9cugG+UZbRSRGtGyFboj+D8JODyme1plMpw==} + hasBin: true + peerDependencies: + eslint: '>=7.0.0' + + eslint-plugin-prettier@5.4.0: + resolution: {integrity: sha512-BvQOvUhkVQM1i63iMETK9Hjud9QhqBnbtT1Zc642p9ynzBuCe5pybkOnvqZIBypXmMlsGcnU4HZ8sCTPfpAexA==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + '@types/eslint': '>=8.0.0' + eslint: '>=8.0.0' + eslint-config-prettier: '>= 7.0.0 <10.0.0 || >=10.1.0' + prettier: '>=3.0.0' + peerDependenciesMeta: + '@types/eslint': + optional: true + eslint-config-prettier: + optional: true + + eslint-scope@5.1.1: + resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} + engines: {node: '>=8.0.0'} + + eslint-scope@8.3.0: + resolution: {integrity: sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint-visitor-keys@4.2.0: + resolution: {integrity: sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint@9.27.0: + resolution: {integrity: sha512-ixRawFQuMB9DZ7fjU3iGGganFDp3+45bPOdaRurcFHSXO1e/sYwUX/FtQZpLZJR6SjMoJH8hR2pPEAfDyCoU2Q==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + hasBin: true + peerDependencies: + jiti: '*' + peerDependenciesMeta: + jiti: + optional: true + + espree@10.3.0: + resolution: {integrity: sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + + esquery@1.6.0: + resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} + engines: {node: '>=0.10'} + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + + estraverse@4.3.0: + resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + + etag@1.8.1: + resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} + engines: {node: '>= 0.6'} + + events@3.3.0: + resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} + engines: {node: '>=0.8.x'} + + execa@5.1.1: + resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} + engines: {node: '>=10'} + + exit@0.1.2: + resolution: {integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==} + engines: {node: '>= 0.8.0'} + + expect@29.7.0: + resolution: {integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + express-session@1.18.1: + resolution: {integrity: sha512-a5mtTqEaZvBCL9A9aqkrtfz+3SMDhOVUnjafjo+s7A9Txkq+SVX2DLvSp1Zrv4uCXa3lMSK3viWnh9Gg07PBUA==} + engines: {node: '>= 0.8.0'} + + express@5.1.0: + resolution: {integrity: sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==} + engines: {node: '>= 18'} + + ext-list@2.2.2: + resolution: {integrity: sha512-u+SQgsubraE6zItfVA0tBuCBhfU9ogSRnsvygI7wht9TS510oLkBRXBsqopeUG/GBOIQyKZO9wjTqIu/sf5zFA==} + engines: {node: '>=0.10.0'} + + ext-name@5.0.0: + resolution: {integrity: sha512-yblEwXAbGv1VQDmow7s38W77hzAgJAO50ztBLMcUyUBfxv1HC+LGwtiEN+Co6LtlqT/5uwVOxsD4TNIilWhwdQ==} + engines: {node: '>=4'} + + external-editor@3.1.0: + resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==} + engines: {node: '>=4'} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-diff@1.3.0: + resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==} + + fast-fifo@1.3.2: + resolution: {integrity: sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==} + + fast-glob@3.3.3: + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} + engines: {node: '>=8.6.0'} + + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + + fast-safe-stringify@2.1.1: + resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==} + + fast-uri@3.0.6: + resolution: {integrity: sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==} + + fastq@1.19.1: + resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} + + fb-watchman@2.0.2: + resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==} + + fflate@0.8.2: + resolution: {integrity: sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==} + + file-entry-cache@8.0.0: + resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} + engines: {node: '>=16.0.0'} + + file-type@19.6.0: + resolution: {integrity: sha512-VZR5I7k5wkD0HgFnMsq5hOsSc710MJMu5Nc5QYsbe38NN5iPV/XTObYLc/cpttRTf6lX538+5uO1ZQRhYibiZQ==} + engines: {node: '>=18'} + + file-type@20.5.0: + resolution: {integrity: sha512-BfHZtG/l9iMm4Ecianu7P8HRD2tBHLtjXinm4X62XBOYzi7CYA7jyqfJzOvXHqzVrVPYqBo2/GvbARMaaJkKVg==} + engines: {node: '>=18'} + + filelist@1.0.4: + resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==} + + filename-reserved-regex@3.0.0: + resolution: {integrity: sha512-hn4cQfU6GOT/7cFHXBqeBg2TbrMBgdD0kcjLhvSQYYwm3s4B6cjvBfb7nBALJLAXqmU5xajSa7X2NnUud/VCdw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + filenamify@6.0.0: + resolution: {integrity: sha512-vqIlNogKeyD3yzrm0yhRMQg8hOVwYcYRfjEoODd49iCprMn4HL85gK3HcykQE53EPIpX3HcAbGA5ELQv216dAQ==} + engines: {node: '>=16'} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + finalhandler@2.1.0: + resolution: {integrity: sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==} + engines: {node: '>= 0.8'} + + find-up@4.1.0: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} + + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + + find-versions@5.1.0: + resolution: {integrity: sha512-+iwzCJ7C5v5KgcBuueqVoNiHVoQpwiUK5XFLjf0affFTep+Wcw93tPvmb8tqujDNmzhBDPddnWV/qgWSXgq+Hg==} + engines: {node: '>=12'} + + flat-cache@4.0.1: + resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} + engines: {node: '>=16'} + + flatted@3.3.3: + resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} + + foreground-child@3.3.1: + resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} + engines: {node: '>=14'} + + fork-ts-checker-webpack-plugin@9.1.0: + resolution: {integrity: sha512-mpafl89VFPJmhnJ1ssH+8wmM2b50n+Rew5x42NeI2U78aRWgtkEtGmctp7iT16UjquJTjorEmIfESj3DxdW84Q==} + engines: {node: '>=14.21.3'} + peerDependencies: + typescript: '>3.6.0' + webpack: ^5.11.0 + + form-data-encoder@2.1.4: + resolution: {integrity: sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==} + engines: {node: '>= 14.17'} + + form-data@4.0.2: + resolution: {integrity: sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==} + engines: {node: '>= 6'} + + formidable@3.5.4: + resolution: {integrity: sha512-YikH+7CUTOtP44ZTnUhR7Ic2UASBPOqmaRkRKxRbywPTe5VxF7RRCck4af9wutiZ/QKM5nME9Bie2fFaPz5Gug==} + engines: {node: '>=14.0.0'} + + forwarded@0.2.0: + resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} + engines: {node: '>= 0.6'} + + fresh@2.0.0: + resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} + engines: {node: '>= 0.8'} + + fs-extra@10.1.0: + resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} + engines: {node: '>=12'} + + fs-monkey@1.0.6: + resolution: {integrity: sha512-b1FMfwetIKymC0eioW7mTywihSQE4oLzQn1dB6rZB5fx/3NpNEdAWeCSMB+60/AeT0TCXsxzAlcYVEFCTAksWg==} + + fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + + get-package-type@0.1.0: + resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} + engines: {node: '>=8.0.0'} + + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + + get-stream@6.0.1: + resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} + engines: {node: '>=10'} + + get-stream@9.0.1: + resolution: {integrity: sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==} + engines: {node: '>=18'} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + + glob-to-regexp@0.4.1: + resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} + + glob@11.0.1: + resolution: {integrity: sha512-zrQDm8XPnYEKawJScsnM0QzobJxlT/kHOOlRTio8IH/GrmxRE5fjllkzdaHclIuNjUQTJYH2xHNIGfdpJkDJUw==} + engines: {node: 20 || >=22} + hasBin: true + + glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + deprecated: Glob versions prior to v9 are no longer supported + + globals@11.12.0: + resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} + engines: {node: '>=4'} + + globals@14.0.0: + resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} + engines: {node: '>=18'} + + globals@16.1.0: + resolution: {integrity: sha512-aibexHNbb/jiUSObBgpHLj+sIuUmJnYcgXBlrfsiDZ9rt4aF2TFRbyLgZ2iFQuVZ1K5Mx3FVkbKRSgKrbK3K2g==} + engines: {node: '>=18'} + + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + + got@13.0.0: + resolution: {integrity: sha512-XfBk1CxOOScDcMr9O1yKkNaQyy865NbYs+F7dr4H0LZMVgCj2Le59k6PqbNHoL5ToeaEQUYh6c6yMfVcc6SJxA==} + engines: {node: '>=16'} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + graphemer@1.4.0: + resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + has-own-prop@2.0.0: + resolution: {integrity: sha512-Pq0h+hvsVm6dDEa8x82GnLSYHOzNDt7f0ddFa3FqcQlgzEiptPqL+XrOJNavjOzSYiYWIrgeVYYgGlLmnxwilQ==} + engines: {node: '>=8'} + + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + html-escaper@2.0.2: + resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} + + http-cache-semantics@4.2.0: + resolution: {integrity: sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==} + + http-errors@2.0.0: + resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} + engines: {node: '>= 0.8'} + + http2-wrapper@2.2.1: + resolution: {integrity: sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==} + engines: {node: '>=10.19.0'} + + human-signals@2.1.0: + resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} + engines: {node: '>=10.17.0'} + + iconv-lite@0.4.24: + resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} + engines: {node: '>=0.10.0'} + + iconv-lite@0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} + engines: {node: '>=0.10.0'} + + ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + ignore@7.0.4: + resolution: {integrity: sha512-gJzzk+PQNznz8ysRrC0aOkBNVRBDtE1n53IqyqEf3PXrYwomFs5q4pGMizBMJF+ykh03insJ27hB8gSrD2Hn8A==} + engines: {node: '>= 4'} + + import-fresh@3.3.1: + resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} + engines: {node: '>=6'} + + import-local@3.2.0: + resolution: {integrity: sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==} + engines: {node: '>=8'} + hasBin: true + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + inspect-with-kind@1.0.5: + resolution: {integrity: sha512-MAQUJuIo7Xqk8EVNP+6d3CKq9c80hi4tjIbIAT6lmGW9W6WzlHiu9PS8uSuUYU+Do+j1baiFp3H25XEVxDIG2g==} + + ipaddr.js@1.9.1: + resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} + engines: {node: '>= 0.10'} + + is-arrayish@0.2.1: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + + is-core-module@2.16.1: + resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} + engines: {node: '>= 0.4'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-generator-fn@2.1.0: + resolution: {integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==} + engines: {node: '>=6'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-interactive@1.0.0: + resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==} + engines: {node: '>=8'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-plain-obj@1.1.0: + resolution: {integrity: sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==} + engines: {node: '>=0.10.0'} + + is-promise@4.0.0: + resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==} + + is-stream@2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + + is-stream@4.0.1: + resolution: {integrity: sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==} + engines: {node: '>=18'} + + is-unicode-supported@0.1.0: + resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} + engines: {node: '>=10'} + + isarray@1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + istanbul-lib-coverage@3.2.2: + resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} + engines: {node: '>=8'} + + istanbul-lib-instrument@5.2.1: + resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==} + engines: {node: '>=8'} + + istanbul-lib-instrument@6.0.3: + resolution: {integrity: sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==} + engines: {node: '>=10'} + + istanbul-lib-report@3.0.1: + resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} + engines: {node: '>=10'} + + istanbul-lib-source-maps@4.0.1: + resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==} + engines: {node: '>=10'} + + istanbul-reports@3.1.7: + resolution: {integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==} + engines: {node: '>=8'} + + iterare@1.2.1: + resolution: {integrity: sha512-RKYVTCjAnRthyJes037NX/IiqeidgN1xc3j1RjFfECFp28A1GVwK9nA+i0rJPaHqSZwygLzRnFlzUuHFoWWy+Q==} + engines: {node: '>=6'} + + jackspeak@4.1.0: + resolution: {integrity: sha512-9DDdhb5j6cpeitCbvLO7n7J4IxnbM6hoF6O1g4HQ5TfhvvKN8ywDM7668ZhMHRqVmxqhps/F6syWK2KcPxYlkw==} + engines: {node: 20 || >=22} + + jake@10.9.2: + resolution: {integrity: sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==} + engines: {node: '>=10'} + hasBin: true + + jest-changed-files@29.7.0: + resolution: {integrity: sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-circus@29.7.0: + resolution: {integrity: sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-cli@29.7.0: + resolution: {integrity: sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + hasBin: true + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + + jest-config@29.7.0: + resolution: {integrity: sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@types/node': '*' + ts-node: '>=9.0.0' + peerDependenciesMeta: + '@types/node': + optional: true + ts-node: + optional: true + + jest-diff@29.7.0: + resolution: {integrity: sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-docblock@29.7.0: + resolution: {integrity: sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-each@29.7.0: + resolution: {integrity: sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-environment-node@29.7.0: + resolution: {integrity: sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-get-type@29.6.3: + resolution: {integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-haste-map@29.7.0: + resolution: {integrity: sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-leak-detector@29.7.0: + resolution: {integrity: sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-matcher-utils@29.7.0: + resolution: {integrity: sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-message-util@29.7.0: + resolution: {integrity: sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-mock@29.7.0: + resolution: {integrity: sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-pnp-resolver@1.2.3: + resolution: {integrity: sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==} + engines: {node: '>=6'} + peerDependencies: + jest-resolve: '*' + peerDependenciesMeta: + jest-resolve: + optional: true + + jest-regex-util@29.6.3: + resolution: {integrity: sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-resolve-dependencies@29.7.0: + resolution: {integrity: sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-resolve@29.7.0: + resolution: {integrity: sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-runner@29.7.0: + resolution: {integrity: sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-runtime@29.7.0: + resolution: {integrity: sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-snapshot@29.7.0: + resolution: {integrity: sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-util@29.7.0: + resolution: {integrity: sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-validate@29.7.0: + resolution: {integrity: sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-watcher@29.7.0: + resolution: {integrity: sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-worker@27.5.1: + resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==} + engines: {node: '>= 10.13.0'} + + jest-worker@29.7.0: + resolution: {integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest@29.7.0: + resolution: {integrity: sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + hasBin: true + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + + jiti@2.4.2: + resolution: {integrity: sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==} + hasBin: true + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + js-yaml@3.14.1: + resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} + hasBin: true + + js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} + hasBin: true + + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + + json-parse-even-better-errors@2.3.1: + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + + json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + + jsonc-parser@3.3.1: + resolution: {integrity: sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==} + + jsonfile@6.1.0: + resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + + kind-of@6.0.3: + resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} + engines: {node: '>=0.10.0'} + + kleur@3.0.3: + resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} + engines: {node: '>=6'} + + leven@3.1.0: + resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} + engines: {node: '>=6'} + + levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + + lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + + load-esm@1.0.2: + resolution: {integrity: sha512-nVAvWk/jeyrWyXEAs84mpQCYccxRqgKY4OznLuJhJCa0XsPSfdOIr2zvBZEj3IHEHbX97jjscKRRV539bW0Gpw==} + engines: {node: '>=13.2.0'} + + loader-runner@4.3.0: + resolution: {integrity: sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==} + engines: {node: '>=6.11.5'} + + locate-path@5.0.0: + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} + engines: {node: '>=8'} + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + + lodash.memoize@4.1.2: + resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==} + + lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + + lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + + log-symbols@4.1.0: + resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} + engines: {node: '>=10'} + + lowercase-keys@3.0.0: + resolution: {integrity: sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + lru-cache@11.1.0: + resolution: {integrity: sha512-QIXZUBJUx+2zHUdQujWejBkcD9+cs94tLn0+YL8UrCh+D5sCXZ4c7LaEH48pNwRY3MLDgqUFyhlCyjJPf1WP0A==} + engines: {node: 20 || >=22} + + lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + + magic-string@0.30.17: + resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} + + make-dir@4.0.0: + resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} + engines: {node: '>=10'} + + make-error@1.3.6: + resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + + makeerror@1.0.12: + resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==} + + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + + media-typer@0.3.0: + resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} + engines: {node: '>= 0.6'} + + media-typer@1.1.0: + resolution: {integrity: sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==} + engines: {node: '>= 0.8'} + + memfs@3.5.3: + resolution: {integrity: sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==} + engines: {node: '>= 4.0.0'} + + merge-descriptors@2.0.0: + resolution: {integrity: sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==} + engines: {node: '>=18'} + + merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + methods@1.1.2: + resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} + engines: {node: '>= 0.6'} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-db@1.54.0: + resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + + mime-types@3.0.1: + resolution: {integrity: sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==} + engines: {node: '>= 0.6'} + + mime@2.6.0: + resolution: {integrity: sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==} + engines: {node: '>=4.0.0'} + hasBin: true + + mimic-fn@2.1.0: + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} + engines: {node: '>=6'} + + mimic-response@3.1.0: + resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} + engines: {node: '>=10'} + + mimic-response@4.0.0: + resolution: {integrity: sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + minimatch@10.0.1: + resolution: {integrity: sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==} + engines: {node: 20 || >=22} + + minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + + minimatch@5.1.6: + resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} + engines: {node: '>=10'} + + minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + engines: {node: '>=16 || 14 >=14.17'} + + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + minipass@7.1.2: + resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + engines: {node: '>=16 || 14 >=14.17'} + + mkdirp@0.5.6: + resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} + hasBin: true + + ms@2.0.0: + resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + multer@1.4.5-lts.2: + resolution: {integrity: sha512-VzGiVigcG9zUAoCNU+xShztrlr1auZOlurXynNvO9GiWD1/mTBbUljOKY+qMeazBqXgRnjzeEgJI/wyjJUHg9A==} + engines: {node: '>= 6.0.0'} + + mute-stream@2.0.0: + resolution: {integrity: sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==} + engines: {node: ^18.17.0 || >=20.5.0} + + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + + negotiator@1.0.0: + resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==} + engines: {node: '>= 0.6'} + + neo-async@2.6.2: + resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} + + node-abort-controller@3.1.1: + resolution: {integrity: sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==} + + node-emoji@1.11.0: + resolution: {integrity: sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==} + + node-int64@0.4.0: + resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} + + node-releases@2.0.19: + resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==} + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + normalize-url@8.0.1: + resolution: {integrity: sha512-IO9QvjUMWxPQQhs60oOu10CRkWCiZzSUkzbXGGV9pviYl1fXYcvkzQ5jV9z8Y6un8ARoVRl4EtC6v6jNqbaJ/w==} + engines: {node: '>=14.16'} + + npm-run-path@4.0.1: + resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} + engines: {node: '>=8'} + + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + object-inspect@1.13.4: + resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} + engines: {node: '>= 0.4'} + + on-finished@2.4.1: + resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} + engines: {node: '>= 0.8'} + + on-headers@1.0.2: + resolution: {integrity: sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==} + engines: {node: '>= 0.8'} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + onetime@5.1.2: + resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} + engines: {node: '>=6'} + + optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} + engines: {node: '>= 0.8.0'} + + ora@5.4.1: + resolution: {integrity: sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==} + engines: {node: '>=10'} + + os-tmpdir@1.0.2: + resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} + engines: {node: '>=0.10.0'} + + p-cancelable@3.0.0: + resolution: {integrity: sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==} + engines: {node: '>=12.20'} + + p-limit@2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-locate@4.1.0: + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + engines: {node: '>=8'} + + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + + p-try@2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + + package-json-from-dist@1.0.1: + resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + + parse-json@5.2.0: + resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} + engines: {node: '>=8'} + + parseurl@1.3.3: + resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} + engines: {node: '>= 0.8'} + + passport-strategy@1.0.0: + resolution: {integrity: sha512-CB97UUvDKJde2V0KDWWB3lyf6PC3FaZP7YxZ2G8OAtn9p4HI9j9JLP9qjOGZFvyl8uwNT8qM+hGnz/n16NI7oA==} + engines: {node: '>= 0.4.0'} + + passport@0.7.0: + resolution: {integrity: sha512-cPLl+qZpSc+ireUvt+IzqbED1cHHkDoVYMo30jbJIdOOjQ1MQYZBPiNvmi8UM6lJuOpTPXJGZQk0DtC4y61MYQ==} + engines: {node: '>= 0.4.0'} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + + path-scurry@2.0.0: + resolution: {integrity: sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==} + engines: {node: 20 || >=22} + + path-to-regexp@8.2.0: + resolution: {integrity: sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==} + engines: {node: '>=16'} + + path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + + pause@0.0.1: + resolution: {integrity: sha512-KG8UEiEVkR3wGEb4m5yZkVCzigAD+cVEJck2CzYZO37ZGJfctvVptVO192MwrtPhzONn6go8ylnOdMhKqi4nfg==} + + peek-readable@5.4.2: + resolution: {integrity: sha512-peBp3qZyuS6cNIJ2akRNG1uo1WJ1d0wTxg/fxMdZ0BqCVhx242bSFHM9eNqflfJVS9SsgkzgT/1UgnsurBOTMg==} + engines: {node: '>=14.16'} + + peek-readable@7.0.0: + resolution: {integrity: sha512-nri2TO5JE3/mRryik9LlHFT53cgHfRK0Lt0BAZQXku/AW3E6XLt2GaY8siWi7dvW/m1z0ecn+J+bpDa9ZN3IsQ==} + engines: {node: '>=18'} + + pend@1.2.0: + resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + picomatch@4.0.2: + resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} + engines: {node: '>=12'} + + pirates@4.0.7: + resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} + engines: {node: '>= 6'} + + piscina@4.9.2: + resolution: {integrity: sha512-Fq0FERJWFEUpB4eSY59wSNwXD4RYqR+nR/WiEVcZW8IWfVBxJJafcgTEZDQo8k3w0sUarJ8RyVbbUF4GQ2LGbQ==} + + pkg-dir@4.2.0: + resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} + engines: {node: '>=8'} + + pluralize@8.0.0: + resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} + engines: {node: '>=4'} + + prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + + prettier-linter-helpers@1.0.0: + resolution: {integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==} + engines: {node: '>=6.0.0'} + + prettier@3.5.3: + resolution: {integrity: sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==} + engines: {node: '>=14'} + hasBin: true + + pretty-format@29.7.0: + resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + prisma@6.8.2: + resolution: {integrity: sha512-JNricTXQxzDtRS7lCGGOB4g5DJ91eg3nozdubXze3LpcMl1oWwcFddrj++Up3jnRE6X/3gB/xz3V+ecBk/eEGA==} + engines: {node: '>=18.18'} + hasBin: true + peerDependencies: + typescript: '>=5.1.0' + peerDependenciesMeta: + typescript: + optional: true + + process-nextick-args@2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + + prompts@2.4.2: + resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} + engines: {node: '>= 6'} + + proxy-addr@2.0.7: + resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} + engines: {node: '>= 0.10'} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + pure-rand@6.1.0: + resolution: {integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==} + + qs@6.14.0: + resolution: {integrity: sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==} + engines: {node: '>=0.6'} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + quick-lru@5.1.1: + resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==} + engines: {node: '>=10'} + + random-bytes@1.0.0: + resolution: {integrity: sha512-iv7LhNVO047HzYR3InF6pUcUsPQiHTM1Qal51DcGSuZFBil1aBBWG5eHPNek7bvILMaYJ/8RU1e8w1AMdHmLQQ==} + engines: {node: '>= 0.8'} + + randombytes@2.1.0: + resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} + + range-parser@1.2.1: + resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} + engines: {node: '>= 0.6'} + + raw-body@3.0.0: + resolution: {integrity: sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==} + engines: {node: '>= 0.8'} + + react-is@18.3.1: + resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} + + readable-stream@2.3.8: + resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + + readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} + + readdirp@4.1.2: + resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} + engines: {node: '>= 14.18.0'} + + reflect-metadata@0.2.2: + resolution: {integrity: sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==} + + repeat-string@1.6.1: + resolution: {integrity: sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==} + engines: {node: '>=0.10'} + + require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + + require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + + resolve-alpn@1.2.1: + resolution: {integrity: sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==} + + resolve-cwd@3.0.0: + resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==} + engines: {node: '>=8'} + + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + + resolve-from@5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + + resolve.exports@2.0.3: + resolution: {integrity: sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==} + engines: {node: '>=10'} + + resolve@1.22.10: + resolution: {integrity: sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==} + engines: {node: '>= 0.4'} + hasBin: true + + responselike@3.0.0: + resolution: {integrity: sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==} + engines: {node: '>=14.16'} + + restore-cursor@3.1.0: + resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} + engines: {node: '>=8'} + + reusify@1.1.0: + resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + router@2.2.0: + resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==} + engines: {node: '>= 18'} + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + rxjs@7.8.1: + resolution: {integrity: sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==} + + rxjs@7.8.2: + resolution: {integrity: sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==} + + safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + schema-utils@3.3.0: + resolution: {integrity: sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==} + engines: {node: '>= 10.13.0'} + + schema-utils@4.3.2: + resolution: {integrity: sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ==} + engines: {node: '>= 10.13.0'} + + seek-bzip@2.0.0: + resolution: {integrity: sha512-SMguiTnYrhpLdk3PwfzHeotrcwi8bNV4iemL9tx9poR/yeaMYwB9VzR1w7b57DuWpuqR8n6oZboi0hj3AxZxQg==} + hasBin: true + + semver-regex@4.0.5: + resolution: {integrity: sha512-hunMQrEy1T6Jr2uEVjrAIqjwWcQTgOAcIM52C8MY1EZSD3DDNft04XzvYKPqjED65bNVVko0YI38nYeEHCX3yw==} + engines: {node: '>=12'} + + semver-truncate@3.0.0: + resolution: {integrity: sha512-LJWA9kSvMolR51oDE6PN3kALBNaUdkxzAGcexw8gjMA8xr5zUqK0JiR3CgARSqanYF3Z1YHvsErb1KDgh+v7Rg==} + engines: {node: '>=12'} + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + semver@7.7.2: + resolution: {integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==} + engines: {node: '>=10'} + hasBin: true + + send@1.2.0: + resolution: {integrity: sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==} + engines: {node: '>= 18'} + + serialize-javascript@6.0.2: + resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} + + serve-static@2.2.0: + resolution: {integrity: sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==} + engines: {node: '>= 18'} + + setprototypeof@1.2.0: + resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + side-channel-list@1.0.0: + resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} + engines: {node: '>= 0.4'} + + side-channel-map@1.0.1: + resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} + engines: {node: '>= 0.4'} + + side-channel-weakmap@1.0.2: + resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} + engines: {node: '>= 0.4'} + + side-channel@1.1.0: + resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} + engines: {node: '>= 0.4'} + + signal-exit@3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + sisteransi@1.0.5: + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + + slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + + sort-keys-length@1.0.1: + resolution: {integrity: sha512-GRbEOUqCxemTAk/b32F2xa8wDTs+Z1QHOkbhJDQTvv/6G3ZkbJ+frYWsTcc7cBB3Fu4wy4XlLCuNtJuMn7Gsvw==} + engines: {node: '>=0.10.0'} + + sort-keys@1.1.2: + resolution: {integrity: sha512-vzn8aSqKgytVik0iwdBEi+zevbTYZogewTUM6dtpmGwEcdzbub/TX4bCzRhebDCRC3QzXgJsLRKB2V/Oof7HXg==} + engines: {node: '>=0.10.0'} + + source-map-support@0.5.13: + resolution: {integrity: sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==} + + source-map-support@0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + + source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + + source-map@0.7.4: + resolution: {integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==} + engines: {node: '>= 8'} + + sprintf-js@1.0.3: + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + + stack-utils@2.0.6: + resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} + engines: {node: '>=10'} + + statuses@2.0.1: + resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} + engines: {node: '>= 0.8'} + + streamsearch@1.1.0: + resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} + engines: {node: '>=10.0.0'} + + streamx@2.22.0: + resolution: {integrity: sha512-sLh1evHOzBy/iWRiR6d1zRcLao4gGZr3C1kzNz4fopCOKJb6xD9ub8Mpi9Mr1R6id5o43S+d93fI48UC5uM9aw==} + + string-length@4.0.2: + resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==} + engines: {node: '>=10'} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + + string_decoder@1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + + string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-ansi@7.1.0: + resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + engines: {node: '>=12'} + + strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + + strip-bom@4.0.0: + resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==} + engines: {node: '>=8'} + + strip-dirs@3.0.0: + resolution: {integrity: sha512-I0sdgcFTfKQlUPZyAqPJmSG3HLO9rWDFnxonnIbskYNM3DwFOeTNB5KzVq3dA1GdRAc/25b5Y7UO2TQfKWw4aQ==} + + strip-final-newline@2.0.0: + resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} + engines: {node: '>=6'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + strtok3@10.2.2: + resolution: {integrity: sha512-Xt18+h4s7Z8xyZ0tmBoRmzxcop97R4BAh+dXouUDCYn+Em+1P3qpkUfI5ueWLT8ynC5hZ+q4iPEmGG1urvQGBg==} + engines: {node: '>=18'} + + strtok3@9.1.1: + resolution: {integrity: sha512-FhwotcEqjr241ZbjFzjlIYg6c5/L/s4yBGWSMvJ9UoExiSqL+FnFA/CaeZx17WGaZMS/4SOZp8wH18jSS4R4lw==} + engines: {node: '>=16'} + + superagent@10.2.1: + resolution: {integrity: sha512-O+PCv11lgTNJUzy49teNAWLjBZfc+A1enOwTpLlH6/rsvKcTwcdTT8m9azGkVqM7HBl5jpyZ7KTPhHweokBcdg==} + engines: {node: '>=14.18.0'} + + supertest@7.1.1: + resolution: {integrity: sha512-aI59HBTlG9e2wTjxGJV+DygfNLgnWbGdZxiA/sgrnNNikIW8lbDvCtF6RnhZoJ82nU7qv7ZLjrvWqCEm52fAmw==} + engines: {node: '>=14.18.0'} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + supports-color@8.1.1: + resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} + engines: {node: '>=10'} + + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + symbol-observable@4.0.0: + resolution: {integrity: sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ==} + engines: {node: '>=0.10'} + + synckit@0.11.5: + resolution: {integrity: sha512-frqvfWyDA5VPVdrWfH24uM6SI/O8NLpVbIIJxb8t/a3YGsp4AW9CYgSKC0OaSEfexnp7Y1pVh2Y6IHO8ggGDmA==} + engines: {node: ^14.18.0 || >=16.0.0} + + tapable@2.2.1: + resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} + engines: {node: '>=6'} + + tar-stream@3.1.7: + resolution: {integrity: sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==} + + terser-webpack-plugin@5.3.14: + resolution: {integrity: sha512-vkZjpUjb6OMS7dhV+tILUW6BhpDR7P2L/aQSAv+Uwk+m8KATX9EccViHTJR2qDtACKPIYndLGCyl3FMo+r2LMw==} + engines: {node: '>= 10.13.0'} + peerDependencies: + '@swc/core': '*' + esbuild: '*' + uglify-js: '*' + webpack: ^5.1.0 + peerDependenciesMeta: + '@swc/core': + optional: true + esbuild: + optional: true + uglify-js: + optional: true + + terser@5.39.2: + resolution: {integrity: sha512-yEPUmWve+VA78bI71BW70Dh0TuV4HHd+I5SHOAfS1+QBOmvmCiiffgjR8ryyEd3KIfvPGFqoADt8LdQ6XpXIvg==} + engines: {node: '>=10'} + hasBin: true + + test-exclude@6.0.0: + resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} + engines: {node: '>=8'} + + text-decoder@1.2.3: + resolution: {integrity: sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==} + + through@2.3.8: + resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} + + tmp@0.0.33: + resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} + engines: {node: '>=0.6.0'} + + tmpl@1.0.5: + resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + toidentifier@1.0.1: + resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} + engines: {node: '>=0.6'} + + token-types@6.0.0: + resolution: {integrity: sha512-lbDrTLVsHhOMljPscd0yitpozq7Ga2M5Cvez5AjGg8GASBjtt6iERCAJ93yommPmz62fb45oFIXHEZ3u9bfJEA==} + engines: {node: '>=14.16'} + + tree-kill@1.2.2: + resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} + hasBin: true + + ts-api-utils@2.1.0: + resolution: {integrity: sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==} + engines: {node: '>=18.12'} + peerDependencies: + typescript: '>=4.8.4' + + ts-jest@29.3.4: + resolution: {integrity: sha512-Iqbrm8IXOmV+ggWHOTEbjwyCf2xZlUMv5npExksXohL+tk8va4Fjhb+X2+Rt9NBmgO7bJ8WpnMLOwih/DnMlFA==} + engines: {node: ^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@babel/core': '>=7.0.0-beta.0 <8' + '@jest/transform': ^29.0.0 + '@jest/types': ^29.0.0 + babel-jest: ^29.0.0 + esbuild: '*' + jest: ^29.0.0 + typescript: '>=4.3 <6' + peerDependenciesMeta: + '@babel/core': + optional: true + '@jest/transform': + optional: true + '@jest/types': + optional: true + babel-jest: + optional: true + esbuild: + optional: true + + ts-loader@9.5.2: + resolution: {integrity: sha512-Qo4piXvOTWcMGIgRiuFa6nHNm+54HbYaZCKqc9eeZCLRy3XqafQgwX2F7mofrbJG3g7EEb+lkiR+z2Lic2s3Zw==} + engines: {node: '>=12.0.0'} + peerDependencies: + typescript: '*' + webpack: ^5.0.0 + + ts-node@10.9.2: + resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==} + hasBin: true + peerDependencies: + '@swc/core': '>=1.2.50' + '@swc/wasm': '>=1.2.50' + '@types/node': '*' + typescript: '>=2.7' + peerDependenciesMeta: + '@swc/core': + optional: true + '@swc/wasm': + optional: true + + tsconfig-paths-webpack-plugin@4.2.0: + resolution: {integrity: sha512-zbem3rfRS8BgeNK50Zz5SIQgXzLafiHjOwUAvk/38/o1jHn/V5QAgVUcz884or7WYcPaH3N2CIfUc2u0ul7UcA==} + engines: {node: '>=10.13.0'} + + tsconfig-paths@4.2.0: + resolution: {integrity: sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==} + engines: {node: '>=6'} + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + + type-detect@4.0.8: + resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} + engines: {node: '>=4'} + + type-fest@0.21.3: + resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} + engines: {node: '>=10'} + + type-fest@4.41.0: + resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} + engines: {node: '>=16'} + + type-is@1.6.18: + resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} + engines: {node: '>= 0.6'} + + type-is@2.0.1: + resolution: {integrity: sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==} + engines: {node: '>= 0.6'} + + typedarray@0.0.6: + resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} + + typescript-eslint@8.32.1: + resolution: {integrity: sha512-D7el+eaDHAmXvrZBy1zpzSNIRqnCOrkwTgZxTu3MUqRWk8k0q9m9Ho4+vPf7iHtgUfrK/o8IZaEApsxPlHTFCg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <5.9.0' + + typescript@5.8.3: + resolution: {integrity: sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==} + engines: {node: '>=14.17'} + hasBin: true + + uid-safe@2.1.5: + resolution: {integrity: sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==} + engines: {node: '>= 0.8'} + + uid@2.0.2: + resolution: {integrity: sha512-u3xV3X7uzvi5b1MncmZo3i2Aw222Zk1keqLA1YkHldREkAhAqi65wuPfe7lHx8H/Wzy+8CE7S7uS3jekIM5s8g==} + engines: {node: '>=8'} + + uint8array-extras@1.4.0: + resolution: {integrity: sha512-ZPtzy0hu4cZjv3z5NW9gfKnNLjoz4y6uv4HlelAjDK7sY/xOkKZv9xK/WQpcsBB3jEybChz9DPC2U/+cusjJVQ==} + engines: {node: '>=18'} + + unbzip2-stream@1.4.3: + resolution: {integrity: sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==} + + undici-types@6.21.0: + resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + + universalify@2.0.1: + resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} + engines: {node: '>= 10.0.0'} + + unpipe@1.0.0: + resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} + engines: {node: '>= 0.8'} + + update-browserslist-db@1.1.3: + resolution: {integrity: sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + utils-merge@1.0.1: + resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} + engines: {node: '>= 0.4.0'} + + v8-compile-cache-lib@3.0.1: + resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} + + v8-to-istanbul@9.3.0: + resolution: {integrity: sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==} + engines: {node: '>=10.12.0'} + + vary@1.1.2: + resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} + engines: {node: '>= 0.8'} + + walker@1.0.8: + resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==} + + watchpack@2.4.2: + resolution: {integrity: sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==} + engines: {node: '>=10.13.0'} + + wcwidth@1.0.1: + resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} + + webpack-node-externals@3.0.0: + resolution: {integrity: sha512-LnL6Z3GGDPht/AigwRh2dvL9PQPFQ8skEpVrWZXLWBYmqcaojHNN0onvHzie6rq7EWKrrBfPYqNEzTJgiwEQDQ==} + engines: {node: '>=6'} + + webpack-sources@3.2.3: + resolution: {integrity: sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==} + engines: {node: '>=10.13.0'} + + webpack@5.99.6: + resolution: {integrity: sha512-TJOLrJ6oeccsGWPl7ujCYuc0pIq2cNsuD6GZDma8i5o5Npvcco/z+NKvZSFsP0/x6SShVb0+X2JK/JHUjKY9dQ==} + engines: {node: '>=10.13.0'} + hasBin: true + peerDependencies: + webpack-cli: '*' + peerDependenciesMeta: + webpack-cli: + optional: true + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + + wrap-ansi@6.2.0: + resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} + engines: {node: '>=8'} + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + write-file-atomic@4.0.2: + resolution: {integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + + xtend@4.0.2: + resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} + engines: {node: '>=0.4'} + + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + + yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + + yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + + yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + + yauzl@3.2.0: + resolution: {integrity: sha512-Ow9nuGZE+qp1u4JIPvg+uCiUr7xGQWdff7JQSk5VGYTAZMDe2q8lxJ10ygv10qmSj031Ty/6FNJpLO4o1Sgc+w==} + engines: {node: '>=12'} + + yn@3.1.1: + resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} + engines: {node: '>=6'} + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + + yoctocolors-cjs@2.1.2: + resolution: {integrity: sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA==} + engines: {node: '>=18'} + +snapshots: + + '@ampproject/remapping@2.3.0': + dependencies: + '@jridgewell/gen-mapping': 0.3.8 + '@jridgewell/trace-mapping': 0.3.25 + + '@angular-devkit/core@19.2.6(chokidar@4.0.3)': + dependencies: + ajv: 8.17.1 + ajv-formats: 3.0.1(ajv@8.17.1) + jsonc-parser: 3.3.1 + picomatch: 4.0.2 + rxjs: 7.8.1 + source-map: 0.7.4 + optionalDependencies: + chokidar: 4.0.3 + + '@angular-devkit/core@19.2.8(chokidar@4.0.3)': + dependencies: + ajv: 8.17.1 + ajv-formats: 3.0.1(ajv@8.17.1) + jsonc-parser: 3.3.1 + picomatch: 4.0.2 + rxjs: 7.8.1 + source-map: 0.7.4 + optionalDependencies: + chokidar: 4.0.3 + + '@angular-devkit/schematics-cli@19.2.8(@types/node@22.15.21)(chokidar@4.0.3)': + dependencies: + '@angular-devkit/core': 19.2.8(chokidar@4.0.3) + '@angular-devkit/schematics': 19.2.8(chokidar@4.0.3) + '@inquirer/prompts': 7.3.2(@types/node@22.15.21) + ansi-colors: 4.1.3 + symbol-observable: 4.0.0 + yargs-parser: 21.1.1 + transitivePeerDependencies: + - '@types/node' + - chokidar + + '@angular-devkit/schematics@19.2.6(chokidar@4.0.3)': + dependencies: + '@angular-devkit/core': 19.2.6(chokidar@4.0.3) + jsonc-parser: 3.3.1 + magic-string: 0.30.17 + ora: 5.4.1 + rxjs: 7.8.1 + transitivePeerDependencies: + - chokidar + + '@angular-devkit/schematics@19.2.8(chokidar@4.0.3)': + dependencies: + '@angular-devkit/core': 19.2.8(chokidar@4.0.3) + jsonc-parser: 3.3.1 + magic-string: 0.30.17 + ora: 5.4.1 + rxjs: 7.8.1 + transitivePeerDependencies: + - chokidar + + '@babel/code-frame@7.27.1': + dependencies: + '@babel/helper-validator-identifier': 7.27.1 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/compat-data@7.27.2': {} + + '@babel/core@7.27.1': + dependencies: + '@ampproject/remapping': 2.3.0 + '@babel/code-frame': 7.27.1 + '@babel/generator': 7.27.1 + '@babel/helper-compilation-targets': 7.27.2 + '@babel/helper-module-transforms': 7.27.1(@babel/core@7.27.1) + '@babel/helpers': 7.27.1 + '@babel/parser': 7.27.2 + '@babel/template': 7.27.2 + '@babel/traverse': 7.27.1 + '@babel/types': 7.27.1 + convert-source-map: 2.0.0 + debug: 4.4.1 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/generator@7.27.1': + dependencies: + '@babel/parser': 7.27.2 + '@babel/types': 7.27.1 + '@jridgewell/gen-mapping': 0.3.8 + '@jridgewell/trace-mapping': 0.3.25 + jsesc: 3.1.0 + + '@babel/helper-compilation-targets@7.27.2': + dependencies: + '@babel/compat-data': 7.27.2 + '@babel/helper-validator-option': 7.27.1 + browserslist: 4.24.5 + lru-cache: 5.1.1 + semver: 6.3.1 + + '@babel/helper-module-imports@7.27.1': + dependencies: + '@babel/traverse': 7.27.1 + '@babel/types': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-transforms@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-module-imports': 7.27.1 + '@babel/helper-validator-identifier': 7.27.1 + '@babel/traverse': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/helper-plugin-utils@7.27.1': {} + + '@babel/helper-string-parser@7.27.1': {} + + '@babel/helper-validator-identifier@7.27.1': {} + + '@babel/helper-validator-option@7.27.1': {} + + '@babel/helpers@7.27.1': + dependencies: + '@babel/template': 7.27.2 + '@babel/types': 7.27.1 + + '@babel/parser@7.27.2': + dependencies: + '@babel/types': 7.27.1 + + '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-import-attributes@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-typescript@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/template@7.27.2': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/parser': 7.27.2 + '@babel/types': 7.27.1 + + '@babel/traverse@7.27.1': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/generator': 7.27.1 + '@babel/parser': 7.27.2 + '@babel/template': 7.27.2 + '@babel/types': 7.27.1 + debug: 4.4.1 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + + '@babel/types@7.27.1': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.27.1 + + '@bcoe/v8-coverage@0.2.3': {} + + '@colors/colors@1.5.0': + optional: true + + '@cspotcode/source-map-support@0.8.1': + dependencies: + '@jridgewell/trace-mapping': 0.3.9 + + '@eslint-community/eslint-utils@4.7.0(eslint@9.27.0(jiti@2.4.2))': + dependencies: + eslint: 9.27.0(jiti@2.4.2) + eslint-visitor-keys: 3.4.3 + + '@eslint-community/regexpp@4.12.1': {} + + '@eslint/config-array@0.20.0': + dependencies: + '@eslint/object-schema': 2.1.6 + debug: 4.4.1 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + + '@eslint/config-helpers@0.2.2': {} + + '@eslint/core@0.14.0': + dependencies: + '@types/json-schema': 7.0.15 + + '@eslint/eslintrc@3.3.1': + dependencies: + ajv: 6.12.6 + debug: 4.4.1 + espree: 10.3.0 + globals: 14.0.0 + ignore: 5.3.2 + import-fresh: 3.3.1 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + + '@eslint/js@9.27.0': {} + + '@eslint/object-schema@2.1.6': {} + + '@eslint/plugin-kit@0.3.1': + dependencies: + '@eslint/core': 0.14.0 + levn: 0.4.1 + + '@humanfs/core@0.19.1': {} + + '@humanfs/node@0.16.6': + dependencies: + '@humanfs/core': 0.19.1 + '@humanwhocodes/retry': 0.3.1 + + '@humanwhocodes/module-importer@1.0.1': {} + + '@humanwhocodes/retry@0.3.1': {} + + '@humanwhocodes/retry@0.4.3': {} + + '@inquirer/checkbox@4.1.6(@types/node@22.15.21)': + dependencies: + '@inquirer/core': 10.1.11(@types/node@22.15.21) + '@inquirer/figures': 1.0.11 + '@inquirer/type': 3.0.6(@types/node@22.15.21) + ansi-escapes: 4.3.2 + yoctocolors-cjs: 2.1.2 + optionalDependencies: + '@types/node': 22.15.21 + + '@inquirer/confirm@5.1.10(@types/node@22.15.21)': + dependencies: + '@inquirer/core': 10.1.11(@types/node@22.15.21) + '@inquirer/type': 3.0.6(@types/node@22.15.21) + optionalDependencies: + '@types/node': 22.15.21 + + '@inquirer/core@10.1.11(@types/node@22.15.21)': + dependencies: + '@inquirer/figures': 1.0.11 + '@inquirer/type': 3.0.6(@types/node@22.15.21) + ansi-escapes: 4.3.2 + cli-width: 4.1.0 + mute-stream: 2.0.0 + signal-exit: 4.1.0 + wrap-ansi: 6.2.0 + yoctocolors-cjs: 2.1.2 + optionalDependencies: + '@types/node': 22.15.21 + + '@inquirer/editor@4.2.11(@types/node@22.15.21)': + dependencies: + '@inquirer/core': 10.1.11(@types/node@22.15.21) + '@inquirer/type': 3.0.6(@types/node@22.15.21) + external-editor: 3.1.0 + optionalDependencies: + '@types/node': 22.15.21 + + '@inquirer/expand@4.0.13(@types/node@22.15.21)': + dependencies: + '@inquirer/core': 10.1.11(@types/node@22.15.21) + '@inquirer/type': 3.0.6(@types/node@22.15.21) + yoctocolors-cjs: 2.1.2 + optionalDependencies: + '@types/node': 22.15.21 + + '@inquirer/figures@1.0.11': {} + + '@inquirer/input@4.1.10(@types/node@22.15.21)': + dependencies: + '@inquirer/core': 10.1.11(@types/node@22.15.21) + '@inquirer/type': 3.0.6(@types/node@22.15.21) + optionalDependencies: + '@types/node': 22.15.21 + + '@inquirer/number@3.0.13(@types/node@22.15.21)': + dependencies: + '@inquirer/core': 10.1.11(@types/node@22.15.21) + '@inquirer/type': 3.0.6(@types/node@22.15.21) + optionalDependencies: + '@types/node': 22.15.21 + + '@inquirer/password@4.0.13(@types/node@22.15.21)': + dependencies: + '@inquirer/core': 10.1.11(@types/node@22.15.21) + '@inquirer/type': 3.0.6(@types/node@22.15.21) + ansi-escapes: 4.3.2 + optionalDependencies: + '@types/node': 22.15.21 + + '@inquirer/prompts@7.3.2(@types/node@22.15.21)': + dependencies: + '@inquirer/checkbox': 4.1.6(@types/node@22.15.21) + '@inquirer/confirm': 5.1.10(@types/node@22.15.21) + '@inquirer/editor': 4.2.11(@types/node@22.15.21) + '@inquirer/expand': 4.0.13(@types/node@22.15.21) + '@inquirer/input': 4.1.10(@types/node@22.15.21) + '@inquirer/number': 3.0.13(@types/node@22.15.21) + '@inquirer/password': 4.0.13(@types/node@22.15.21) + '@inquirer/rawlist': 4.1.1(@types/node@22.15.21) + '@inquirer/search': 3.0.13(@types/node@22.15.21) + '@inquirer/select': 4.2.1(@types/node@22.15.21) + optionalDependencies: + '@types/node': 22.15.21 + + '@inquirer/prompts@7.4.1(@types/node@22.15.21)': + dependencies: + '@inquirer/checkbox': 4.1.6(@types/node@22.15.21) + '@inquirer/confirm': 5.1.10(@types/node@22.15.21) + '@inquirer/editor': 4.2.11(@types/node@22.15.21) + '@inquirer/expand': 4.0.13(@types/node@22.15.21) + '@inquirer/input': 4.1.10(@types/node@22.15.21) + '@inquirer/number': 3.0.13(@types/node@22.15.21) + '@inquirer/password': 4.0.13(@types/node@22.15.21) + '@inquirer/rawlist': 4.1.1(@types/node@22.15.21) + '@inquirer/search': 3.0.13(@types/node@22.15.21) + '@inquirer/select': 4.2.1(@types/node@22.15.21) + optionalDependencies: + '@types/node': 22.15.21 + + '@inquirer/rawlist@4.1.1(@types/node@22.15.21)': + dependencies: + '@inquirer/core': 10.1.11(@types/node@22.15.21) + '@inquirer/type': 3.0.6(@types/node@22.15.21) + yoctocolors-cjs: 2.1.2 + optionalDependencies: + '@types/node': 22.15.21 + + '@inquirer/search@3.0.13(@types/node@22.15.21)': + dependencies: + '@inquirer/core': 10.1.11(@types/node@22.15.21) + '@inquirer/figures': 1.0.11 + '@inquirer/type': 3.0.6(@types/node@22.15.21) + yoctocolors-cjs: 2.1.2 + optionalDependencies: + '@types/node': 22.15.21 + + '@inquirer/select@4.2.1(@types/node@22.15.21)': + dependencies: + '@inquirer/core': 10.1.11(@types/node@22.15.21) + '@inquirer/figures': 1.0.11 + '@inquirer/type': 3.0.6(@types/node@22.15.21) + ansi-escapes: 4.3.2 + yoctocolors-cjs: 2.1.2 + optionalDependencies: + '@types/node': 22.15.21 + + '@inquirer/type@3.0.6(@types/node@22.15.21)': + optionalDependencies: + '@types/node': 22.15.21 + + '@isaacs/cliui@8.0.2': + dependencies: + string-width: 5.1.2 + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.1.0 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 + + '@istanbuljs/load-nyc-config@1.1.0': + dependencies: + camelcase: 5.3.1 + find-up: 4.1.0 + get-package-type: 0.1.0 + js-yaml: 3.14.1 + resolve-from: 5.0.0 + + '@istanbuljs/schema@0.1.3': {} + + '@jest/console@29.7.0': + dependencies: + '@jest/types': 29.6.3 + '@types/node': 22.15.21 + chalk: 4.1.2 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + slash: 3.0.0 + + '@jest/core@29.7.0(ts-node@10.9.2(@swc/core@1.11.29)(@types/node@22.15.21)(typescript@5.8.3))': + dependencies: + '@jest/console': 29.7.0 + '@jest/reporters': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 22.15.21 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + ci-info: 3.9.0 + exit: 0.1.2 + graceful-fs: 4.2.11 + jest-changed-files: 29.7.0 + jest-config: 29.7.0(@types/node@22.15.21)(ts-node@10.9.2(@swc/core@1.11.29)(@types/node@22.15.21)(typescript@5.8.3)) + jest-haste-map: 29.7.0 + jest-message-util: 29.7.0 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-resolve-dependencies: 29.7.0 + jest-runner: 29.7.0 + jest-runtime: 29.7.0 + jest-snapshot: 29.7.0 + jest-util: 29.7.0 + jest-validate: 29.7.0 + jest-watcher: 29.7.0 + micromatch: 4.0.8 + pretty-format: 29.7.0 + slash: 3.0.0 + strip-ansi: 6.0.1 + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + - ts-node + + '@jest/environment@29.7.0': + dependencies: + '@jest/fake-timers': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 22.15.21 + jest-mock: 29.7.0 + + '@jest/expect-utils@29.7.0': + dependencies: + jest-get-type: 29.6.3 + + '@jest/expect@29.7.0': + dependencies: + expect: 29.7.0 + jest-snapshot: 29.7.0 + transitivePeerDependencies: + - supports-color + + '@jest/fake-timers@29.7.0': + dependencies: + '@jest/types': 29.6.3 + '@sinonjs/fake-timers': 10.3.0 + '@types/node': 22.15.21 + jest-message-util: 29.7.0 + jest-mock: 29.7.0 + jest-util: 29.7.0 + + '@jest/globals@29.7.0': + dependencies: + '@jest/environment': 29.7.0 + '@jest/expect': 29.7.0 + '@jest/types': 29.6.3 + jest-mock: 29.7.0 + transitivePeerDependencies: + - supports-color + + '@jest/reporters@29.7.0': + dependencies: + '@bcoe/v8-coverage': 0.2.3 + '@jest/console': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@jridgewell/trace-mapping': 0.3.25 + '@types/node': 22.15.21 + chalk: 4.1.2 + collect-v8-coverage: 1.0.2 + exit: 0.1.2 + glob: 7.2.3 + graceful-fs: 4.2.11 + istanbul-lib-coverage: 3.2.2 + istanbul-lib-instrument: 6.0.3 + istanbul-lib-report: 3.0.1 + istanbul-lib-source-maps: 4.0.1 + istanbul-reports: 3.1.7 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + jest-worker: 29.7.0 + slash: 3.0.0 + string-length: 4.0.2 + strip-ansi: 6.0.1 + v8-to-istanbul: 9.3.0 + transitivePeerDependencies: + - supports-color + + '@jest/schemas@29.6.3': + dependencies: + '@sinclair/typebox': 0.27.8 + + '@jest/source-map@29.6.3': + dependencies: + '@jridgewell/trace-mapping': 0.3.25 + callsites: 3.1.0 + graceful-fs: 4.2.11 + + '@jest/test-result@29.7.0': + dependencies: + '@jest/console': 29.7.0 + '@jest/types': 29.6.3 + '@types/istanbul-lib-coverage': 2.0.6 + collect-v8-coverage: 1.0.2 + + '@jest/test-sequencer@29.7.0': + dependencies: + '@jest/test-result': 29.7.0 + graceful-fs: 4.2.11 + jest-haste-map: 29.7.0 + slash: 3.0.0 + + '@jest/transform@29.7.0': + dependencies: + '@babel/core': 7.27.1 + '@jest/types': 29.6.3 + '@jridgewell/trace-mapping': 0.3.25 + babel-plugin-istanbul: 6.1.1 + chalk: 4.1.2 + convert-source-map: 2.0.0 + fast-json-stable-stringify: 2.1.0 + graceful-fs: 4.2.11 + jest-haste-map: 29.7.0 + jest-regex-util: 29.6.3 + jest-util: 29.7.0 + micromatch: 4.0.8 + pirates: 4.0.7 + slash: 3.0.0 + write-file-atomic: 4.0.2 + transitivePeerDependencies: + - supports-color + + '@jest/types@29.6.3': + dependencies: + '@jest/schemas': 29.6.3 + '@types/istanbul-lib-coverage': 2.0.6 + '@types/istanbul-reports': 3.0.4 + '@types/node': 22.15.21 + '@types/yargs': 17.0.33 + chalk: 4.1.2 + + '@jridgewell/gen-mapping@0.3.8': + dependencies: + '@jridgewell/set-array': 1.2.1 + '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/trace-mapping': 0.3.25 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/set-array@1.2.1': {} + + '@jridgewell/source-map@0.3.6': + dependencies: + '@jridgewell/gen-mapping': 0.3.8 + '@jridgewell/trace-mapping': 0.3.25 + + '@jridgewell/sourcemap-codec@1.5.0': {} + + '@jridgewell/trace-mapping@0.3.25': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.0 + + '@jridgewell/trace-mapping@0.3.9': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.0 + + '@lukeed/csprng@1.1.0': {} + + '@napi-rs/nice-android-arm-eabi@1.0.1': + optional: true + + '@napi-rs/nice-android-arm64@1.0.1': + optional: true + + '@napi-rs/nice-darwin-arm64@1.0.1': + optional: true + + '@napi-rs/nice-darwin-x64@1.0.1': + optional: true + + '@napi-rs/nice-freebsd-x64@1.0.1': + optional: true + + '@napi-rs/nice-linux-arm-gnueabihf@1.0.1': + optional: true + + '@napi-rs/nice-linux-arm64-gnu@1.0.1': + optional: true + + '@napi-rs/nice-linux-arm64-musl@1.0.1': + optional: true + + '@napi-rs/nice-linux-ppc64-gnu@1.0.1': + optional: true + + '@napi-rs/nice-linux-riscv64-gnu@1.0.1': + optional: true + + '@napi-rs/nice-linux-s390x-gnu@1.0.1': + optional: true + + '@napi-rs/nice-linux-x64-gnu@1.0.1': + optional: true + + '@napi-rs/nice-linux-x64-musl@1.0.1': + optional: true + + '@napi-rs/nice-win32-arm64-msvc@1.0.1': + optional: true + + '@napi-rs/nice-win32-ia32-msvc@1.0.1': + optional: true + + '@napi-rs/nice-win32-x64-msvc@1.0.1': + optional: true + + '@napi-rs/nice@1.0.1': + optionalDependencies: + '@napi-rs/nice-android-arm-eabi': 1.0.1 + '@napi-rs/nice-android-arm64': 1.0.1 + '@napi-rs/nice-darwin-arm64': 1.0.1 + '@napi-rs/nice-darwin-x64': 1.0.1 + '@napi-rs/nice-freebsd-x64': 1.0.1 + '@napi-rs/nice-linux-arm-gnueabihf': 1.0.1 + '@napi-rs/nice-linux-arm64-gnu': 1.0.1 + '@napi-rs/nice-linux-arm64-musl': 1.0.1 + '@napi-rs/nice-linux-ppc64-gnu': 1.0.1 + '@napi-rs/nice-linux-riscv64-gnu': 1.0.1 + '@napi-rs/nice-linux-s390x-gnu': 1.0.1 + '@napi-rs/nice-linux-x64-gnu': 1.0.1 + '@napi-rs/nice-linux-x64-musl': 1.0.1 + '@napi-rs/nice-win32-arm64-msvc': 1.0.1 + '@napi-rs/nice-win32-ia32-msvc': 1.0.1 + '@napi-rs/nice-win32-x64-msvc': 1.0.1 + optional: true + + '@nestjs/cli@11.0.7(@swc/cli@0.6.0(@swc/core@1.11.29)(chokidar@4.0.3))(@swc/core@1.11.29)(@types/node@22.15.21)': + dependencies: + '@angular-devkit/core': 19.2.8(chokidar@4.0.3) + '@angular-devkit/schematics': 19.2.8(chokidar@4.0.3) + '@angular-devkit/schematics-cli': 19.2.8(@types/node@22.15.21)(chokidar@4.0.3) + '@inquirer/prompts': 7.4.1(@types/node@22.15.21) + '@nestjs/schematics': 11.0.5(chokidar@4.0.3)(typescript@5.8.3) + ansis: 3.17.0 + chokidar: 4.0.3 + cli-table3: 0.6.5 + commander: 4.1.1 + fork-ts-checker-webpack-plugin: 9.1.0(typescript@5.8.3)(webpack@5.99.6(@swc/core@1.11.29)) + glob: 11.0.1 + node-emoji: 1.11.0 + ora: 5.4.1 + tree-kill: 1.2.2 + tsconfig-paths: 4.2.0 + tsconfig-paths-webpack-plugin: 4.2.0 + typescript: 5.8.3 + webpack: 5.99.6(@swc/core@1.11.29) + webpack-node-externals: 3.0.0 + optionalDependencies: + '@swc/cli': 0.6.0(@swc/core@1.11.29)(chokidar@4.0.3) + '@swc/core': 1.11.29 + transitivePeerDependencies: + - '@types/node' + - esbuild + - uglify-js + - webpack-cli + + '@nestjs/common@11.1.1(reflect-metadata@0.2.2)(rxjs@7.8.2)': + dependencies: + file-type: 20.5.0 + iterare: 1.2.1 + load-esm: 1.0.2 + reflect-metadata: 0.2.2 + rxjs: 7.8.2 + tslib: 2.8.1 + uid: 2.0.2 + transitivePeerDependencies: + - supports-color + + '@nestjs/config@4.0.2(@nestjs/common@11.1.1(reflect-metadata@0.2.2)(rxjs@7.8.2))(rxjs@7.8.2)': + dependencies: + '@nestjs/common': 11.1.1(reflect-metadata@0.2.2)(rxjs@7.8.2) + dotenv: 16.4.7 + dotenv-expand: 12.0.1 + lodash: 4.17.21 + rxjs: 7.8.2 + + '@nestjs/core@11.1.1(@nestjs/common@11.1.1(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)': + dependencies: + '@nestjs/common': 11.1.1(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nuxt/opencollective': 0.4.1 + fast-safe-stringify: 2.1.1 + iterare: 1.2.1 + path-to-regexp: 8.2.0 + reflect-metadata: 0.2.2 + rxjs: 7.8.2 + tslib: 2.8.1 + uid: 2.0.2 + optionalDependencies: + '@nestjs/platform-express': 11.1.1(@nestjs/common@11.1.1(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.1) + + '@nestjs/passport@11.0.5(@nestjs/common@11.1.1(reflect-metadata@0.2.2)(rxjs@7.8.2))(passport@0.7.0)': + dependencies: + '@nestjs/common': 11.1.1(reflect-metadata@0.2.2)(rxjs@7.8.2) + passport: 0.7.0 + + '@nestjs/platform-express@11.1.1(@nestjs/common@11.1.1(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.1)': + dependencies: + '@nestjs/common': 11.1.1(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.1(@nestjs/common@11.1.1(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) + cors: 2.8.5 + express: 5.1.0 + multer: 1.4.5-lts.2 + path-to-regexp: 8.2.0 + tslib: 2.8.1 + transitivePeerDependencies: + - supports-color + + '@nestjs/schematics@11.0.5(chokidar@4.0.3)(typescript@5.8.3)': + dependencies: + '@angular-devkit/core': 19.2.6(chokidar@4.0.3) + '@angular-devkit/schematics': 19.2.6(chokidar@4.0.3) + comment-json: 4.2.5 + jsonc-parser: 3.3.1 + pluralize: 8.0.0 + typescript: 5.8.3 + transitivePeerDependencies: + - chokidar + + '@nestjs/testing@11.1.1(@nestjs/common@11.1.1(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.1)(@nestjs/platform-express@11.1.1)': + dependencies: + '@nestjs/common': 11.1.1(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.1(@nestjs/common@11.1.1(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) + tslib: 2.8.1 + optionalDependencies: + '@nestjs/platform-express': 11.1.1(@nestjs/common@11.1.1(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.1) + + '@noble/hashes@1.8.0': {} + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.19.1 + + '@nuxt/opencollective@0.4.1': + dependencies: + consola: 3.4.2 + + '@paralleldrive/cuid2@2.2.2': + dependencies: + '@noble/hashes': 1.8.0 + + '@pkgr/core@0.2.4': {} + + '@prisma/client@6.8.2(prisma@6.8.2(typescript@5.8.3))(typescript@5.8.3)': + optionalDependencies: + prisma: 6.8.2(typescript@5.8.3) + typescript: 5.8.3 + + '@prisma/config@6.8.2': + dependencies: + jiti: 2.4.2 + + '@prisma/debug@6.8.2': {} + + '@prisma/engines-version@6.8.0-43.2060c79ba17c6bb9f5823312b6f6b7f4a845738e': {} + + '@prisma/engines@6.8.2': + dependencies: + '@prisma/debug': 6.8.2 + '@prisma/engines-version': 6.8.0-43.2060c79ba17c6bb9f5823312b6f6b7f4a845738e + '@prisma/fetch-engine': 6.8.2 + '@prisma/get-platform': 6.8.2 + + '@prisma/fetch-engine@6.8.2': + dependencies: + '@prisma/debug': 6.8.2 + '@prisma/engines-version': 6.8.0-43.2060c79ba17c6bb9f5823312b6f6b7f4a845738e + '@prisma/get-platform': 6.8.2 + + '@prisma/get-platform@6.8.2': + dependencies: + '@prisma/debug': 6.8.2 + + '@sec-ant/readable-stream@0.4.1': {} + + '@sinclair/typebox@0.27.8': {} + + '@sindresorhus/is@5.6.0': {} + + '@sinonjs/commons@3.0.1': + dependencies: + type-detect: 4.0.8 + + '@sinonjs/fake-timers@10.3.0': + dependencies: + '@sinonjs/commons': 3.0.1 + + '@swc/cli@0.6.0(@swc/core@1.11.29)(chokidar@4.0.3)': + dependencies: + '@swc/core': 1.11.29 + '@swc/counter': 0.1.3 + '@xhmikosr/bin-wrapper': 13.0.5 + commander: 8.3.0 + fast-glob: 3.3.3 + minimatch: 9.0.5 + piscina: 4.9.2 + semver: 7.7.2 + slash: 3.0.0 + source-map: 0.7.4 + optionalDependencies: + chokidar: 4.0.3 + + '@swc/core-darwin-arm64@1.11.29': + optional: true + + '@swc/core-darwin-x64@1.11.29': + optional: true + + '@swc/core-linux-arm-gnueabihf@1.11.29': + optional: true + + '@swc/core-linux-arm64-gnu@1.11.29': + optional: true + + '@swc/core-linux-arm64-musl@1.11.29': + optional: true + + '@swc/core-linux-x64-gnu@1.11.29': + optional: true + + '@swc/core-linux-x64-musl@1.11.29': + optional: true + + '@swc/core-win32-arm64-msvc@1.11.29': + optional: true + + '@swc/core-win32-ia32-msvc@1.11.29': + optional: true + + '@swc/core-win32-x64-msvc@1.11.29': + optional: true + + '@swc/core@1.11.29': + dependencies: + '@swc/counter': 0.1.3 + '@swc/types': 0.1.21 + optionalDependencies: + '@swc/core-darwin-arm64': 1.11.29 + '@swc/core-darwin-x64': 1.11.29 + '@swc/core-linux-arm-gnueabihf': 1.11.29 + '@swc/core-linux-arm64-gnu': 1.11.29 + '@swc/core-linux-arm64-musl': 1.11.29 + '@swc/core-linux-x64-gnu': 1.11.29 + '@swc/core-linux-x64-musl': 1.11.29 + '@swc/core-win32-arm64-msvc': 1.11.29 + '@swc/core-win32-ia32-msvc': 1.11.29 + '@swc/core-win32-x64-msvc': 1.11.29 + + '@swc/counter@0.1.3': {} + + '@swc/types@0.1.21': + dependencies: + '@swc/counter': 0.1.3 + + '@szmarczak/http-timer@5.0.1': + dependencies: + defer-to-connect: 2.0.1 + + '@tokenizer/inflate@0.2.7': + dependencies: + debug: 4.4.1 + fflate: 0.8.2 + token-types: 6.0.0 + transitivePeerDependencies: + - supports-color + + '@tokenizer/token@0.3.0': {} + + '@tsconfig/node10@1.0.11': {} + + '@tsconfig/node12@1.0.11': {} + + '@tsconfig/node14@1.0.3': {} + + '@tsconfig/node16@1.0.4': {} + + '@types/babel__core@7.20.5': + dependencies: + '@babel/parser': 7.27.2 + '@babel/types': 7.27.1 + '@types/babel__generator': 7.27.0 + '@types/babel__template': 7.4.4 + '@types/babel__traverse': 7.20.7 + + '@types/babel__generator@7.27.0': + dependencies: + '@babel/types': 7.27.1 + + '@types/babel__template@7.4.4': + dependencies: + '@babel/parser': 7.27.2 + '@babel/types': 7.27.1 + + '@types/babel__traverse@7.20.7': + dependencies: + '@babel/types': 7.27.1 + + '@types/body-parser@1.19.5': + dependencies: + '@types/connect': 3.4.38 + '@types/node': 22.15.21 + + '@types/connect@3.4.38': + dependencies: + '@types/node': 22.15.21 + + '@types/cookiejar@2.1.5': {} + + '@types/eslint-scope@3.7.7': + dependencies: + '@types/eslint': 9.6.1 + '@types/estree': 1.0.7 + + '@types/eslint@9.6.1': + dependencies: + '@types/estree': 1.0.7 + '@types/json-schema': 7.0.15 + + '@types/estree@1.0.7': {} + + '@types/express-serve-static-core@5.0.6': + dependencies: + '@types/node': 22.15.21 + '@types/qs': 6.14.0 + '@types/range-parser': 1.2.7 + '@types/send': 0.17.4 + + '@types/express-session@1.18.1': + dependencies: + '@types/express': 5.0.2 + + '@types/express@5.0.2': + dependencies: + '@types/body-parser': 1.19.5 + '@types/express-serve-static-core': 5.0.6 + '@types/serve-static': 1.15.7 + + '@types/graceful-fs@4.1.9': + dependencies: + '@types/node': 22.15.21 + + '@types/http-cache-semantics@4.0.4': {} + + '@types/http-errors@2.0.4': {} + + '@types/istanbul-lib-coverage@2.0.6': {} + + '@types/istanbul-lib-report@3.0.3': + dependencies: + '@types/istanbul-lib-coverage': 2.0.6 + + '@types/istanbul-reports@3.0.4': + dependencies: + '@types/istanbul-lib-report': 3.0.3 + + '@types/jest@29.5.14': + dependencies: + expect: 29.7.0 + pretty-format: 29.7.0 + + '@types/json-schema@7.0.15': {} + + '@types/methods@1.1.4': {} + + '@types/mime@1.3.5': {} + + '@types/node@22.15.21': + dependencies: + undici-types: 6.21.0 + + '@types/passport@1.0.17': + dependencies: + '@types/express': 5.0.2 + + '@types/qs@6.14.0': {} + + '@types/range-parser@1.2.7': {} + + '@types/send@0.17.4': + dependencies: + '@types/mime': 1.3.5 + '@types/node': 22.15.21 + + '@types/serve-static@1.15.7': + dependencies: + '@types/http-errors': 2.0.4 + '@types/node': 22.15.21 + '@types/send': 0.17.4 + + '@types/stack-utils@2.0.3': {} + + '@types/superagent@8.1.9': + dependencies: + '@types/cookiejar': 2.1.5 + '@types/methods': 1.1.4 + '@types/node': 22.15.21 + form-data: 4.0.2 + + '@types/supertest@6.0.3': + dependencies: + '@types/methods': 1.1.4 + '@types/superagent': 8.1.9 + + '@types/yargs-parser@21.0.3': {} + + '@types/yargs@17.0.33': + dependencies: + '@types/yargs-parser': 21.0.3 + + '@typescript-eslint/eslint-plugin@8.32.1(@typescript-eslint/parser@8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3)': + dependencies: + '@eslint-community/regexpp': 4.12.1 + '@typescript-eslint/parser': 8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/scope-manager': 8.32.1 + '@typescript-eslint/type-utils': 8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/utils': 8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/visitor-keys': 8.32.1 + eslint: 9.27.0(jiti@2.4.2) + graphemer: 1.4.0 + ignore: 7.0.4 + natural-compare: 1.4.0 + ts-api-utils: 2.1.0(typescript@5.8.3) + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3)': + dependencies: + '@typescript-eslint/scope-manager': 8.32.1 + '@typescript-eslint/types': 8.32.1 + '@typescript-eslint/typescript-estree': 8.32.1(typescript@5.8.3) + '@typescript-eslint/visitor-keys': 8.32.1 + debug: 4.4.1 + eslint: 9.27.0(jiti@2.4.2) + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/scope-manager@8.32.1': + dependencies: + '@typescript-eslint/types': 8.32.1 + '@typescript-eslint/visitor-keys': 8.32.1 + + '@typescript-eslint/type-utils@8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3)': + dependencies: + '@typescript-eslint/typescript-estree': 8.32.1(typescript@5.8.3) + '@typescript-eslint/utils': 8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3) + debug: 4.4.1 + eslint: 9.27.0(jiti@2.4.2) + ts-api-utils: 2.1.0(typescript@5.8.3) + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/types@8.32.1': {} + + '@typescript-eslint/typescript-estree@8.32.1(typescript@5.8.3)': + dependencies: + '@typescript-eslint/types': 8.32.1 + '@typescript-eslint/visitor-keys': 8.32.1 + debug: 4.4.1 + fast-glob: 3.3.3 + is-glob: 4.0.3 + minimatch: 9.0.5 + semver: 7.7.2 + ts-api-utils: 2.1.0(typescript@5.8.3) + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3)': + dependencies: + '@eslint-community/eslint-utils': 4.7.0(eslint@9.27.0(jiti@2.4.2)) + '@typescript-eslint/scope-manager': 8.32.1 + '@typescript-eslint/types': 8.32.1 + '@typescript-eslint/typescript-estree': 8.32.1(typescript@5.8.3) + eslint: 9.27.0(jiti@2.4.2) + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/visitor-keys@8.32.1': + dependencies: + '@typescript-eslint/types': 8.32.1 + eslint-visitor-keys: 4.2.0 + + '@webassemblyjs/ast@1.14.1': + dependencies: + '@webassemblyjs/helper-numbers': 1.13.2 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + + '@webassemblyjs/floating-point-hex-parser@1.13.2': {} + + '@webassemblyjs/helper-api-error@1.13.2': {} + + '@webassemblyjs/helper-buffer@1.14.1': {} + + '@webassemblyjs/helper-numbers@1.13.2': + dependencies: + '@webassemblyjs/floating-point-hex-parser': 1.13.2 + '@webassemblyjs/helper-api-error': 1.13.2 + '@xtuc/long': 4.2.2 + + '@webassemblyjs/helper-wasm-bytecode@1.13.2': {} + + '@webassemblyjs/helper-wasm-section@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-buffer': 1.14.1 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/wasm-gen': 1.14.1 + + '@webassemblyjs/ieee754@1.13.2': + dependencies: + '@xtuc/ieee754': 1.2.0 + + '@webassemblyjs/leb128@1.13.2': + dependencies: + '@xtuc/long': 4.2.2 + + '@webassemblyjs/utf8@1.13.2': {} + + '@webassemblyjs/wasm-edit@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-buffer': 1.14.1 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/helper-wasm-section': 1.14.1 + '@webassemblyjs/wasm-gen': 1.14.1 + '@webassemblyjs/wasm-opt': 1.14.1 + '@webassemblyjs/wasm-parser': 1.14.1 + '@webassemblyjs/wast-printer': 1.14.1 + + '@webassemblyjs/wasm-gen@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/ieee754': 1.13.2 + '@webassemblyjs/leb128': 1.13.2 + '@webassemblyjs/utf8': 1.13.2 + + '@webassemblyjs/wasm-opt@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-buffer': 1.14.1 + '@webassemblyjs/wasm-gen': 1.14.1 + '@webassemblyjs/wasm-parser': 1.14.1 + + '@webassemblyjs/wasm-parser@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-api-error': 1.13.2 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/ieee754': 1.13.2 + '@webassemblyjs/leb128': 1.13.2 + '@webassemblyjs/utf8': 1.13.2 + + '@webassemblyjs/wast-printer@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@xtuc/long': 4.2.2 + + '@xhmikosr/archive-type@7.0.0': + dependencies: + file-type: 19.6.0 + + '@xhmikosr/bin-check@7.0.3': + dependencies: + execa: 5.1.1 + isexe: 2.0.0 + + '@xhmikosr/bin-wrapper@13.0.5': + dependencies: + '@xhmikosr/bin-check': 7.0.3 + '@xhmikosr/downloader': 15.0.1 + '@xhmikosr/os-filter-obj': 3.0.0 + bin-version-check: 5.1.0 + + '@xhmikosr/decompress-tar@8.0.1': + dependencies: + file-type: 19.6.0 + is-stream: 2.0.1 + tar-stream: 3.1.7 + + '@xhmikosr/decompress-tarbz2@8.0.2': + dependencies: + '@xhmikosr/decompress-tar': 8.0.1 + file-type: 19.6.0 + is-stream: 2.0.1 + seek-bzip: 2.0.0 + unbzip2-stream: 1.4.3 + + '@xhmikosr/decompress-targz@8.0.1': + dependencies: + '@xhmikosr/decompress-tar': 8.0.1 + file-type: 19.6.0 + is-stream: 2.0.1 + + '@xhmikosr/decompress-unzip@7.0.0': + dependencies: + file-type: 19.6.0 + get-stream: 6.0.1 + yauzl: 3.2.0 + + '@xhmikosr/decompress@10.0.1': + dependencies: + '@xhmikosr/decompress-tar': 8.0.1 + '@xhmikosr/decompress-tarbz2': 8.0.2 + '@xhmikosr/decompress-targz': 8.0.1 + '@xhmikosr/decompress-unzip': 7.0.0 + graceful-fs: 4.2.11 + make-dir: 4.0.0 + strip-dirs: 3.0.0 + + '@xhmikosr/downloader@15.0.1': + dependencies: + '@xhmikosr/archive-type': 7.0.0 + '@xhmikosr/decompress': 10.0.1 + content-disposition: 0.5.4 + defaults: 3.0.0 + ext-name: 5.0.0 + file-type: 19.6.0 + filenamify: 6.0.0 + get-stream: 6.0.1 + got: 13.0.0 + + '@xhmikosr/os-filter-obj@3.0.0': + dependencies: + arch: 3.0.0 + + '@xtuc/ieee754@1.2.0': {} + + '@xtuc/long@4.2.2': {} + + accepts@2.0.0: + dependencies: + mime-types: 3.0.1 + negotiator: 1.0.0 + + acorn-jsx@5.3.2(acorn@8.14.1): + dependencies: + acorn: 8.14.1 + + acorn-walk@8.3.4: + dependencies: + acorn: 8.14.1 + + acorn@8.14.1: {} + + ajv-formats@2.1.1(ajv@8.17.1): + optionalDependencies: + ajv: 8.17.1 + + ajv-formats@3.0.1(ajv@8.17.1): + optionalDependencies: + ajv: 8.17.1 + + ajv-keywords@3.5.2(ajv@6.12.6): + dependencies: + ajv: 6.12.6 + + ajv-keywords@5.1.0(ajv@8.17.1): + dependencies: + ajv: 8.17.1 + fast-deep-equal: 3.1.3 + + ajv@6.12.6: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + + ajv@8.17.1: + dependencies: + fast-deep-equal: 3.1.3 + fast-uri: 3.0.6 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + + ansi-colors@4.1.3: {} + + ansi-escapes@4.3.2: + dependencies: + type-fest: 0.21.3 + + ansi-regex@5.0.1: {} + + ansi-regex@6.1.0: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@5.2.0: {} + + ansi-styles@6.2.1: {} + + ansis@3.17.0: {} + + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + + append-field@1.0.0: {} + + arch@3.0.0: {} + + arg@4.1.3: {} + + argparse@1.0.10: + dependencies: + sprintf-js: 1.0.3 + + argparse@2.0.1: {} + + array-timsort@1.0.3: {} + + asap@2.0.6: {} + + async@3.2.6: {} + + asynckit@0.4.0: {} + + b4a@1.6.7: {} + + babel-jest@29.7.0(@babel/core@7.27.1): + dependencies: + '@babel/core': 7.27.1 + '@jest/transform': 29.7.0 + '@types/babel__core': 7.20.5 + babel-plugin-istanbul: 6.1.1 + babel-preset-jest: 29.6.3(@babel/core@7.27.1) + chalk: 4.1.2 + graceful-fs: 4.2.11 + slash: 3.0.0 + transitivePeerDependencies: + - supports-color + + babel-plugin-istanbul@6.1.1: + dependencies: + '@babel/helper-plugin-utils': 7.27.1 + '@istanbuljs/load-nyc-config': 1.1.0 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-instrument: 5.2.1 + test-exclude: 6.0.0 + transitivePeerDependencies: + - supports-color + + babel-plugin-jest-hoist@29.6.3: + dependencies: + '@babel/template': 7.27.2 + '@babel/types': 7.27.1 + '@types/babel__core': 7.20.5 + '@types/babel__traverse': 7.20.7 + + babel-preset-current-node-syntax@1.1.0(@babel/core@7.27.1): + dependencies: + '@babel/core': 7.27.1 + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.27.1) + '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.27.1) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.27.1) + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.27.1) + '@babel/plugin-syntax-import-attributes': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.27.1) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.27.1) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.27.1) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.27.1) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.27.1) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.27.1) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.27.1) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.27.1) + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.27.1) + '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.27.1) + + babel-preset-jest@29.6.3(@babel/core@7.27.1): + dependencies: + '@babel/core': 7.27.1 + babel-plugin-jest-hoist: 29.6.3 + babel-preset-current-node-syntax: 1.1.0(@babel/core@7.27.1) + + balanced-match@1.0.2: {} + + bare-events@2.5.4: + optional: true + + base64-js@1.5.1: {} + + bin-version-check@5.1.0: + dependencies: + bin-version: 6.0.0 + semver: 7.7.2 + semver-truncate: 3.0.0 + + bin-version@6.0.0: + dependencies: + execa: 5.1.1 + find-versions: 5.1.0 + + bl@4.1.0: + dependencies: + buffer: 5.7.1 + inherits: 2.0.4 + readable-stream: 3.6.2 + + body-parser@2.2.0: + dependencies: + bytes: 3.1.2 + content-type: 1.0.5 + debug: 4.4.1 + http-errors: 2.0.0 + iconv-lite: 0.6.3 + on-finished: 2.4.1 + qs: 6.14.0 + raw-body: 3.0.0 + type-is: 2.0.1 + transitivePeerDependencies: + - supports-color + + brace-expansion@1.1.11: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@2.0.1: + dependencies: + balanced-match: 1.0.2 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + browserslist@4.24.5: + dependencies: + caniuse-lite: 1.0.30001718 + electron-to-chromium: 1.5.155 + node-releases: 2.0.19 + update-browserslist-db: 1.1.3(browserslist@4.24.5) + + bs-logger@0.2.6: + dependencies: + fast-json-stable-stringify: 2.1.0 + + bser@2.1.1: + dependencies: + node-int64: 0.4.0 + + buffer-crc32@0.2.13: {} + + buffer-from@1.1.2: {} + + buffer@5.7.1: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + + busboy@1.6.0: + dependencies: + streamsearch: 1.1.0 + + bytes@3.1.2: {} + + cacheable-lookup@7.0.0: {} + + cacheable-request@10.2.14: + dependencies: + '@types/http-cache-semantics': 4.0.4 + get-stream: 6.0.1 + http-cache-semantics: 4.2.0 + keyv: 4.5.4 + mimic-response: 4.0.0 + normalize-url: 8.0.1 + responselike: 3.0.0 + + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + call-bound@1.0.4: + dependencies: + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 + + callsites@3.1.0: {} + + camelcase@5.3.1: {} + + camelcase@6.3.0: {} + + caniuse-lite@1.0.30001718: {} + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + char-regex@1.0.2: {} + + chardet@0.7.0: {} + + chokidar@4.0.3: + dependencies: + readdirp: 4.1.2 + + chrome-trace-event@1.0.4: {} + + ci-info@3.9.0: {} + + cjs-module-lexer@1.4.3: {} + + cli-cursor@3.1.0: + dependencies: + restore-cursor: 3.1.0 + + cli-spinners@2.9.2: {} + + cli-table3@0.6.5: + dependencies: + string-width: 4.2.3 + optionalDependencies: + '@colors/colors': 1.5.0 + + cli-width@4.1.0: {} + + cliui@8.0.1: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + + clone@1.0.4: {} + + co@4.6.0: {} + + collect-v8-coverage@1.0.2: {} + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + + commander@2.20.3: {} + + commander@4.1.1: {} + + commander@6.2.1: {} + + commander@8.3.0: {} + + comment-json@4.2.5: + dependencies: + array-timsort: 1.0.3 + core-util-is: 1.0.3 + esprima: 4.0.1 + has-own-prop: 2.0.0 + repeat-string: 1.6.1 + + component-emitter@1.3.1: {} + + concat-map@0.0.1: {} + + concat-stream@1.6.2: + dependencies: + buffer-from: 1.1.2 + inherits: 2.0.4 + readable-stream: 2.3.8 + typedarray: 0.0.6 + + consola@3.4.2: {} + + content-disposition@0.5.4: + dependencies: + safe-buffer: 5.2.1 + + content-disposition@1.0.0: + dependencies: + safe-buffer: 5.2.1 + + content-type@1.0.5: {} + + convert-source-map@2.0.0: {} + + cookie-signature@1.0.7: {} + + cookie-signature@1.2.2: {} + + cookie@0.7.1: {} + + cookie@0.7.2: {} + + cookiejar@2.1.4: {} + + core-util-is@1.0.3: {} + + cors@2.8.5: + dependencies: + object-assign: 4.1.1 + vary: 1.1.2 + + cosmiconfig@8.3.6(typescript@5.8.3): + dependencies: + import-fresh: 3.3.1 + js-yaml: 4.1.0 + parse-json: 5.2.0 + path-type: 4.0.0 + optionalDependencies: + typescript: 5.8.3 + + create-jest@29.7.0(@types/node@22.15.21)(ts-node@10.9.2(@swc/core@1.11.29)(@types/node@22.15.21)(typescript@5.8.3)): + dependencies: + '@jest/types': 29.6.3 + chalk: 4.1.2 + exit: 0.1.2 + graceful-fs: 4.2.11 + jest-config: 29.7.0(@types/node@22.15.21)(ts-node@10.9.2(@swc/core@1.11.29)(@types/node@22.15.21)(typescript@5.8.3)) + jest-util: 29.7.0 + prompts: 2.4.2 + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + + create-require@1.1.1: {} + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + debug@2.6.9: + dependencies: + ms: 2.0.0 + + debug@4.4.1: + dependencies: + ms: 2.1.3 + + decompress-response@6.0.0: + dependencies: + mimic-response: 3.1.0 + + dedent@1.6.0: {} + + deep-is@0.1.4: {} + + deepmerge@4.3.1: {} + + defaults@1.0.4: + dependencies: + clone: 1.0.4 + + defaults@3.0.0: {} + + defer-to-connect@2.0.1: {} + + delayed-stream@1.0.0: {} + + depd@2.0.0: {} + + detect-newline@3.1.0: {} + + dezalgo@1.0.4: + dependencies: + asap: 2.0.6 + wrappy: 1.0.2 + + diff-sequences@29.6.3: {} + + diff@4.0.2: {} + + dotenv-expand@12.0.1: + dependencies: + dotenv: 16.4.7 + + dotenv@16.4.7: {} + + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + + eastasianwidth@0.2.0: {} + + ee-first@1.1.1: {} + + ejs@3.1.10: + dependencies: + jake: 10.9.2 + + electron-to-chromium@1.5.155: {} + + emittery@0.13.1: {} + + emoji-regex@8.0.0: {} + + emoji-regex@9.2.2: {} + + encodeurl@2.0.0: {} + + enhanced-resolve@5.18.1: + dependencies: + graceful-fs: 4.2.11 + tapable: 2.2.1 + + error-ex@1.3.2: + dependencies: + is-arrayish: 0.2.1 + + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-module-lexer@1.7.0: {} + + es-object-atoms@1.1.1: + dependencies: + es-errors: 1.3.0 + + es-set-tostringtag@2.1.0: + dependencies: + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + + escalade@3.2.0: {} + + escape-html@1.0.3: {} + + escape-string-regexp@2.0.0: {} + + escape-string-regexp@4.0.0: {} + + eslint-config-prettier@10.1.5(eslint@9.27.0(jiti@2.4.2)): + dependencies: + eslint: 9.27.0(jiti@2.4.2) + + eslint-plugin-prettier@5.4.0(@types/eslint@9.6.1)(eslint-config-prettier@10.1.5(eslint@9.27.0(jiti@2.4.2)))(eslint@9.27.0(jiti@2.4.2))(prettier@3.5.3): + dependencies: + eslint: 9.27.0(jiti@2.4.2) + prettier: 3.5.3 + prettier-linter-helpers: 1.0.0 + synckit: 0.11.5 + optionalDependencies: + '@types/eslint': 9.6.1 + eslint-config-prettier: 10.1.5(eslint@9.27.0(jiti@2.4.2)) + + eslint-scope@5.1.1: + dependencies: + esrecurse: 4.3.0 + estraverse: 4.3.0 + + eslint-scope@8.3.0: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + + eslint-visitor-keys@3.4.3: {} + + eslint-visitor-keys@4.2.0: {} + + eslint@9.27.0(jiti@2.4.2): + dependencies: + '@eslint-community/eslint-utils': 4.7.0(eslint@9.27.0(jiti@2.4.2)) + '@eslint-community/regexpp': 4.12.1 + '@eslint/config-array': 0.20.0 + '@eslint/config-helpers': 0.2.2 + '@eslint/core': 0.14.0 + '@eslint/eslintrc': 3.3.1 + '@eslint/js': 9.27.0 + '@eslint/plugin-kit': 0.3.1 + '@humanfs/node': 0.16.6 + '@humanwhocodes/module-importer': 1.0.1 + '@humanwhocodes/retry': 0.4.3 + '@types/estree': 1.0.7 + '@types/json-schema': 7.0.15 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.6 + debug: 4.4.1 + escape-string-regexp: 4.0.0 + eslint-scope: 8.3.0 + eslint-visitor-keys: 4.2.0 + espree: 10.3.0 + esquery: 1.6.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 8.0.0 + find-up: 5.0.0 + glob-parent: 6.0.2 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + json-stable-stringify-without-jsonify: 1.0.1 + lodash.merge: 4.6.2 + minimatch: 3.1.2 + natural-compare: 1.4.0 + optionator: 0.9.4 + optionalDependencies: + jiti: 2.4.2 + transitivePeerDependencies: + - supports-color + + espree@10.3.0: + dependencies: + acorn: 8.14.1 + acorn-jsx: 5.3.2(acorn@8.14.1) + eslint-visitor-keys: 4.2.0 + + esprima@4.0.1: {} + + esquery@1.6.0: + dependencies: + estraverse: 5.3.0 + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@4.3.0: {} + + estraverse@5.3.0: {} + + esutils@2.0.3: {} + + etag@1.8.1: {} + + events@3.3.0: {} + + execa@5.1.1: + dependencies: + cross-spawn: 7.0.6 + get-stream: 6.0.1 + human-signals: 2.1.0 + is-stream: 2.0.1 + merge-stream: 2.0.0 + npm-run-path: 4.0.1 + onetime: 5.1.2 + signal-exit: 3.0.7 + strip-final-newline: 2.0.0 + + exit@0.1.2: {} + + expect@29.7.0: + dependencies: + '@jest/expect-utils': 29.7.0 + jest-get-type: 29.6.3 + jest-matcher-utils: 29.7.0 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + + express-session@1.18.1: + dependencies: + cookie: 0.7.2 + cookie-signature: 1.0.7 + debug: 2.6.9 + depd: 2.0.0 + on-headers: 1.0.2 + parseurl: 1.3.3 + safe-buffer: 5.2.1 + uid-safe: 2.1.5 + transitivePeerDependencies: + - supports-color + + express@5.1.0: + dependencies: + accepts: 2.0.0 + body-parser: 2.2.0 + content-disposition: 1.0.0 + content-type: 1.0.5 + cookie: 0.7.1 + cookie-signature: 1.2.2 + debug: 4.4.1 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + finalhandler: 2.1.0 + fresh: 2.0.0 + http-errors: 2.0.0 + merge-descriptors: 2.0.0 + mime-types: 3.0.1 + on-finished: 2.4.1 + once: 1.4.0 + parseurl: 1.3.3 + proxy-addr: 2.0.7 + qs: 6.14.0 + range-parser: 1.2.1 + router: 2.2.0 + send: 1.2.0 + serve-static: 2.2.0 + statuses: 2.0.1 + type-is: 2.0.1 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + + ext-list@2.2.2: + dependencies: + mime-db: 1.54.0 + + ext-name@5.0.0: + dependencies: + ext-list: 2.2.2 + sort-keys-length: 1.0.1 + + external-editor@3.1.0: + dependencies: + chardet: 0.7.0 + iconv-lite: 0.4.24 + tmp: 0.0.33 + + fast-deep-equal@3.1.3: {} + + fast-diff@1.3.0: {} + + fast-fifo@1.3.2: {} + + fast-glob@3.3.3: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fast-json-stable-stringify@2.1.0: {} + + fast-levenshtein@2.0.6: {} + + fast-safe-stringify@2.1.1: {} + + fast-uri@3.0.6: {} + + fastq@1.19.1: + dependencies: + reusify: 1.1.0 + + fb-watchman@2.0.2: + dependencies: + bser: 2.1.1 + + fflate@0.8.2: {} + + file-entry-cache@8.0.0: + dependencies: + flat-cache: 4.0.1 + + file-type@19.6.0: + dependencies: + get-stream: 9.0.1 + strtok3: 9.1.1 + token-types: 6.0.0 + uint8array-extras: 1.4.0 + + file-type@20.5.0: + dependencies: + '@tokenizer/inflate': 0.2.7 + strtok3: 10.2.2 + token-types: 6.0.0 + uint8array-extras: 1.4.0 + transitivePeerDependencies: + - supports-color + + filelist@1.0.4: + dependencies: + minimatch: 5.1.6 + + filename-reserved-regex@3.0.0: {} + + filenamify@6.0.0: + dependencies: + filename-reserved-regex: 3.0.0 + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + finalhandler@2.1.0: + dependencies: + debug: 4.4.1 + encodeurl: 2.0.0 + escape-html: 1.0.3 + on-finished: 2.4.1 + parseurl: 1.3.3 + statuses: 2.0.1 + transitivePeerDependencies: + - supports-color + + find-up@4.1.0: + dependencies: + locate-path: 5.0.0 + path-exists: 4.0.0 + + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + + find-versions@5.1.0: + dependencies: + semver-regex: 4.0.5 + + flat-cache@4.0.1: + dependencies: + flatted: 3.3.3 + keyv: 4.5.4 + + flatted@3.3.3: {} + + foreground-child@3.3.1: + dependencies: + cross-spawn: 7.0.6 + signal-exit: 4.1.0 + + fork-ts-checker-webpack-plugin@9.1.0(typescript@5.8.3)(webpack@5.99.6(@swc/core@1.11.29)): + dependencies: + '@babel/code-frame': 7.27.1 + chalk: 4.1.2 + chokidar: 4.0.3 + cosmiconfig: 8.3.6(typescript@5.8.3) + deepmerge: 4.3.1 + fs-extra: 10.1.0 + memfs: 3.5.3 + minimatch: 3.1.2 + node-abort-controller: 3.1.1 + schema-utils: 3.3.0 + semver: 7.7.2 + tapable: 2.2.1 + typescript: 5.8.3 + webpack: 5.99.6(@swc/core@1.11.29) + + form-data-encoder@2.1.4: {} + + form-data@4.0.2: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + es-set-tostringtag: 2.1.0 + mime-types: 2.1.35 + + formidable@3.5.4: + dependencies: + '@paralleldrive/cuid2': 2.2.2 + dezalgo: 1.0.4 + once: 1.4.0 + + forwarded@0.2.0: {} + + fresh@2.0.0: {} + + fs-extra@10.1.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.1.0 + universalify: 2.0.1 + + fs-monkey@1.0.6: {} + + fs.realpath@1.0.0: {} + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + gensync@1.0.0-beta.2: {} + + get-caller-file@2.0.5: {} + + get-intrinsic@1.3.0: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.2 + math-intrinsics: 1.1.0 + + get-package-type@0.1.0: {} + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.1 + + get-stream@6.0.1: {} + + get-stream@9.0.1: + dependencies: + '@sec-ant/readable-stream': 0.4.1 + is-stream: 4.0.1 + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob-parent@6.0.2: + dependencies: + is-glob: 4.0.3 + + glob-to-regexp@0.4.1: {} + + glob@11.0.1: + dependencies: + foreground-child: 3.3.1 + jackspeak: 4.1.0 + minimatch: 10.0.1 + minipass: 7.1.2 + package-json-from-dist: 1.0.1 + path-scurry: 2.0.0 + + glob@7.2.3: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + + globals@11.12.0: {} + + globals@14.0.0: {} + + globals@16.1.0: {} + + gopd@1.2.0: {} + + got@13.0.0: + dependencies: + '@sindresorhus/is': 5.6.0 + '@szmarczak/http-timer': 5.0.1 + cacheable-lookup: 7.0.0 + cacheable-request: 10.2.14 + decompress-response: 6.0.0 + form-data-encoder: 2.1.4 + get-stream: 6.0.1 + http2-wrapper: 2.2.1 + lowercase-keys: 3.0.0 + p-cancelable: 3.0.0 + responselike: 3.0.0 + + graceful-fs@4.2.11: {} + + graphemer@1.4.0: {} + + has-flag@4.0.0: {} + + has-own-prop@2.0.0: {} + + has-symbols@1.1.0: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.1.0 + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + html-escaper@2.0.2: {} + + http-cache-semantics@4.2.0: {} + + http-errors@2.0.0: + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.1 + toidentifier: 1.0.1 + + http2-wrapper@2.2.1: + dependencies: + quick-lru: 5.1.1 + resolve-alpn: 1.2.1 + + human-signals@2.1.0: {} + + iconv-lite@0.4.24: + dependencies: + safer-buffer: 2.1.2 + + iconv-lite@0.6.3: + dependencies: + safer-buffer: 2.1.2 + + ieee754@1.2.1: {} + + ignore@5.3.2: {} + + ignore@7.0.4: {} + + import-fresh@3.3.1: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + + import-local@3.2.0: + dependencies: + pkg-dir: 4.2.0 + resolve-cwd: 3.0.0 + + imurmurhash@0.1.4: {} + + inflight@1.0.6: + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + + inherits@2.0.4: {} + + inspect-with-kind@1.0.5: + dependencies: + kind-of: 6.0.3 + + ipaddr.js@1.9.1: {} + + is-arrayish@0.2.1: {} + + is-core-module@2.16.1: + dependencies: + hasown: 2.0.2 + + is-extglob@2.1.1: {} + + is-fullwidth-code-point@3.0.0: {} + + is-generator-fn@2.1.0: {} + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-interactive@1.0.0: {} + + is-number@7.0.0: {} + + is-plain-obj@1.1.0: {} + + is-promise@4.0.0: {} + + is-stream@2.0.1: {} + + is-stream@4.0.1: {} + + is-unicode-supported@0.1.0: {} + + isarray@1.0.0: {} + + isexe@2.0.0: {} + + istanbul-lib-coverage@3.2.2: {} + + istanbul-lib-instrument@5.2.1: + dependencies: + '@babel/core': 7.27.1 + '@babel/parser': 7.27.2 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-coverage: 3.2.2 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + istanbul-lib-instrument@6.0.3: + dependencies: + '@babel/core': 7.27.1 + '@babel/parser': 7.27.2 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-coverage: 3.2.2 + semver: 7.7.2 + transitivePeerDependencies: + - supports-color + + istanbul-lib-report@3.0.1: + dependencies: + istanbul-lib-coverage: 3.2.2 + make-dir: 4.0.0 + supports-color: 7.2.0 + + istanbul-lib-source-maps@4.0.1: + dependencies: + debug: 4.4.1 + istanbul-lib-coverage: 3.2.2 + source-map: 0.6.1 + transitivePeerDependencies: + - supports-color + + istanbul-reports@3.1.7: + dependencies: + html-escaper: 2.0.2 + istanbul-lib-report: 3.0.1 + + iterare@1.2.1: {} + + jackspeak@4.1.0: + dependencies: + '@isaacs/cliui': 8.0.2 + + jake@10.9.2: + dependencies: + async: 3.2.6 + chalk: 4.1.2 + filelist: 1.0.4 + minimatch: 3.1.2 + + jest-changed-files@29.7.0: + dependencies: + execa: 5.1.1 + jest-util: 29.7.0 + p-limit: 3.1.0 + + jest-circus@29.7.0: + dependencies: + '@jest/environment': 29.7.0 + '@jest/expect': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 22.15.21 + chalk: 4.1.2 + co: 4.6.0 + dedent: 1.6.0 + is-generator-fn: 2.1.0 + jest-each: 29.7.0 + jest-matcher-utils: 29.7.0 + jest-message-util: 29.7.0 + jest-runtime: 29.7.0 + jest-snapshot: 29.7.0 + jest-util: 29.7.0 + p-limit: 3.1.0 + pretty-format: 29.7.0 + pure-rand: 6.1.0 + slash: 3.0.0 + stack-utils: 2.0.6 + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + + jest-cli@29.7.0(@types/node@22.15.21)(ts-node@10.9.2(@swc/core@1.11.29)(@types/node@22.15.21)(typescript@5.8.3)): + dependencies: + '@jest/core': 29.7.0(ts-node@10.9.2(@swc/core@1.11.29)(@types/node@22.15.21)(typescript@5.8.3)) + '@jest/test-result': 29.7.0 + '@jest/types': 29.6.3 + chalk: 4.1.2 + create-jest: 29.7.0(@types/node@22.15.21)(ts-node@10.9.2(@swc/core@1.11.29)(@types/node@22.15.21)(typescript@5.8.3)) + exit: 0.1.2 + import-local: 3.2.0 + jest-config: 29.7.0(@types/node@22.15.21)(ts-node@10.9.2(@swc/core@1.11.29)(@types/node@22.15.21)(typescript@5.8.3)) + jest-util: 29.7.0 + jest-validate: 29.7.0 + yargs: 17.7.2 + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + + jest-config@29.7.0(@types/node@22.15.21)(ts-node@10.9.2(@swc/core@1.11.29)(@types/node@22.15.21)(typescript@5.8.3)): + dependencies: + '@babel/core': 7.27.1 + '@jest/test-sequencer': 29.7.0 + '@jest/types': 29.6.3 + babel-jest: 29.7.0(@babel/core@7.27.1) + chalk: 4.1.2 + ci-info: 3.9.0 + deepmerge: 4.3.1 + glob: 7.2.3 + graceful-fs: 4.2.11 + jest-circus: 29.7.0 + jest-environment-node: 29.7.0 + jest-get-type: 29.6.3 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-runner: 29.7.0 + jest-util: 29.7.0 + jest-validate: 29.7.0 + micromatch: 4.0.8 + parse-json: 5.2.0 + pretty-format: 29.7.0 + slash: 3.0.0 + strip-json-comments: 3.1.1 + optionalDependencies: + '@types/node': 22.15.21 + ts-node: 10.9.2(@swc/core@1.11.29)(@types/node@22.15.21)(typescript@5.8.3) + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + + jest-diff@29.7.0: + dependencies: + chalk: 4.1.2 + diff-sequences: 29.6.3 + jest-get-type: 29.6.3 + pretty-format: 29.7.0 + + jest-docblock@29.7.0: + dependencies: + detect-newline: 3.1.0 + + jest-each@29.7.0: + dependencies: + '@jest/types': 29.6.3 + chalk: 4.1.2 + jest-get-type: 29.6.3 + jest-util: 29.7.0 + pretty-format: 29.7.0 + + jest-environment-node@29.7.0: + dependencies: + '@jest/environment': 29.7.0 + '@jest/fake-timers': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 22.15.21 + jest-mock: 29.7.0 + jest-util: 29.7.0 + + jest-get-type@29.6.3: {} + + jest-haste-map@29.7.0: + dependencies: + '@jest/types': 29.6.3 + '@types/graceful-fs': 4.1.9 + '@types/node': 22.15.21 + anymatch: 3.1.3 + fb-watchman: 2.0.2 + graceful-fs: 4.2.11 + jest-regex-util: 29.6.3 + jest-util: 29.7.0 + jest-worker: 29.7.0 + micromatch: 4.0.8 + walker: 1.0.8 + optionalDependencies: + fsevents: 2.3.3 + + jest-leak-detector@29.7.0: + dependencies: + jest-get-type: 29.6.3 + pretty-format: 29.7.0 + + jest-matcher-utils@29.7.0: + dependencies: + chalk: 4.1.2 + jest-diff: 29.7.0 + jest-get-type: 29.6.3 + pretty-format: 29.7.0 + + jest-message-util@29.7.0: + dependencies: + '@babel/code-frame': 7.27.1 + '@jest/types': 29.6.3 + '@types/stack-utils': 2.0.3 + chalk: 4.1.2 + graceful-fs: 4.2.11 + micromatch: 4.0.8 + pretty-format: 29.7.0 + slash: 3.0.0 + stack-utils: 2.0.6 + + jest-mock@29.7.0: + dependencies: + '@jest/types': 29.6.3 + '@types/node': 22.15.21 + jest-util: 29.7.0 + + jest-pnp-resolver@1.2.3(jest-resolve@29.7.0): + optionalDependencies: + jest-resolve: 29.7.0 + + jest-regex-util@29.6.3: {} + + jest-resolve-dependencies@29.7.0: + dependencies: + jest-regex-util: 29.6.3 + jest-snapshot: 29.7.0 + transitivePeerDependencies: + - supports-color + + jest-resolve@29.7.0: + dependencies: + chalk: 4.1.2 + graceful-fs: 4.2.11 + jest-haste-map: 29.7.0 + jest-pnp-resolver: 1.2.3(jest-resolve@29.7.0) + jest-util: 29.7.0 + jest-validate: 29.7.0 + resolve: 1.22.10 + resolve.exports: 2.0.3 + slash: 3.0.0 + + jest-runner@29.7.0: + dependencies: + '@jest/console': 29.7.0 + '@jest/environment': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 22.15.21 + chalk: 4.1.2 + emittery: 0.13.1 + graceful-fs: 4.2.11 + jest-docblock: 29.7.0 + jest-environment-node: 29.7.0 + jest-haste-map: 29.7.0 + jest-leak-detector: 29.7.0 + jest-message-util: 29.7.0 + jest-resolve: 29.7.0 + jest-runtime: 29.7.0 + jest-util: 29.7.0 + jest-watcher: 29.7.0 + jest-worker: 29.7.0 + p-limit: 3.1.0 + source-map-support: 0.5.13 + transitivePeerDependencies: + - supports-color + + jest-runtime@29.7.0: + dependencies: + '@jest/environment': 29.7.0 + '@jest/fake-timers': 29.7.0 + '@jest/globals': 29.7.0 + '@jest/source-map': 29.6.3 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 22.15.21 + chalk: 4.1.2 + cjs-module-lexer: 1.4.3 + collect-v8-coverage: 1.0.2 + glob: 7.2.3 + graceful-fs: 4.2.11 + jest-haste-map: 29.7.0 + jest-message-util: 29.7.0 + jest-mock: 29.7.0 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-snapshot: 29.7.0 + jest-util: 29.7.0 + slash: 3.0.0 + strip-bom: 4.0.0 + transitivePeerDependencies: + - supports-color + + jest-snapshot@29.7.0: + dependencies: + '@babel/core': 7.27.1 + '@babel/generator': 7.27.1 + '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.27.1) + '@babel/types': 7.27.1 + '@jest/expect-utils': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + babel-preset-current-node-syntax: 1.1.0(@babel/core@7.27.1) + chalk: 4.1.2 + expect: 29.7.0 + graceful-fs: 4.2.11 + jest-diff: 29.7.0 + jest-get-type: 29.6.3 + jest-matcher-utils: 29.7.0 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + natural-compare: 1.4.0 + pretty-format: 29.7.0 + semver: 7.7.2 + transitivePeerDependencies: + - supports-color + + jest-util@29.7.0: + dependencies: + '@jest/types': 29.6.3 + '@types/node': 22.15.21 + chalk: 4.1.2 + ci-info: 3.9.0 + graceful-fs: 4.2.11 + picomatch: 2.3.1 + + jest-validate@29.7.0: + dependencies: + '@jest/types': 29.6.3 + camelcase: 6.3.0 + chalk: 4.1.2 + jest-get-type: 29.6.3 + leven: 3.1.0 + pretty-format: 29.7.0 + + jest-watcher@29.7.0: + dependencies: + '@jest/test-result': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 22.15.21 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + emittery: 0.13.1 + jest-util: 29.7.0 + string-length: 4.0.2 + + jest-worker@27.5.1: + dependencies: + '@types/node': 22.15.21 + merge-stream: 2.0.0 + supports-color: 8.1.1 + + jest-worker@29.7.0: + dependencies: + '@types/node': 22.15.21 + jest-util: 29.7.0 + merge-stream: 2.0.0 + supports-color: 8.1.1 + + jest@29.7.0(@types/node@22.15.21)(ts-node@10.9.2(@swc/core@1.11.29)(@types/node@22.15.21)(typescript@5.8.3)): + dependencies: + '@jest/core': 29.7.0(ts-node@10.9.2(@swc/core@1.11.29)(@types/node@22.15.21)(typescript@5.8.3)) + '@jest/types': 29.6.3 + import-local: 3.2.0 + jest-cli: 29.7.0(@types/node@22.15.21)(ts-node@10.9.2(@swc/core@1.11.29)(@types/node@22.15.21)(typescript@5.8.3)) + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + + jiti@2.4.2: {} + + js-tokens@4.0.0: {} + + js-yaml@3.14.1: + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 + + js-yaml@4.1.0: + dependencies: + argparse: 2.0.1 + + jsesc@3.1.0: {} + + json-buffer@3.0.1: {} + + json-parse-even-better-errors@2.3.1: {} + + json-schema-traverse@0.4.1: {} + + json-schema-traverse@1.0.0: {} + + json-stable-stringify-without-jsonify@1.0.1: {} + + json5@2.2.3: {} + + jsonc-parser@3.3.1: {} + + jsonfile@6.1.0: + dependencies: + universalify: 2.0.1 + optionalDependencies: + graceful-fs: 4.2.11 + + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + + kind-of@6.0.3: {} + + kleur@3.0.3: {} + + leven@3.1.0: {} + + levn@0.4.1: + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + + lines-and-columns@1.2.4: {} + + load-esm@1.0.2: {} + + loader-runner@4.3.0: {} + + locate-path@5.0.0: + dependencies: + p-locate: 4.1.0 + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + lodash.memoize@4.1.2: {} + + lodash.merge@4.6.2: {} + + lodash@4.17.21: {} + + log-symbols@4.1.0: + dependencies: + chalk: 4.1.2 + is-unicode-supported: 0.1.0 + + lowercase-keys@3.0.0: {} + + lru-cache@11.1.0: {} + + lru-cache@5.1.1: + dependencies: + yallist: 3.1.1 + + magic-string@0.30.17: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.0 + + make-dir@4.0.0: + dependencies: + semver: 7.7.2 + + make-error@1.3.6: {} + + makeerror@1.0.12: + dependencies: + tmpl: 1.0.5 + + math-intrinsics@1.1.0: {} + + media-typer@0.3.0: {} + + media-typer@1.1.0: {} + + memfs@3.5.3: + dependencies: + fs-monkey: 1.0.6 + + merge-descriptors@2.0.0: {} + + merge-stream@2.0.0: {} + + merge2@1.4.1: {} + + methods@1.1.2: {} + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + + mime-db@1.52.0: {} + + mime-db@1.54.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + + mime-types@3.0.1: + dependencies: + mime-db: 1.54.0 + + mime@2.6.0: {} + + mimic-fn@2.1.0: {} + + mimic-response@3.1.0: {} + + mimic-response@4.0.0: {} + + minimatch@10.0.1: + dependencies: + brace-expansion: 2.0.1 + + minimatch@3.1.2: + dependencies: + brace-expansion: 1.1.11 + + minimatch@5.1.6: + dependencies: + brace-expansion: 2.0.1 + + minimatch@9.0.5: + dependencies: + brace-expansion: 2.0.1 + + minimist@1.2.8: {} + + minipass@7.1.2: {} + + mkdirp@0.5.6: + dependencies: + minimist: 1.2.8 + + ms@2.0.0: {} + + ms@2.1.3: {} + + multer@1.4.5-lts.2: + dependencies: + append-field: 1.0.0 + busboy: 1.6.0 + concat-stream: 1.6.2 + mkdirp: 0.5.6 + object-assign: 4.1.1 + type-is: 1.6.18 + xtend: 4.0.2 + + mute-stream@2.0.0: {} + + natural-compare@1.4.0: {} + + negotiator@1.0.0: {} + + neo-async@2.6.2: {} + + node-abort-controller@3.1.1: {} + + node-emoji@1.11.0: + dependencies: + lodash: 4.17.21 + + node-int64@0.4.0: {} + + node-releases@2.0.19: {} + + normalize-path@3.0.0: {} + + normalize-url@8.0.1: {} + + npm-run-path@4.0.1: + dependencies: + path-key: 3.1.1 + + object-assign@4.1.1: {} + + object-inspect@1.13.4: {} + + on-finished@2.4.1: + dependencies: + ee-first: 1.1.1 + + on-headers@1.0.2: {} + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + onetime@5.1.2: + dependencies: + mimic-fn: 2.1.0 + + optionator@0.9.4: + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.5 + + ora@5.4.1: + dependencies: + bl: 4.1.0 + chalk: 4.1.2 + cli-cursor: 3.1.0 + cli-spinners: 2.9.2 + is-interactive: 1.0.0 + is-unicode-supported: 0.1.0 + log-symbols: 4.1.0 + strip-ansi: 6.0.1 + wcwidth: 1.0.1 + + os-tmpdir@1.0.2: {} + + p-cancelable@3.0.0: {} + + p-limit@2.3.0: + dependencies: + p-try: 2.2.0 + + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-locate@4.1.0: + dependencies: + p-limit: 2.3.0 + + p-locate@5.0.0: + dependencies: + p-limit: 3.1.0 + + p-try@2.2.0: {} + + package-json-from-dist@1.0.1: {} + + parent-module@1.0.1: + dependencies: + callsites: 3.1.0 + + parse-json@5.2.0: + dependencies: + '@babel/code-frame': 7.27.1 + error-ex: 1.3.2 + json-parse-even-better-errors: 2.3.1 + lines-and-columns: 1.2.4 + + parseurl@1.3.3: {} + + passport-strategy@1.0.0: {} + + passport@0.7.0: + dependencies: + passport-strategy: 1.0.0 + pause: 0.0.1 + utils-merge: 1.0.1 + + path-exists@4.0.0: {} + + path-is-absolute@1.0.1: {} + + path-key@3.1.1: {} + + path-parse@1.0.7: {} + + path-scurry@2.0.0: + dependencies: + lru-cache: 11.1.0 + minipass: 7.1.2 + + path-to-regexp@8.2.0: {} + + path-type@4.0.0: {} + + pause@0.0.1: {} + + peek-readable@5.4.2: {} + + peek-readable@7.0.0: {} + + pend@1.2.0: {} + + picocolors@1.1.1: {} + + picomatch@2.3.1: {} + + picomatch@4.0.2: {} + + pirates@4.0.7: {} + + piscina@4.9.2: + optionalDependencies: + '@napi-rs/nice': 1.0.1 + + pkg-dir@4.2.0: + dependencies: + find-up: 4.1.0 + + pluralize@8.0.0: {} + + prelude-ls@1.2.1: {} + + prettier-linter-helpers@1.0.0: + dependencies: + fast-diff: 1.3.0 + + prettier@3.5.3: {} + + pretty-format@29.7.0: + dependencies: + '@jest/schemas': 29.6.3 + ansi-styles: 5.2.0 + react-is: 18.3.1 + + prisma@6.8.2(typescript@5.8.3): + dependencies: + '@prisma/config': 6.8.2 + '@prisma/engines': 6.8.2 + optionalDependencies: + typescript: 5.8.3 + + process-nextick-args@2.0.1: {} + + prompts@2.4.2: + dependencies: + kleur: 3.0.3 + sisteransi: 1.0.5 + + proxy-addr@2.0.7: + dependencies: + forwarded: 0.2.0 + ipaddr.js: 1.9.1 + + punycode@2.3.1: {} + + pure-rand@6.1.0: {} + + qs@6.14.0: + dependencies: + side-channel: 1.1.0 + + queue-microtask@1.2.3: {} + + quick-lru@5.1.1: {} + + random-bytes@1.0.0: {} + + randombytes@2.1.0: + dependencies: + safe-buffer: 5.2.1 + + range-parser@1.2.1: {} + + raw-body@3.0.0: + dependencies: + bytes: 3.1.2 + http-errors: 2.0.0 + iconv-lite: 0.6.3 + unpipe: 1.0.0 + + react-is@18.3.1: {} + + readable-stream@2.3.8: + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + + readable-stream@3.6.2: + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + + readdirp@4.1.2: {} + + reflect-metadata@0.2.2: {} + + repeat-string@1.6.1: {} + + require-directory@2.1.1: {} + + require-from-string@2.0.2: {} + + resolve-alpn@1.2.1: {} + + resolve-cwd@3.0.0: + dependencies: + resolve-from: 5.0.0 + + resolve-from@4.0.0: {} + + resolve-from@5.0.0: {} + + resolve.exports@2.0.3: {} + + resolve@1.22.10: + dependencies: + is-core-module: 2.16.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + responselike@3.0.0: + dependencies: + lowercase-keys: 3.0.0 + + restore-cursor@3.1.0: + dependencies: + onetime: 5.1.2 + signal-exit: 3.0.7 + + reusify@1.1.0: {} + + router@2.2.0: + dependencies: + debug: 4.4.1 + depd: 2.0.0 + is-promise: 4.0.0 + parseurl: 1.3.3 + path-to-regexp: 8.2.0 + transitivePeerDependencies: + - supports-color + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + rxjs@7.8.1: + dependencies: + tslib: 2.8.1 + + rxjs@7.8.2: + dependencies: + tslib: 2.8.1 + + safe-buffer@5.1.2: {} + + safe-buffer@5.2.1: {} + + safer-buffer@2.1.2: {} + + schema-utils@3.3.0: + dependencies: + '@types/json-schema': 7.0.15 + ajv: 6.12.6 + ajv-keywords: 3.5.2(ajv@6.12.6) + + schema-utils@4.3.2: + dependencies: + '@types/json-schema': 7.0.15 + ajv: 8.17.1 + ajv-formats: 2.1.1(ajv@8.17.1) + ajv-keywords: 5.1.0(ajv@8.17.1) + + seek-bzip@2.0.0: + dependencies: + commander: 6.2.1 + + semver-regex@4.0.5: {} + + semver-truncate@3.0.0: + dependencies: + semver: 7.7.2 + + semver@6.3.1: {} + + semver@7.7.2: {} + + send@1.2.0: + dependencies: + debug: 4.4.1 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 2.0.0 + http-errors: 2.0.0 + mime-types: 3.0.1 + ms: 2.1.3 + on-finished: 2.4.1 + range-parser: 1.2.1 + statuses: 2.0.1 + transitivePeerDependencies: + - supports-color + + serialize-javascript@6.0.2: + dependencies: + randombytes: 2.1.0 + + serve-static@2.2.0: + dependencies: + encodeurl: 2.0.0 + escape-html: 1.0.3 + parseurl: 1.3.3 + send: 1.2.0 + transitivePeerDependencies: + - supports-color + + setprototypeof@1.2.0: {} + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + side-channel-list@1.0.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + + side-channel-map@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + + side-channel-weakmap@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + side-channel-map: 1.0.1 + + side-channel@1.1.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + side-channel-list: 1.0.0 + side-channel-map: 1.0.1 + side-channel-weakmap: 1.0.2 + + signal-exit@3.0.7: {} + + signal-exit@4.1.0: {} + + sisteransi@1.0.5: {} + + slash@3.0.0: {} + + sort-keys-length@1.0.1: + dependencies: + sort-keys: 1.1.2 + + sort-keys@1.1.2: + dependencies: + is-plain-obj: 1.1.0 + + source-map-support@0.5.13: + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + + source-map-support@0.5.21: + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + + source-map@0.6.1: {} + + source-map@0.7.4: {} + + sprintf-js@1.0.3: {} + + stack-utils@2.0.6: + dependencies: + escape-string-regexp: 2.0.0 + + statuses@2.0.1: {} + + streamsearch@1.1.0: {} + + streamx@2.22.0: + dependencies: + fast-fifo: 1.3.2 + text-decoder: 1.2.3 + optionalDependencies: + bare-events: 2.5.4 + + string-length@4.0.2: + dependencies: + char-regex: 1.0.2 + strip-ansi: 6.0.1 + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string-width@5.1.2: + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.1.0 + + string_decoder@1.1.1: + dependencies: + safe-buffer: 5.1.2 + + string_decoder@1.3.0: + dependencies: + safe-buffer: 5.2.1 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-ansi@7.1.0: + dependencies: + ansi-regex: 6.1.0 + + strip-bom@3.0.0: {} + + strip-bom@4.0.0: {} + + strip-dirs@3.0.0: + dependencies: + inspect-with-kind: 1.0.5 + is-plain-obj: 1.1.0 + + strip-final-newline@2.0.0: {} + + strip-json-comments@3.1.1: {} + + strtok3@10.2.2: + dependencies: + '@tokenizer/token': 0.3.0 + peek-readable: 7.0.0 + + strtok3@9.1.1: + dependencies: + '@tokenizer/token': 0.3.0 + peek-readable: 5.4.2 + + superagent@10.2.1: + dependencies: + component-emitter: 1.3.1 + cookiejar: 2.1.4 + debug: 4.4.1 + fast-safe-stringify: 2.1.1 + form-data: 4.0.2 + formidable: 3.5.4 + methods: 1.1.2 + mime: 2.6.0 + qs: 6.14.0 + transitivePeerDependencies: + - supports-color + + supertest@7.1.1: + dependencies: + methods: 1.1.2 + superagent: 10.2.1 + transitivePeerDependencies: + - supports-color + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + supports-color@8.1.1: + dependencies: + has-flag: 4.0.0 + + supports-preserve-symlinks-flag@1.0.0: {} + + symbol-observable@4.0.0: {} + + synckit@0.11.5: + dependencies: + '@pkgr/core': 0.2.4 + tslib: 2.8.1 + + tapable@2.2.1: {} + + tar-stream@3.1.7: + dependencies: + b4a: 1.6.7 + fast-fifo: 1.3.2 + streamx: 2.22.0 + + terser-webpack-plugin@5.3.14(@swc/core@1.11.29)(webpack@5.99.6(@swc/core@1.11.29)): + dependencies: + '@jridgewell/trace-mapping': 0.3.25 + jest-worker: 27.5.1 + schema-utils: 4.3.2 + serialize-javascript: 6.0.2 + terser: 5.39.2 + webpack: 5.99.6(@swc/core@1.11.29) + optionalDependencies: + '@swc/core': 1.11.29 + + terser@5.39.2: + dependencies: + '@jridgewell/source-map': 0.3.6 + acorn: 8.14.1 + commander: 2.20.3 + source-map-support: 0.5.21 + + test-exclude@6.0.0: + dependencies: + '@istanbuljs/schema': 0.1.3 + glob: 7.2.3 + minimatch: 3.1.2 + + text-decoder@1.2.3: + dependencies: + b4a: 1.6.7 + + through@2.3.8: {} + + tmp@0.0.33: + dependencies: + os-tmpdir: 1.0.2 + + tmpl@1.0.5: {} + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + toidentifier@1.0.1: {} + + token-types@6.0.0: + dependencies: + '@tokenizer/token': 0.3.0 + ieee754: 1.2.1 + + tree-kill@1.2.2: {} + + ts-api-utils@2.1.0(typescript@5.8.3): + dependencies: + typescript: 5.8.3 + + ts-jest@29.3.4(@babel/core@7.27.1)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.27.1))(jest@29.7.0(@types/node@22.15.21)(ts-node@10.9.2(@swc/core@1.11.29)(@types/node@22.15.21)(typescript@5.8.3)))(typescript@5.8.3): + dependencies: + bs-logger: 0.2.6 + ejs: 3.1.10 + fast-json-stable-stringify: 2.1.0 + jest: 29.7.0(@types/node@22.15.21)(ts-node@10.9.2(@swc/core@1.11.29)(@types/node@22.15.21)(typescript@5.8.3)) + jest-util: 29.7.0 + json5: 2.2.3 + lodash.memoize: 4.1.2 + make-error: 1.3.6 + semver: 7.7.2 + type-fest: 4.41.0 + typescript: 5.8.3 + yargs-parser: 21.1.1 + optionalDependencies: + '@babel/core': 7.27.1 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + babel-jest: 29.7.0(@babel/core@7.27.1) + + ts-loader@9.5.2(typescript@5.8.3)(webpack@5.99.6(@swc/core@1.11.29)): + dependencies: + chalk: 4.1.2 + enhanced-resolve: 5.18.1 + micromatch: 4.0.8 + semver: 7.7.2 + source-map: 0.7.4 + typescript: 5.8.3 + webpack: 5.99.6(@swc/core@1.11.29) + + ts-node@10.9.2(@swc/core@1.11.29)(@types/node@22.15.21)(typescript@5.8.3): + dependencies: + '@cspotcode/source-map-support': 0.8.1 + '@tsconfig/node10': 1.0.11 + '@tsconfig/node12': 1.0.11 + '@tsconfig/node14': 1.0.3 + '@tsconfig/node16': 1.0.4 + '@types/node': 22.15.21 + acorn: 8.14.1 + acorn-walk: 8.3.4 + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.2 + make-error: 1.3.6 + typescript: 5.8.3 + v8-compile-cache-lib: 3.0.1 + yn: 3.1.1 + optionalDependencies: + '@swc/core': 1.11.29 + + tsconfig-paths-webpack-plugin@4.2.0: + dependencies: + chalk: 4.1.2 + enhanced-resolve: 5.18.1 + tapable: 2.2.1 + tsconfig-paths: 4.2.0 + + tsconfig-paths@4.2.0: + dependencies: + json5: 2.2.3 + minimist: 1.2.8 + strip-bom: 3.0.0 + + tslib@2.8.1: {} + + type-check@0.4.0: + dependencies: + prelude-ls: 1.2.1 + + type-detect@4.0.8: {} + + type-fest@0.21.3: {} + + type-fest@4.41.0: {} + + type-is@1.6.18: + dependencies: + media-typer: 0.3.0 + mime-types: 2.1.35 + + type-is@2.0.1: + dependencies: + content-type: 1.0.5 + media-typer: 1.1.0 + mime-types: 3.0.1 + + typedarray@0.0.6: {} + + typescript-eslint@8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3): + dependencies: + '@typescript-eslint/eslint-plugin': 8.32.1(@typescript-eslint/parser@8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/parser': 8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/utils': 8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3) + eslint: 9.27.0(jiti@2.4.2) + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + + typescript@5.8.3: {} + + uid-safe@2.1.5: + dependencies: + random-bytes: 1.0.0 + + uid@2.0.2: + dependencies: + '@lukeed/csprng': 1.1.0 + + uint8array-extras@1.4.0: {} + + unbzip2-stream@1.4.3: + dependencies: + buffer: 5.7.1 + through: 2.3.8 + + undici-types@6.21.0: {} + + universalify@2.0.1: {} + + unpipe@1.0.0: {} + + update-browserslist-db@1.1.3(browserslist@4.24.5): + dependencies: + browserslist: 4.24.5 + escalade: 3.2.0 + picocolors: 1.1.1 + + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + + util-deprecate@1.0.2: {} + + utils-merge@1.0.1: {} + + v8-compile-cache-lib@3.0.1: {} + + v8-to-istanbul@9.3.0: + dependencies: + '@jridgewell/trace-mapping': 0.3.25 + '@types/istanbul-lib-coverage': 2.0.6 + convert-source-map: 2.0.0 + + vary@1.1.2: {} + + walker@1.0.8: + dependencies: + makeerror: 1.0.12 + + watchpack@2.4.2: + dependencies: + glob-to-regexp: 0.4.1 + graceful-fs: 4.2.11 + + wcwidth@1.0.1: + dependencies: + defaults: 1.0.4 + + webpack-node-externals@3.0.0: {} + + webpack-sources@3.2.3: {} + + webpack@5.99.6(@swc/core@1.11.29): + dependencies: + '@types/eslint-scope': 3.7.7 + '@types/estree': 1.0.7 + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/wasm-edit': 1.14.1 + '@webassemblyjs/wasm-parser': 1.14.1 + acorn: 8.14.1 + browserslist: 4.24.5 + chrome-trace-event: 1.0.4 + enhanced-resolve: 5.18.1 + es-module-lexer: 1.7.0 + eslint-scope: 5.1.1 + events: 3.3.0 + glob-to-regexp: 0.4.1 + graceful-fs: 4.2.11 + json-parse-even-better-errors: 2.3.1 + loader-runner: 4.3.0 + mime-types: 2.1.35 + neo-async: 2.6.2 + schema-utils: 4.3.2 + tapable: 2.2.1 + terser-webpack-plugin: 5.3.14(@swc/core@1.11.29)(webpack@5.99.6(@swc/core@1.11.29)) + watchpack: 2.4.2 + webpack-sources: 3.2.3 + transitivePeerDependencies: + - '@swc/core' + - esbuild + - uglify-js + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + word-wrap@1.2.5: {} + + wrap-ansi@6.2.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@8.1.0: + dependencies: + ansi-styles: 6.2.1 + string-width: 5.1.2 + strip-ansi: 7.1.0 + + wrappy@1.0.2: {} + + write-file-atomic@4.0.2: + dependencies: + imurmurhash: 0.1.4 + signal-exit: 3.0.7 + + xtend@4.0.2: {} + + y18n@5.0.8: {} + + yallist@3.1.1: {} + + yargs-parser@21.1.1: {} + + yargs@17.7.2: + dependencies: + cliui: 8.0.1 + escalade: 3.2.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 + + yauzl@3.2.0: + dependencies: + buffer-crc32: 0.2.13 + pend: 1.2.0 + + yn@3.1.1: {} + + yocto-queue@0.1.0: {} + + yoctocolors-cjs@2.1.2: {} diff --git a/server/pnpm-workspace.yaml b/server/pnpm-workspace.yaml new file mode 100644 index 000000000..358fb5cae --- /dev/null +++ b/server/pnpm-workspace.yaml @@ -0,0 +1,6 @@ +onlyBuiltDependencies: + - '@nestjs/core' + - '@prisma/client' + - '@prisma/engines' + - '@swc/core' + - prisma diff --git a/server/prisma/migrations/20250523064317_inital/migration.sql b/server/prisma/migrations/20250523064317_inital/migration.sql new file mode 100644 index 000000000..f7083f79f --- /dev/null +++ b/server/prisma/migrations/20250523064317_inital/migration.sql @@ -0,0 +1,83 @@ +-- CreateEnum +CREATE TYPE "EventType" AS ENUM ('CUSTOM', 'TUTORING'); + +-- CreateTable +CREATE TABLE "user" ( + "id" VARCHAR(30) NOT NULL, + "oidcId" TEXT, + "isGuest" BOOLEAN NOT NULL DEFAULT true, + "firstName" TEXT NOT NULL, + "lastName" TEXT NOT NULL, + "profilePictureUrl" TEXT, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "lastLogin" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + + CONSTRAINT "user_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "settings" ( + "userId" TEXT NOT NULL, + "preferredTheme" TEXT NOT NULL DEFAULT 'classic', + "use24HourClock" BOOLEAN NOT NULL DEFAULT false, + "useDarkMode" BOOLEAN NOT NULL DEFAULT false, + "useSquareEdges" BOOLEAN NOT NULL DEFAULT false, + "hideFullClasses" BOOLEAN NOT NULL DEFAULT false, + "hideClassInfo" BOOLEAN NOT NULL DEFAULT false, + "unscheduleClassesByDefault" BOOLEAN NOT NULL DEFAULT true, + "hideExamClasses" BOOLEAN NOT NULL DEFAULT false +); + +-- CreateTable +CREATE TABLE "timetable" ( + "userId" TEXT NOT NULL, + "id" TEXT NOT NULL, + "name" TEXT NOT NULL, + "year" INTEGER NOT NULL, + "term" TEXT NOT NULL, + "primary" BOOLEAN NOT NULL DEFAULT false, + + CONSTRAINT "timetable_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "course" ( + "id" TEXT NOT NULL, + "timetableId" TEXT NOT NULL, + "courseId" TEXT NOT NULL, + "selectedClasses" TEXT[], + "colour" TEXT NOT NULL, + + CONSTRAINT "course_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "event" ( + "id" TEXT NOT NULL, + "timetableId" TEXT NOT NULL, + "colour" TEXT NOT NULL, + "dayOfWeek" INTEGER NOT NULL, + "start" INTEGER NOT NULL, + "end" INTEGER NOT NULL, + "type" "EventType" NOT NULL, + + CONSTRAINT "event_pkey" PRIMARY KEY ("id") +); + +-- CreateIndex +CREATE UNIQUE INDEX "user_oidcId_key" ON "user"("oidcId"); + +-- CreateIndex +CREATE UNIQUE INDEX "settings_userId_key" ON "settings"("userId"); + +-- AddForeignKey +ALTER TABLE "settings" ADD CONSTRAINT "settings_userId_fkey" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "timetable" ADD CONSTRAINT "timetable_userId_fkey" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "course" ADD CONSTRAINT "course_timetableId_fkey" FOREIGN KEY ("timetableId") REFERENCES "timetable"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "event" ADD CONSTRAINT "event_timetableId_fkey" FOREIGN KEY ("timetableId") REFERENCES "timetable"("id") ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/server/prisma/migrations/migration_lock.toml b/server/prisma/migrations/migration_lock.toml new file mode 100644 index 000000000..044d57cdb --- /dev/null +++ b/server/prisma/migrations/migration_lock.toml @@ -0,0 +1,3 @@ +# Please do not edit this file manually +# It should be added in your version-control system (e.g., Git) +provider = "postgresql" diff --git a/server/prisma/schema.prisma b/server/prisma/schema.prisma new file mode 100644 index 000000000..13831ec45 --- /dev/null +++ b/server/prisma/schema.prisma @@ -0,0 +1,113 @@ +generator client { + provider = "prisma-client" + output = "../src/generated/prisma" +} + +datasource db { + provider = "postgresql" + url = env("DATABASE_URL") +} + +model User { + // Unique per-user ID + id String @id @default(cuid(2)) @db.VarChar(30) + // ID given by auth - probably zID + oidcId String? @unique + isGuest Boolean @default(true) + + firstName String + lastName String + profilePictureUrl String? + timetables Timetable[] + settings Settings? + + createdAt DateTime @default(now()) + lastLogin DateTime @default(now()) + + @@map("user") +} + +// model FriendRequest { +// id String @id @default(uuid()) +// fromId String +// toId String + +// @@unique([fromId, toId]) +// @@map("friend_request") +// } + +// model Friendship { +// id String @id @default(uuid()) +// user1Id String +// user2Id String + +// @@unique([user1Id, user2Id]) +// @@map("friendship") +// } + +model Settings { + user User @relation(fields: [userId], references: [id], onDelete: Cascade) + userId String @unique + + preferredTheme String @default("classic") + use24HourClock Boolean @default(false) + useDarkMode Boolean @default(false) + useSquareEdges Boolean @default(false) + hideFullClasses Boolean @default(false) + hideClassInfo Boolean @default(false) + unscheduleClassesByDefault Boolean @default(true) + hideExamClasses Boolean @default(false) + + @@map("settings") +} + +model Timetable { + User User @relation(fields: [userId], references: [id], onDelete: Cascade) + userId String + + // Unique ID for the timetable, need this to attach courses and events + id String @id @default(uuid()) + name String + year Int + term String + // Courses are UNSW items, events are user-defined/tutoring + courses Course[] + events Event[] + // One timetable should be primary per term per user + primary Boolean @default(false) + + @@map("timetable") +} + +model Course { + id String @id @default(uuid()) + timetable Timetable @relation(fields: [timetableId], references: [id], onDelete: Cascade) + timetableId String + + // This is the course id field in our GraphQL API + courseId String + // This is an array of class ids in our GraphQL API + selectedClasses String[] + colour String + + @@map("course") +} + +model Event { + id String @id @default(uuid()) + timetable Timetable @relation(fields: [timetableId], references: [id], onDelete: Cascade) + timetableId String + + colour String + dayOfWeek Int + start Int + end Int + type EventType + + @@map("event") +} + +enum EventType { + CUSTOM + TUTORING +} diff --git a/server/src/app.controller.spec.ts b/server/src/app.controller.spec.ts new file mode 100644 index 000000000..d22f3890a --- /dev/null +++ b/server/src/app.controller.spec.ts @@ -0,0 +1,22 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { AppController } from './app.controller'; +import { AppService } from './app.service'; + +describe('AppController', () => { + let appController: AppController; + + beforeEach(async () => { + const app: TestingModule = await Test.createTestingModule({ + controllers: [AppController], + providers: [AppService], + }).compile(); + + appController = app.get(AppController); + }); + + describe('root', () => { + it('should return "Hello World!"', () => { + expect(appController.getHello()).toBe('Hello World!'); + }); + }); +}); diff --git a/server/src/app.controller.ts b/server/src/app.controller.ts new file mode 100644 index 000000000..cce879ee6 --- /dev/null +++ b/server/src/app.controller.ts @@ -0,0 +1,12 @@ +import { Controller, Get } from '@nestjs/common'; +import { AppService } from './app.service'; + +@Controller() +export class AppController { + constructor(private readonly appService: AppService) {} + + @Get() + getHello(): string { + return this.appService.getHello(); + } +} diff --git a/server/src/app.module.ts b/server/src/app.module.ts new file mode 100644 index 000000000..dbd7bc8c9 --- /dev/null +++ b/server/src/app.module.ts @@ -0,0 +1,20 @@ +import { Module } from '@nestjs/common'; +import { AppController } from './app.controller'; +import { AppService } from './app.service'; +import { ConfigModule } from '@nestjs/config'; +import config from './config'; +import { UserModule } from './user/user.module'; + +@Module({ + imports: [ + ConfigModule.forRoot({ + load: [config], + isGlobal: true, + expandVariables: true, + }), + UserModule, + ], + controllers: [AppController], + providers: [AppService], +}) +export class AppModule {} diff --git a/server/src/app.service.ts b/server/src/app.service.ts new file mode 100644 index 000000000..927d7cca0 --- /dev/null +++ b/server/src/app.service.ts @@ -0,0 +1,8 @@ +import { Injectable } from '@nestjs/common'; + +@Injectable() +export class AppService { + getHello(): string { + return 'Hello World!'; + } +} diff --git a/server/src/auth/authenticated.guard.ts b/server/src/auth/authenticated.guard.ts new file mode 100644 index 000000000..41432908c --- /dev/null +++ b/server/src/auth/authenticated.guard.ts @@ -0,0 +1,11 @@ +import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common'; + +@Injectable() +export class AuthenticatedGuard implements CanActivate { + canActivate(context: ExecutionContext): boolean { + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + const req = context.switchToHttp().getRequest(); + // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access + return req.isAuthenticated?.() === true; + } +} diff --git a/server/src/config.ts b/server/src/config.ts new file mode 100644 index 000000000..b9331b630 --- /dev/null +++ b/server/src/config.ts @@ -0,0 +1,4 @@ +export default () => ({ + env: process.env.NODE_ENV || 'dev', + port: parseInt(process.env.PORT ?? '3001', 10), +}); diff --git a/server/src/main.ts b/server/src/main.ts new file mode 100644 index 000000000..212351b4a --- /dev/null +++ b/server/src/main.ts @@ -0,0 +1,35 @@ +import { NestFactory } from '@nestjs/core'; +import { AppModule } from './app.module'; +import { ConfigService } from '@nestjs/config'; +import * as passport from 'passport'; +import * as session from 'express-session'; + +async function bootstrap() { + const app = await NestFactory.create(AppModule); + const configService = app.get(ConfigService); + app.setGlobalPrefix('api'); + + app.enableCors({ + origin: [ + 'http://localhost:5173', + 'https://notanglesstaging.devsoc.app', + 'https://notangles.devsoc.app', + ], + }); + + // TODO: Validate session secret using configService + // TODO: Experiment with secure: true + app.use( + session({ + secret: configService.get('SESSION_SECRET') ?? 'secret', + resave: false, + saveUninitialized: false, + }), + ); + + app.use(passport.initialize()); + app.use(passport.session()); + + await app.listen(configService.get('port') ?? 3001); +} +bootstrap(); diff --git a/server/src/prisma/prisma.service.ts b/server/src/prisma/prisma.service.ts new file mode 100644 index 000000000..27b13025f --- /dev/null +++ b/server/src/prisma/prisma.service.ts @@ -0,0 +1,9 @@ +import { Injectable, OnModuleInit } from '@nestjs/common'; +import { PrismaClient } from '../generated/prisma'; + +@Injectable() +export class PrismaService extends PrismaClient implements OnModuleInit { + async onModuleInit() { + await this.$connect(); + } +} diff --git a/server/src/types/express.d.ts b/server/src/types/express.d.ts new file mode 100644 index 000000000..dd9f6a58b --- /dev/null +++ b/server/src/types/express.d.ts @@ -0,0 +1,9 @@ +declare module 'express' { + interface Request { + user?: { + id: string; + isGuest: boolean; + }; + isAuthenticated(): boolean; + } +} diff --git a/server/src/user/types.ts b/server/src/user/types.ts new file mode 100644 index 000000000..d7e12c64f --- /dev/null +++ b/server/src/user/types.ts @@ -0,0 +1,17 @@ +export class UserInfo { + id: string; + firstName: string; + lastName: string; + profilePictureUrl?: string; +} + +export class UserSettings { + preferredTheme: string; + use24HourClock: boolean; + useDarkMode: boolean; + useSquareEdges: boolean; + hideFullClasses: boolean; + hideClassInfo: boolean; + unscheduleClassesByDefault: boolean; + hideExamClasses: boolean; +} diff --git a/server/src/user/user.controller.ts b/server/src/user/user.controller.ts new file mode 100644 index 000000000..4085751d4 --- /dev/null +++ b/server/src/user/user.controller.ts @@ -0,0 +1,38 @@ +import { Body, Controller, Get, Post, Req, UseGuards } from '@nestjs/common'; +import { UserService } from './user.service'; +import { AuthenticatedGuard } from 'src/auth/authenticated.guard'; +import { Request } from 'express'; +import { UserSettings } from './types'; + +@Controller('user') +export class UserController { + constructor(private userService: UserService) {} + + @Get('profile') + @UseGuards(AuthenticatedGuard) + async getProfile(@Req() req: Request) { + const userInfo = await this.userService.getUserInfo(req.user!.id); + return userInfo; + } + + @Post('profile/picture') + @UseGuards(AuthenticatedGuard) + async setProfilePicture(@Req() req: Request, @Body('url') url: string) { + await this.userService.setProfilePicture(req.user!.id, url); + return; + } + + @Get('settings') + @UseGuards(AuthenticatedGuard) + async getSettings(@Req() req: Request) { + const settings = await this.userService.getSettings(req.user!.id); + return settings; + } + + @Post('settings') + @UseGuards(AuthenticatedGuard) + async setSettings(@Req() req: Request, @Body() settings: UserSettings) { + await this.userService.setSettings(req.user!.id, settings); + return; + } +} diff --git a/server/src/user/user.module.ts b/server/src/user/user.module.ts new file mode 100644 index 000000000..7629f686f --- /dev/null +++ b/server/src/user/user.module.ts @@ -0,0 +1,10 @@ +import { Module } from '@nestjs/common'; +import { PrismaService } from 'src/prisma/prisma.service'; +import { UserService } from './user.service'; +import { UserController } from './user.controller'; + +@Module({ + providers: [UserService, PrismaService], + controllers: [UserController], +}) +export class UserModule {} diff --git a/server/src/user/user.service.ts b/server/src/user/user.service.ts new file mode 100644 index 000000000..40c13e820 --- /dev/null +++ b/server/src/user/user.service.ts @@ -0,0 +1,67 @@ +import { Injectable } from '@nestjs/common'; +import { PrismaService } from 'src/prisma/prisma.service'; +import { UserInfo, UserSettings } from './types'; + +@Injectable({}) +export class UserService { + constructor(private readonly prisma: PrismaService) {} + + async getUserInfo(userId: string): Promise { + const data = await this.prisma.user.findUniqueOrThrow({ + where: { + id: userId, + }, + }); + + return { + id: data.id, + firstName: data.firstName, + lastName: data.lastName, + profilePictureUrl: data.profilePictureUrl ?? undefined, + }; + } + + async setProfilePicture( + userId: string, + profilePictureUrl: string, + ): Promise { + await this.prisma.user.update({ + where: { + id: userId, + }, + data: { + profilePictureUrl, + }, + }); + } + + async getSettings(userId: string): Promise { + const data = await this.prisma.user.findUniqueOrThrow({ + where: { + id: userId, + }, + select: { + settings: true, + }, + }); + + if (!data.settings) { + throw new Error('User settings not found'); + } + + return data.settings; + } + + async setSettings(userId: string, settings: UserSettings): Promise { + await this.prisma.user.update({ + where: { + id: userId, + }, + data: { + settings: { + update: settings, + }, + }, + }); + } +} diff --git a/server/test/app.e2e-spec.ts b/server/test/app.e2e-spec.ts new file mode 100644 index 000000000..4df6580c7 --- /dev/null +++ b/server/test/app.e2e-spec.ts @@ -0,0 +1,25 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { INestApplication } from '@nestjs/common'; +import * as request from 'supertest'; +import { App } from 'supertest/types'; +import { AppModule } from './../src/app.module'; + +describe('AppController (e2e)', () => { + let app: INestApplication; + + beforeEach(async () => { + const moduleFixture: TestingModule = await Test.createTestingModule({ + imports: [AppModule], + }).compile(); + + app = moduleFixture.createNestApplication(); + await app.init(); + }); + + it('/ (GET)', () => { + return request(app.getHttpServer()) + .get('/') + .expect(200) + .expect('Hello World!'); + }); +}); diff --git a/server/test/jest-e2e.json b/server/test/jest-e2e.json new file mode 100644 index 000000000..e9d912f3e --- /dev/null +++ b/server/test/jest-e2e.json @@ -0,0 +1,9 @@ +{ + "moduleFileExtensions": ["js", "json", "ts"], + "rootDir": ".", + "testEnvironment": "node", + "testRegex": ".e2e-spec.ts$", + "transform": { + "^.+\\.(t|j)s$": "ts-jest" + } +} diff --git a/server/tsconfig.build.json b/server/tsconfig.build.json new file mode 100644 index 000000000..64f86c6bd --- /dev/null +++ b/server/tsconfig.build.json @@ -0,0 +1,4 @@ +{ + "extends": "./tsconfig.json", + "exclude": ["node_modules", "test", "dist", "**/*spec.ts"] +} diff --git a/server/tsconfig.json b/server/tsconfig.json new file mode 100644 index 000000000..f668e37e1 --- /dev/null +++ b/server/tsconfig.json @@ -0,0 +1,21 @@ +{ + "compilerOptions": { + "module": "commonjs", + "declaration": true, + "removeComments": true, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "allowSyntheticDefaultImports": true, + "target": "ES2023", + "sourceMap": true, + "outDir": "./dist", + "baseUrl": "./", + "incremental": true, + "skipLibCheck": true, + "strictNullChecks": true, + "forceConsistentCasingInFileNames": true, + "noImplicitAny": true, + "strictBindCallApply": true, + "noFallthroughCasesInSwitch": true + } +} From a571a145c9ae006ba324750f883f60f9604cda10 Mon Sep 17 00:00:00 2001 From: Lucas Date: Thu, 29 May 2025 15:16:47 +1000 Subject: [PATCH 03/33] Add docker compose for database --- server/docker-compose.yml | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 server/docker-compose.yml diff --git a/server/docker-compose.yml b/server/docker-compose.yml new file mode 100644 index 000000000..a1717e0a3 --- /dev/null +++ b/server/docker-compose.yml @@ -0,0 +1,25 @@ +# This should will be redone when the server is ready to replace the old one +# Currently it uses different names and ports to avoid conflicts with the old server +services: + database-new: + container_name: notangles-database-new + hostname: notangles_database_new + restart: always + image: postgres:17-alpine + ports: + - '5433:5432' + environment: + - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} + - POSTGRES_USER=${POSTGRES_USER} + - POSTGRES_DB=${POSTGRES_DB} + volumes: + - postgres:/var/lib/postgresql/data + networks: + - notangles_network_new + +volumes: + postgres: + name: server-new +networks: + notangles_network_new: + driver: bridge From 2465473adbac72b8a0d4a55ac4c689e0a774a9ae Mon Sep 17 00:00:00 2001 From: Lucas Date: Thu, 29 May 2025 16:45:24 +1000 Subject: [PATCH 04/33] Setup server graphql client --- server/codegen.ts | 22 + server/package.json | 12 +- server/pnpm-lock.yaml | 2576 ++++++++++++++++++++++++- server/pnpm-workspace.yaml | 1 + server/src/graphql/graphql.module.ts | 7 + server/src/graphql/graphql.service.ts | 24 + server/src/graphql/queries.ts | 13 + server/tsconfig.json | 8 +- 8 files changed, 2660 insertions(+), 3 deletions(-) create mode 100644 server/codegen.ts create mode 100644 server/src/graphql/graphql.module.ts create mode 100644 server/src/graphql/graphql.service.ts create mode 100644 server/src/graphql/queries.ts diff --git a/server/codegen.ts b/server/codegen.ts new file mode 100644 index 000000000..9dd24ebec --- /dev/null +++ b/server/codegen.ts @@ -0,0 +1,22 @@ +import type { CodegenConfig } from '@graphql-codegen/cli'; + +const config: CodegenConfig = { + schema: 'https://graphql.csesoc.app/v1/graphql', + documents: ['src/**/*.ts'], + ignoreNoDocuments: true, + generates: { + './src/generated/graphql/': { + plugins: [ + 'typescript', + 'typescript-operations', + 'typescript-graphql-request', + ], + preset: 'client', + config: { + documentMode: 'string', + }, + }, + }, +}; + +export default config; diff --git a/server/package.json b/server/package.json index 81fd31ffc..156c618ca 100644 --- a/server/package.json +++ b/server/package.json @@ -17,7 +17,8 @@ "test:watch": "jest --watch", "test:cov": "jest --coverage", "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand", - "test:e2e": "jest --config ./test/jest-e2e.json" + "test:e2e": "jest --config ./test/jest-e2e.json", + "graphql": "graphql-codegen --config codegen.ts" }, "dependencies": { "@nestjs/common": "11.1.1", @@ -27,16 +28,25 @@ "@nestjs/platform-express": "11.1.1", "@prisma/client": "6.8.2", "express-session": "1.18.1", + "graphql": "16.11.0", + "graphql-request": "7.2.0", "passport": "0.7.0", "reflect-metadata": "0.2.2", "rxjs": "7.8.2" }, "devDependencies": { + "@0no-co/graphqlsp": "1.12.16", "@eslint/eslintrc": "3.3.1", "@eslint/js": "9.27.0", + "@graphql-codegen/cli": "5.0.6", + "@graphql-codegen/client-preset": "4.8.1", + "@graphql-codegen/typescript": "4.1.6", + "@graphql-codegen/typescript-graphql-request": "6.3.0", + "@graphql-codegen/typescript-operations": "4.6.1", "@nestjs/cli": "11.0.7", "@nestjs/schematics": "11.0.5", "@nestjs/testing": "11.1.1", + "@parcel/watcher": "2.5.1", "@swc/cli": "0.6.0", "@swc/core": "1.11.29", "@types/express": "5.0.2", diff --git a/server/pnpm-lock.yaml b/server/pnpm-lock.yaml index ccd99eec1..cd2264de7 100644 --- a/server/pnpm-lock.yaml +++ b/server/pnpm-lock.yaml @@ -29,6 +29,12 @@ importers: express-session: specifier: 1.18.1 version: 1.18.1 + graphql: + specifier: 16.11.0 + version: 16.11.0 + graphql-request: + specifier: 7.2.0 + version: 7.2.0(graphql@16.11.0) passport: specifier: 0.7.0 version: 0.7.0 @@ -39,12 +45,30 @@ importers: specifier: 7.8.2 version: 7.8.2 devDependencies: + '@0no-co/graphqlsp': + specifier: 1.12.16 + version: 1.12.16(graphql@16.11.0)(typescript@5.8.3) '@eslint/eslintrc': specifier: 3.3.1 version: 3.3.1 '@eslint/js': specifier: 9.27.0 version: 9.27.0 + '@graphql-codegen/cli': + specifier: 5.0.6 + version: 5.0.6(@parcel/watcher@2.5.1)(@types/node@22.15.21)(graphql@16.11.0)(typescript@5.8.3) + '@graphql-codegen/client-preset': + specifier: 4.8.1 + version: 4.8.1(graphql@16.11.0) + '@graphql-codegen/typescript': + specifier: 4.1.6 + version: 4.1.6(graphql@16.11.0) + '@graphql-codegen/typescript-graphql-request': + specifier: 6.3.0 + version: 6.3.0(graphql-request@7.2.0(graphql@16.11.0))(graphql-tag@2.12.6(graphql@16.11.0))(graphql@16.11.0) + '@graphql-codegen/typescript-operations': + specifier: 4.6.1 + version: 4.6.1(graphql@16.11.0) '@nestjs/cli': specifier: 11.0.7 version: 11.0.7(@swc/cli@0.6.0(@swc/core@1.11.29)(chokidar@4.0.3))(@swc/core@1.11.29)(@types/node@22.15.21) @@ -54,6 +78,9 @@ importers: '@nestjs/testing': specifier: 11.1.1 version: 11.1.1(@nestjs/common@11.1.1(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.1)(@nestjs/platform-express@11.1.1) + '@parcel/watcher': + specifier: 2.5.1 + version: 2.5.1 '@swc/cli': specifier: 0.6.0 version: 0.6.0(@swc/core@1.11.29)(chokidar@4.0.3) @@ -126,6 +153,20 @@ importers: packages: + '@0no-co/graphql.web@1.1.2': + resolution: {integrity: sha512-N2NGsU5FLBhT8NZ+3l2YrzZSHITjNXNuDhC4iDiikv0IujaJ0Xc6xIxQZ/Ek3Cb+rgPjnLHYyJm11tInuJn+cw==} + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 + peerDependenciesMeta: + graphql: + optional: true + + '@0no-co/graphqlsp@1.12.16': + resolution: {integrity: sha512-B5pyYVH93Etv7xjT6IfB7QtMBdaaC07yjbhN6v8H7KgFStMkPvi+oWYBTibMFRMY89qwc9H8YixXg8SXDVgYWw==} + peerDependencies: + graphql: ^15.5.0 || ^16.0.0 || ^17.0.0 + typescript: ^5.0.0 + '@ampproject/remapping@2.3.0': resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} engines: {node: '>=6.0.0'} @@ -161,6 +202,18 @@ packages: resolution: {integrity: sha512-QsmFuYdAyeCyg9WF/AJBhFXDUfCwmDFTEbsv5t5KPSP6slhk0GoLNZApniiFytU2siRlSxVNpve2uATyYuAYkQ==} engines: {node: ^18.19.1 || ^20.11.1 || >=22.0.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} + '@ardatan/relay-compiler@12.0.0': + resolution: {integrity: sha512-9anThAaj1dQr6IGmzBMcfzOQKTa5artjuPmw8NYK/fiGEMjADbSguBY2FMDykt+QhilR3wc9VA/3yVju7JHg7Q==} + hasBin: true + peerDependencies: + graphql: '*' + + '@ardatan/relay-compiler@12.0.3': + resolution: {integrity: sha512-mBDFOGvAoVlWaWqs3hm1AciGHSQE1rqFc/liZTyYz/Oek9yZdT5H26pH2zAFuEiTiBVPPyMuqf5VjOFPI2DGsQ==} + hasBin: true + peerDependencies: + graphql: '*' + '@babel/code-frame@7.27.1': resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} engines: {node: '>=6.9.0'} @@ -177,10 +230,24 @@ packages: resolution: {integrity: sha512-UnJfnIpc/+JO0/+KRVQNGU+y5taA5vCbwN8+azkX6beii/ZF+enZJSOKo11ZSzGJjlNfJHfQtmQT8H+9TXPG2w==} engines: {node: '>=6.9.0'} + '@babel/helper-annotate-as-pure@7.27.3': + resolution: {integrity: sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==} + engines: {node: '>=6.9.0'} + '@babel/helper-compilation-targets@7.27.2': resolution: {integrity: sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==} engines: {node: '>=6.9.0'} + '@babel/helper-create-class-features-plugin@7.27.1': + resolution: {integrity: sha512-QwGAmuvM17btKU5VqXfb+Giw4JcN0hjuufz3DYnpeVDvZLAObloM77bhMXiqry3Iio+Ai4phVRDwl6WU10+r5A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-member-expression-to-functions@7.27.1': + resolution: {integrity: sha512-E5chM8eWjTp/aNoVpcbfM7mLxu9XGLWYise2eBKGQomAk/Mb4XoxyqXTZbuTohbsl8EKqdlMhnDI2CCLfcs9wA==} + engines: {node: '>=6.9.0'} + '@babel/helper-module-imports@7.27.1': resolution: {integrity: sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==} engines: {node: '>=6.9.0'} @@ -191,10 +258,24 @@ packages: peerDependencies: '@babel/core': ^7.0.0 + '@babel/helper-optimise-call-expression@7.27.1': + resolution: {integrity: sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==} + engines: {node: '>=6.9.0'} + '@babel/helper-plugin-utils@7.27.1': resolution: {integrity: sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==} engines: {node: '>=6.9.0'} + '@babel/helper-replace-supers@7.27.1': + resolution: {integrity: sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-skip-transparent-expression-wrappers@7.27.1': + resolution: {integrity: sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==} + engines: {node: '>=6.9.0'} + '@babel/helper-string-parser@7.27.1': resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} engines: {node: '>=6.9.0'} @@ -216,6 +297,20 @@ packages: engines: {node: '>=6.0.0'} hasBin: true + '@babel/plugin-proposal-class-properties@7.18.6': + resolution: {integrity: sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==} + engines: {node: '>=6.9.0'} + 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. + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-proposal-object-rest-spread@7.20.7': + resolution: {integrity: sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg==} + engines: {node: '>=6.9.0'} + 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. + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/plugin-syntax-async-generators@7.8.4': resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} peerDependencies: @@ -237,6 +332,18 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-syntax-flow@7.27.1': + resolution: {integrity: sha512-p9OkPbZ5G7UT1MofwYFigGebnrzGJacoBSQM0/6bi/PUMVE+qlWDD/OalvQKbwgQzU6dl0xAv6r4X7Jme0RYxA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-import-assertions@7.27.1': + resolution: {integrity: sha512-UT/Jrhw57xg4ILHLFnzFpPDlMbcdEicaAtjPQpbj9wa8T4r5KVWCimHcL/460g8Ht0DMxDyjsLgiWSkVjnwPFg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/plugin-syntax-import-attributes@7.27.1': resolution: {integrity: sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww==} engines: {node: '>=6.9.0'} @@ -307,6 +414,130 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-arrow-functions@7.27.1': + resolution: {integrity: sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-block-scoped-functions@7.27.1': + resolution: {integrity: sha512-cnqkuOtZLapWYZUYM5rVIdv1nXYuFVIltZ6ZJ7nIj585QsjKM5dhL2Fu/lICXZ1OyIAFc7Qy+bvDAtTXqGrlhg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-block-scoping@7.27.3': + resolution: {integrity: sha512-+F8CnfhuLhwUACIJMLWnjz6zvzYM2r0yeIHKlbgfw7ml8rOMJsXNXV/hyRcb3nb493gRs4WvYpQAndWj/qQmkQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-classes@7.27.1': + resolution: {integrity: sha512-7iLhfFAubmpeJe/Wo2TVuDrykh/zlWXLzPNdL0Jqn/Xu8R3QQ8h9ff8FQoISZOsw74/HFqFI7NX63HN7QFIHKA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-computed-properties@7.27.1': + resolution: {integrity: sha512-lj9PGWvMTVksbWiDT2tW68zGS/cyo4AkZ/QTp0sQT0mjPopCmrSkzxeXkznjqBxzDI6TclZhOJbBmbBLjuOZUw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-destructuring@7.27.3': + resolution: {integrity: sha512-s4Jrok82JpiaIprtY2nHsYmrThKvvwgHwjgd7UMiYhZaN0asdXNLr0y+NjTfkA7SyQE5i2Fb7eawUOZmLvyqOA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-flow-strip-types@7.27.1': + resolution: {integrity: sha512-G5eDKsu50udECw7DL2AcsysXiQyB7Nfg521t2OAJ4tbfTJ27doHLeF/vlI1NZGlLdbb/v+ibvtL1YBQqYOwJGg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-for-of@7.27.1': + resolution: {integrity: sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-function-name@7.27.1': + resolution: {integrity: sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-literals@7.27.1': + resolution: {integrity: sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-member-expression-literals@7.27.1': + resolution: {integrity: sha512-hqoBX4dcZ1I33jCSWcXrP+1Ku7kdqXf1oeah7ooKOIiAdKQ+uqftgCFNOSzA5AMS2XIHEYeGFg4cKRCdpxzVOQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-modules-commonjs@7.27.1': + resolution: {integrity: sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-object-super@7.27.1': + resolution: {integrity: sha512-SFy8S9plRPbIcxlJ8A6mT/CxFdJx/c04JEctz4jf8YZaVS2px34j7NXRrlGlHkN/M2gnpL37ZpGRGVFLd3l8Ng==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-parameters@7.27.1': + resolution: {integrity: sha512-018KRk76HWKeZ5l4oTj2zPpSh+NbGdt0st5S6x0pga6HgrjBOJb24mMDHorFopOOd6YHkLgOZ+zaCjZGPO4aKg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-property-literals@7.27.1': + resolution: {integrity: sha512-oThy3BCuCha8kDZ8ZkgOg2exvPYUlprMukKQXI1r1pJ47NCvxfkEy8vK+r/hT9nF0Aa4H1WUPZZjHTFtAhGfmQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-react-display-name@7.27.1': + resolution: {integrity: sha512-p9+Vl3yuHPmkirRrg021XiP+EETmPMQTLr6Ayjj85RLNEbb3Eya/4VI0vAdzQG9SEAl2Lnt7fy5lZyMzjYoZQQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-react-jsx@7.27.1': + resolution: {integrity: sha512-2KH4LWGSrJIkVf5tSiBFYuXDAoWRq2MMwgivCf+93dd0GQi8RXLjKA/0EvRnVV5G0hrHczsquXuD01L8s6dmBw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-shorthand-properties@7.27.1': + resolution: {integrity: sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-spread@7.27.1': + resolution: {integrity: sha512-kpb3HUqaILBJcRFVhFUs6Trdd4mkrzcGXss+6/mxUd273PfbWqSDHRzMT2234gIg2QYfAjvXLSquP1xECSg09Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-template-literals@7.27.1': + resolution: {integrity: sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/runtime@7.27.3': + resolution: {integrity: sha512-7EYtGezsdiDMyY80+65EzwiGmcJqpmcZCojSXaRgdrBaGtWTgDZKq69cPIVped6MkIM78cTQ2GOiEYjwOlG4xw==} + engines: {node: '>=6.9.0'} + '@babel/template@7.27.2': resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==} engines: {node: '>=6.9.0'} @@ -319,6 +550,10 @@ packages: resolution: {integrity: sha512-+EzkxvLNfiUeKMgy/3luqfsCWFRXLb7U6wNQTk60tovuckwB15B191tJWvpp4HjiQWdJkCxO3Wbvc6jlk3Xb2Q==} engines: {node: '>=6.9.0'} + '@babel/types@7.27.3': + resolution: {integrity: sha512-Y1GkI4ktrtvmawoSq+4FCVHNryea6uR+qUQy0AGxLSsjCX0nVmkYQMBLHDkXZuo5hGx7eYdnIaslsdBFm7zbUw==} + engines: {node: '>=6.9.0'} + '@bcoe/v8-coverage@0.2.3': resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} @@ -330,6 +565,18 @@ packages: resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} engines: {node: '>=12'} + '@envelop/core@5.2.3': + resolution: {integrity: sha512-KfoGlYD/XXQSc3BkM1/k15+JQbkQ4ateHazeZoWl9P71FsLTDXSjGy6j7QqfhpIDSbxNISqhPMfZHYSbDFOofQ==} + engines: {node: '>=18.0.0'} + + '@envelop/instrumentation@1.0.0': + resolution: {integrity: sha512-cxgkB66RQB95H3X27jlnxCRNTmPuSTgmBAq6/4n2Dtv4hsk4yz8FadA1ggmd0uZzvKqWD6CR+WFgTjhDqg7eyw==} + engines: {node: '>=18.0.0'} + + '@envelop/types@5.2.1': + resolution: {integrity: sha512-CsFmA3u3c2QoLDTfEpGr4t25fjMU31nyvse7IzWTvb0ZycuPjMjb0fjlheh+PbhBYb9YLugnT2uY6Mwcg1o+Zg==} + engines: {node: '>=18.0.0'} + '@eslint-community/eslint-utils@4.7.0': resolution: {integrity: sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -368,6 +615,283 @@ packages: resolution: {integrity: sha512-0J+zgWxHN+xXONWIyPWKFMgVuJoZuGiIFu8yxk7RJjxkzpGmyja5wRFqZIVtjDVOQpV+Rw0iOAjYPE2eQyjr0w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@fastify/busboy@3.1.1': + resolution: {integrity: sha512-5DGmA8FTdB2XbDeEwc/5ZXBl6UbBAyBOOLlPuBnZ/N1SwdH9Ii+cOX3tBROlDgcTXxjOYnLMVoKk9+FXAw0CJw==} + + '@gql.tada/internal@1.0.8': + resolution: {integrity: sha512-XYdxJhtHC5WtZfdDqtKjcQ4d7R1s0d1rnlSs3OcBEUbYiPoJJfZU7tWsVXuv047Z6msvmr4ompJ7eLSK5Km57g==} + peerDependencies: + graphql: ^15.5.0 || ^16.0.0 || ^17.0.0 + typescript: ^5.0.0 + + '@graphql-codegen/add@5.0.3': + resolution: {integrity: sha512-SxXPmramkth8XtBlAHu4H4jYcYXM/o3p01+psU+0NADQowA8jtYkK6MW5rV6T+CxkEaNZItfSmZRPgIuypcqnA==} + 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 + + '@graphql-codegen/cli@5.0.6': + resolution: {integrity: sha512-1r5dtZ2l1jiCF/4qLMTcT7mEoWWWeqQlmn7HcPHgnV/OXIEodwox7XRGAmOKUygoabRjFF3S0jd0TWbkq5Otsw==} + engines: {node: '>=16'} + hasBin: true + 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 + + '@graphql-codegen/client-preset@4.8.1': + resolution: {integrity: sha512-XLF2V7WKLnepvrGE44JP+AvjS+Oz9AT0oYgTl/6d9btQ+2VYFcmwQPjNAuMVHipqE9I6h8hSEfH9hUrzUptB1g==} + engines: {node: '>=16'} + 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 + graphql-sock: ^1.0.0 + peerDependenciesMeta: + graphql-sock: + optional: true + + '@graphql-codegen/core@4.0.2': + resolution: {integrity: sha512-IZbpkhwVqgizcjNiaVzNAzm/xbWT6YnGgeOLwVjm4KbJn3V2jchVtuzHH09G5/WkkLSk2wgbXNdwjM41JxO6Eg==} + 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 + + '@graphql-codegen/gql-tag-operations@4.0.17': + resolution: {integrity: sha512-2pnvPdIG6W9OuxkrEZ6hvZd142+O3B13lvhrZ48yyEBh2ujtmKokw0eTwDHtlXUqjVS0I3q7+HB2y12G/m69CA==} + engines: {node: '>=16'} + 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 + + '@graphql-codegen/plugin-helpers@3.1.2': + resolution: {integrity: sha512-emOQiHyIliVOIjKVKdsI5MXj312zmRDwmHpyUTZMjfpvxq/UVAHUJIVdVf+lnjjrI+LXBTgMlTWTgHQfmICxjg==} + 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 + + '@graphql-codegen/plugin-helpers@5.1.0': + resolution: {integrity: sha512-Y7cwEAkprbTKzVIe436TIw4w03jorsMruvCvu0HJkavaKMQbWY+lQ1RIuROgszDbxAyM35twB5/sUvYG5oW+yg==} + engines: {node: '>=16'} + 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 + + '@graphql-codegen/schema-ast@4.1.0': + resolution: {integrity: sha512-kZVn0z+th9SvqxfKYgztA6PM7mhnSZaj4fiuBWvMTqA+QqQ9BBed6Pz41KuD/jr0gJtnlr2A4++/0VlpVbCTmQ==} + 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 + + '@graphql-codegen/typed-document-node@5.1.1': + resolution: {integrity: sha512-Bp/BrMZDKRwzuVeLv+pSljneqONM7gqu57ZaV34Jbncu2hZWMRDMfizTKghoEwwZbRCYYfJO9tA0sYVVIfI1kg==} + engines: {node: '>=16'} + 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 + + '@graphql-codegen/typescript-graphql-request@6.3.0': + resolution: {integrity: sha512-IX42XakdcbGosIQo0jkH/4Tj5hk5smDmACYHMJbuSAA9vlcJNHkl3LGyG1Ggy2qVSI20nmNMaxpTg74SSyb4Yg==} + engines: {node: '>= 16.0.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 + graphql-request: ^6.0.0 || ^7.0.0 + graphql-tag: ^2.0.0 + + '@graphql-codegen/typescript-operations@4.6.1': + resolution: {integrity: sha512-k92laxhih7s0WZ8j5WMIbgKwhe64C0As6x+PdcvgZFMudDJ7rPJ/hFqJ9DCRxNjXoHmSjnr6VUuQZq4lT1RzCA==} + engines: {node: '>=16'} + 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 + graphql-sock: ^1.0.0 + peerDependenciesMeta: + graphql-sock: + optional: true + + '@graphql-codegen/typescript@4.1.6': + resolution: {integrity: sha512-vpw3sfwf9A7S+kIUjyFxuvrywGxd4lmwmyYnnDVjVE4kSQ6Td3DpqaPTy8aNQ6O96vFoi/bxbZS2BW49PwSUUA==} + engines: {node: '>=16'} + peerDependencies: + graphql: ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 + + '@graphql-codegen/visitor-plugin-common@2.13.8': + resolution: {integrity: sha512-IQWu99YV4wt8hGxIbBQPtqRuaWZhkQRG2IZKbMoSvh0vGeWb3dB0n0hSgKaOOxDY+tljtOf9MTcUYvJslQucMQ==} + 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 + + '@graphql-codegen/visitor-plugin-common@5.8.0': + resolution: {integrity: sha512-lC1E1Kmuzi3WZUlYlqB4fP6+CvbKH9J+haU1iWmgsBx5/sO2ROeXJG4Dmt8gP03bI2BwjiwV5WxCEMlyeuzLnA==} + engines: {node: '>=16'} + 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 + + '@graphql-hive/signal@1.0.0': + resolution: {integrity: sha512-RiwLMc89lTjvyLEivZ/qxAC5nBHoS2CtsWFSOsN35sxG9zoo5Z+JsFHM8MlvmO9yt+MJNIyC5MLE1rsbOphlag==} + engines: {node: '>=18.0.0'} + + '@graphql-tools/apollo-engine-loader@8.0.20': + resolution: {integrity: sha512-m5k9nXSyjq31yNsEqDXLyykEjjn3K3Mo73oOKI+Xjy8cpnsgbT4myeUJIYYQdLrp7fr9Y9p7ZgwT5YcnwmnAbA==} + engines: {node: '>=16.0.0'} + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + + '@graphql-tools/batch-execute@9.0.16': + resolution: {integrity: sha512-sLAzEPrmrMTJrlNqmmsc34DtMA//FsoTsGC3V5bHA+EnNlwbwhsSQBSNXvIwsPLRSRwSjGKOpDG7KSxldDe2Rg==} + engines: {node: '>=18.0.0'} + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + + '@graphql-tools/code-file-loader@8.1.20': + resolution: {integrity: sha512-GzIbjjWJIc04KWnEr8VKuPe0FA2vDTlkaeub5p4lLimljnJ6C0QSkOyCUnFmsB9jetQcHm0Wfmn/akMnFUG+wA==} + engines: {node: '>=16.0.0'} + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + + '@graphql-tools/delegate@10.2.18': + resolution: {integrity: sha512-UynhjLwBZUapjNSHJ7FhGMd7/sRjqB7nk6EcYDZFWQkACTaQKa14Vkv2y2O6rEu61xQxP3/E1+fr/mLn46Zf9A==} + engines: {node: '>=18.0.0'} + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + + '@graphql-tools/documents@1.0.1': + resolution: {integrity: sha512-aweoMH15wNJ8g7b2r4C4WRuJxZ0ca8HtNO54rkye/3duxTkW4fGBEutCx03jCIr5+a1l+4vFJNP859QnAVBVCA==} + engines: {node: '>=16.0.0'} + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + + '@graphql-tools/executor-common@0.0.4': + resolution: {integrity: sha512-SEH/OWR+sHbknqZyROCFHcRrbZeUAyjCsgpVWCRjqjqRbiJiXq6TxNIIOmpXgkrXWW/2Ev4Wms6YSGJXjdCs6Q==} + engines: {node: '>=18.0.0'} + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + + '@graphql-tools/executor-graphql-ws@2.0.5': + resolution: {integrity: sha512-gI/D9VUzI1Jt1G28GYpvm5ckupgJ5O8mi5Y657UyuUozX34ErfVdZ81g6oVcKFQZ60LhCzk7jJeykK48gaLhDw==} + engines: {node: '>=18.0.0'} + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + + '@graphql-tools/executor-http@1.3.3': + resolution: {integrity: sha512-LIy+l08/Ivl8f8sMiHW2ebyck59JzyzO/yF9SFS4NH6MJZUezA1xThUXCDIKhHiD56h/gPojbkpcFvM2CbNE7A==} + engines: {node: '>=18.0.0'} + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + + '@graphql-tools/executor-legacy-ws@1.1.17': + resolution: {integrity: sha512-TvltY6eL4DY1Vt66Z8kt9jVmNcI+WkvVPQZrPbMCM3rv2Jw/sWvSwzUBezRuWX0sIckMifYVh23VPcGBUKX/wg==} + engines: {node: '>=16.0.0'} + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + + '@graphql-tools/executor@1.4.7': + resolution: {integrity: sha512-U0nK9jzJRP9/9Izf1+0Gggd6K6RNRsheFo1gC/VWzfnsr0qjcOSS9qTjY0OTC5iTPt4tQ+W5Zpw/uc7mebI6aA==} + engines: {node: '>=16.0.0'} + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + + '@graphql-tools/git-loader@8.0.24': + resolution: {integrity: sha512-ypLC9N2bKNC0QNbrEBTbWKwbV607f7vK2rSGi9uFeGr8E29tWplo6or9V/+TM0ZfIkUsNp/4QX/zKTgo8SbwQg==} + engines: {node: '>=16.0.0'} + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + + '@graphql-tools/github-loader@8.0.20': + resolution: {integrity: sha512-Icch8bKZ1iP3zXCB9I0ded1hda9NPskSSalw7ZM21kXvLiOR5nZhdqPF65gCFkIKo+O4NR4Bp51MkKj+wl+vpg==} + engines: {node: '>=16.0.0'} + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + + '@graphql-tools/graphql-file-loader@8.0.20': + resolution: {integrity: sha512-inds4My+JJxmg5mxKWYtMIJNRxa7MtX+XIYqqD/nu6G4LzQ5KGaBJg6wEl103KxXli7qNOWeVAUmEjZeYhwNEg==} + engines: {node: '>=16.0.0'} + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + + '@graphql-tools/graphql-tag-pluck@8.3.19': + resolution: {integrity: sha512-LEw/6IYOUz48HjbWntZXDCzSXsOIM1AyWZrlLoJOrA8QAlhFd8h5Tny7opCypj8FO9VvpPFugWoNDh5InPOEQA==} + engines: {node: '>=16.0.0'} + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + + '@graphql-tools/import@7.0.19': + resolution: {integrity: sha512-Xtku8G4bxnrr6I3hVf8RrBFGYIbQ1OYVjl7jgcy092aBkNZvy1T6EDmXmYXn5F+oLd9Bks3K3WaMm8gma/nM/Q==} + engines: {node: '>=16.0.0'} + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + + '@graphql-tools/json-file-loader@8.0.18': + resolution: {integrity: sha512-JjjIxxewgk8HeMR3npR3YbOkB7fxmdgmqB9kZLWdkRKBxrRXVzhryyq+mhmI0Evzt6pNoHIc3vqwmSctG2sddg==} + engines: {node: '>=16.0.0'} + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + + '@graphql-tools/load@8.1.0': + resolution: {integrity: sha512-OGfOm09VyXdNGJS/rLqZ6ztCiG2g6AMxhwtET8GZXTbnjptFc17GtKwJ3Jv5w7mjJ8dn0BHydvIuEKEUK4ciYw==} + engines: {node: '>=16.0.0'} + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + + '@graphql-tools/merge@9.0.24': + resolution: {integrity: sha512-NzWx/Afl/1qHT3Nm1bghGG2l4jub28AdvtG11PoUlmjcIjnFBJMv4vqL0qnxWe8A82peWo4/TkVdjJRLXwgGEw==} + engines: {node: '>=16.0.0'} + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + + '@graphql-tools/optimize@1.4.0': + resolution: {integrity: sha512-dJs/2XvZp+wgHH8T5J2TqptT9/6uVzIYvA6uFACha+ufvdMBedkfR4b4GbT8jAKLRARiqRTxy3dctnwkTM2tdw==} + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + + '@graphql-tools/optimize@2.0.0': + resolution: {integrity: sha512-nhdT+CRGDZ+bk68ic+Jw1OZ99YCDIKYA5AlVAnBHJvMawSx9YQqQAIj4refNc1/LRieGiuWvhbG3jvPVYho0Dg==} + engines: {node: '>=16.0.0'} + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + + '@graphql-tools/prisma-loader@8.0.17': + resolution: {integrity: sha512-fnuTLeQhqRbA156pAyzJYN0KxCjKYRU5bz1q/SKOwElSnAU4k7/G1kyVsWLh7fneY78LoMNH5n+KlFV8iQlnyg==} + engines: {node: '>=16.0.0'} + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + + '@graphql-tools/relay-operation-optimizer@6.5.18': + resolution: {integrity: sha512-mc5VPyTeV+LwiM+DNvoDQfPqwQYhPV/cl5jOBjTgSniyaq8/86aODfMkrE2OduhQ5E00hqrkuL2Fdrgk0w1QJg==} + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + + '@graphql-tools/relay-operation-optimizer@7.0.19': + resolution: {integrity: sha512-xnjLpfzw63yIX1bo+BVh4j1attSwqEkUbpJ+HAhdiSUa3FOQFfpWgijRju+3i87CwhjBANqdTZbcsqLT1hEXig==} + engines: {node: '>=16.0.0'} + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + + '@graphql-tools/schema@10.0.23': + resolution: {integrity: sha512-aEGVpd1PCuGEwqTXCStpEkmheTHNdMayiIKH1xDWqYp9i8yKv9FRDgkGrY4RD8TNxnf7iII+6KOBGaJ3ygH95A==} + engines: {node: '>=16.0.0'} + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + + '@graphql-tools/url-loader@8.0.31': + resolution: {integrity: sha512-QGP3py6DAdKERHO5D38Oi+6j+v0O3rkBbnLpyOo87rmIRbwE6sOkL5JeHegHs7EEJ279fBX6lMt8ry0wBMGtyA==} + engines: {node: '>=16.0.0'} + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + + '@graphql-tools/utils@10.8.6': + resolution: {integrity: sha512-Alc9Vyg0oOsGhRapfL3xvqh1zV8nKoFUdtLhXX7Ki4nClaIJXckrA86j+uxEuG3ic6j4jlM1nvcWXRn/71AVLQ==} + engines: {node: '>=16.0.0'} + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + + '@graphql-tools/utils@9.2.1': + resolution: {integrity: sha512-WUw506Ql6xzmOORlriNrD6Ugx+HjVgYxt9KCXD9mHAak+eaXSwuGGPyE60hy9xaDEoXKBsG7SkG69ybitaVl6A==} + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + + '@graphql-tools/wrap@10.0.36': + resolution: {integrity: sha512-sLm9j/T6mlKklSMOCDjrGMi39MRAUzRXsc8tTugZZl0yJEtfU7tX1UaYJQNVsar7vkjLofaWtS7Jf6vcWgGYgQ==} + engines: {node: '>=18.0.0'} + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + + '@graphql-typed-document-node/core@3.2.0': + resolution: {integrity: sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ==} + 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 + '@humanfs/core@0.19.1': resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} engines: {node: '>=18.18.0'} @@ -828,6 +1352,88 @@ packages: '@paralleldrive/cuid2@2.2.2': resolution: {integrity: sha512-ZOBkgDwEdoYVlSeRbYYXs0S9MejQofiVYoTbKzy/6GQa39/q5tQU2IX46+shYnUkpEl3wc+J6wRlar7r2EK2xA==} + '@parcel/watcher-android-arm64@2.5.1': + resolution: {integrity: sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [android] + + '@parcel/watcher-darwin-arm64@2.5.1': + resolution: {integrity: sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [darwin] + + '@parcel/watcher-darwin-x64@2.5.1': + resolution: {integrity: sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [darwin] + + '@parcel/watcher-freebsd-x64@2.5.1': + resolution: {integrity: sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [freebsd] + + '@parcel/watcher-linux-arm-glibc@2.5.1': + resolution: {integrity: sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==} + engines: {node: '>= 10.0.0'} + cpu: [arm] + os: [linux] + + '@parcel/watcher-linux-arm-musl@2.5.1': + resolution: {integrity: sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==} + engines: {node: '>= 10.0.0'} + cpu: [arm] + os: [linux] + + '@parcel/watcher-linux-arm64-glibc@2.5.1': + resolution: {integrity: sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [linux] + + '@parcel/watcher-linux-arm64-musl@2.5.1': + resolution: {integrity: sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [linux] + + '@parcel/watcher-linux-x64-glibc@2.5.1': + resolution: {integrity: sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [linux] + + '@parcel/watcher-linux-x64-musl@2.5.1': + resolution: {integrity: sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [linux] + + '@parcel/watcher-win32-arm64@2.5.1': + resolution: {integrity: sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [win32] + + '@parcel/watcher-win32-ia32@2.5.1': + resolution: {integrity: sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ==} + engines: {node: '>= 10.0.0'} + cpu: [ia32] + os: [win32] + + '@parcel/watcher-win32-x64@2.5.1': + resolution: {integrity: sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [win32] + + '@parcel/watcher@2.5.1': + resolution: {integrity: sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==} + engines: {node: '>= 10.0.0'} + '@pkgr/core@0.2.4': resolution: {integrity: sha512-ROFF39F6ZrnzSUEmQQZUar0Jt4xVoP9WnDRdWwF4NNcXs3xBTLgBUDoOwW141y1jP+S8nahIbdxbFC7IShw9Iw==} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} @@ -862,6 +1468,9 @@ packages: '@prisma/get-platform@6.8.2': resolution: {integrity: sha512-vXSxyUgX3vm1Q70QwzwkjeYfRryIvKno1SXbIqwSptKwqKzskINnDUcx85oX+ys6ooN2ATGSD0xN2UTfg6Zcow==} + '@repeaterjs/repeater@3.0.6': + resolution: {integrity: sha512-Javneu5lsuhwNCryN+pXH93VPQ8g0dBX7wItHFgYiwQmzE1sVdg5tWHiOgHywzL2W21XQopa7IwIEnNbmeUJYA==} + '@sec-ant/readable-stream@0.4.1': resolution: {integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==} @@ -1047,6 +1656,9 @@ packages: '@types/jest@29.5.14': resolution: {integrity: sha512-ZN+4sdnLUbo8EVvVc2ao0GFW6oVrQRPn4K2lglySj7APvSrgzxHiNNK99us4WDMi57xxA2yggblIAMNhXOotLQ==} + '@types/js-yaml@4.0.9': + resolution: {integrity: sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==} + '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} @@ -1083,6 +1695,9 @@ packages: '@types/supertest@6.0.3': resolution: {integrity: sha512-8WzXq62EXFhJ7QsH3Ocb/iKQ/Ty9ZVWnVzoTKc9tyyFRRF3a74Tk2+TLFgaFFw364Ere+npzHKEJ6ga2LzIL7w==} + '@types/ws@8.18.1': + resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} + '@types/yargs-parser@21.0.3': resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} @@ -1181,6 +1796,22 @@ packages: '@webassemblyjs/wast-printer@1.14.1': resolution: {integrity: sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==} + '@whatwg-node/disposablestack@0.0.6': + resolution: {integrity: sha512-LOtTn+JgJvX8WfBVJtF08TGrdjuFzGJc4mkP8EdDI8ADbvO7kiexYep1o8dwnt0okb0jYclCDXF13xU7Ge4zSw==} + engines: {node: '>=18.0.0'} + + '@whatwg-node/fetch@0.10.8': + resolution: {integrity: sha512-Rw9z3ctmeEj8QIB9MavkNJqekiu9usBCSMZa+uuAvM0lF3v70oQVCXNppMIqaV6OTZbdaHF1M2HLow58DEw+wg==} + engines: {node: '>=18.0.0'} + + '@whatwg-node/node-fetch@0.7.21': + resolution: {integrity: sha512-QC16IdsEyIW7kZd77aodrMO7zAoDyyqRCTLg+qG4wqtP4JV9AA+p7/lgqMdD29XyiYdVvIdFrfI9yh7B1QvRvw==} + engines: {node: '>=18.0.0'} + + '@whatwg-node/promise-helpers@1.3.2': + resolution: {integrity: sha512-Nst5JdK47VIl9UcGwtv2Rcgyn5lWtZ0/mhRQ4G8NN2isxpq2TO30iqHzmwoJycjWuyUfg3GFXqP/gFHXeV57IA==} + engines: {node: '>=16.0.0'} + '@xhmikosr/archive-type@7.0.0': resolution: {integrity: sha512-sIm84ZneCOJuiy3PpWR5bxkx3HaNt1pqaN+vncUBZIlPZCq8ASZH+hBVdu5H8znR7qYC6sKwx+ie2Q7qztJTxA==} engines: {node: ^14.14.0 || >=16.0.0} @@ -1245,6 +1876,14 @@ packages: engines: {node: '>=0.4.0'} hasBin: true + agent-base@7.1.3: + resolution: {integrity: sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==} + engines: {node: '>= 14'} + + aggregate-error@3.1.0: + resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} + engines: {node: '>=8'} + ajv-formats@2.1.1: resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==} peerDependencies: @@ -1331,15 +1970,27 @@ packages: array-timsort@1.0.3: resolution: {integrity: sha512-/+3GRL7dDAGEfM6TseQk/U+mi18TU2Ms9I3UlLdUMhz2hbvGNTKdj9xniwXfUqgYhHxRx0+8UnKkvlNwVU+cWQ==} + array-union@2.1.0: + resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} + engines: {node: '>=8'} + asap@2.0.6: resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==} + astral-regex@2.0.0: + resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} + engines: {node: '>=8'} + async@3.2.6: resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==} asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + auto-bind@4.0.0: + resolution: {integrity: sha512-Hdw8qdNiqdJ8LqT0iK0sVzkFbzg6fhnQqqfWhBDxcHZvU75+B+ayzTy8x+k5Ix0Y92XOhOUlx74ps+bA6BeYMQ==} + engines: {node: '>=8'} + b4a@1.6.7: resolution: {integrity: sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg==} @@ -1357,11 +2008,19 @@ packages: resolution: {integrity: sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + babel-plugin-syntax-trailing-function-commas@7.0.0-beta.0: + resolution: {integrity: sha512-Xj9XuRuz3nTSbaTXWv3itLOcxyF4oPD8douBBmj7U9BBC6nEBYfyOJYQMf/8PJAFotC62UY5dFfIGEPr7WswzQ==} + babel-preset-current-node-syntax@1.1.0: resolution: {integrity: sha512-ldYss8SbBlWva1bs28q78Ju5Zq1F+8BrqBZZ0VFhLBvhh6lCpC2o3gDJi/5DRLs9FgYZCnmPYIVFU4lRXCkyUw==} peerDependencies: '@babel/core': ^7.0.0 + babel-preset-fbjs@3.4.0: + resolution: {integrity: sha512-9ywCsCvo1ojrw0b+XYk7aFvTH6D9064t0RIL1rtMf3nsa02Xw41MS7sZw216Im35xj/UY0PDBQsa1brUDDF1Ow==} + peerDependencies: + '@babel/core': ^7.0.0 + babel-preset-jest@29.6.3: resolution: {integrity: sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -1451,6 +2110,9 @@ packages: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} + camel-case@4.1.2: + resolution: {integrity: sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==} + camelcase@5.3.1: resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} engines: {node: '>=6'} @@ -1462,10 +2124,19 @@ packages: caniuse-lite@1.0.30001718: resolution: {integrity: sha512-AflseV1ahcSunK53NfEs9gFWgOEmzr0f+kaMFA4xiLZlr9Hzt7HxcSpIFcnNCUkz6R6dWKa54rUz3HUmI3nVcw==} + capital-case@1.0.4: + resolution: {integrity: sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A==} + chalk@4.1.2: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} + change-case-all@1.0.15: + resolution: {integrity: sha512-3+GIFhk3sNuvFAJKU46o26OdzudQlPNBCu1ZQi3cMeMHhty1bhDxu2WrEilVNYaGvqUtR1VSigFcJOiS13dRhQ==} + + change-case@4.1.2: + resolution: {integrity: sha512-bSxY2ws9OtviILG1EiY5K7NNxkqg/JnRnFxLtKQ96JaviiIxi7djMrSd0ECT9AC+lttClmYwKw53BWpOMblo7A==} + char-regex@1.0.2: resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} engines: {node: '>=10'} @@ -1488,6 +2159,10 @@ packages: cjs-module-lexer@1.4.3: resolution: {integrity: sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==} + clean-stack@2.2.0: + resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} + engines: {node: '>=6'} + cli-cursor@3.1.0: resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} engines: {node: '>=8'} @@ -1500,10 +2175,21 @@ packages: resolution: {integrity: sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==} engines: {node: 10.* || >= 12.*} + cli-truncate@2.1.0: + resolution: {integrity: sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==} + engines: {node: '>=8'} + + cli-width@3.0.0: + resolution: {integrity: sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==} + engines: {node: '>= 10'} + cli-width@4.1.0: resolution: {integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==} engines: {node: '>= 12'} + cliui@6.0.0: + resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==} + cliui@8.0.1: resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} engines: {node: '>=12'} @@ -1526,6 +2212,9 @@ packages: color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + colorette@2.0.20: + resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} + combined-stream@1.0.8: resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} engines: {node: '>= 0.8'} @@ -1549,6 +2238,10 @@ packages: resolution: {integrity: sha512-bKw/r35jR3HGt5PEPm1ljsQQGyCrR8sFGNiN5L+ykDHdpO8Smxkrkla9Yi6NkQyUrb8V54PGhfMs6NrIwtxtdw==} engines: {node: '>= 6'} + common-tags@1.8.2: + resolution: {integrity: sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==} + engines: {node: '>=4.0.0'} + component-emitter@1.3.1: resolution: {integrity: sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==} @@ -1563,6 +2256,9 @@ packages: resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} engines: {node: ^14.18.0 || >=16.10.0} + constant-case@3.0.4: + resolution: {integrity: sha512-I2hSBi7Vvs7BEuJDr5dDHfzb/Ruj3FyvFyh7KLilAjNQw3Be+xgqUBA2W6scVEcL0hL1dwPRtIqEPVUCKkSsyQ==} + content-disposition@0.5.4: resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} engines: {node: '>= 0.6'} @@ -1620,10 +2316,27 @@ packages: create-require@1.1.1: resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} + cross-fetch@3.2.0: + resolution: {integrity: sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q==} + + cross-inspect@1.0.1: + resolution: {integrity: sha512-Pcw1JTvZLSJH83iiGWt6fRcT+BjZlCDRVwYLbUcHzv/CRpB7r0MlSrGbIyQvVSNyGnbt7G4AXuyCiDR3POvZ1A==} + engines: {node: '>=16.0.0'} + cross-spawn@7.0.6: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} + data-uri-to-buffer@4.0.1: + resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==} + engines: {node: '>= 12'} + + dataloader@2.2.3: + resolution: {integrity: sha512-y2krtASINtPFS1rSDjacrFgn1dcUuoREVabwlOGOe4SdxenREqwjwjElAdwvbGM7kgZz9a3KVicWR7vcz8rnzA==} + + debounce@1.2.1: + resolution: {integrity: sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==} + debug@2.6.9: resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} peerDependencies: @@ -1641,6 +2354,10 @@ packages: supports-color: optional: true + decamelize@1.2.0: + resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} + engines: {node: '>=0.10.0'} + decompress-response@6.0.0: resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} engines: {node: '>=10'} @@ -1679,6 +2396,19 @@ packages: resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} engines: {node: '>= 0.8'} + dependency-graph@0.11.0: + resolution: {integrity: sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg==} + engines: {node: '>= 0.6.0'} + + detect-indent@6.1.0: + resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==} + engines: {node: '>=8'} + + detect-libc@1.0.3: + resolution: {integrity: sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==} + engines: {node: '>=0.10'} + hasBin: true + detect-newline@3.1.0: resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} engines: {node: '>=8'} @@ -1694,6 +2424,13 @@ packages: resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} engines: {node: '>=0.3.1'} + dir-glob@3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} + engines: {node: '>=8'} + + dot-case@3.0.4: + resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==} + dotenv-expand@12.0.1: resolution: {integrity: sha512-LaKRbou8gt0RNID/9RoI+J2rvXsBRPMV7p+ElHlPhcSARbCPDYcYG2s1TIzAfWv4YSgyY5taidWzzs31lNV3yQ==} engines: {node: '>=12'} @@ -1702,6 +2439,10 @@ packages: resolution: {integrity: sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==} engines: {node: '>=12'} + dset@3.1.4: + resolution: {integrity: sha512-2QF/g9/zTaPDc3BjNcVTGoBbXBgYfMTTceLaYcFJ/W9kggFUkhxD/hMEeuLKbugyef9SqAx8cpgwlIP/jinUTA==} + engines: {node: '>=4'} + dunder-proto@1.0.1: resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} engines: {node: '>= 0.4'} @@ -1767,6 +2508,10 @@ packages: escape-html@1.0.3: resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + escape-string-regexp@1.0.5: + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} + engines: {node: '>=0.8.0'} + escape-string-regexp@2.0.0: resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} engines: {node: '>=8'} @@ -1921,9 +2666,23 @@ packages: fb-watchman@2.0.2: resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==} + fbjs-css-vars@1.0.2: + resolution: {integrity: sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ==} + + fbjs@3.0.5: + resolution: {integrity: sha512-ztsSx77JBtkuMrEypfhgc3cI0+0h+svqeie7xHbh1k/IKdcydnvadp/mUaGgjAOXQmQSxsqgaRhS3q9fy+1kxg==} + + fetch-blob@3.2.0: + resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==} + engines: {node: ^12.20 || >= 14.13} + fflate@0.8.2: resolution: {integrity: sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==} + figures@3.2.0: + resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==} + engines: {node: '>=8'} + file-entry-cache@8.0.0: resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} engines: {node: '>=16.0.0'} @@ -1993,6 +2752,10 @@ packages: resolution: {integrity: sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==} engines: {node: '>= 6'} + formdata-polyfill@4.0.10: + resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} + engines: {node: '>=12.20.0'} + formidable@3.5.4: resolution: {integrity: sha512-YikH+7CUTOtP44ZTnUhR7Ic2UASBPOqmaRkRKxRbywPTe5VxF7RRCck4af9wutiZ/QKM5nME9Bie2fFaPz5Gug==} engines: {node: '>=14.0.0'} @@ -2083,6 +2846,10 @@ packages: resolution: {integrity: sha512-aibexHNbb/jiUSObBgpHLj+sIuUmJnYcgXBlrfsiDZ9rt4aF2TFRbyLgZ2iFQuVZ1K5Mx3FVkbKRSgKrbK3K2g==} engines: {node: '>=18'} + globby@11.1.0: + resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} + engines: {node: '>=10'} + gopd@1.2.0: resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} engines: {node: '>= 0.4'} @@ -2097,6 +2864,55 @@ packages: graphemer@1.4.0: resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + graphql-config@5.1.5: + resolution: {integrity: sha512-mG2LL1HccpU8qg5ajLROgdsBzx/o2M6kgI3uAmoaXiSH9PCUbtIyLomLqUtCFaAeG2YCFsl0M5cfQ9rKmDoMVA==} + 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 + + graphql-request@6.1.0: + resolution: {integrity: sha512-p+XPfS4q7aIpKVcgmnZKhMNqhltk20hfXtkaIkTfjjmiKMJ5xrt5c743cL03y/K7y1rg3WrIC49xGiEQ4mxdNw==} + peerDependencies: + graphql: 14 - 16 + + graphql-request@7.2.0: + resolution: {integrity: sha512-0GR7eQHBFYz372u9lxS16cOtEekFlZYB2qOyq8wDvzRmdRSJ0mgUVX1tzNcIzk3G+4NY+mGtSz411wZdeDF/+A==} + peerDependencies: + graphql: 14 - 16 + + graphql-tag@2.12.6: + resolution: {integrity: sha512-FdSNcu2QQcWnM2VNvSCCDCVS5PpPqpzgFT8+GXzqJuoDd0CBncxCY278u4mhRO7tMgo2JjgJA5aZ+nWSQ/Z+xg==} + 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 + + graphql-ws@6.0.5: + resolution: {integrity: sha512-HzYw057ch0hx2gZjkbgk1pur4kAtgljlWRP+Gccudqm3BRrTpExjWCQ9OHdIsq47Y6lHL++1lTvuQHhgRRcevw==} + engines: {node: '>=20'} + peerDependencies: + '@fastify/websocket': ^10 || ^11 + crossws: ~0.3 + graphql: ^15.10.1 || ^16 + uWebSockets.js: ^20 + ws: ^8 + peerDependenciesMeta: + '@fastify/websocket': + optional: true + crossws: + optional: true + uWebSockets.js: + optional: true + ws: + optional: true + + graphql@16.11.0: + resolution: {integrity: sha512-mS1lbMsxgQj6hge1XZ6p7GPhbrtFwUFYi3wRzXAC/FmYnyXMTvvI3td3rjmQ2u8ewXueaSvRPWaEcgVVOT9Jnw==} + engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0} + has-flag@4.0.0: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} @@ -2117,6 +2933,9 @@ packages: resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} engines: {node: '>= 0.4'} + header-case@2.0.4: + resolution: {integrity: sha512-H/vuk5TEEVZwrR0lp2zed9OCo1uAILMlx0JEMgC26rzyJJ3N1v6XkwHHXJQdR2doSjcGPM6OKPYoJgf0plJ11Q==} + html-escaper@2.0.2: resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} @@ -2127,10 +2946,18 @@ packages: resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} engines: {node: '>= 0.8'} + http-proxy-agent@7.0.2: + resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} + engines: {node: '>= 14'} + http2-wrapper@2.2.1: resolution: {integrity: sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==} engines: {node: '>=10.19.0'} + https-proxy-agent@7.0.6: + resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} + engines: {node: '>= 14'} + human-signals@2.1.0: resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} engines: {node: '>=10.17.0'} @@ -2154,10 +2981,18 @@ packages: resolution: {integrity: sha512-gJzzk+PQNznz8ysRrC0aOkBNVRBDtE1n53IqyqEf3PXrYwomFs5q4pGMizBMJF+ykh03insJ27hB8gSrD2Hn8A==} engines: {node: '>= 4'} + immutable@3.7.6: + resolution: {integrity: sha512-AizQPcaofEtO11RZhPPHBOJRdo/20MKQF9mBLnVkBoyHi1/zXK8fzVdnEpSV9gxqtnh6Qomfp3F0xT5qP/vThw==} + engines: {node: '>=0.8.0'} + import-fresh@3.3.1: resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} engines: {node: '>=6'} + import-from@4.0.0: + resolution: {integrity: sha512-P9J71vT5nLlDeV8FHs5nNxaLbrpfAV5cF5srvbZfpwpcJoM/xZR3hiv+q+SAnuSmuGbXMWud063iIMx/V/EWZQ==} + engines: {node: '>=12.2'} + import-local@3.2.0: resolution: {integrity: sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==} engines: {node: '>=8'} @@ -2167,6 +3002,10 @@ packages: resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} engines: {node: '>=0.8.19'} + indent-string@4.0.0: + resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} + engines: {node: '>=8'} + inflight@1.0.6: resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. @@ -2174,13 +3013,24 @@ packages: inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + inquirer@8.2.6: + resolution: {integrity: sha512-M1WuAmb7pn9zdFRtQYk26ZBoY043Sse0wVDdk4Bppr+JOXyQYybdtvK+l9wUibhtjdjvtoiNy8tk+EgsYIUqKg==} + engines: {node: '>=12.0.0'} + inspect-with-kind@1.0.5: resolution: {integrity: sha512-MAQUJuIo7Xqk8EVNP+6d3CKq9c80hi4tjIbIAT6lmGW9W6WzlHiu9PS8uSuUYU+Do+j1baiFp3H25XEVxDIG2g==} + invariant@2.2.4: + resolution: {integrity: sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==} + ipaddr.js@1.9.1: resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} engines: {node: '>= 0.10'} + is-absolute@1.0.0: + resolution: {integrity: sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==} + engines: {node: '>=0.10.0'} + is-arrayish@0.2.1: resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} @@ -2208,6 +3058,9 @@ packages: resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==} engines: {node: '>=8'} + is-lower-case@2.0.2: + resolution: {integrity: sha512-bVcMJy4X5Og6VZfdOZstSexlEy20Sr0k/p/b2IlQJlfdKAQuMpiv5w2Ccxb8sKdRUNAG1PnHVHjFSdRDVS6NlQ==} + is-number@7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} @@ -2219,6 +3072,10 @@ packages: is-promise@4.0.0: resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==} + is-relative@1.0.0: + resolution: {integrity: sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==} + engines: {node: '>=0.10.0'} + is-stream@2.0.1: resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} engines: {node: '>=8'} @@ -2227,16 +3084,32 @@ packages: resolution: {integrity: sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==} engines: {node: '>=18'} + is-unc-path@1.0.0: + resolution: {integrity: sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==} + engines: {node: '>=0.10.0'} + is-unicode-supported@0.1.0: resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} engines: {node: '>=10'} + is-upper-case@2.0.2: + resolution: {integrity: sha512-44pxmxAvnnAOwBg4tHPnkfvgjPwbc5QIsSstNU+YcJ1ovxVzCWpSGosPJOZh/a1tdl81fbgnLc9LLv+x2ywbPQ==} + + is-windows@1.0.2: + resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} + engines: {node: '>=0.10.0'} + isarray@1.0.0: resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + isomorphic-ws@5.0.0: + resolution: {integrity: sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw==} + peerDependencies: + ws: '*' + istanbul-lib-coverage@3.2.2: resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} engines: {node: '>=8'} @@ -2407,10 +3280,17 @@ packages: node-notifier: optional: true + jiti@1.21.7: + resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==} + hasBin: true + jiti@2.4.2: resolution: {integrity: sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==} hasBin: true + jose@5.10.0: + resolution: {integrity: sha512-s+3Al/p9g32Iq+oqXxkW//7jk2Vig6FF1CFqzVXoTUXt2qz89YWbL+OwS17NFYEvxC35n0FKeGO2LGYSxeM2Gg==} + js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} @@ -2442,6 +3322,10 @@ packages: json-stable-stringify-without-jsonify@1.0.1: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + json-to-pretty-yaml@1.2.2: + resolution: {integrity: sha512-rvm6hunfCcqegwYaG5T4yKJWxc9FXFgBVrcTZ4XfSVRwa5HA/Xs+vB/Eo9treYYHCeNM0nrSUr82V/M31Urc7A==} + engines: {node: '>= 0.2.0'} + json5@2.2.3: resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} engines: {node: '>=6'} @@ -2475,6 +3359,15 @@ packages: lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + listr2@4.0.5: + resolution: {integrity: sha512-juGHV1doQdpNT3GSTs9IUN43QJb7KHdF9uqg7Vufs/tG9VTzpFphqF4pm/ICdAABGQxsyNn9CiYA3StkI6jpwA==} + engines: {node: '>=12'} + peerDependencies: + enquirer: '>= 2.3.0 < 3' + peerDependenciesMeta: + enquirer: + optional: true + load-esm@1.0.2: resolution: {integrity: sha512-nVAvWk/jeyrWyXEAs84mpQCYccxRqgKY4OznLuJhJCa0XsPSfdOIr2zvBZEj3IHEHbX97jjscKRRV539bW0Gpw==} engines: {node: '>=13.2.0'} @@ -2497,6 +3390,9 @@ packages: lodash.merge@4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + lodash.sortby@4.7.0: + resolution: {integrity: sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==} + lodash@4.17.21: resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} @@ -2504,6 +3400,20 @@ packages: resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} engines: {node: '>=10'} + log-update@4.0.0: + resolution: {integrity: sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==} + engines: {node: '>=10'} + + loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + + lower-case-first@2.0.2: + resolution: {integrity: sha512-EVm/rR94FJTZi3zefZ82fLWab+GX14LJN4HrWBcuo6Evmsl9hEfnqxgcHCKb9q+mNf6EVdsjx/qucYFIIB84pg==} + + lower-case@2.0.2: + resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} + lowercase-keys@3.0.0: resolution: {integrity: sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -2528,6 +3438,10 @@ packages: makeerror@1.0.12: resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==} + map-cache@0.2.2: + resolution: {integrity: sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==} + engines: {node: '>=0.10.0'} + math-intrinsics@1.1.0: resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} engines: {node: '>= 0.4'} @@ -2555,6 +3469,15 @@ packages: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} + meros@1.3.0: + resolution: {integrity: sha512-2BNGOimxEz5hmjUG2FwoxCt5HN7BXdaWyFqEwxPTrJzVdABtrL4TiHTcsWSFAxPQ/tOnEaQEJh3qWq71QRMY+w==} + engines: {node: '>=13'} + peerDependencies: + '@types/node': '>=13' + peerDependenciesMeta: + '@types/node': + optional: true + methods@1.1.2: resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} engines: {node: '>= 0.6'} @@ -2632,6 +3555,9 @@ packages: resolution: {integrity: sha512-VzGiVigcG9zUAoCNU+xShztrlr1auZOlurXynNvO9GiWD1/mTBbUljOKY+qMeazBqXgRnjzeEgJI/wyjJUHg9A==} engines: {node: '>= 6.0.0'} + mute-stream@0.0.8: + resolution: {integrity: sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==} + mute-stream@2.0.0: resolution: {integrity: sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==} engines: {node: ^18.17.0 || >=20.5.0} @@ -2646,18 +3572,46 @@ packages: neo-async@2.6.2: resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} + no-case@3.0.4: + resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} + node-abort-controller@3.1.1: resolution: {integrity: sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==} + node-addon-api@7.1.1: + resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==} + + node-domexception@1.0.0: + resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} + engines: {node: '>=10.5.0'} + deprecated: Use your platform's native DOMException instead + node-emoji@1.11.0: resolution: {integrity: sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==} + node-fetch@2.7.0: + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + + node-fetch@3.3.2: + resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + node-int64@0.4.0: resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} node-releases@2.0.19: resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==} + normalize-path@2.1.1: + resolution: {integrity: sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==} + engines: {node: '>=0.10.0'} + normalize-path@3.0.0: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} @@ -2670,6 +3624,9 @@ packages: resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} engines: {node: '>=8'} + nullthrows@1.1.1: + resolution: {integrity: sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==} + object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} @@ -2725,6 +3682,10 @@ packages: resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} engines: {node: '>=10'} + p-map@4.0.0: + resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==} + engines: {node: '>=10'} + p-try@2.2.0: resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} engines: {node: '>=6'} @@ -2732,10 +3693,17 @@ packages: package-json-from-dist@1.0.1: resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + param-case@3.0.4: + resolution: {integrity: sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==} + parent-module@1.0.1: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} + parse-filepath@1.0.2: + resolution: {integrity: sha512-FwdRXKCohSVeXqwtYonZTXtbGJKrn+HNyWDYVcp5yuJlesTwNH4rsmRZ+GrKAPJ5bLpRxESMeS+Rl0VCHRvB2Q==} + engines: {node: '>=0.8'} + parse-json@5.2.0: resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} engines: {node: '>=8'} @@ -2744,6 +3712,9 @@ packages: resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} engines: {node: '>= 0.8'} + pascal-case@3.1.2: + resolution: {integrity: sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==} + passport-strategy@1.0.0: resolution: {integrity: sha512-CB97UUvDKJde2V0KDWWB3lyf6PC3FaZP7YxZ2G8OAtn9p4HI9j9JLP9qjOGZFvyl8uwNT8qM+hGnz/n16NI7oA==} engines: {node: '>= 0.4.0'} @@ -2752,6 +3723,9 @@ packages: resolution: {integrity: sha512-cPLl+qZpSc+ireUvt+IzqbED1cHHkDoVYMo30jbJIdOOjQ1MQYZBPiNvmi8UM6lJuOpTPXJGZQk0DtC4y61MYQ==} engines: {node: '>= 0.4.0'} + path-case@3.0.4: + resolution: {integrity: sha512-qO4qCFjXqVTrcbPt/hQfhTQ+VhFsqNKOPtytgNKkKxSoEp3XPUQ8ObFuePylOIok5gjn69ry8XiULxCwot3Wfg==} + path-exists@4.0.0: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} @@ -2767,6 +3741,14 @@ packages: path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + path-root-regex@0.1.2: + resolution: {integrity: sha512-4GlJ6rZDhQZFE0DPVKh0e9jmZ5egZfxTkp7bcRDuPlJXbAwhxcl2dINPUAsjLdejqaLsCeg8axcLjIbvBjN4pQ==} + engines: {node: '>=0.10.0'} + + path-root@0.1.1: + resolution: {integrity: sha512-QLcPegTHF11axjfojBIoDygmS2E3Lf+8+jI6wOVmNVenrKSo3mFdSGiIgdSHenczw3wPtlVMQaFVwGmM7BJdtg==} + engines: {node: '>=0.10.0'} + path-scurry@2.0.0: resolution: {integrity: sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==} engines: {node: 20 || >=22} @@ -2849,6 +3831,9 @@ packages: process-nextick-args@2.0.1: resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + promise@7.3.1: + resolution: {integrity: sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==} + prompts@2.4.2: resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} engines: {node: '>= 6'} @@ -2907,6 +3892,18 @@ packages: reflect-metadata@0.2.2: resolution: {integrity: sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==} + relay-runtime@12.0.0: + resolution: {integrity: sha512-QU6JKr1tMsry22DXNy9Whsq5rmvwr3LSZiiWV/9+DFpuTWvp+WFhobWMc8TC4OjKFfNhEZy7mOiqUAn5atQtug==} + + remedial@1.0.8: + resolution: {integrity: sha512-/62tYiOe6DzS5BqVsNpH/nkGlX45C/Sp6V+NtiN6JQNS1Viay7cWkazmRkrQrdFj2eshDe96SIQNIoMxqhzBOg==} + + remove-trailing-separator@1.1.0: + resolution: {integrity: sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==} + + remove-trailing-spaces@1.0.9: + resolution: {integrity: sha512-xzG7w5IRijvIkHIjDk65URsJJ7k4J95wmcArY5PRcmjldIOl7oTvG8+X2Ag690R7SfwiOcHrWZKVc1Pp5WIOzA==} + repeat-string@1.6.1: resolution: {integrity: sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==} engines: {node: '>=0.10'} @@ -2919,6 +3916,9 @@ packages: resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} engines: {node: '>=0.10.0'} + require-main-filename@2.0.0: + resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} + resolve-alpn@1.2.1: resolution: {integrity: sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==} @@ -2955,10 +3955,17 @@ packages: resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + rfdc@1.4.1: + resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==} + router@2.2.0: resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==} engines: {node: '>= 18'} + run-async@2.4.1: + resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==} + engines: {node: '>=0.12.0'} + run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} @@ -2985,6 +3992,9 @@ packages: resolution: {integrity: sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ==} engines: {node: '>= 10.13.0'} + scuid@1.1.0: + resolution: {integrity: sha512-MuCAyrGZcTLfQoH2XoBlQ8C6bzwN88XT/0slOGz0pn8+gIP85BOAfYa44ZXQUTOwRwPU0QvgU+V+OSajl/59Xg==} + seek-bzip@2.0.0: resolution: {integrity: sha512-SMguiTnYrhpLdk3PwfzHeotrcwi8bNV4iemL9tx9poR/yeaMYwB9VzR1w7b57DuWpuqR8n6oZboi0hj3AxZxQg==} hasBin: true @@ -3010,6 +4020,9 @@ packages: resolution: {integrity: sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==} engines: {node: '>= 18'} + sentence-case@3.0.4: + resolution: {integrity: sha512-8LS0JInaQMCRoQ7YUytAo/xUu5W2XnQxV2HI/6uM6U7CITS1RqPElr30V6uIqyMKM9lJGRVFy5/4CuzcixNYSg==} + serialize-javascript@6.0.2: resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} @@ -3017,6 +4030,12 @@ packages: resolution: {integrity: sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==} engines: {node: '>= 18'} + set-blocking@2.0.0: + resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} + + setimmediate@1.0.5: + resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==} + setprototypeof@1.2.0: resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} @@ -3028,6 +4047,10 @@ packages: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} + shell-quote@1.8.2: + resolution: {integrity: sha512-AzqKpGKjrj7EM6rKVQEPpB288oCfnrEIuyoT9cyF4nmGa7V8Zk6f7RRqYisX8X9m+Q7bd632aZW4ky7EhbQztA==} + engines: {node: '>= 0.4'} + side-channel-list@1.0.0: resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} engines: {node: '>= 0.4'} @@ -3051,6 +4074,9 @@ packages: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} engines: {node: '>=14'} + signedsource@1.0.0: + resolution: {integrity: sha512-6+eerH9fEnNmi/hyM1DXcRK3pWdoMQtlkQ+ns0ntzunjKqp5i3sKCc80ym8Fib3iaYhdJUOPdhlJWj1tvge2Ww==} + sisteransi@1.0.5: resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} @@ -3058,6 +4084,17 @@ packages: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} + slice-ansi@3.0.0: + resolution: {integrity: sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==} + engines: {node: '>=8'} + + slice-ansi@4.0.0: + resolution: {integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==} + engines: {node: '>=10'} + + snake-case@3.0.4: + resolution: {integrity: sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==} + sort-keys-length@1.0.1: resolution: {integrity: sha512-GRbEOUqCxemTAk/b32F2xa8wDTs+Z1QHOkbhJDQTvv/6G3ZkbJ+frYWsTcc7cBB3Fu4wy4XlLCuNtJuMn7Gsvw==} engines: {node: '>=0.10.0'} @@ -3080,6 +4117,9 @@ packages: resolution: {integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==} engines: {node: '>= 8'} + sponge-case@1.0.1: + resolution: {integrity: sha512-dblb9Et4DAtiZ5YSUZHLl4XhH4uK80GhAZrVXdN4O2P4gQ40Wa5UIOPUHlA/nFd2PLblBZWUioLMMAVrgpoYcA==} + sprintf-js@1.0.3: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} @@ -3098,6 +4138,9 @@ packages: streamx@2.22.0: resolution: {integrity: sha512-sLh1evHOzBy/iWRiR6d1zRcLao4gGZr3C1kzNz4fopCOKJb6xD9ub8Mpi9Mr1R6id5o43S+d93fI48UC5uM9aw==} + string-env-interpolation@1.0.1: + resolution: {integrity: sha512-78lwMoCcn0nNu8LszbP1UA7g55OeE4v7rCeWnM5B453rnNr4aq+5it3FEYtZrSEiMvHZOZ9Jlqb0OD0M2VInqg==} + string-length@4.0.2: resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==} engines: {node: '>=10'} @@ -3171,10 +4214,17 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} + swap-case@2.0.2: + resolution: {integrity: sha512-kc6S2YS/2yXbtkSMunBtKdah4VFETZ8Oh6ONSmSd9bRxhqTrtARUCBUiWXH3xVPpvR7tz2CSnkuXVE42EcGnMw==} + symbol-observable@4.0.0: resolution: {integrity: sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ==} engines: {node: '>=0.10'} + sync-fetch@0.6.0-2: + resolution: {integrity: sha512-c7AfkZ9udatCuAy9RSfiGPpeOKKUAUK5e1cXadLOGUjasdxqYqAK0jTNkM/FSEyJ3a5Ra27j/tw/PS0qLmaF/A==} + engines: {node: '>=18'} + synckit@0.11.5: resolution: {integrity: sha512-frqvfWyDA5VPVdrWfH24uM6SI/O8NLpVbIIJxb8t/a3YGsp4AW9CYgSKC0OaSEfexnp7Y1pVh2Y6IHO8ggGDmA==} engines: {node: ^14.18.0 || >=16.0.0} @@ -3217,6 +4267,13 @@ packages: through@2.3.8: resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} + timeout-signal@2.0.0: + resolution: {integrity: sha512-YBGpG4bWsHoPvofT6y/5iqulfXIiIErl5B0LdtHT1mGXDFTAhhRrbUpTvBgYbovr+3cKblya2WAOcpoy90XguA==} + engines: {node: '>=16'} + + title-case@3.0.3: + resolution: {integrity: sha512-e1zGYRvbffpcHIrnuqT0Dh+gEJtDaxDSoG4JAIpq4oDFyooziLBIiYQv0GBT4FUAnUop5uZ1hiIAj7oAF6sOCA==} + tmp@0.0.33: resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} engines: {node: '>=0.6.0'} @@ -3236,6 +4293,9 @@ packages: resolution: {integrity: sha512-lbDrTLVsHhOMljPscd0yitpozq7Ga2M5Cvez5AjGg8GASBjtt6iERCAJ93yommPmz62fb45oFIXHEZ3u9bfJEA==} engines: {node: '>=14.16'} + tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + tree-kill@1.2.2: resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} hasBin: true @@ -3277,6 +4337,9 @@ packages: typescript: '*' webpack: ^5.0.0 + ts-log@2.2.7: + resolution: {integrity: sha512-320x5Ggei84AxzlXp91QkIGSw5wgaLT6GeAH0KsqDmRZdVWW2OiSeVvElVoatk3f7nicwXlElXsoFkARiGE2yg==} + ts-node@10.9.2: resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==} hasBin: true @@ -3299,6 +4362,12 @@ packages: resolution: {integrity: sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==} engines: {node: '>=6'} + tslib@2.4.1: + resolution: {integrity: sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==} + + tslib@2.6.3: + resolution: {integrity: sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==} + tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} @@ -3341,6 +4410,10 @@ packages: engines: {node: '>=14.17'} hasBin: true + ua-parser-js@1.0.40: + resolution: {integrity: sha512-z6PJ8Lml+v3ichVojCiB8toQJBuwR42ySM4ezjXIqXK3M0HczmKQ3LF4rhU55PfD99KEEXQG6yb7iOMyvYuHew==} + hasBin: true + uid-safe@2.1.5: resolution: {integrity: sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==} engines: {node: '>= 0.8'} @@ -3356,6 +4429,10 @@ packages: unbzip2-stream@1.4.3: resolution: {integrity: sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==} + unc-path-regex@0.1.2: + resolution: {integrity: sha512-eXL4nmJT7oCpkZsHZUOJo8hcX3GbsiDOa0Qu9F646fi8dT3XuSVopVqAcEiVzSKKH7UoDti23wNX3qGFxcW5Qg==} + engines: {node: '>=0.10.0'} + undici-types@6.21.0: resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} @@ -3363,6 +4440,10 @@ packages: resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} engines: {node: '>= 10.0.0'} + unixify@1.0.0: + resolution: {integrity: sha512-6bc58dPYhCMHHuwxldQxO3RRNZ4eCogZ/st++0+fcC1nr0jiGUtAdBJ2qzmLQWSxbtz42pWt4QQMiZ9HvZf5cg==} + engines: {node: '>=0.10.0'} + unpipe@1.0.0: resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} engines: {node: '>= 0.8'} @@ -3373,9 +4454,18 @@ packages: peerDependencies: browserslist: '>= 4.21.0' + upper-case-first@2.0.2: + resolution: {integrity: sha512-514ppYHBaKwfJRK/pNC6c/OxfGa0obSnAl106u97Ed0I625Nin96KAjttZF6ZL3e1XLtphxnqrOi9iWgm+u+bg==} + + upper-case@2.0.2: + resolution: {integrity: sha512-KgdgDGJt2TpuwBUIjgG6lzw2GWFRCW9Qkfkiv0DxqHHLYJHmtmdUIKcZd8rHgFSjopVTlw6ggzCm1b8MFQwikg==} + uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + urlpattern-polyfill@10.1.0: + resolution: {integrity: sha512-IGjKp/o0NL3Bso1PymYURCJxMPNAf/ILOpendP9f5B6e1rTJgdgiOvgfoT8VxCAdY+Wisb9uhGaJJf3yZ2V9nw==} + util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} @@ -3404,6 +4494,13 @@ packages: wcwidth@1.0.1: resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} + web-streams-polyfill@3.3.3: + resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==} + engines: {node: '>= 8'} + + webidl-conversions@3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + webpack-node-externals@3.0.0: resolution: {integrity: sha512-LnL6Z3GGDPht/AigwRh2dvL9PQPFQ8skEpVrWZXLWBYmqcaojHNN0onvHzie6rq7EWKrrBfPYqNEzTJgiwEQDQ==} engines: {node: '>=6'} @@ -3422,6 +4519,16 @@ packages: webpack-cli: optional: true + whatwg-mimetype@4.0.0: + resolution: {integrity: sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==} + engines: {node: '>=18'} + + whatwg-url@5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + + which-module@2.0.1: + resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==} + which@2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} engines: {node: '>= 8'} @@ -3450,10 +4557,25 @@ packages: resolution: {integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + ws@8.18.2: + resolution: {integrity: sha512-DMricUmwGZUVr++AEAe2uiVM7UoO9MAVZMDu05UQOaUII0lp+zOzLLU4Xqh/JvTqklB1T4uELaaPBKyjE1r4fQ==} + 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 + xtend@4.0.2: resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} engines: {node: '>=0.4'} + y18n@4.0.3: + resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==} + y18n@5.0.8: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} @@ -3461,10 +4583,26 @@ packages: yallist@3.1.1: resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + yaml-ast-parser@0.0.43: + resolution: {integrity: sha512-2PTINUwsRqSd+s8XxKaJWQlUuEMHJQyEuh2edBbW8KNJz0SJPwUSD2zRWqezFEdN7IzAgeuYHFUCF7o8zRdZ0A==} + + yaml@2.8.0: + resolution: {integrity: sha512-4lLa/EcQCB0cJkyts+FpIRx5G/llPxfP6VQU5KByHEhLxY3IJCH0f0Hy1MHI8sClTvsIb8qwRJ6R/ZdlDJ/leQ==} + engines: {node: '>= 14.6'} + hasBin: true + + yargs-parser@18.1.3: + resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==} + engines: {node: '>=6'} + yargs-parser@21.1.1: resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} engines: {node: '>=12'} + yargs@15.4.1: + resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==} + engines: {node: '>=8'} + yargs@17.7.2: resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} engines: {node: '>=12'} @@ -3487,6 +4625,16 @@ packages: snapshots: + '@0no-co/graphql.web@1.1.2(graphql@16.11.0)': + optionalDependencies: + graphql: 16.11.0 + + '@0no-co/graphqlsp@1.12.16(graphql@16.11.0)(typescript@5.8.3)': + dependencies: + '@gql.tada/internal': 1.0.8(graphql@16.11.0)(typescript@5.8.3) + graphql: 16.11.0 + typescript: 5.8.3 + '@ampproject/remapping@2.3.0': dependencies: '@jridgewell/gen-mapping': 0.3.8 @@ -3546,6 +4694,46 @@ snapshots: transitivePeerDependencies: - chokidar + '@ardatan/relay-compiler@12.0.0(graphql@16.11.0)': + dependencies: + '@babel/core': 7.27.1 + '@babel/generator': 7.27.1 + '@babel/parser': 7.27.2 + '@babel/runtime': 7.27.3 + '@babel/traverse': 7.27.1 + '@babel/types': 7.27.1 + babel-preset-fbjs: 3.4.0(@babel/core@7.27.1) + chalk: 4.1.2 + fb-watchman: 2.0.2 + fbjs: 3.0.5 + glob: 7.2.3 + graphql: 16.11.0 + immutable: 3.7.6 + invariant: 2.2.4 + nullthrows: 1.1.1 + relay-runtime: 12.0.0 + signedsource: 1.0.0 + yargs: 15.4.1 + transitivePeerDependencies: + - encoding + - supports-color + + '@ardatan/relay-compiler@12.0.3(graphql@16.11.0)': + dependencies: + '@babel/generator': 7.27.1 + '@babel/parser': 7.27.2 + '@babel/runtime': 7.27.3 + chalk: 4.1.2 + fb-watchman: 2.0.2 + graphql: 16.11.0 + immutable: 3.7.6 + invariant: 2.2.4 + nullthrows: 1.1.1 + relay-runtime: 12.0.0 + signedsource: 1.0.0 + transitivePeerDependencies: + - encoding + '@babel/code-frame@7.27.1': dependencies: '@babel/helper-validator-identifier': 7.27.1 @@ -3582,6 +4770,10 @@ snapshots: '@jridgewell/trace-mapping': 0.3.25 jsesc: 3.1.0 + '@babel/helper-annotate-as-pure@7.27.3': + dependencies: + '@babel/types': 7.27.3 + '@babel/helper-compilation-targets@7.27.2': dependencies: '@babel/compat-data': 7.27.2 @@ -3590,6 +4782,26 @@ snapshots: lru-cache: 5.1.1 semver: 6.3.1 + '@babel/helper-create-class-features-plugin@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-member-expression-to-functions': 7.27.1 + '@babel/helper-optimise-call-expression': 7.27.1 + '@babel/helper-replace-supers': 7.27.1(@babel/core@7.27.1) + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/traverse': 7.27.1 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/helper-member-expression-to-functions@7.27.1': + dependencies: + '@babel/traverse': 7.27.1 + '@babel/types': 7.27.1 + transitivePeerDependencies: + - supports-color + '@babel/helper-module-imports@7.27.1': dependencies: '@babel/traverse': 7.27.1 @@ -3606,8 +4818,28 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/helper-optimise-call-expression@7.27.1': + dependencies: + '@babel/types': 7.27.1 + '@babel/helper-plugin-utils@7.27.1': {} + '@babel/helper-replace-supers@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-member-expression-to-functions': 7.27.1 + '@babel/helper-optimise-call-expression': 7.27.1 + '@babel/traverse': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/helper-skip-transparent-expression-wrappers@7.27.1': + dependencies: + '@babel/traverse': 7.27.1 + '@babel/types': 7.27.1 + transitivePeerDependencies: + - supports-color + '@babel/helper-string-parser@7.27.1': {} '@babel/helper-validator-identifier@7.27.1': {} @@ -3623,6 +4855,23 @@ snapshots: dependencies: '@babel/types': 7.27.1 + '@babel/plugin-proposal-class-properties@7.18.6(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-create-class-features-plugin': 7.27.1(@babel/core@7.27.1) + '@babel/helper-plugin-utils': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-proposal-object-rest-spread@7.20.7(@babel/core@7.27.1)': + dependencies: + '@babel/compat-data': 7.27.2 + '@babel/core': 7.27.1 + '@babel/helper-compilation-targets': 7.27.2 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.27.1) + '@babel/plugin-transform-parameters': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.27.1)': dependencies: '@babel/core': 7.27.1 @@ -3643,6 +4892,16 @@ snapshots: '@babel/core': 7.27.1 '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-flow@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-import-assertions@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-import-attributes@7.27.1(@babel/core@7.27.1)': dependencies: '@babel/core': 7.27.1 @@ -3703,11 +4962,144 @@ snapshots: '@babel/core': 7.27.1 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-typescript@7.27.1(@babel/core@7.27.1)': + '@babel/plugin-syntax-typescript@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-arrow-functions@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-block-scoped-functions@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-block-scoping@7.27.3(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-classes@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-compilation-targets': 7.27.2 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-replace-supers': 7.27.1(@babel/core@7.27.1) + '@babel/traverse': 7.27.1 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-computed-properties@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/template': 7.27.2 + + '@babel/plugin-transform-destructuring@7.27.3(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-flow-strip-types@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-flow': 7.27.1(@babel/core@7.27.1) + + '@babel/plugin-transform-for-of@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-function-name@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-compilation-targets': 7.27.2 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/traverse': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-literals@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-member-expression-literals@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-modules-commonjs@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-module-transforms': 7.27.1(@babel/core@7.27.1) + '@babel/helper-plugin-utils': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-object-super@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-replace-supers': 7.27.1(@babel/core@7.27.1) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-parameters@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-property-literals@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-react-display-name@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-react-jsx@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-module-imports': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.27.1) + '@babel/types': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-shorthand-properties@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-spread@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-template-literals@7.27.1(@babel/core@7.27.1)': dependencies: '@babel/core': 7.27.1 '@babel/helper-plugin-utils': 7.27.1 + '@babel/runtime@7.27.3': {} + '@babel/template@7.27.2': dependencies: '@babel/code-frame': 7.27.1 @@ -3731,6 +5123,11 @@ snapshots: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.27.1 + '@babel/types@7.27.3': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.27.1 + '@bcoe/v8-coverage@0.2.3': {} '@colors/colors@1.5.0': @@ -3740,6 +5137,23 @@ snapshots: dependencies: '@jridgewell/trace-mapping': 0.3.9 + '@envelop/core@5.2.3': + dependencies: + '@envelop/instrumentation': 1.0.0 + '@envelop/types': 5.2.1 + '@whatwg-node/promise-helpers': 1.3.2 + tslib: 2.8.1 + + '@envelop/instrumentation@1.0.0': + dependencies: + '@whatwg-node/promise-helpers': 1.3.2 + tslib: 2.8.1 + + '@envelop/types@5.2.1': + dependencies: + '@whatwg-node/promise-helpers': 1.3.2 + tslib: 2.8.1 + '@eslint-community/eslint-utils@4.7.0(eslint@9.27.0(jiti@2.4.2))': dependencies: eslint: 9.27.0(jiti@2.4.2) @@ -3784,6 +5198,519 @@ snapshots: '@eslint/core': 0.14.0 levn: 0.4.1 + '@fastify/busboy@3.1.1': {} + + '@gql.tada/internal@1.0.8(graphql@16.11.0)(typescript@5.8.3)': + dependencies: + '@0no-co/graphql.web': 1.1.2(graphql@16.11.0) + graphql: 16.11.0 + typescript: 5.8.3 + + '@graphql-codegen/add@5.0.3(graphql@16.11.0)': + dependencies: + '@graphql-codegen/plugin-helpers': 5.1.0(graphql@16.11.0) + graphql: 16.11.0 + tslib: 2.6.3 + + '@graphql-codegen/cli@5.0.6(@parcel/watcher@2.5.1)(@types/node@22.15.21)(graphql@16.11.0)(typescript@5.8.3)': + dependencies: + '@babel/generator': 7.27.1 + '@babel/template': 7.27.2 + '@babel/types': 7.27.1 + '@graphql-codegen/client-preset': 4.8.1(graphql@16.11.0) + '@graphql-codegen/core': 4.0.2(graphql@16.11.0) + '@graphql-codegen/plugin-helpers': 5.1.0(graphql@16.11.0) + '@graphql-tools/apollo-engine-loader': 8.0.20(graphql@16.11.0) + '@graphql-tools/code-file-loader': 8.1.20(graphql@16.11.0) + '@graphql-tools/git-loader': 8.0.24(graphql@16.11.0) + '@graphql-tools/github-loader': 8.0.20(@types/node@22.15.21)(graphql@16.11.0) + '@graphql-tools/graphql-file-loader': 8.0.20(graphql@16.11.0) + '@graphql-tools/json-file-loader': 8.0.18(graphql@16.11.0) + '@graphql-tools/load': 8.1.0(graphql@16.11.0) + '@graphql-tools/prisma-loader': 8.0.17(@types/node@22.15.21)(graphql@16.11.0) + '@graphql-tools/url-loader': 8.0.31(@types/node@22.15.21)(graphql@16.11.0) + '@graphql-tools/utils': 10.8.6(graphql@16.11.0) + '@whatwg-node/fetch': 0.10.8 + chalk: 4.1.2 + cosmiconfig: 8.3.6(typescript@5.8.3) + debounce: 1.2.1 + detect-indent: 6.1.0 + graphql: 16.11.0 + graphql-config: 5.1.5(@types/node@22.15.21)(graphql@16.11.0)(typescript@5.8.3) + inquirer: 8.2.6 + is-glob: 4.0.3 + jiti: 1.21.7 + json-to-pretty-yaml: 1.2.2 + listr2: 4.0.5 + log-symbols: 4.1.0 + micromatch: 4.0.8 + shell-quote: 1.8.2 + string-env-interpolation: 1.0.1 + ts-log: 2.2.7 + tslib: 2.8.1 + yaml: 2.8.0 + yargs: 17.7.2 + optionalDependencies: + '@parcel/watcher': 2.5.1 + transitivePeerDependencies: + - '@fastify/websocket' + - '@types/node' + - bufferutil + - cosmiconfig-toml-loader + - crossws + - encoding + - enquirer + - graphql-sock + - supports-color + - typescript + - uWebSockets.js + - utf-8-validate + + '@graphql-codegen/client-preset@4.8.1(graphql@16.11.0)': + dependencies: + '@babel/helper-plugin-utils': 7.27.1 + '@babel/template': 7.27.2 + '@graphql-codegen/add': 5.0.3(graphql@16.11.0) + '@graphql-codegen/gql-tag-operations': 4.0.17(graphql@16.11.0) + '@graphql-codegen/plugin-helpers': 5.1.0(graphql@16.11.0) + '@graphql-codegen/typed-document-node': 5.1.1(graphql@16.11.0) + '@graphql-codegen/typescript': 4.1.6(graphql@16.11.0) + '@graphql-codegen/typescript-operations': 4.6.1(graphql@16.11.0) + '@graphql-codegen/visitor-plugin-common': 5.8.0(graphql@16.11.0) + '@graphql-tools/documents': 1.0.1(graphql@16.11.0) + '@graphql-tools/utils': 10.8.6(graphql@16.11.0) + '@graphql-typed-document-node/core': 3.2.0(graphql@16.11.0) + graphql: 16.11.0 + tslib: 2.6.3 + transitivePeerDependencies: + - encoding + + '@graphql-codegen/core@4.0.2(graphql@16.11.0)': + dependencies: + '@graphql-codegen/plugin-helpers': 5.1.0(graphql@16.11.0) + '@graphql-tools/schema': 10.0.23(graphql@16.11.0) + '@graphql-tools/utils': 10.8.6(graphql@16.11.0) + graphql: 16.11.0 + tslib: 2.6.3 + + '@graphql-codegen/gql-tag-operations@4.0.17(graphql@16.11.0)': + dependencies: + '@graphql-codegen/plugin-helpers': 5.1.0(graphql@16.11.0) + '@graphql-codegen/visitor-plugin-common': 5.8.0(graphql@16.11.0) + '@graphql-tools/utils': 10.8.6(graphql@16.11.0) + auto-bind: 4.0.0 + graphql: 16.11.0 + tslib: 2.6.3 + transitivePeerDependencies: + - encoding + + '@graphql-codegen/plugin-helpers@3.1.2(graphql@16.11.0)': + dependencies: + '@graphql-tools/utils': 9.2.1(graphql@16.11.0) + change-case-all: 1.0.15 + common-tags: 1.8.2 + graphql: 16.11.0 + import-from: 4.0.0 + lodash: 4.17.21 + tslib: 2.4.1 + + '@graphql-codegen/plugin-helpers@5.1.0(graphql@16.11.0)': + dependencies: + '@graphql-tools/utils': 10.8.6(graphql@16.11.0) + change-case-all: 1.0.15 + common-tags: 1.8.2 + graphql: 16.11.0 + import-from: 4.0.0 + lodash: 4.17.21 + tslib: 2.6.3 + + '@graphql-codegen/schema-ast@4.1.0(graphql@16.11.0)': + dependencies: + '@graphql-codegen/plugin-helpers': 5.1.0(graphql@16.11.0) + '@graphql-tools/utils': 10.8.6(graphql@16.11.0) + graphql: 16.11.0 + tslib: 2.6.3 + + '@graphql-codegen/typed-document-node@5.1.1(graphql@16.11.0)': + dependencies: + '@graphql-codegen/plugin-helpers': 5.1.0(graphql@16.11.0) + '@graphql-codegen/visitor-plugin-common': 5.8.0(graphql@16.11.0) + auto-bind: 4.0.0 + change-case-all: 1.0.15 + graphql: 16.11.0 + tslib: 2.6.3 + transitivePeerDependencies: + - encoding + + '@graphql-codegen/typescript-graphql-request@6.3.0(graphql-request@7.2.0(graphql@16.11.0))(graphql-tag@2.12.6(graphql@16.11.0))(graphql@16.11.0)': + dependencies: + '@graphql-codegen/plugin-helpers': 3.1.2(graphql@16.11.0) + '@graphql-codegen/visitor-plugin-common': 2.13.8(graphql@16.11.0) + auto-bind: 4.0.0 + graphql: 16.11.0 + graphql-request: 7.2.0(graphql@16.11.0) + graphql-tag: 2.12.6(graphql@16.11.0) + tslib: 2.8.1 + transitivePeerDependencies: + - encoding + - supports-color + + '@graphql-codegen/typescript-operations@4.6.1(graphql@16.11.0)': + dependencies: + '@graphql-codegen/plugin-helpers': 5.1.0(graphql@16.11.0) + '@graphql-codegen/typescript': 4.1.6(graphql@16.11.0) + '@graphql-codegen/visitor-plugin-common': 5.8.0(graphql@16.11.0) + auto-bind: 4.0.0 + graphql: 16.11.0 + tslib: 2.6.3 + transitivePeerDependencies: + - encoding + + '@graphql-codegen/typescript@4.1.6(graphql@16.11.0)': + dependencies: + '@graphql-codegen/plugin-helpers': 5.1.0(graphql@16.11.0) + '@graphql-codegen/schema-ast': 4.1.0(graphql@16.11.0) + '@graphql-codegen/visitor-plugin-common': 5.8.0(graphql@16.11.0) + auto-bind: 4.0.0 + graphql: 16.11.0 + tslib: 2.6.3 + transitivePeerDependencies: + - encoding + + '@graphql-codegen/visitor-plugin-common@2.13.8(graphql@16.11.0)': + dependencies: + '@graphql-codegen/plugin-helpers': 3.1.2(graphql@16.11.0) + '@graphql-tools/optimize': 1.4.0(graphql@16.11.0) + '@graphql-tools/relay-operation-optimizer': 6.5.18(graphql@16.11.0) + '@graphql-tools/utils': 9.2.1(graphql@16.11.0) + auto-bind: 4.0.0 + change-case-all: 1.0.15 + dependency-graph: 0.11.0 + graphql: 16.11.0 + graphql-tag: 2.12.6(graphql@16.11.0) + parse-filepath: 1.0.2 + tslib: 2.4.1 + transitivePeerDependencies: + - encoding + - supports-color + + '@graphql-codegen/visitor-plugin-common@5.8.0(graphql@16.11.0)': + dependencies: + '@graphql-codegen/plugin-helpers': 5.1.0(graphql@16.11.0) + '@graphql-tools/optimize': 2.0.0(graphql@16.11.0) + '@graphql-tools/relay-operation-optimizer': 7.0.19(graphql@16.11.0) + '@graphql-tools/utils': 10.8.6(graphql@16.11.0) + auto-bind: 4.0.0 + change-case-all: 1.0.15 + dependency-graph: 0.11.0 + graphql: 16.11.0 + graphql-tag: 2.12.6(graphql@16.11.0) + parse-filepath: 1.0.2 + tslib: 2.6.3 + transitivePeerDependencies: + - encoding + + '@graphql-hive/signal@1.0.0': {} + + '@graphql-tools/apollo-engine-loader@8.0.20(graphql@16.11.0)': + dependencies: + '@graphql-tools/utils': 10.8.6(graphql@16.11.0) + '@whatwg-node/fetch': 0.10.8 + graphql: 16.11.0 + sync-fetch: 0.6.0-2 + tslib: 2.8.1 + + '@graphql-tools/batch-execute@9.0.16(graphql@16.11.0)': + dependencies: + '@graphql-tools/utils': 10.8.6(graphql@16.11.0) + '@whatwg-node/promise-helpers': 1.3.2 + dataloader: 2.2.3 + graphql: 16.11.0 + tslib: 2.8.1 + + '@graphql-tools/code-file-loader@8.1.20(graphql@16.11.0)': + dependencies: + '@graphql-tools/graphql-tag-pluck': 8.3.19(graphql@16.11.0) + '@graphql-tools/utils': 10.8.6(graphql@16.11.0) + globby: 11.1.0 + graphql: 16.11.0 + tslib: 2.8.1 + unixify: 1.0.0 + transitivePeerDependencies: + - supports-color + + '@graphql-tools/delegate@10.2.18(graphql@16.11.0)': + dependencies: + '@graphql-tools/batch-execute': 9.0.16(graphql@16.11.0) + '@graphql-tools/executor': 1.4.7(graphql@16.11.0) + '@graphql-tools/schema': 10.0.23(graphql@16.11.0) + '@graphql-tools/utils': 10.8.6(graphql@16.11.0) + '@repeaterjs/repeater': 3.0.6 + '@whatwg-node/promise-helpers': 1.3.2 + dataloader: 2.2.3 + dset: 3.1.4 + graphql: 16.11.0 + tslib: 2.8.1 + + '@graphql-tools/documents@1.0.1(graphql@16.11.0)': + dependencies: + graphql: 16.11.0 + lodash.sortby: 4.7.0 + tslib: 2.8.1 + + '@graphql-tools/executor-common@0.0.4(graphql@16.11.0)': + dependencies: + '@envelop/core': 5.2.3 + '@graphql-tools/utils': 10.8.6(graphql@16.11.0) + graphql: 16.11.0 + + '@graphql-tools/executor-graphql-ws@2.0.5(graphql@16.11.0)': + dependencies: + '@graphql-tools/executor-common': 0.0.4(graphql@16.11.0) + '@graphql-tools/utils': 10.8.6(graphql@16.11.0) + '@whatwg-node/disposablestack': 0.0.6 + graphql: 16.11.0 + graphql-ws: 6.0.5(graphql@16.11.0)(ws@8.18.2) + isomorphic-ws: 5.0.0(ws@8.18.2) + tslib: 2.8.1 + ws: 8.18.2 + transitivePeerDependencies: + - '@fastify/websocket' + - bufferutil + - crossws + - uWebSockets.js + - utf-8-validate + + '@graphql-tools/executor-http@1.3.3(@types/node@22.15.21)(graphql@16.11.0)': + dependencies: + '@graphql-hive/signal': 1.0.0 + '@graphql-tools/executor-common': 0.0.4(graphql@16.11.0) + '@graphql-tools/utils': 10.8.6(graphql@16.11.0) + '@repeaterjs/repeater': 3.0.6 + '@whatwg-node/disposablestack': 0.0.6 + '@whatwg-node/fetch': 0.10.8 + '@whatwg-node/promise-helpers': 1.3.2 + graphql: 16.11.0 + meros: 1.3.0(@types/node@22.15.21) + tslib: 2.8.1 + transitivePeerDependencies: + - '@types/node' + + '@graphql-tools/executor-legacy-ws@1.1.17(graphql@16.11.0)': + dependencies: + '@graphql-tools/utils': 10.8.6(graphql@16.11.0) + '@types/ws': 8.18.1 + graphql: 16.11.0 + isomorphic-ws: 5.0.0(ws@8.18.2) + tslib: 2.8.1 + ws: 8.18.2 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@graphql-tools/executor@1.4.7(graphql@16.11.0)': + dependencies: + '@graphql-tools/utils': 10.8.6(graphql@16.11.0) + '@graphql-typed-document-node/core': 3.2.0(graphql@16.11.0) + '@repeaterjs/repeater': 3.0.6 + '@whatwg-node/disposablestack': 0.0.6 + '@whatwg-node/promise-helpers': 1.3.2 + graphql: 16.11.0 + tslib: 2.8.1 + + '@graphql-tools/git-loader@8.0.24(graphql@16.11.0)': + dependencies: + '@graphql-tools/graphql-tag-pluck': 8.3.19(graphql@16.11.0) + '@graphql-tools/utils': 10.8.6(graphql@16.11.0) + graphql: 16.11.0 + is-glob: 4.0.3 + micromatch: 4.0.8 + tslib: 2.8.1 + unixify: 1.0.0 + transitivePeerDependencies: + - supports-color + + '@graphql-tools/github-loader@8.0.20(@types/node@22.15.21)(graphql@16.11.0)': + dependencies: + '@graphql-tools/executor-http': 1.3.3(@types/node@22.15.21)(graphql@16.11.0) + '@graphql-tools/graphql-tag-pluck': 8.3.19(graphql@16.11.0) + '@graphql-tools/utils': 10.8.6(graphql@16.11.0) + '@whatwg-node/fetch': 0.10.8 + '@whatwg-node/promise-helpers': 1.3.2 + graphql: 16.11.0 + sync-fetch: 0.6.0-2 + tslib: 2.8.1 + transitivePeerDependencies: + - '@types/node' + - supports-color + + '@graphql-tools/graphql-file-loader@8.0.20(graphql@16.11.0)': + dependencies: + '@graphql-tools/import': 7.0.19(graphql@16.11.0) + '@graphql-tools/utils': 10.8.6(graphql@16.11.0) + globby: 11.1.0 + graphql: 16.11.0 + tslib: 2.8.1 + unixify: 1.0.0 + + '@graphql-tools/graphql-tag-pluck@8.3.19(graphql@16.11.0)': + dependencies: + '@babel/core': 7.27.1 + '@babel/parser': 7.27.2 + '@babel/plugin-syntax-import-assertions': 7.27.1(@babel/core@7.27.1) + '@babel/traverse': 7.27.1 + '@babel/types': 7.27.1 + '@graphql-tools/utils': 10.8.6(graphql@16.11.0) + graphql: 16.11.0 + tslib: 2.8.1 + transitivePeerDependencies: + - supports-color + + '@graphql-tools/import@7.0.19(graphql@16.11.0)': + dependencies: + '@graphql-tools/utils': 10.8.6(graphql@16.11.0) + graphql: 16.11.0 + resolve-from: 5.0.0 + tslib: 2.8.1 + + '@graphql-tools/json-file-loader@8.0.18(graphql@16.11.0)': + dependencies: + '@graphql-tools/utils': 10.8.6(graphql@16.11.0) + globby: 11.1.0 + graphql: 16.11.0 + tslib: 2.8.1 + unixify: 1.0.0 + + '@graphql-tools/load@8.1.0(graphql@16.11.0)': + dependencies: + '@graphql-tools/schema': 10.0.23(graphql@16.11.0) + '@graphql-tools/utils': 10.8.6(graphql@16.11.0) + graphql: 16.11.0 + p-limit: 3.1.0 + tslib: 2.8.1 + + '@graphql-tools/merge@9.0.24(graphql@16.11.0)': + dependencies: + '@graphql-tools/utils': 10.8.6(graphql@16.11.0) + graphql: 16.11.0 + tslib: 2.8.1 + + '@graphql-tools/optimize@1.4.0(graphql@16.11.0)': + dependencies: + graphql: 16.11.0 + tslib: 2.8.1 + + '@graphql-tools/optimize@2.0.0(graphql@16.11.0)': + dependencies: + graphql: 16.11.0 + tslib: 2.8.1 + + '@graphql-tools/prisma-loader@8.0.17(@types/node@22.15.21)(graphql@16.11.0)': + dependencies: + '@graphql-tools/url-loader': 8.0.31(@types/node@22.15.21)(graphql@16.11.0) + '@graphql-tools/utils': 10.8.6(graphql@16.11.0) + '@types/js-yaml': 4.0.9 + '@whatwg-node/fetch': 0.10.8 + chalk: 4.1.2 + debug: 4.4.1 + dotenv: 16.4.7 + graphql: 16.11.0 + graphql-request: 6.1.0(graphql@16.11.0) + http-proxy-agent: 7.0.2 + https-proxy-agent: 7.0.6 + jose: 5.10.0 + js-yaml: 4.1.0 + lodash: 4.17.21 + scuid: 1.1.0 + tslib: 2.8.1 + yaml-ast-parser: 0.0.43 + transitivePeerDependencies: + - '@fastify/websocket' + - '@types/node' + - bufferutil + - crossws + - encoding + - supports-color + - uWebSockets.js + - utf-8-validate + + '@graphql-tools/relay-operation-optimizer@6.5.18(graphql@16.11.0)': + dependencies: + '@ardatan/relay-compiler': 12.0.0(graphql@16.11.0) + '@graphql-tools/utils': 9.2.1(graphql@16.11.0) + graphql: 16.11.0 + tslib: 2.8.1 + transitivePeerDependencies: + - encoding + - supports-color + + '@graphql-tools/relay-operation-optimizer@7.0.19(graphql@16.11.0)': + dependencies: + '@ardatan/relay-compiler': 12.0.3(graphql@16.11.0) + '@graphql-tools/utils': 10.8.6(graphql@16.11.0) + graphql: 16.11.0 + tslib: 2.8.1 + transitivePeerDependencies: + - encoding + + '@graphql-tools/schema@10.0.23(graphql@16.11.0)': + dependencies: + '@graphql-tools/merge': 9.0.24(graphql@16.11.0) + '@graphql-tools/utils': 10.8.6(graphql@16.11.0) + graphql: 16.11.0 + tslib: 2.8.1 + + '@graphql-tools/url-loader@8.0.31(@types/node@22.15.21)(graphql@16.11.0)': + dependencies: + '@graphql-tools/executor-graphql-ws': 2.0.5(graphql@16.11.0) + '@graphql-tools/executor-http': 1.3.3(@types/node@22.15.21)(graphql@16.11.0) + '@graphql-tools/executor-legacy-ws': 1.1.17(graphql@16.11.0) + '@graphql-tools/utils': 10.8.6(graphql@16.11.0) + '@graphql-tools/wrap': 10.0.36(graphql@16.11.0) + '@types/ws': 8.18.1 + '@whatwg-node/fetch': 0.10.8 + '@whatwg-node/promise-helpers': 1.3.2 + graphql: 16.11.0 + isomorphic-ws: 5.0.0(ws@8.18.2) + sync-fetch: 0.6.0-2 + tslib: 2.8.1 + ws: 8.18.2 + transitivePeerDependencies: + - '@fastify/websocket' + - '@types/node' + - bufferutil + - crossws + - uWebSockets.js + - utf-8-validate + + '@graphql-tools/utils@10.8.6(graphql@16.11.0)': + dependencies: + '@graphql-typed-document-node/core': 3.2.0(graphql@16.11.0) + '@whatwg-node/promise-helpers': 1.3.2 + cross-inspect: 1.0.1 + dset: 3.1.4 + graphql: 16.11.0 + tslib: 2.8.1 + + '@graphql-tools/utils@9.2.1(graphql@16.11.0)': + dependencies: + '@graphql-typed-document-node/core': 3.2.0(graphql@16.11.0) + graphql: 16.11.0 + tslib: 2.8.1 + + '@graphql-tools/wrap@10.0.36(graphql@16.11.0)': + dependencies: + '@graphql-tools/delegate': 10.2.18(graphql@16.11.0) + '@graphql-tools/schema': 10.0.23(graphql@16.11.0) + '@graphql-tools/utils': 10.8.6(graphql@16.11.0) + '@whatwg-node/promise-helpers': 1.3.2 + graphql: 16.11.0 + tslib: 2.8.1 + + '@graphql-typed-document-node/core@3.2.0(graphql@16.11.0)': + dependencies: + graphql: 16.11.0 + '@humanfs/core@0.19.1': {} '@humanfs/node@0.16.6': @@ -4328,6 +6255,66 @@ snapshots: dependencies: '@noble/hashes': 1.8.0 + '@parcel/watcher-android-arm64@2.5.1': + optional: true + + '@parcel/watcher-darwin-arm64@2.5.1': + optional: true + + '@parcel/watcher-darwin-x64@2.5.1': + optional: true + + '@parcel/watcher-freebsd-x64@2.5.1': + optional: true + + '@parcel/watcher-linux-arm-glibc@2.5.1': + optional: true + + '@parcel/watcher-linux-arm-musl@2.5.1': + optional: true + + '@parcel/watcher-linux-arm64-glibc@2.5.1': + optional: true + + '@parcel/watcher-linux-arm64-musl@2.5.1': + optional: true + + '@parcel/watcher-linux-x64-glibc@2.5.1': + optional: true + + '@parcel/watcher-linux-x64-musl@2.5.1': + optional: true + + '@parcel/watcher-win32-arm64@2.5.1': + optional: true + + '@parcel/watcher-win32-ia32@2.5.1': + optional: true + + '@parcel/watcher-win32-x64@2.5.1': + optional: true + + '@parcel/watcher@2.5.1': + dependencies: + detect-libc: 1.0.3 + is-glob: 4.0.3 + micromatch: 4.0.8 + node-addon-api: 7.1.1 + optionalDependencies: + '@parcel/watcher-android-arm64': 2.5.1 + '@parcel/watcher-darwin-arm64': 2.5.1 + '@parcel/watcher-darwin-x64': 2.5.1 + '@parcel/watcher-freebsd-x64': 2.5.1 + '@parcel/watcher-linux-arm-glibc': 2.5.1 + '@parcel/watcher-linux-arm-musl': 2.5.1 + '@parcel/watcher-linux-arm64-glibc': 2.5.1 + '@parcel/watcher-linux-arm64-musl': 2.5.1 + '@parcel/watcher-linux-x64-glibc': 2.5.1 + '@parcel/watcher-linux-x64-musl': 2.5.1 + '@parcel/watcher-win32-arm64': 2.5.1 + '@parcel/watcher-win32-ia32': 2.5.1 + '@parcel/watcher-win32-x64': 2.5.1 + '@pkgr/core@0.2.4': {} '@prisma/client@6.8.2(prisma@6.8.2(typescript@5.8.3))(typescript@5.8.3)': @@ -4360,6 +6347,8 @@ snapshots: dependencies: '@prisma/debug': 6.8.2 + '@repeaterjs/repeater@3.0.6': {} + '@sec-ant/readable-stream@0.4.1': {} '@sinclair/typebox@0.27.8': {} @@ -4547,6 +6536,8 @@ snapshots: expect: 29.7.0 pretty-format: 29.7.0 + '@types/js-yaml@4.0.9': {} + '@types/json-schema@7.0.15': {} '@types/methods@1.1.4': {} @@ -4590,6 +6581,10 @@ snapshots: '@types/methods': 1.1.4 '@types/superagent': 8.1.9 + '@types/ws@8.18.1': + dependencies: + '@types/node': 22.15.21 + '@types/yargs-parser@21.0.3': {} '@types/yargs@17.0.33': @@ -4749,6 +6744,27 @@ snapshots: '@webassemblyjs/ast': 1.14.1 '@xtuc/long': 4.2.2 + '@whatwg-node/disposablestack@0.0.6': + dependencies: + '@whatwg-node/promise-helpers': 1.3.2 + tslib: 2.8.1 + + '@whatwg-node/fetch@0.10.8': + dependencies: + '@whatwg-node/node-fetch': 0.7.21 + urlpattern-polyfill: 10.1.0 + + '@whatwg-node/node-fetch@0.7.21': + dependencies: + '@fastify/busboy': 3.1.1 + '@whatwg-node/disposablestack': 0.0.6 + '@whatwg-node/promise-helpers': 1.3.2 + tslib: 2.8.1 + + '@whatwg-node/promise-helpers@1.3.2': + dependencies: + tslib: 2.8.1 + '@xhmikosr/archive-type@7.0.0': dependencies: file-type: 19.6.0 @@ -4836,6 +6852,13 @@ snapshots: acorn@8.14.1: {} + agent-base@7.1.3: {} + + aggregate-error@3.1.0: + dependencies: + clean-stack: 2.2.0 + indent-string: 4.0.0 + ajv-formats@2.1.1(ajv@8.17.1): optionalDependencies: ajv: 8.17.1 @@ -4906,12 +6929,18 @@ snapshots: array-timsort@1.0.3: {} + array-union@2.1.0: {} + asap@2.0.6: {} + astral-regex@2.0.0: {} + async@3.2.6: {} asynckit@0.4.0: {} + auto-bind@4.0.0: {} + b4a@1.6.7: {} babel-jest@29.7.0(@babel/core@7.27.1): @@ -4944,6 +6973,8 @@ snapshots: '@types/babel__core': 7.20.5 '@types/babel__traverse': 7.20.7 + babel-plugin-syntax-trailing-function-commas@7.0.0-beta.0: {} + babel-preset-current-node-syntax@1.1.0(@babel/core@7.27.1): dependencies: '@babel/core': 7.27.1 @@ -4963,6 +6994,39 @@ snapshots: '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.27.1) '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.27.1) + babel-preset-fbjs@3.4.0(@babel/core@7.27.1): + dependencies: + '@babel/core': 7.27.1 + '@babel/plugin-proposal-class-properties': 7.18.6(@babel/core@7.27.1) + '@babel/plugin-proposal-object-rest-spread': 7.20.7(@babel/core@7.27.1) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.27.1) + '@babel/plugin-syntax-flow': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.27.1) + '@babel/plugin-transform-arrow-functions': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-transform-block-scoped-functions': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-transform-block-scoping': 7.27.3(@babel/core@7.27.1) + '@babel/plugin-transform-classes': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-transform-computed-properties': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-transform-destructuring': 7.27.3(@babel/core@7.27.1) + '@babel/plugin-transform-flow-strip-types': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-transform-for-of': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-transform-function-name': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-transform-literals': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-transform-member-expression-literals': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-transform-modules-commonjs': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-transform-object-super': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-transform-parameters': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-transform-property-literals': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-transform-react-display-name': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-transform-react-jsx': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-transform-shorthand-properties': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-transform-spread': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-transform-template-literals': 7.27.1(@babel/core@7.27.1) + babel-plugin-syntax-trailing-function-commas: 7.0.0-beta.0 + transitivePeerDependencies: + - supports-color + babel-preset-jest@29.6.3(@babel/core@7.27.1): dependencies: '@babel/core': 7.27.1 @@ -5074,17 +7138,56 @@ snapshots: callsites@3.1.0: {} + camel-case@4.1.2: + dependencies: + pascal-case: 3.1.2 + tslib: 2.8.1 + camelcase@5.3.1: {} camelcase@6.3.0: {} caniuse-lite@1.0.30001718: {} + capital-case@1.0.4: + dependencies: + no-case: 3.0.4 + tslib: 2.8.1 + upper-case-first: 2.0.2 + chalk@4.1.2: dependencies: ansi-styles: 4.3.0 supports-color: 7.2.0 + change-case-all@1.0.15: + 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 + + change-case@4.1.2: + 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.8.1 + char-regex@1.0.2: {} chardet@0.7.0: {} @@ -5099,6 +7202,8 @@ snapshots: cjs-module-lexer@1.4.3: {} + clean-stack@2.2.0: {} + cli-cursor@3.1.0: dependencies: restore-cursor: 3.1.0 @@ -5111,8 +7216,21 @@ snapshots: optionalDependencies: '@colors/colors': 1.5.0 + cli-truncate@2.1.0: + dependencies: + slice-ansi: 3.0.0 + string-width: 4.2.3 + + cli-width@3.0.0: {} + cli-width@4.1.0: {} + cliui@6.0.0: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 6.2.0 + cliui@8.0.1: dependencies: string-width: 4.2.3 @@ -5131,6 +7249,8 @@ snapshots: color-name@1.1.4: {} + colorette@2.0.20: {} + combined-stream@1.0.8: dependencies: delayed-stream: 1.0.0 @@ -5151,6 +7271,8 @@ snapshots: has-own-prop: 2.0.0 repeat-string: 1.6.1 + common-tags@1.8.2: {} + component-emitter@1.3.1: {} concat-map@0.0.1: {} @@ -5164,6 +7286,12 @@ snapshots: consola@3.4.2: {} + constant-case@3.0.4: + dependencies: + no-case: 3.0.4 + tslib: 2.8.1 + upper-case: 2.0.2 + content-disposition@0.5.4: dependencies: safe-buffer: 5.2.1 @@ -5219,12 +7347,28 @@ snapshots: create-require@1.1.1: {} + cross-fetch@3.2.0: + dependencies: + node-fetch: 2.7.0 + transitivePeerDependencies: + - encoding + + cross-inspect@1.0.1: + dependencies: + tslib: 2.8.1 + cross-spawn@7.0.6: dependencies: path-key: 3.1.1 shebang-command: 2.0.0 which: 2.0.2 + data-uri-to-buffer@4.0.1: {} + + dataloader@2.2.3: {} + + debounce@1.2.1: {} + debug@2.6.9: dependencies: ms: 2.0.0 @@ -5233,6 +7377,8 @@ snapshots: dependencies: ms: 2.1.3 + decamelize@1.2.0: {} + decompress-response@6.0.0: dependencies: mimic-response: 3.1.0 @@ -5255,6 +7401,12 @@ snapshots: depd@2.0.0: {} + dependency-graph@0.11.0: {} + + detect-indent@6.1.0: {} + + detect-libc@1.0.3: {} + detect-newline@3.1.0: {} dezalgo@1.0.4: @@ -5266,12 +7418,23 @@ snapshots: diff@4.0.2: {} + dir-glob@3.0.1: + dependencies: + path-type: 4.0.0 + + dot-case@3.0.4: + dependencies: + no-case: 3.0.4 + tslib: 2.8.1 + dotenv-expand@12.0.1: dependencies: dotenv: 16.4.7 dotenv@16.4.7: {} + dset@3.1.4: {} + dunder-proto@1.0.1: dependencies: call-bind-apply-helpers: 1.0.2 @@ -5326,6 +7489,8 @@ snapshots: escape-html@1.0.3: {} + escape-string-regexp@1.0.5: {} + escape-string-regexp@2.0.0: {} escape-string-regexp@4.0.0: {} @@ -5538,8 +7703,31 @@ snapshots: dependencies: bser: 2.1.1 + fbjs-css-vars@1.0.2: {} + + fbjs@3.0.5: + dependencies: + cross-fetch: 3.2.0 + fbjs-css-vars: 1.0.2 + loose-envify: 1.4.0 + object-assign: 4.1.1 + promise: 7.3.1 + setimmediate: 1.0.5 + ua-parser-js: 1.0.40 + transitivePeerDependencies: + - encoding + + fetch-blob@3.2.0: + dependencies: + node-domexception: 1.0.0 + web-streams-polyfill: 3.3.3 + fflate@0.8.2: {} + figures@3.2.0: + dependencies: + escape-string-regexp: 1.0.5 + file-entry-cache@8.0.0: dependencies: flat-cache: 4.0.1 @@ -5637,6 +7825,10 @@ snapshots: es-set-tostringtag: 2.1.0 mime-types: 2.1.35 + formdata-polyfill@4.0.10: + dependencies: + fetch-blob: 3.2.0 + formidable@3.5.4: dependencies: '@paralleldrive/cuid2': 2.2.2 @@ -5727,6 +7919,15 @@ snapshots: globals@16.1.0: {} + globby@11.1.0: + dependencies: + array-union: 2.1.0 + dir-glob: 3.0.1 + fast-glob: 3.3.3 + ignore: 5.3.2 + merge2: 1.4.1 + slash: 3.0.0 + gopd@1.2.0: {} got@13.0.0: @@ -5747,6 +7948,55 @@ snapshots: graphemer@1.4.0: {} + graphql-config@5.1.5(@types/node@22.15.21)(graphql@16.11.0)(typescript@5.8.3): + dependencies: + '@graphql-tools/graphql-file-loader': 8.0.20(graphql@16.11.0) + '@graphql-tools/json-file-loader': 8.0.18(graphql@16.11.0) + '@graphql-tools/load': 8.1.0(graphql@16.11.0) + '@graphql-tools/merge': 9.0.24(graphql@16.11.0) + '@graphql-tools/url-loader': 8.0.31(@types/node@22.15.21)(graphql@16.11.0) + '@graphql-tools/utils': 10.8.6(graphql@16.11.0) + cosmiconfig: 8.3.6(typescript@5.8.3) + graphql: 16.11.0 + jiti: 2.4.2 + minimatch: 9.0.5 + string-env-interpolation: 1.0.1 + tslib: 2.8.1 + transitivePeerDependencies: + - '@fastify/websocket' + - '@types/node' + - bufferutil + - crossws + - typescript + - uWebSockets.js + - utf-8-validate + + graphql-request@6.1.0(graphql@16.11.0): + dependencies: + '@graphql-typed-document-node/core': 3.2.0(graphql@16.11.0) + cross-fetch: 3.2.0 + graphql: 16.11.0 + transitivePeerDependencies: + - encoding + + graphql-request@7.2.0(graphql@16.11.0): + dependencies: + '@graphql-typed-document-node/core': 3.2.0(graphql@16.11.0) + graphql: 16.11.0 + + graphql-tag@2.12.6(graphql@16.11.0): + dependencies: + graphql: 16.11.0 + tslib: 2.8.1 + + graphql-ws@6.0.5(graphql@16.11.0)(ws@8.18.2): + dependencies: + graphql: 16.11.0 + optionalDependencies: + ws: 8.18.2 + + graphql@16.11.0: {} + has-flag@4.0.0: {} has-own-prop@2.0.0: {} @@ -5761,6 +8011,11 @@ snapshots: dependencies: function-bind: 1.1.2 + header-case@2.0.4: + dependencies: + capital-case: 1.0.4 + tslib: 2.8.1 + html-escaper@2.0.2: {} http-cache-semantics@4.2.0: {} @@ -5773,11 +8028,25 @@ snapshots: statuses: 2.0.1 toidentifier: 1.0.1 + http-proxy-agent@7.0.2: + dependencies: + agent-base: 7.1.3 + debug: 4.4.1 + transitivePeerDependencies: + - supports-color + http2-wrapper@2.2.1: dependencies: quick-lru: 5.1.1 resolve-alpn: 1.2.1 + https-proxy-agent@7.0.6: + dependencies: + agent-base: 7.1.3 + debug: 4.4.1 + transitivePeerDependencies: + - supports-color + human-signals@2.1.0: {} iconv-lite@0.4.24: @@ -5794,11 +8063,15 @@ snapshots: ignore@7.0.4: {} + immutable@3.7.6: {} + import-fresh@3.3.1: dependencies: parent-module: 1.0.1 resolve-from: 4.0.0 + import-from@4.0.0: {} + import-local@3.2.0: dependencies: pkg-dir: 4.2.0 @@ -5806,6 +8079,8 @@ snapshots: imurmurhash@0.1.4: {} + indent-string@4.0.0: {} + inflight@1.0.6: dependencies: once: 1.4.0 @@ -5813,12 +8088,39 @@ snapshots: inherits@2.0.4: {} + inquirer@8.2.6: + dependencies: + ansi-escapes: 4.3.2 + chalk: 4.1.2 + cli-cursor: 3.1.0 + cli-width: 3.0.0 + external-editor: 3.1.0 + figures: 3.2.0 + lodash: 4.17.21 + mute-stream: 0.0.8 + ora: 5.4.1 + run-async: 2.4.1 + rxjs: 7.8.2 + string-width: 4.2.3 + strip-ansi: 6.0.1 + through: 2.3.8 + wrap-ansi: 6.2.0 + inspect-with-kind@1.0.5: dependencies: kind-of: 6.0.3 + invariant@2.2.4: + dependencies: + loose-envify: 1.4.0 + ipaddr.js@1.9.1: {} + is-absolute@1.0.0: + dependencies: + is-relative: 1.0.0 + is-windows: 1.0.2 + is-arrayish@0.2.1: {} is-core-module@2.16.1: @@ -5837,22 +8139,44 @@ snapshots: is-interactive@1.0.0: {} + is-lower-case@2.0.2: + dependencies: + tslib: 2.8.1 + is-number@7.0.0: {} is-plain-obj@1.1.0: {} is-promise@4.0.0: {} + is-relative@1.0.0: + dependencies: + is-unc-path: 1.0.0 + is-stream@2.0.1: {} is-stream@4.0.1: {} + is-unc-path@1.0.0: + dependencies: + unc-path-regex: 0.1.2 + is-unicode-supported@0.1.0: {} + is-upper-case@2.0.2: + dependencies: + tslib: 2.8.1 + + is-windows@1.0.2: {} + isarray@1.0.0: {} isexe@2.0.0: {} + isomorphic-ws@5.0.0(ws@8.18.2): + dependencies: + ws: 8.18.2 + istanbul-lib-coverage@3.2.2: {} istanbul-lib-instrument@5.2.1: @@ -6222,8 +8546,12 @@ snapshots: - supports-color - ts-node + jiti@1.21.7: {} + jiti@2.4.2: {} + jose@5.10.0: {} + js-tokens@4.0.0: {} js-yaml@3.14.1: @@ -6247,6 +8575,11 @@ snapshots: json-stable-stringify-without-jsonify@1.0.1: {} + json-to-pretty-yaml@1.2.2: + dependencies: + remedial: 1.0.8 + remove-trailing-spaces: 1.0.9 + json5@2.2.3: {} jsonc-parser@3.3.1: {} @@ -6274,6 +8607,17 @@ snapshots: lines-and-columns@1.2.4: {} + listr2@4.0.5: + dependencies: + cli-truncate: 2.1.0 + colorette: 2.0.20 + log-update: 4.0.0 + p-map: 4.0.0 + rfdc: 1.4.1 + rxjs: 7.8.2 + through: 2.3.8 + wrap-ansi: 7.0.0 + load-esm@1.0.2: {} loader-runner@4.3.0: {} @@ -6290,6 +8634,8 @@ snapshots: lodash.merge@4.6.2: {} + lodash.sortby@4.7.0: {} + lodash@4.17.21: {} log-symbols@4.1.0: @@ -6297,6 +8643,25 @@ snapshots: chalk: 4.1.2 is-unicode-supported: 0.1.0 + log-update@4.0.0: + dependencies: + ansi-escapes: 4.3.2 + cli-cursor: 3.1.0 + slice-ansi: 4.0.0 + wrap-ansi: 6.2.0 + + loose-envify@1.4.0: + dependencies: + js-tokens: 4.0.0 + + lower-case-first@2.0.2: + dependencies: + tslib: 2.8.1 + + lower-case@2.0.2: + dependencies: + tslib: 2.8.1 + lowercase-keys@3.0.0: {} lru-cache@11.1.0: {} @@ -6319,6 +8684,8 @@ snapshots: dependencies: tmpl: 1.0.5 + map-cache@0.2.2: {} + math-intrinsics@1.1.0: {} media-typer@0.3.0: {} @@ -6335,6 +8702,10 @@ snapshots: merge2@1.4.1: {} + meros@1.3.0(@types/node@22.15.21): + optionalDependencies: + '@types/node': 22.15.21 + methods@1.1.2: {} micromatch@4.0.8: @@ -6400,6 +8771,8 @@ snapshots: type-is: 1.6.18 xtend: 4.0.2 + mute-stream@0.0.8: {} + mute-stream@2.0.0: {} natural-compare@1.4.0: {} @@ -6408,16 +8781,39 @@ snapshots: neo-async@2.6.2: {} + no-case@3.0.4: + dependencies: + lower-case: 2.0.2 + tslib: 2.8.1 + node-abort-controller@3.1.1: {} + node-addon-api@7.1.1: {} + + node-domexception@1.0.0: {} + node-emoji@1.11.0: dependencies: lodash: 4.17.21 + node-fetch@2.7.0: + dependencies: + whatwg-url: 5.0.0 + + node-fetch@3.3.2: + dependencies: + data-uri-to-buffer: 4.0.1 + fetch-blob: 3.2.0 + formdata-polyfill: 4.0.10 + node-int64@0.4.0: {} node-releases@2.0.19: {} + normalize-path@2.1.1: + dependencies: + remove-trailing-separator: 1.1.0 + normalize-path@3.0.0: {} normalize-url@8.0.1: {} @@ -6426,6 +8822,8 @@ snapshots: dependencies: path-key: 3.1.1 + nullthrows@1.1.1: {} + object-assign@4.1.1: {} object-inspect@1.13.4: {} @@ -6485,14 +8883,29 @@ snapshots: dependencies: p-limit: 3.1.0 + p-map@4.0.0: + dependencies: + aggregate-error: 3.1.0 + p-try@2.2.0: {} package-json-from-dist@1.0.1: {} + param-case@3.0.4: + dependencies: + dot-case: 3.0.4 + tslib: 2.8.1 + parent-module@1.0.1: dependencies: callsites: 3.1.0 + parse-filepath@1.0.2: + dependencies: + is-absolute: 1.0.0 + map-cache: 0.2.2 + path-root: 0.1.1 + parse-json@5.2.0: dependencies: '@babel/code-frame': 7.27.1 @@ -6502,6 +8915,11 @@ snapshots: parseurl@1.3.3: {} + pascal-case@3.1.2: + dependencies: + no-case: 3.0.4 + tslib: 2.8.1 + passport-strategy@1.0.0: {} passport@0.7.0: @@ -6510,6 +8928,11 @@ snapshots: pause: 0.0.1 utils-merge: 1.0.1 + path-case@3.0.4: + dependencies: + dot-case: 3.0.4 + tslib: 2.8.1 + path-exists@4.0.0: {} path-is-absolute@1.0.1: {} @@ -6518,6 +8941,12 @@ snapshots: path-parse@1.0.7: {} + path-root-regex@0.1.2: {} + + path-root@0.1.1: + dependencies: + path-root-regex: 0.1.2 + path-scurry@2.0.0: dependencies: lru-cache: 11.1.0 @@ -6576,6 +9005,10 @@ snapshots: process-nextick-args@2.0.1: {} + promise@7.3.1: + dependencies: + asap: 2.0.6 + prompts@2.4.2: dependencies: kleur: 3.0.3 @@ -6635,12 +9068,28 @@ snapshots: reflect-metadata@0.2.2: {} + relay-runtime@12.0.0: + dependencies: + '@babel/runtime': 7.27.3 + fbjs: 3.0.5 + invariant: 2.2.4 + transitivePeerDependencies: + - encoding + + remedial@1.0.8: {} + + remove-trailing-separator@1.1.0: {} + + remove-trailing-spaces@1.0.9: {} + repeat-string@1.6.1: {} require-directory@2.1.1: {} require-from-string@2.0.2: {} + require-main-filename@2.0.0: {} + resolve-alpn@1.2.1: {} resolve-cwd@3.0.0: @@ -6670,6 +9119,8 @@ snapshots: reusify@1.1.0: {} + rfdc@1.4.1: {} + router@2.2.0: dependencies: debug: 4.4.1 @@ -6680,6 +9131,8 @@ snapshots: transitivePeerDependencies: - supports-color + run-async@2.4.1: {} + run-parallel@1.2.0: dependencies: queue-microtask: 1.2.3 @@ -6711,6 +9164,8 @@ snapshots: ajv-formats: 2.1.1(ajv@8.17.1) ajv-keywords: 5.1.0(ajv@8.17.1) + scuid@1.1.0: {} + seek-bzip@2.0.0: dependencies: commander: 6.2.1 @@ -6741,6 +9196,12 @@ snapshots: transitivePeerDependencies: - supports-color + sentence-case@3.0.4: + dependencies: + no-case: 3.0.4 + tslib: 2.8.1 + upper-case-first: 2.0.2 + serialize-javascript@6.0.2: dependencies: randombytes: 2.1.0 @@ -6754,6 +9215,10 @@ snapshots: transitivePeerDependencies: - supports-color + set-blocking@2.0.0: {} + + setimmediate@1.0.5: {} + setprototypeof@1.2.0: {} shebang-command@2.0.0: @@ -6762,6 +9227,8 @@ snapshots: shebang-regex@3.0.0: {} + shell-quote@1.8.2: {} + side-channel-list@1.0.0: dependencies: es-errors: 1.3.0 @@ -6794,10 +9261,29 @@ snapshots: signal-exit@4.1.0: {} + signedsource@1.0.0: {} + sisteransi@1.0.5: {} slash@3.0.0: {} + slice-ansi@3.0.0: + dependencies: + ansi-styles: 4.3.0 + astral-regex: 2.0.0 + is-fullwidth-code-point: 3.0.0 + + slice-ansi@4.0.0: + dependencies: + ansi-styles: 4.3.0 + astral-regex: 2.0.0 + is-fullwidth-code-point: 3.0.0 + + snake-case@3.0.4: + dependencies: + dot-case: 3.0.4 + tslib: 2.8.1 + sort-keys-length@1.0.1: dependencies: sort-keys: 1.1.2 @@ -6820,6 +9306,10 @@ snapshots: source-map@0.7.4: {} + sponge-case@1.0.1: + dependencies: + tslib: 2.8.1 + sprintf-js@1.0.3: {} stack-utils@2.0.6: @@ -6837,6 +9327,8 @@ snapshots: optionalDependencies: bare-events: 2.5.4 + string-env-interpolation@1.0.1: {} + string-length@4.0.2: dependencies: char-regex: 1.0.2 @@ -6924,8 +9416,18 @@ snapshots: supports-preserve-symlinks-flag@1.0.0: {} + swap-case@2.0.2: + dependencies: + tslib: 2.8.1 + symbol-observable@4.0.0: {} + sync-fetch@0.6.0-2: + dependencies: + node-fetch: 3.3.2 + timeout-signal: 2.0.0 + whatwg-mimetype: 4.0.0 + synckit@0.11.5: dependencies: '@pkgr/core': 0.2.4 @@ -6969,6 +9471,12 @@ snapshots: through@2.3.8: {} + timeout-signal@2.0.0: {} + + title-case@3.0.3: + dependencies: + tslib: 2.8.1 + tmp@0.0.33: dependencies: os-tmpdir: 1.0.2 @@ -6986,6 +9494,8 @@ snapshots: '@tokenizer/token': 0.3.0 ieee754: 1.2.1 + tr46@0.0.3: {} + tree-kill@1.2.2: {} ts-api-utils@2.1.0(typescript@5.8.3): @@ -7022,6 +9532,8 @@ snapshots: typescript: 5.8.3 webpack: 5.99.6(@swc/core@1.11.29) + ts-log@2.2.7: {} + ts-node@10.9.2(@swc/core@1.11.29)(@types/node@22.15.21)(typescript@5.8.3): dependencies: '@cspotcode/source-map-support': 0.8.1 @@ -7055,6 +9567,10 @@ snapshots: minimist: 1.2.8 strip-bom: 3.0.0 + tslib@2.4.1: {} + + tslib@2.6.3: {} + tslib@2.8.1: {} type-check@0.4.0: @@ -7092,6 +9608,8 @@ snapshots: typescript@5.8.3: {} + ua-parser-js@1.0.40: {} + uid-safe@2.1.5: dependencies: random-bytes: 1.0.0 @@ -7107,10 +9625,16 @@ snapshots: buffer: 5.7.1 through: 2.3.8 + unc-path-regex@0.1.2: {} + undici-types@6.21.0: {} universalify@2.0.1: {} + unixify@1.0.0: + dependencies: + normalize-path: 2.1.1 + unpipe@1.0.0: {} update-browserslist-db@1.1.3(browserslist@4.24.5): @@ -7119,10 +9643,20 @@ snapshots: escalade: 3.2.0 picocolors: 1.1.1 + upper-case-first@2.0.2: + dependencies: + tslib: 2.8.1 + + upper-case@2.0.2: + dependencies: + tslib: 2.8.1 + uri-js@4.4.1: dependencies: punycode: 2.3.1 + urlpattern-polyfill@10.1.0: {} + util-deprecate@1.0.2: {} utils-merge@1.0.1: {} @@ -7150,6 +9684,10 @@ snapshots: dependencies: defaults: 1.0.4 + web-streams-polyfill@3.3.3: {} + + webidl-conversions@3.0.1: {} + webpack-node-externals@3.0.0: {} webpack-sources@3.2.3: {} @@ -7184,6 +9722,15 @@ snapshots: - esbuild - uglify-js + whatwg-mimetype@4.0.0: {} + + whatwg-url@5.0.0: + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + + which-module@2.0.1: {} + which@2.0.2: dependencies: isexe: 2.0.0 @@ -7215,14 +9762,41 @@ snapshots: imurmurhash: 0.1.4 signal-exit: 3.0.7 + ws@8.18.2: {} + xtend@4.0.2: {} + y18n@4.0.3: {} + y18n@5.0.8: {} yallist@3.1.1: {} + yaml-ast-parser@0.0.43: {} + + yaml@2.8.0: {} + + yargs-parser@18.1.3: + dependencies: + camelcase: 5.3.1 + decamelize: 1.2.0 + yargs-parser@21.1.1: {} + yargs@15.4.1: + dependencies: + cliui: 6.0.0 + decamelize: 1.2.0 + find-up: 4.1.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + require-main-filename: 2.0.0 + set-blocking: 2.0.0 + string-width: 4.2.3 + which-module: 2.0.1 + y18n: 4.0.3 + yargs-parser: 18.1.3 + yargs@17.7.2: dependencies: cliui: 8.0.1 diff --git a/server/pnpm-workspace.yaml b/server/pnpm-workspace.yaml index 358fb5cae..5dd3de53c 100644 --- a/server/pnpm-workspace.yaml +++ b/server/pnpm-workspace.yaml @@ -1,5 +1,6 @@ onlyBuiltDependencies: - '@nestjs/core' + - '@parcel/watcher' - '@prisma/client' - '@prisma/engines' - '@swc/core' diff --git a/server/src/graphql/graphql.module.ts b/server/src/graphql/graphql.module.ts new file mode 100644 index 000000000..19b41c5b5 --- /dev/null +++ b/server/src/graphql/graphql.module.ts @@ -0,0 +1,7 @@ +import { Module } from '@nestjs/common'; +import { GraphqlService } from './graphql.service'; + +@Module({ + providers: [GraphqlService], +}) +export class GraphqlModule {} diff --git a/server/src/graphql/graphql.service.ts b/server/src/graphql/graphql.service.ts new file mode 100644 index 000000000..7ff7e8ab6 --- /dev/null +++ b/server/src/graphql/graphql.service.ts @@ -0,0 +1,24 @@ +import { Injectable } from '@nestjs/common'; +import { GraphQLClient } from 'graphql-request'; +import { getSdk } from '../generated/graphql/graphql'; + +const HASURAGRES_GRAPHQL_API = 'https://graphql.csesoc.app/v1/graphql'; + +@Injectable() +export class GraphqlService { + private readonly sdk: ReturnType; + + constructor() { + const client = new GraphQLClient(HASURAGRES_GRAPHQL_API); + this.sdk = getSdk(client); + } + + async courseExists(courseId: string, term: string): Promise { + const { courseExists } = await this.sdk.CourseExists({ + courseId, + term, + }); + + return courseExists.aggregate != null && courseExists.aggregate.count > 0; + } +} diff --git a/server/src/graphql/queries.ts b/server/src/graphql/queries.ts new file mode 100644 index 000000000..bb60c8be6 --- /dev/null +++ b/server/src/graphql/queries.ts @@ -0,0 +1,13 @@ +import { graphql } from '../generated/graphql'; + +export const COURSE_EXISTS = graphql(` + query CourseExists($courseId: String!, $term: String!) { + courseExists: classes_aggregate( + where: { course_id: { _eq: $courseId }, term: { _eq: $term } } + ) { + aggregate { + count + } + } + } +`); diff --git a/server/tsconfig.json b/server/tsconfig.json index f668e37e1..5e4654c74 100644 --- a/server/tsconfig.json +++ b/server/tsconfig.json @@ -16,6 +16,12 @@ "forceConsistentCasingInFileNames": true, "noImplicitAny": true, "strictBindCallApply": true, - "noFallthroughCasesInSwitch": true + "noFallthroughCasesInSwitch": true, + "plugins": [ + { + "name": "@0no-co/graphqlsp", + "schema": "./schema.graphql" + } + ] } } From 49ae71a4e0a8ef82c9899b700e1265530289b066 Mon Sep 17 00:00:00 2001 From: Lucas Date: Mon, 23 Jun 2025 14:11:15 +1000 Subject: [PATCH 05/33] Fix GraphQL codegen --- server/codegen.ts | 10 +++++----- server/package.json | 3 ++- server/pnpm-lock.yaml | 3 +++ server/src/graphql/graphql.service.ts | 2 +- server/src/graphql/queries.ts | 2 +- 5 files changed, 12 insertions(+), 8 deletions(-) diff --git a/server/codegen.ts b/server/codegen.ts index 9dd24ebec..db9704356 100644 --- a/server/codegen.ts +++ b/server/codegen.ts @@ -6,11 +6,11 @@ const config: CodegenConfig = { ignoreNoDocuments: true, generates: { './src/generated/graphql/': { - plugins: [ - 'typescript', - 'typescript-operations', - 'typescript-graphql-request', - ], + // plugins: [ + // 'typescript', + // 'typescript-operations', + // 'typescript-graphql-request', + // ], preset: 'client', config: { documentMode: 'string', diff --git a/server/package.json b/server/package.json index 156c618ca..5beb1efc3 100644 --- a/server/package.json +++ b/server/package.json @@ -43,6 +43,7 @@ "@graphql-codegen/typescript": "4.1.6", "@graphql-codegen/typescript-graphql-request": "6.3.0", "@graphql-codegen/typescript-operations": "4.6.1", + "@graphql-typed-document-node/core": "3.2.0", "@nestjs/cli": "11.0.7", "@nestjs/schematics": "11.0.5", "@nestjs/testing": "11.1.1", @@ -88,5 +89,5 @@ "coverageDirectory": "../coverage", "testEnvironment": "node" }, - "packageManager": "pnpm@10.11.0+sha512.6540583f41cc5f628eb3d9773ecee802f4f9ef9923cc45b69890fb47991d4b092964694ec3a4f738a420c918a333062c8b925d312f42e4f0c263eb603551f977" + "packageManager": "pnpm@10.12.2+sha512.a32540185b964ee30bb4e979e405adc6af59226b438ee4cc19f9e8773667a66d302f5bfee60a39d3cac69e35e4b96e708a71dd002b7e9359c4112a1722ac323f" } diff --git a/server/pnpm-lock.yaml b/server/pnpm-lock.yaml index cd2264de7..6d8f9fcb7 100644 --- a/server/pnpm-lock.yaml +++ b/server/pnpm-lock.yaml @@ -69,6 +69,9 @@ importers: '@graphql-codegen/typescript-operations': specifier: 4.6.1 version: 4.6.1(graphql@16.11.0) + '@graphql-typed-document-node/core': + specifier: 3.2.0 + version: 3.2.0(graphql@16.11.0) '@nestjs/cli': specifier: 11.0.7 version: 11.0.7(@swc/cli@0.6.0(@swc/core@1.11.29)(chokidar@4.0.3))(@swc/core@1.11.29)(@types/node@22.15.21) diff --git a/server/src/graphql/graphql.service.ts b/server/src/graphql/graphql.service.ts index 7ff7e8ab6..b8f687d6b 100644 --- a/server/src/graphql/graphql.service.ts +++ b/server/src/graphql/graphql.service.ts @@ -1,6 +1,6 @@ import { Injectable } from '@nestjs/common'; import { GraphQLClient } from 'graphql-request'; -import { getSdk } from '../generated/graphql/graphql'; +import { getSdk } from '../generated/graphql'; const HASURAGRES_GRAPHQL_API = 'https://graphql.csesoc.app/v1/graphql'; diff --git a/server/src/graphql/queries.ts b/server/src/graphql/queries.ts index bb60c8be6..7e890c98f 100644 --- a/server/src/graphql/queries.ts +++ b/server/src/graphql/queries.ts @@ -1,4 +1,4 @@ -import { graphql } from '../generated/graphql'; +import { graphql } from '../generated/graphql/gql'; export const COURSE_EXISTS = graphql(` query CourseExists($courseId: String!, $term: String!) { From 70a470927c6b0d22cc6554204499dfeff792de1d Mon Sep 17 00:00:00 2001 From: Lucas Date: Thu, 26 Jun 2025 18:14:36 +1000 Subject: [PATCH 06/33] Fix GraphQL properly and add basic ODIC --- server/codegen.ts | 21 +- server/package.json | 38 +- server/pnpm-lock.yaml | 2061 ++++++++++++++++----------- server/pnpm-workspace.yaml | 1 + server/src/app.module.ts | 2 + server/src/auth/auth.controller.ts | 18 + server/src/auth/auth.module.ts | 23 + server/src/auth/auth.service.ts | 4 + server/src/auth/oidc.strategy.ts | 42 + server/src/graphql/queries.ts | 4 +- server/src/prisma/prisma.service.ts | 2 +- 11 files changed, 1345 insertions(+), 871 deletions(-) create mode 100644 server/src/auth/auth.controller.ts create mode 100644 server/src/auth/auth.module.ts create mode 100644 server/src/auth/auth.service.ts create mode 100644 server/src/auth/oidc.strategy.ts diff --git a/server/codegen.ts b/server/codegen.ts index db9704356..2041cddbf 100644 --- a/server/codegen.ts +++ b/server/codegen.ts @@ -5,18 +5,25 @@ const config: CodegenConfig = { documents: ['src/**/*.ts'], ignoreNoDocuments: true, generates: { - './src/generated/graphql/': { - // plugins: [ - // 'typescript', - // 'typescript-operations', - // 'typescript-graphql-request', - // ], - preset: 'client', + './src/generated/graphql.ts': { + plugins: [ + 'typescript', + 'typescript-operations', + 'typescript-graphql-request', + ], config: { documentMode: 'string', }, }, }, + pluckConfig: { + modules: [ + { + name: 'graphql-tag', + identifier: 'graphql', + }, + ], + }, }; export default config; diff --git a/server/package.json b/server/package.json index 5beb1efc3..fd97bf6c5 100644 --- a/server/package.json +++ b/server/package.json @@ -21,15 +21,17 @@ "graphql": "graphql-codegen --config codegen.ts" }, "dependencies": { - "@nestjs/common": "11.1.1", + "@nestjs/common": "11.1.3", "@nestjs/config": "4.0.2", - "@nestjs/core": "11.1.1", + "@nestjs/core": "11.1.3", "@nestjs/passport": "11.0.5", - "@nestjs/platform-express": "11.1.1", + "@nestjs/platform-express": "11.1.3", "@prisma/client": "6.8.2", "express-session": "1.18.1", "graphql": "16.11.0", "graphql-request": "7.2.0", + "graphql-tag": "2.12.6", + "openid-client": "6.6.1", "passport": "0.7.0", "reflect-metadata": "0.2.2", "rxjs": "7.8.2" @@ -37,40 +39,40 @@ "devDependencies": { "@0no-co/graphqlsp": "1.12.16", "@eslint/eslintrc": "3.3.1", - "@eslint/js": "9.27.0", - "@graphql-codegen/cli": "5.0.6", - "@graphql-codegen/client-preset": "4.8.1", + "@eslint/js": "9.29.0", + "@graphql-codegen/cli": "5.0.7", + "@graphql-codegen/client-preset": "4.8.3", "@graphql-codegen/typescript": "4.1.6", "@graphql-codegen/typescript-graphql-request": "6.3.0", "@graphql-codegen/typescript-operations": "4.6.1", - "@graphql-typed-document-node/core": "3.2.0", + "@graphql-tools/graphql-tag-pluck": "8.3.19", "@nestjs/cli": "11.0.7", "@nestjs/schematics": "11.0.5", - "@nestjs/testing": "11.1.1", + "@nestjs/testing": "11.1.3", "@parcel/watcher": "2.5.1", "@swc/cli": "0.6.0", "@swc/core": "1.11.29", - "@types/express": "5.0.2", - "@types/express-session": "1.18.1", - "@types/jest": "29.5.14", + "@types/express": "5.0.3", + "@types/express-session": "1.18.2", + "@types/jest": "30.0.0", "@types/node": "22.15.21", "@types/passport": "1.0.17", "@types/supertest": "6.0.3", - "eslint": "9.27.0", + "eslint": "9.29.0", "eslint-config-prettier": "10.1.5", - "eslint-plugin-prettier": "5.4.0", + "eslint-plugin-prettier": "5.5.1", "globals": "16.1.0", - "jest": "29.7.0", - "prettier": "3.5.3", + "jest": "30.0.3", + "prettier": "3.6.1", "prisma": "6.8.2", "source-map-support": "0.5.21", "supertest": "7.1.1", - "ts-jest": "29.3.4", + "ts-jest": "29.4.0", "ts-loader": "9.5.2", "ts-node": "10.9.2", "tsconfig-paths": "4.2.0", "typescript": "5.8.3", - "typescript-eslint": "8.32.1" + "typescript-eslint": "8.35.0" }, "jest": { "moduleFileExtensions": [ @@ -89,5 +91,5 @@ "coverageDirectory": "../coverage", "testEnvironment": "node" }, - "packageManager": "pnpm@10.12.2+sha512.a32540185b964ee30bb4e979e405adc6af59226b438ee4cc19f9e8773667a66d302f5bfee60a39d3cac69e35e4b96e708a71dd002b7e9359c4112a1722ac323f" + "packageManager": "pnpm@10.12.3+sha512.467df2c586056165580ad6dfb54ceaad94c5a30f80893ebdec5a44c5aa73c205ae4a5bb9d5ed6bb84ea7c249ece786642bbb49d06a307df218d03da41c317417" } diff --git a/server/pnpm-lock.yaml b/server/pnpm-lock.yaml index 6d8f9fcb7..eba35752d 100644 --- a/server/pnpm-lock.yaml +++ b/server/pnpm-lock.yaml @@ -9,20 +9,20 @@ importers: .: dependencies: '@nestjs/common': - specifier: 11.1.1 - version: 11.1.1(reflect-metadata@0.2.2)(rxjs@7.8.2) + specifier: 11.1.3 + version: 11.1.3(reflect-metadata@0.2.2)(rxjs@7.8.2) '@nestjs/config': specifier: 4.0.2 - version: 4.0.2(@nestjs/common@11.1.1(reflect-metadata@0.2.2)(rxjs@7.8.2))(rxjs@7.8.2) + version: 4.0.2(@nestjs/common@11.1.3(reflect-metadata@0.2.2)(rxjs@7.8.2))(rxjs@7.8.2) '@nestjs/core': - specifier: 11.1.1 - version: 11.1.1(@nestjs/common@11.1.1(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) + specifier: 11.1.3 + version: 11.1.3(@nestjs/common@11.1.3(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.3)(reflect-metadata@0.2.2)(rxjs@7.8.2) '@nestjs/passport': specifier: 11.0.5 - version: 11.0.5(@nestjs/common@11.1.1(reflect-metadata@0.2.2)(rxjs@7.8.2))(passport@0.7.0) + version: 11.0.5(@nestjs/common@11.1.3(reflect-metadata@0.2.2)(rxjs@7.8.2))(passport@0.7.0) '@nestjs/platform-express': - specifier: 11.1.1 - version: 11.1.1(@nestjs/common@11.1.1(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.1) + specifier: 11.1.3 + version: 11.1.3(@nestjs/common@11.1.3(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.3) '@prisma/client': specifier: 6.8.2 version: 6.8.2(prisma@6.8.2(typescript@5.8.3))(typescript@5.8.3) @@ -35,6 +35,12 @@ importers: graphql-request: specifier: 7.2.0 version: 7.2.0(graphql@16.11.0) + graphql-tag: + specifier: 2.12.6 + version: 2.12.6(graphql@16.11.0) + openid-client: + specifier: 6.6.1 + version: 6.6.1 passport: specifier: 0.7.0 version: 0.7.0 @@ -52,14 +58,14 @@ importers: specifier: 3.3.1 version: 3.3.1 '@eslint/js': - specifier: 9.27.0 - version: 9.27.0 + specifier: 9.29.0 + version: 9.29.0 '@graphql-codegen/cli': - specifier: 5.0.6 - version: 5.0.6(@parcel/watcher@2.5.1)(@types/node@22.15.21)(graphql@16.11.0)(typescript@5.8.3) + specifier: 5.0.7 + version: 5.0.7(@parcel/watcher@2.5.1)(@types/node@22.15.21)(graphql@16.11.0)(typescript@5.8.3) '@graphql-codegen/client-preset': - specifier: 4.8.1 - version: 4.8.1(graphql@16.11.0) + specifier: 4.8.3 + version: 4.8.3(graphql@16.11.0) '@graphql-codegen/typescript': specifier: 4.1.6 version: 4.1.6(graphql@16.11.0) @@ -69,9 +75,9 @@ importers: '@graphql-codegen/typescript-operations': specifier: 4.6.1 version: 4.6.1(graphql@16.11.0) - '@graphql-typed-document-node/core': - specifier: 3.2.0 - version: 3.2.0(graphql@16.11.0) + '@graphql-tools/graphql-tag-pluck': + specifier: 8.3.19 + version: 8.3.19(graphql@16.11.0) '@nestjs/cli': specifier: 11.0.7 version: 11.0.7(@swc/cli@0.6.0(@swc/core@1.11.29)(chokidar@4.0.3))(@swc/core@1.11.29)(@types/node@22.15.21) @@ -79,8 +85,8 @@ importers: specifier: 11.0.5 version: 11.0.5(chokidar@4.0.3)(typescript@5.8.3) '@nestjs/testing': - specifier: 11.1.1 - version: 11.1.1(@nestjs/common@11.1.1(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.1)(@nestjs/platform-express@11.1.1) + specifier: 11.1.3 + version: 11.1.3(@nestjs/common@11.1.3(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.3)(@nestjs/platform-express@11.1.3) '@parcel/watcher': specifier: 2.5.1 version: 2.5.1 @@ -91,14 +97,14 @@ importers: specifier: 1.11.29 version: 1.11.29 '@types/express': - specifier: 5.0.2 - version: 5.0.2 + specifier: 5.0.3 + version: 5.0.3 '@types/express-session': - specifier: 1.18.1 - version: 1.18.1 + specifier: 1.18.2 + version: 1.18.2 '@types/jest': - specifier: 29.5.14 - version: 29.5.14 + specifier: 30.0.0 + version: 30.0.0 '@types/node': specifier: 22.15.21 version: 22.15.21 @@ -109,23 +115,23 @@ importers: specifier: 6.0.3 version: 6.0.3 eslint: - specifier: 9.27.0 - version: 9.27.0(jiti@2.4.2) + specifier: 9.29.0 + version: 9.29.0(jiti@2.4.2) eslint-config-prettier: specifier: 10.1.5 - version: 10.1.5(eslint@9.27.0(jiti@2.4.2)) + version: 10.1.5(eslint@9.29.0(jiti@2.4.2)) eslint-plugin-prettier: - specifier: 5.4.0 - version: 5.4.0(@types/eslint@9.6.1)(eslint-config-prettier@10.1.5(eslint@9.27.0(jiti@2.4.2)))(eslint@9.27.0(jiti@2.4.2))(prettier@3.5.3) + specifier: 5.5.1 + version: 5.5.1(@types/eslint@9.6.1)(eslint-config-prettier@10.1.5(eslint@9.29.0(jiti@2.4.2)))(eslint@9.29.0(jiti@2.4.2))(prettier@3.6.1) globals: specifier: 16.1.0 version: 16.1.0 jest: - specifier: 29.7.0 - version: 29.7.0(@types/node@22.15.21)(ts-node@10.9.2(@swc/core@1.11.29)(@types/node@22.15.21)(typescript@5.8.3)) + specifier: 30.0.3 + version: 30.0.3(@types/node@22.15.21)(ts-node@10.9.2(@swc/core@1.11.29)(@types/node@22.15.21)(typescript@5.8.3)) prettier: - specifier: 3.5.3 - version: 3.5.3 + specifier: 3.6.1 + version: 3.6.1 prisma: specifier: 6.8.2 version: 6.8.2(typescript@5.8.3) @@ -136,8 +142,8 @@ importers: specifier: 7.1.1 version: 7.1.1 ts-jest: - specifier: 29.3.4 - version: 29.3.4(@babel/core@7.27.1)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.27.1))(jest@29.7.0(@types/node@22.15.21)(ts-node@10.9.2(@swc/core@1.11.29)(@types/node@22.15.21)(typescript@5.8.3)))(typescript@5.8.3) + specifier: 29.4.0 + version: 29.4.0(@babel/core@7.27.4)(@jest/transform@30.0.2)(@jest/types@30.0.1)(babel-jest@30.0.2(@babel/core@7.27.4))(jest-util@30.0.2)(jest@30.0.3(@types/node@22.15.21)(ts-node@10.9.2(@swc/core@1.11.29)(@types/node@22.15.21)(typescript@5.8.3)))(typescript@5.8.3) ts-loader: specifier: 9.5.2 version: 9.5.2(typescript@5.8.3)(webpack@5.99.6(@swc/core@1.11.29)) @@ -151,8 +157,8 @@ importers: specifier: 5.8.3 version: 5.8.3 typescript-eslint: - specifier: 8.32.1 - version: 8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3) + specifier: 8.35.0 + version: 8.35.0(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3) packages: @@ -229,10 +235,18 @@ packages: resolution: {integrity: sha512-IaaGWsQqfsQWVLqMn9OB92MNN7zukfVA4s7KKAI0KfrrDsZ0yhi5uV4baBuLuN7n3vsZpwP8asPPcVwApxvjBQ==} engines: {node: '>=6.9.0'} + '@babel/core@7.27.4': + resolution: {integrity: sha512-bXYxrXFubeYdvB0NhD/NBB3Qi6aZeV20GOWVI47t2dkecCEoneR4NPVcb7abpXDEvejgrUfFtG6vG/zxAKmg+g==} + engines: {node: '>=6.9.0'} + '@babel/generator@7.27.1': resolution: {integrity: sha512-UnJfnIpc/+JO0/+KRVQNGU+y5taA5vCbwN8+azkX6beii/ZF+enZJSOKo11ZSzGJjlNfJHfQtmQT8H+9TXPG2w==} engines: {node: '>=6.9.0'} + '@babel/generator@7.27.5': + resolution: {integrity: sha512-ZGhA37l0e/g2s1Cnzdix0O3aLYm66eF8aufiVteOgnwxgnRP8GoyMj7VWsgWnQbVKXyge7hqrFh2K2TQM6t1Hw==} + engines: {node: '>=6.9.0'} + '@babel/helper-annotate-as-pure@7.27.3': resolution: {integrity: sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==} engines: {node: '>=6.9.0'} @@ -261,6 +275,12 @@ packages: peerDependencies: '@babel/core': ^7.0.0 + '@babel/helper-module-transforms@7.27.3': + resolution: {integrity: sha512-dSOvYwvyLsWBeIRyOeHXp5vPj5l1I011r52FM1+r1jCERv+aFXYk4whgQccYEGYxK2H3ZAIA8nuPkQ0HaUo3qg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + '@babel/helper-optimise-call-expression@7.27.1': resolution: {integrity: sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==} engines: {node: '>=6.9.0'} @@ -295,11 +315,20 @@ packages: resolution: {integrity: sha512-FCvFTm0sWV8Fxhpp2McP5/W53GPllQ9QeQ7SiqGWjMf/LVG07lFa5+pgK05IRhVwtvafT22KF+ZSnM9I545CvQ==} engines: {node: '>=6.9.0'} + '@babel/helpers@7.27.6': + resolution: {integrity: sha512-muE8Tt8M22638HU31A3CgfSUciwz1fhATfoVai05aPXGor//CdWDCbnlY1yvBPo07njuVOCNGCSp/GTt12lIug==} + engines: {node: '>=6.9.0'} + '@babel/parser@7.27.2': resolution: {integrity: sha512-QYLs8299NA7WM/bZAdp+CviYYkVoYXlDW2rzliy3chxd1PQjej7JORuMJDJXJUb9g0TT+B99EwaVLKmX+sPXWw==} engines: {node: '>=6.0.0'} hasBin: true + '@babel/parser@7.27.5': + resolution: {integrity: sha512-OsQd175SxWkGlzbny8J3K8TnnDD0N3lrIUtB92xwyRpzaenGZhxDvxN/JgU00U3CDZNj9tPuDJ5H0WS4Nt3vKg==} + engines: {node: '>=6.0.0'} + hasBin: true + '@babel/plugin-proposal-class-properties@7.18.6': resolution: {integrity: sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==} engines: {node: '>=6.9.0'} @@ -549,6 +578,10 @@ packages: resolution: {integrity: sha512-ZCYtZciz1IWJB4U61UPu4KEaqyfj+r5T1Q5mqPo+IBpcG9kHv30Z0aD8LXPgC1trYa6rK0orRyAhqUgk4MjmEg==} engines: {node: '>=6.9.0'} + '@babel/traverse@7.27.4': + resolution: {integrity: sha512-oNcu2QbHqts9BtOWJosOVJapWjBDSxGCpFvikNR5TGDYDQf3JwpIoMzIKrvfoti93cLfPJEG4tH9SPVeyCGgdA==} + engines: {node: '>=6.9.0'} + '@babel/types@7.27.1': resolution: {integrity: sha512-+EzkxvLNfiUeKMgy/3luqfsCWFRXLb7U6wNQTk60tovuckwB15B191tJWvpp4HjiQWdJkCxO3Wbvc6jlk3Xb2Q==} engines: {node: '>=6.9.0'} @@ -557,6 +590,10 @@ packages: resolution: {integrity: sha512-Y1GkI4ktrtvmawoSq+4FCVHNryea6uR+qUQy0AGxLSsjCX0nVmkYQMBLHDkXZuo5hGx7eYdnIaslsdBFm7zbUw==} engines: {node: '>=6.9.0'} + '@babel/types@7.27.6': + resolution: {integrity: sha512-ETyHEk2VHHvl9b9jZP5IHPavHYk57EhanlRRuae9XCpb/j5bDCbPPMOBfCWhnl/7EDJz0jEMCi/RhccCE8r1+Q==} + engines: {node: '>=6.9.0'} + '@bcoe/v8-coverage@0.2.3': resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} @@ -568,6 +605,15 @@ packages: resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} engines: {node: '>=12'} + '@emnapi/core@1.4.3': + resolution: {integrity: sha512-4m62DuCE07lw01soJwPiBGC0nAww0Q+RY70VZ+n49yDIO13yyinhbWCeNnaob0lakDtWQzSdtNWzJeOJt2ma+g==} + + '@emnapi/runtime@1.4.3': + resolution: {integrity: sha512-pBPWdu6MLKROBX05wSNKcNb++m5Er+KQ9QkB+WVM+pW2Kx9hoSrVTnu3BdkI5eBLZoKu/J6mW/B6i6bJB2ytXQ==} + + '@emnapi/wasi-threads@1.0.2': + resolution: {integrity: sha512-5n3nTJblwRi8LlXkJ9eBzu+kZR8Yxcc7ubakyQTFzPMtIhFpUBRbsnc2Dv88IZDIbCDlBiWrknhB4Lsz7mg6BA==} + '@envelop/core@5.2.3': resolution: {integrity: sha512-KfoGlYD/XXQSc3BkM1/k15+JQbkQ4ateHazeZoWl9P71FsLTDXSjGy6j7QqfhpIDSbxNISqhPMfZHYSbDFOofQ==} engines: {node: '>=18.0.0'} @@ -590,8 +636,8 @@ packages: resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - '@eslint/config-array@0.20.0': - resolution: {integrity: sha512-fxlS1kkIjx8+vy2SjuCB94q3htSNrufYTXubwiBFeaQHbH6Ipi43gFJq2zCMt6PHhImH3Xmr0NksKDvchWlpQQ==} + '@eslint/config-array@0.20.1': + resolution: {integrity: sha512-OL0RJzC/CBzli0DrrR31qzj6d6i6Mm3HByuhflhl4LOBiWxN+3i6/t/ZQQNii4tjksXi8r2CRW1wMpWA2ULUEw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@eslint/config-helpers@0.2.2': @@ -606,8 +652,8 @@ packages: resolution: {integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/js@9.27.0': - resolution: {integrity: sha512-G5JD9Tu5HJEu4z2Uo4aHY2sLV64B7CDMXxFzqzjl3NKd6RVzSXNoE80jk7Y0lJkTTkjiIhBAqmlYwjuBY3tvpA==} + '@eslint/js@9.29.0': + resolution: {integrity: sha512-3PIF4cBw/y+1u2EazflInpV+lYsSG0aByVIQzAgb1m1MhHFSbqTyNqtBKHgWf/9Ykud+DhILS9EGkmekVhbKoQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@eslint/object-schema@2.1.6': @@ -632,8 +678,8 @@ packages: 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 - '@graphql-codegen/cli@5.0.6': - resolution: {integrity: sha512-1r5dtZ2l1jiCF/4qLMTcT7mEoWWWeqQlmn7HcPHgnV/OXIEodwox7XRGAmOKUygoabRjFF3S0jd0TWbkq5Otsw==} + '@graphql-codegen/cli@5.0.7': + resolution: {integrity: sha512-h/sxYvSaWtxZxo8GtaA8SvcHTyViaaPd7dweF/hmRDpaQU1o3iU3EZxlcJ+oLTunU0tSMFsnrIXm/mhXxI11Cw==} engines: {node: '>=16'} hasBin: true peerDependencies: @@ -643,8 +689,8 @@ packages: '@parcel/watcher': optional: true - '@graphql-codegen/client-preset@4.8.1': - resolution: {integrity: sha512-XLF2V7WKLnepvrGE44JP+AvjS+Oz9AT0oYgTl/6d9btQ+2VYFcmwQPjNAuMVHipqE9I6h8hSEfH9hUrzUptB1g==} + '@graphql-codegen/client-preset@4.8.3': + resolution: {integrity: sha512-QpEsPSO9fnRxA6Z66AmBuGcwHjZ6dYSxYo5ycMlYgSPzAbyG8gn/kWljofjJfWqSY+T/lRn+r8IXTH14ml24vQ==} engines: {node: '>=16'} 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 @@ -675,13 +721,19 @@ packages: 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 + '@graphql-codegen/plugin-helpers@5.1.1': + resolution: {integrity: sha512-28GHODK2HY1NhdyRcPP3sCz0Kqxyfiz7boIZ8qIxFYmpLYnlDgiYok5fhFLVSZihyOpCs4Fa37gVHf/Q4I2FEg==} + engines: {node: '>=16'} + 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 + '@graphql-codegen/schema-ast@4.1.0': resolution: {integrity: sha512-kZVn0z+th9SvqxfKYgztA6PM7mhnSZaj4fiuBWvMTqA+QqQ9BBed6Pz41KuD/jr0gJtnlr2A4++/0VlpVbCTmQ==} 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 - '@graphql-codegen/typed-document-node@5.1.1': - resolution: {integrity: sha512-Bp/BrMZDKRwzuVeLv+pSljneqONM7gqu57ZaV34Jbncu2hZWMRDMfizTKghoEwwZbRCYYfJO9tA0sYVVIfI1kg==} + '@graphql-codegen/typed-document-node@5.1.2': + resolution: {integrity: sha512-jaxfViDqFRbNQmfKwUY8hDyjnLTw2Z7DhGutxoOiiAI0gE/LfPe0LYaVFKVmVOOD7M3bWxoWfu4slrkbWbUbEw==} engines: {node: '>=16'} 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 @@ -1057,71 +1109,87 @@ packages: resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} engines: {node: '>=8'} - '@jest/console@29.7.0': - resolution: {integrity: sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/console@30.0.2': + resolution: {integrity: sha512-krGElPU0FipAqpVZ/BRZOy0MZh/ARdJ0Nj+PiH1ykFY1+VpBlYNLjdjVA5CFKxnKR6PFqFutO4Z7cdK9BlGiDA==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - '@jest/core@29.7.0': - resolution: {integrity: sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/core@30.0.3': + resolution: {integrity: sha512-Mgs1N+NSHD3Fusl7bOq1jyxv1JDAUwjy+0DhVR93Q6xcBP9/bAQ+oZhXb5TTnP5sQzAHgb7ROCKQ2SnovtxYtg==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} peerDependencies: node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 peerDependenciesMeta: node-notifier: optional: true - '@jest/environment@29.7.0': - resolution: {integrity: sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/diff-sequences@30.0.1': + resolution: {integrity: sha512-n5H8QLDJ47QqbCNn5SuFjCRDrOLEZ0h8vAHCK5RL9Ls7Xa8AQLa/YxAc9UjFqoEDM48muwtBGjtMY5cr0PLDCw==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + '@jest/environment@30.0.2': + resolution: {integrity: sha512-hRLhZRJNxBiOhxIKSq2UkrlhMt3/zVFQOAi5lvS8T9I03+kxsbflwHJEF+eXEYXCrRGRhHwECT7CDk6DyngsRA==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + '@jest/expect-utils@30.0.3': + resolution: {integrity: sha512-SMtBvf2sfX2agcT0dA9pXwcUrKvOSDqBY4e4iRfT+Hya33XzV35YVg+98YQFErVGA/VR1Gto5Y2+A6G9LSQ3Yg==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + '@jest/expect@30.0.3': + resolution: {integrity: sha512-73BVLqfCeWjYWPEQoYjiRZ4xuQRhQZU0WdgvbyXGRHItKQqg5e6mt2y1kVhzLSuZpmUnccZHbGynoaL7IcLU3A==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - '@jest/expect-utils@29.7.0': - resolution: {integrity: sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/fake-timers@30.0.2': + resolution: {integrity: sha512-jfx0Xg7l0gmphTY9UKm5RtH12BlLYj/2Plj6wXjVW5Era4FZKfXeIvwC67WX+4q8UCFxYS20IgnMcFBcEU0DtA==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - '@jest/expect@29.7.0': - resolution: {integrity: sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/get-type@30.0.1': + resolution: {integrity: sha512-AyYdemXCptSRFirI5EPazNxyPwAL0jXt3zceFjaj8NFiKP9pOi0bfXonf6qkf82z2t3QWPeLCWWw4stPBzctLw==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - '@jest/fake-timers@29.7.0': - resolution: {integrity: sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/globals@30.0.3': + resolution: {integrity: sha512-fIduqNyYpMeeSr5iEAiMn15KxCzvrmxl7X7VwLDRGj7t5CoHtbF+7K3EvKk32mOUIJ4kIvFRlaixClMH2h/Vaw==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - '@jest/globals@29.7.0': - resolution: {integrity: sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/pattern@30.0.1': + resolution: {integrity: sha512-gWp7NfQW27LaBQz3TITS8L7ZCQ0TLvtmI//4OwlQRx4rnWxcPNIYjxZpDcN4+UlGxgm3jS5QPz8IPTCkb59wZA==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - '@jest/reporters@29.7.0': - resolution: {integrity: sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/reporters@30.0.2': + resolution: {integrity: sha512-l4QzS/oKf57F8WtPZK+vvF4Io6ukplc6XgNFu4Hd/QxaLEO9f+8dSFzUua62Oe0HKlCUjKHpltKErAgDiMJKsA==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} peerDependencies: node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 peerDependenciesMeta: node-notifier: optional: true - '@jest/schemas@29.6.3': - resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/schemas@30.0.1': + resolution: {integrity: sha512-+g/1TKjFuGrf1Hh0QPCv0gISwBxJ+MQSNXmG9zjHy7BmFhtoJ9fdNhWJp3qUKRi93AOZHXtdxZgJ1vAtz6z65w==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - '@jest/source-map@29.6.3': - resolution: {integrity: sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/snapshot-utils@30.0.1': + resolution: {integrity: sha512-6Dpv7vdtoRiISEFwYF8/c7LIvqXD7xDXtLPNzC2xqAfBznKip0MQM+rkseKwUPUpv2PJ7KW/YsnwWXrIL2xF+A==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - '@jest/test-result@29.7.0': - resolution: {integrity: sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/source-map@30.0.1': + resolution: {integrity: sha512-MIRWMUUR3sdbP36oyNyhbThLHyJ2eEDClPCiHVbrYAe5g3CHRArIVpBw7cdSB5fr+ofSfIb2Tnsw8iEHL0PYQg==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - '@jest/test-sequencer@29.7.0': - resolution: {integrity: sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/test-result@30.0.2': + resolution: {integrity: sha512-KKMuBKkkZYP/GfHMhI+cH2/P3+taMZS3qnqqiPC1UXZTJskkCS+YU/ILCtw5anw1+YsTulDHFpDo70mmCedW8w==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - '@jest/transform@29.7.0': - resolution: {integrity: sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/test-sequencer@30.0.2': + resolution: {integrity: sha512-fbyU5HPka0rkalZ3MXVvq0hwZY8dx3Y6SCqR64zRmh+xXlDeFl0IdL4l9e7vp4gxEXTYHbwLFA1D+WW5CucaSw==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - '@jest/types@29.6.3': - resolution: {integrity: sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/transform@30.0.2': + resolution: {integrity: sha512-kJIuhLMTxRF7sc0gPzPtCDib/V9KwW3I2U25b+lYCYMVqHHSrcZopS8J8H+znx9yixuFv+Iozl8raLt/4MoxrA==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + '@jest/types@30.0.1': + resolution: {integrity: sha512-HGwoYRVF0QSKJu1ZQX0o5ZrUrrhj0aOOFA8hXrumD7SIzjouevhawbTjmXdwOmURdGluU9DM/XvGm3NyFoiQjw==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} '@jridgewell/gen-mapping@0.3.8': resolution: {integrity: sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==} @@ -1251,6 +1319,9 @@ packages: resolution: {integrity: sha512-zM0mVWSXE0a0h9aKACLwKmD6nHcRiKrPpCfvaKqG1CqDEyjEawId0ocXxVzPMCAm6kkWr2P025msfxXEnt8UGQ==} engines: {node: '>= 10'} + '@napi-rs/wasm-runtime@0.2.11': + resolution: {integrity: sha512-9DPkXtvHydrcOsopiYpUgPHpmj0HWZKMUnL2dZqpvC42lsratuBG06V5ipyno0fUek5VlFsNQ+AcFATSrJXgMA==} + '@nestjs/cli@11.0.7': resolution: {integrity: sha512-svrP8j1R0/lQVJ8ZI3BlDtuZxmkvVJokUJSB04sr6uibunk2wHeVDDVLZvYBUorCdGU/RHJl1IufhqUBM91vAQ==} engines: {node: '>= 20.11'} @@ -1264,8 +1335,8 @@ packages: '@swc/core': optional: true - '@nestjs/common@11.1.1': - resolution: {integrity: sha512-crzp+1qeZ5EGL0nFTPy9NrVMAaUWewV5AwtQyv6SQ9yQPXwRl9W9hm1pt0nAtUu5QbYMbSuo7lYcF81EjM+nCA==} + '@nestjs/common@11.1.3': + resolution: {integrity: sha512-ogEK+GriWodIwCw6buQ1rpcH4Kx+G7YQ9EwuPySI3rS05pSdtQ++UhucjusSI9apNidv+QURBztJkRecwwJQXg==} peerDependencies: class-transformer: '>=0.4.1' class-validator: '>=0.13.2' @@ -1283,8 +1354,8 @@ packages: '@nestjs/common': ^10.0.0 || ^11.0.0 rxjs: ^7.1.0 - '@nestjs/core@11.1.1': - resolution: {integrity: sha512-UFoUAgLKFT+RwHTANJdr0dF7p0qS9QjkaUPjg8aafnjM/qxxxrUVDB49nVvyMlk+Hr1+vvcNaOHbWWQBxoZcHA==} + '@nestjs/core@11.1.3': + resolution: {integrity: sha512-5lTni0TCh8x7bXETRD57pQFnKnEg1T6M+VLE7wAmyQRIecKQU+2inRGZD+A4v2DC1I04eA0WffP0GKLxjOKlzw==} engines: {node: '>= 20'} peerDependencies: '@nestjs/common': ^11.0.0 @@ -1307,8 +1378,8 @@ packages: '@nestjs/common': ^10.0.0 || ^11.0.0 passport: ^0.5.0 || ^0.6.0 || ^0.7.0 - '@nestjs/platform-express@11.1.1': - resolution: {integrity: sha512-IUxk380qnUtz0PCRQ5i+o9UHlGMrFzGPIJxDwyt3JZZwx2AngOlcEcm5e+7YeJQEr2QYX2QyC4tUQg0zde+D7A==} + '@nestjs/platform-express@11.1.3': + resolution: {integrity: sha512-hEDNMlaPiBO72fxxX/CuRQL3MEhKRc/sIYGVoXjrnw6hTxZdezvvM6A95UaLsYknfmcZZa/CdG1SMBZOu9agHQ==} peerDependencies: '@nestjs/common': ^11.0.0 '@nestjs/core': ^11.0.0 @@ -1318,8 +1389,8 @@ packages: peerDependencies: typescript: '>=4.8.2' - '@nestjs/testing@11.1.1': - resolution: {integrity: sha512-stzm8YrLDGAijHYQw+8Z9dD6lGdvahL0hIjGVZ/0KBxLZht0/rvRjgV31UK+DUqXaF7yhJTw9ryrPaITxI1J6A==} + '@nestjs/testing@11.1.3': + resolution: {integrity: sha512-CeXG6/eEqgFIkPkmU00y18Dd3DLOIDFhPItzJK1SWckKo6IhcnfoRJzGx75bmuvUMjb51j6An96S/+MJ2ty9jA==} peerDependencies: '@nestjs/common': ^11.0.0 '@nestjs/core': ^11.0.0 @@ -1437,6 +1508,10 @@ packages: resolution: {integrity: sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==} engines: {node: '>= 10.0.0'} + '@pkgjs/parseargs@0.11.0': + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + '@pkgr/core@0.2.4': resolution: {integrity: sha512-ROFF39F6ZrnzSUEmQQZUar0Jt4xVoP9WnDRdWwF4NNcXs3xBTLgBUDoOwW141y1jP+S8nahIbdxbFC7IShw9Iw==} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} @@ -1477,8 +1552,8 @@ packages: '@sec-ant/readable-stream@0.4.1': resolution: {integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==} - '@sinclair/typebox@0.27.8': - resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} + '@sinclair/typebox@0.34.37': + resolution: {integrity: sha512-2TRuQVgQYfy+EzHRTIvkhv2ADEouJ2xNS/Vq+W5EuuewBdOrvATvljZTxHWZSTYr2sTjTHpGvucaGAt67S2akw==} '@sindresorhus/is@5.6.0': resolution: {integrity: sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==} @@ -1487,8 +1562,8 @@ packages: '@sinonjs/commons@3.0.1': resolution: {integrity: sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==} - '@sinonjs/fake-timers@10.3.0': - resolution: {integrity: sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==} + '@sinonjs/fake-timers@13.0.5': + resolution: {integrity: sha512-36/hTbH2uaWuGVERyC6da9YwGWnzUZXuPro/F2LfsdOsLnCojz/iSH8MxUt/FD2S5XBSVPhmArFUXcpCQ2Hkiw==} '@swc/cli@0.6.0': resolution: {integrity: sha512-Q5FsI3Cw0fGMXhmsg7c08i4EmXCrcl+WnAxb6LYOLHw4JFFC3yzmx9LaXZ7QMbA+JZXbigU2TirI7RAfO0Qlnw==} @@ -1599,6 +1674,9 @@ packages: '@tsconfig/node16@1.0.4': resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} + '@tybys/wasm-util@0.9.0': + resolution: {integrity: sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw==} + '@types/babel__core@7.20.5': resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} @@ -1632,14 +1710,11 @@ packages: '@types/express-serve-static-core@5.0.6': resolution: {integrity: sha512-3xhRnjJPkULekpSzgtoNYYcTWgEZkp4myc+Saevii5JPnHNvHMRlBSHDbs7Bh1iPPoVTERHEZXyhyLbMEsExsA==} - '@types/express-session@1.18.1': - resolution: {integrity: sha512-S6TkD/lljxDlQ2u/4A70luD8/ZxZcrU5pQwI1rVXCiaVIywoFgbA+PIUNDjPhQpPdK0dGleLtYc/y7XWBfclBg==} - - '@types/express@5.0.2': - resolution: {integrity: sha512-BtjL3ZwbCQriyb0DGw+Rt12qAXPiBTPs815lsUvtt1Grk0vLRMZNMUZ741d5rjk+UQOxfDiBZ3dxpX00vSkK3g==} + '@types/express-session@1.18.2': + resolution: {integrity: sha512-k+I0BxwVXsnEU2hV77cCobC08kIsn4y44C3gC0b46uxZVMaXA04lSPgRLR/bSL2w0t0ShJiG8o4jPzRG/nscFg==} - '@types/graceful-fs@4.1.9': - resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==} + '@types/express@5.0.3': + resolution: {integrity: sha512-wGA0NX93b19/dZC1J18tKWVIYWyyF2ZjT9vin/NRu0qzzvfVzWjs04iq2rQ3H65vCTQYlRqs3YHfY7zjdV+9Kw==} '@types/http-cache-semantics@4.0.4': resolution: {integrity: sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==} @@ -1656,8 +1731,8 @@ packages: '@types/istanbul-reports@3.0.4': resolution: {integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==} - '@types/jest@29.5.14': - resolution: {integrity: sha512-ZN+4sdnLUbo8EVvVc2ao0GFW6oVrQRPn4K2lglySj7APvSrgzxHiNNK99us4WDMi57xxA2yggblIAMNhXOotLQ==} + '@types/jest@30.0.0': + resolution: {integrity: sha512-XTYugzhuwqWjws0CVz8QpM36+T+Dz5mTEBKhNs/esGLnCIlGdRy+Dq78NRjd7ls7r8BC8ZRMOrKlkO1hU0JOwA==} '@types/js-yaml@4.0.9': resolution: {integrity: sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==} @@ -1707,53 +1782,163 @@ packages: '@types/yargs@17.0.33': resolution: {integrity: sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==} - '@typescript-eslint/eslint-plugin@8.32.1': - resolution: {integrity: sha512-6u6Plg9nP/J1GRpe/vcjjabo6Uc5YQPAMxsgQyGC/I0RuukiG1wIe3+Vtg3IrSCVJDmqK3j8adrtzXSENRtFgg==} + '@typescript-eslint/eslint-plugin@8.35.0': + resolution: {integrity: sha512-ijItUYaiWuce0N1SoSMrEd0b6b6lYkYt99pqCPfybd+HKVXtEvYhICfLdwp42MhiI5mp0oq7PKEL+g1cNiz/Eg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.0.0 || ^8.0.0-alpha.0 + '@typescript-eslint/parser': ^8.35.0 eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/parser@8.32.1': - resolution: {integrity: sha512-LKMrmwCPoLhM45Z00O1ulb6jwyVr2kr3XJp+G+tSEZcbauNnScewcQwtJqXDhXeYPDEjZ8C1SjXm015CirEmGg==} + '@typescript-eslint/parser@8.35.0': + resolution: {integrity: sha512-6sMvZePQrnZH2/cJkwRpkT7DxoAWh+g6+GFRK6bV3YQo7ogi3SX5rgF6099r5Q53Ma5qeT7LGmOmuIutF4t3lA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/scope-manager@8.32.1': - resolution: {integrity: sha512-7IsIaIDeZn7kffk7qXC3o6Z4UblZJKV3UBpkvRNpr5NSyLji7tvTcvmnMNYuYLyh26mN8W723xpo3i4MlD33vA==} + '@typescript-eslint/project-service@8.35.0': + resolution: {integrity: sha512-41xatqRwWZuhUMF/aZm2fcUsOFKNcG28xqRSS6ZVr9BVJtGExosLAm5A1OxTjRMagx8nJqva+P5zNIGt8RIgbQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/type-utils@8.32.1': - resolution: {integrity: sha512-mv9YpQGA8iIsl5KyUPi+FGLm7+bA4fgXaeRcFKRDRwDMu4iwrSHeDPipwueNXhdIIZltwCJv+NkxftECbIZWfA==} + '@typescript-eslint/scope-manager@8.35.0': + resolution: {integrity: sha512-+AgL5+mcoLxl1vGjwNfiWq5fLDZM1TmTPYs2UkyHfFhgERxBbqHlNjRzhThJqz+ktBqTChRYY6zwbMwy0591AA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/tsconfig-utils@8.35.0': + resolution: {integrity: sha512-04k/7247kZzFraweuEirmvUj+W3bJLI9fX6fbo1Qm2YykuBvEhRTPl8tcxlYO8kZZW+HIXfkZNoasVb8EV4jpA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <5.9.0' + + '@typescript-eslint/type-utils@8.35.0': + resolution: {integrity: sha512-ceNNttjfmSEoM9PW87bWLDEIaLAyR+E6BoYJQ5PfaDau37UGca9Nyq3lBk8Bw2ad0AKvYabz6wxc7DMTO2jnNA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/types@8.32.1': - resolution: {integrity: sha512-YmybwXUJcgGqgAp6bEsgpPXEg6dcCyPyCSr0CAAueacR/CCBi25G3V8gGQ2kRzQRBNol7VQknxMs9HvVa9Rvfg==} + '@typescript-eslint/types@8.35.0': + resolution: {integrity: sha512-0mYH3emanku0vHw2aRLNGqe7EXh9WHEhi7kZzscrMDf6IIRUQ5Jk4wp1QrledE/36KtdZrVfKnE32eZCf/vaVQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@8.32.1': - resolution: {integrity: sha512-Y3AP9EIfYwBb4kWGb+simvPaqQoT5oJuzzj9m0i6FCY6SPvlomY2Ei4UEMm7+FXtlNJbor80ximyslzaQF6xhg==} + '@typescript-eslint/typescript-estree@8.35.0': + resolution: {integrity: sha512-F+BhnaBemgu1Qf8oHrxyw14wq6vbL8xwWKKMwTMwYIRmFFY/1n/9T/jpbobZL8vp7QyEUcC6xGrnAO4ua8Kp7w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/utils@8.32.1': - resolution: {integrity: sha512-DsSFNIgLSrc89gpq1LJB7Hm1YpuhK086DRDJSNrewcGvYloWW1vZLHBTIvarKZDcAORIy/uWNx8Gad+4oMpkSA==} + '@typescript-eslint/utils@8.35.0': + resolution: {integrity: sha512-nqoMu7WWM7ki5tPgLVsmPM8CkqtoPUG6xXGeefM5t4x3XumOEKMoUZPdi+7F+/EotukN4R9OWdmDxN80fqoZeg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/visitor-keys@8.32.1': - resolution: {integrity: sha512-ar0tjQfObzhSaW3C3QNmTc5ofj0hDoNQ5XWrCy6zDyabdr0TWhCkClp+rywGNj/odAFBVzzJrK4tEq5M4Hmu4w==} + '@typescript-eslint/visitor-keys@8.35.0': + resolution: {integrity: sha512-zTh2+1Y8ZpmeQaQVIc/ZZxsx8UzgKJyNg1PTvjzC7WMhPSVS8bfDX34k1SrwOf016qd5RU3az2UxUNue3IfQ5g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@ungap/structured-clone@1.3.0': + resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} + + '@unrs/resolver-binding-android-arm-eabi@1.9.2': + resolution: {integrity: sha512-tS+lqTU3N0kkthU+rYp0spAYq15DU8ld9kXkaKg9sbQqJNF+WPMuNHZQGCgdxrUOEO0j22RKMwRVhF1HTl+X8A==} + cpu: [arm] + os: [android] + + '@unrs/resolver-binding-android-arm64@1.9.2': + resolution: {integrity: sha512-MffGiZULa/KmkNjHeuuflLVqfhqLv1vZLm8lWIyeADvlElJ/GLSOkoUX+5jf4/EGtfwrNFcEaB8BRas03KT0/Q==} + cpu: [arm64] + os: [android] + + '@unrs/resolver-binding-darwin-arm64@1.9.2': + resolution: {integrity: sha512-dzJYK5rohS1sYl1DHdJ3mwfwClJj5BClQnQSyAgEfggbUwA9RlROQSSbKBLqrGfsiC/VyrDPtbO8hh56fnkbsQ==} + cpu: [arm64] + os: [darwin] + + '@unrs/resolver-binding-darwin-x64@1.9.2': + resolution: {integrity: sha512-gaIMWK+CWtXcg9gUyznkdV54LzQ90S3X3dn8zlh+QR5Xy7Y+Efqw4Rs4im61K1juy4YNb67vmJsCDAGOnIeffQ==} + cpu: [x64] + os: [darwin] + + '@unrs/resolver-binding-freebsd-x64@1.9.2': + resolution: {integrity: sha512-S7QpkMbVoVJb0xwHFwujnwCAEDe/596xqY603rpi/ioTn9VDgBHnCCxh+UFrr5yxuMH+dliHfjwCZJXOPJGPnw==} + cpu: [x64] + os: [freebsd] + + '@unrs/resolver-binding-linux-arm-gnueabihf@1.9.2': + resolution: {integrity: sha512-+XPUMCuCCI80I46nCDFbGum0ZODP5NWGiwS3Pj8fOgsG5/ctz+/zzuBlq/WmGa+EjWZdue6CF0aWWNv84sE1uw==} + cpu: [arm] + os: [linux] + + '@unrs/resolver-binding-linux-arm-musleabihf@1.9.2': + resolution: {integrity: sha512-sqvUyAd1JUpwbz33Ce2tuTLJKM+ucSsYpPGl2vuFwZnEIg0CmdxiZ01MHQ3j6ExuRqEDUCy8yvkDKvjYFPb8Zg==} + cpu: [arm] + os: [linux] + + '@unrs/resolver-binding-linux-arm64-gnu@1.9.2': + resolution: {integrity: sha512-UYA0MA8ajkEDCFRQdng/FVx3F6szBvk3EPnkTTQuuO9lV1kPGuTB+V9TmbDxy5ikaEgyWKxa4CI3ySjklZ9lFA==} + cpu: [arm64] + os: [linux] + + '@unrs/resolver-binding-linux-arm64-musl@1.9.2': + resolution: {integrity: sha512-P/CO3ODU9YJIHFqAkHbquKtFst0COxdphc8TKGL5yCX75GOiVpGqd1d15ahpqu8xXVsqP4MGFP2C3LRZnnL5MA==} + cpu: [arm64] + os: [linux] + + '@unrs/resolver-binding-linux-ppc64-gnu@1.9.2': + resolution: {integrity: sha512-uKStFlOELBxBum2s1hODPtgJhY4NxYJE9pAeyBgNEzHgTqTiVBPjfTlPFJkfxyTjQEuxZbbJlJnMCrRgD7ubzw==} + cpu: [ppc64] + os: [linux] + + '@unrs/resolver-binding-linux-riscv64-gnu@1.9.2': + resolution: {integrity: sha512-LkbNnZlhINfY9gK30AHs26IIVEZ9PEl9qOScYdmY2o81imJYI4IMnJiW0vJVtXaDHvBvxeAgEy5CflwJFIl3tQ==} + cpu: [riscv64] + os: [linux] + + '@unrs/resolver-binding-linux-riscv64-musl@1.9.2': + resolution: {integrity: sha512-vI+e6FzLyZHSLFNomPi+nT+qUWN4YSj8pFtQZSFTtmgFoxqB6NyjxSjAxEC1m93qn6hUXhIsh8WMp+fGgxCoRg==} + cpu: [riscv64] + os: [linux] + + '@unrs/resolver-binding-linux-s390x-gnu@1.9.2': + resolution: {integrity: sha512-sSO4AlAYhSM2RAzBsRpahcJB1msc6uYLAtP6pesPbZtptF8OU/CbCPhSRW6cnYOGuVmEmWVW5xVboAqCnWTeHQ==} + cpu: [s390x] + os: [linux] + + '@unrs/resolver-binding-linux-x64-gnu@1.9.2': + resolution: {integrity: sha512-jkSkwch0uPFva20Mdu8orbQjv2A3G88NExTN2oPTI1AJ+7mZfYW3cDCTyoH6OnctBKbBVeJCEqh0U02lTkqD5w==} + cpu: [x64] + os: [linux] + + '@unrs/resolver-binding-linux-x64-musl@1.9.2': + resolution: {integrity: sha512-Uk64NoiTpQbkpl+bXsbeyOPRpUoMdcUqa+hDC1KhMW7aN1lfW8PBlBH4mJ3n3Y47dYE8qi0XTxy1mBACruYBaw==} + cpu: [x64] + os: [linux] + + '@unrs/resolver-binding-wasm32-wasi@1.9.2': + resolution: {integrity: sha512-EpBGwkcjDicjR/ybC0g8wO5adPNdVuMrNalVgYcWi+gYtC1XYNuxe3rufcO7dA76OHGeVabcO6cSkPJKVcbCXQ==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + + '@unrs/resolver-binding-win32-arm64-msvc@1.9.2': + resolution: {integrity: sha512-EdFbGn7o1SxGmN6aZw9wAkehZJetFPao0VGZ9OMBwKx6TkvDuj6cNeLimF/Psi6ts9lMOe+Dt6z19fZQ9Ye2fw==} + cpu: [arm64] + os: [win32] + + '@unrs/resolver-binding-win32-ia32-msvc@1.9.2': + resolution: {integrity: sha512-JY9hi1p7AG+5c/dMU8o2kWemM8I6VZxfGwn1GCtf3c5i+IKcMo2NQ8OjZ4Z3/itvY/Si3K10jOBQn7qsD/whUA==} + cpu: [ia32] + os: [win32] + + '@unrs/resolver-binding-win32-x64-msvc@1.9.2': + resolution: {integrity: sha512-ryoo+EB19lMxAd80ln9BVf8pdOAxLb97amrQ3SFN9OCRn/5M5wvwDgAe4i8ZjhpbiHoDeP8yavcTEnpKBo7lZg==} + cpu: [x64] + os: [win32] + '@webassemblyjs/ast@1.14.1': resolution: {integrity: sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==} @@ -1879,6 +2064,11 @@ packages: engines: {node: '>=0.4.0'} hasBin: true + acorn@8.15.0: + resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} + engines: {node: '>=0.4.0'} + hasBin: true + agent-base@7.1.3: resolution: {integrity: sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==} engines: {node: '>= 14'} @@ -1997,19 +2187,19 @@ packages: b4a@1.6.7: resolution: {integrity: sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg==} - babel-jest@29.7.0: - resolution: {integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + babel-jest@30.0.2: + resolution: {integrity: sha512-A5kqR1/EUTidM2YC2YMEUDP2+19ppgOwK0IAd9Swc3q2KqFb5f9PtRUXVeZcngu0z5mDMyZ9zH2huJZSOMLiTQ==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} peerDependencies: - '@babel/core': ^7.8.0 + '@babel/core': ^7.11.0 - babel-plugin-istanbul@6.1.1: - resolution: {integrity: sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==} - engines: {node: '>=8'} + babel-plugin-istanbul@7.0.0: + resolution: {integrity: sha512-C5OzENSx/A+gt7t4VH1I2XsflxyPUmXRFPKBxt33xncdOmq7oROVM3bZv9Ysjjkv8OJYDMa+tKuKMvqU/H3xdw==} + engines: {node: '>=12'} - babel-plugin-jest-hoist@29.6.3: - resolution: {integrity: sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + babel-plugin-jest-hoist@30.0.1: + resolution: {integrity: sha512-zTPME3pI50NsFW8ZBaVIOeAxzEY7XHlmWeXXu9srI+9kNfzCUTy8MFan46xOGZY8NZThMqq+e3qZUKsvXbasnQ==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} babel-plugin-syntax-trailing-function-commas@7.0.0-beta.0: resolution: {integrity: sha512-Xj9XuRuz3nTSbaTXWv3itLOcxyF4oPD8douBBmj7U9BBC6nEBYfyOJYQMf/8PJAFotC62UY5dFfIGEPr7WswzQ==} @@ -2024,11 +2214,11 @@ packages: peerDependencies: '@babel/core': ^7.0.0 - babel-preset-jest@29.6.3: - resolution: {integrity: sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + babel-preset-jest@30.0.1: + resolution: {integrity: sha512-+YHejD5iTWI46cZmcc/YtX4gaKBtdqCHCVfuVinizVpbmyjO3zYmeuyFdfA8duRqQZfgCAMlsfmkVbJ+e2MAJw==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} peerDependencies: - '@babel/core': ^7.0.0 + '@babel/core': ^7.11.0 balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} @@ -2155,12 +2345,12 @@ packages: resolution: {integrity: sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==} engines: {node: '>=6.0'} - ci-info@3.9.0: - resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} + ci-info@4.2.0: + resolution: {integrity: sha512-cYY9mypksY8NRqgDB1XD1RiJL338v/551niynFTGkZOO2LHuB2OmOYxDIe/ttN9AHwrqdum1360G3ald0W9kCg==} engines: {node: '>=8'} - cjs-module-lexer@1.4.3: - resolution: {integrity: sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==} + cjs-module-lexer@2.1.0: + resolution: {integrity: sha512-UX0OwmYRYQQetfrLEZeewIFFI+wSTofC+pMBLNuH3RUuu/xzG1oz84UCEDOSoQlN3fZ4+AzmV50ZYvGqkMh9yA==} clean-stack@2.2.0: resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} @@ -2251,9 +2441,9 @@ packages: concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - concat-stream@1.6.2: - resolution: {integrity: sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==} - engines: {'0': node >= 0.8} + concat-stream@2.0.0: + resolution: {integrity: sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==} + engines: {'0': node >= 6.0} consola@3.4.2: resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} @@ -2284,10 +2474,6 @@ packages: resolution: {integrity: sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==} engines: {node: '>=6.6.0'} - cookie@0.7.1: - resolution: {integrity: sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==} - engines: {node: '>= 0.6'} - cookie@0.7.2: resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} engines: {node: '>= 0.6'} @@ -2311,11 +2497,6 @@ packages: typescript: optional: true - create-jest@29.7.0: - resolution: {integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - hasBin: true - create-require@1.1.1: resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} @@ -2419,10 +2600,6 @@ packages: dezalgo@1.0.4: resolution: {integrity: sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==} - diff-sequences@29.6.3: - resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - diff@4.0.2: resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} engines: {node: '>=0.3.1'} @@ -2529,8 +2706,8 @@ packages: peerDependencies: eslint: '>=7.0.0' - eslint-plugin-prettier@5.4.0: - resolution: {integrity: sha512-BvQOvUhkVQM1i63iMETK9Hjud9QhqBnbtT1Zc642p9ynzBuCe5pybkOnvqZIBypXmMlsGcnU4HZ8sCTPfpAexA==} + eslint-plugin-prettier@5.5.1: + resolution: {integrity: sha512-dobTkHT6XaEVOo8IO90Q4DOSxnm3Y151QxPJlM/vKC0bVy+d6cVWQZLlFiuZPP0wS6vZwSKeJgKkcS+KfMBlRw==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: '@types/eslint': '>=8.0.0' @@ -2547,8 +2724,8 @@ packages: resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} engines: {node: '>=8.0.0'} - eslint-scope@8.3.0: - resolution: {integrity: sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==} + eslint-scope@8.4.0: + resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} eslint-visitor-keys@3.4.3: @@ -2559,8 +2736,12 @@ packages: resolution: {integrity: sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - eslint@9.27.0: - resolution: {integrity: sha512-ixRawFQuMB9DZ7fjU3iGGganFDp3+45bPOdaRurcFHSXO1e/sYwUX/FtQZpLZJR6SjMoJH8hR2pPEAfDyCoU2Q==} + eslint-visitor-keys@4.2.1: + resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint@9.29.0: + resolution: {integrity: sha512-GsGizj2Y1rCWDu6XoEekL3RLilp0voSePurjZIkxL3wlm5o5EC9VpgaP7lrCvjnkuLvzFBQWB3vWB3K5KQTveQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} hasBin: true peerDependencies: @@ -2573,6 +2754,10 @@ packages: resolution: {integrity: sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + espree@10.4.0: + resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + esprima@4.0.1: resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} engines: {node: '>=4'} @@ -2610,13 +2795,13 @@ packages: resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} engines: {node: '>=10'} - exit@0.1.2: - resolution: {integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==} + exit-x@0.2.2: + resolution: {integrity: sha512-+I6B/IkJc1o/2tiURyz/ivu/O0nKNEArIUB5O7zBrlDVJr22SCLH3xTeEry428LvFhRzIA1g8izguxJ/gbNcVQ==} engines: {node: '>= 0.8.0'} - expect@29.7.0: - resolution: {integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + expect@30.0.3: + resolution: {integrity: sha512-HXg6NvK35/cSYZCUKAtmlgCFyqKM4frEPbzrav5hRqb0GMz0E0lS5hfzYjSaiaE5ysnp/qI2aeZkeyeIAOeXzQ==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} express-session@1.18.1: resolution: {integrity: sha512-a5mtTqEaZvBCL9A9aqkrtfz+3SMDhOVUnjafjo+s7A9Txkq+SVX2DLvSp1Zrv4uCXa3lMSK3viWnh9Gg07PBUA==} @@ -2694,9 +2879,9 @@ packages: resolution: {integrity: sha512-VZR5I7k5wkD0HgFnMsq5hOsSc710MJMu5Nc5QYsbe38NN5iPV/XTObYLc/cpttRTf6lX538+5uO1ZQRhYibiZQ==} engines: {node: '>=18'} - file-type@20.5.0: - resolution: {integrity: sha512-BfHZtG/l9iMm4Ecianu7P8HRD2tBHLtjXinm4X62XBOYzi7CYA7jyqfJzOvXHqzVrVPYqBo2/GvbARMaaJkKVg==} - engines: {node: '>=18'} + file-type@21.0.0: + resolution: {integrity: sha512-ek5xNX2YBYlXhiUXui3D/BXa3LdqPmoLJ7rqEx2bKJ7EAUEfmXgW0Das7Dc6Nr9MvqaOnIqiPV0mZk/r/UpNAg==} + engines: {node: '>=20'} filelist@1.0.4: resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==} @@ -2828,6 +3013,10 @@ packages: glob-to-regexp@0.4.1: resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} + glob@10.4.5: + resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} + hasBin: true + glob@11.0.1: resolution: {integrity: sha512-zrQDm8XPnYEKawJScsnM0QzobJxlT/kHOOlRTio8IH/GrmxRE5fjllkzdaHclIuNjUQTJYH2xHNIGfdpJkDJUw==} engines: {node: 20 || >=22} @@ -3037,10 +3226,6 @@ packages: is-arrayish@0.2.1: resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} - is-core-module@2.16.1: - resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} - engines: {node: '>= 0.4'} - is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} @@ -3102,9 +3287,6 @@ packages: resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} engines: {node: '>=0.10.0'} - isarray@1.0.0: - resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} - isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} @@ -3117,10 +3299,6 @@ packages: resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} engines: {node: '>=8'} - istanbul-lib-instrument@5.2.1: - resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==} - engines: {node: '>=8'} - istanbul-lib-instrument@6.0.3: resolution: {integrity: sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==} engines: {node: '>=10'} @@ -3129,8 +3307,8 @@ packages: resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} engines: {node: '>=10'} - istanbul-lib-source-maps@4.0.1: - resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==} + istanbul-lib-source-maps@5.0.6: + resolution: {integrity: sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==} engines: {node: '>=10'} istanbul-reports@3.1.7: @@ -3141,6 +3319,9 @@ packages: resolution: {integrity: sha512-RKYVTCjAnRthyJes037NX/IiqeidgN1xc3j1RjFfECFp28A1GVwK9nA+i0rJPaHqSZwygLzRnFlzUuHFoWWy+Q==} engines: {node: '>=6'} + jackspeak@3.4.3: + resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + jackspeak@4.1.0: resolution: {integrity: sha512-9DDdhb5j6cpeitCbvLO7n7J4IxnbM6hoF6O1g4HQ5TfhvvKN8ywDM7668ZhMHRqVmxqhps/F6syWK2KcPxYlkw==} engines: {node: 20 || >=22} @@ -3150,17 +3331,17 @@ packages: engines: {node: '>=10'} hasBin: true - jest-changed-files@29.7.0: - resolution: {integrity: sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-changed-files@30.0.2: + resolution: {integrity: sha512-Ius/iRST9FKfJI+I+kpiDh8JuUlAISnRszF9ixZDIqJF17FckH5sOzKC8a0wd0+D+8em5ADRHA5V5MnfeDk2WA==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - jest-circus@29.7.0: - resolution: {integrity: sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-circus@30.0.3: + resolution: {integrity: sha512-rD9qq2V28OASJHJWDRVdhoBdRs6k3u3EmBzDYcyuMby8XCO3Ll1uq9kyqM41ZcC4fMiPulMVh3qMw0cBvDbnyg==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - jest-cli@29.7.0: - resolution: {integrity: sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-cli@30.0.3: + resolution: {integrity: sha512-UWDSj0ayhumEAxpYRlqQLrssEi29kdQ+kddP94AuHhZknrE+mT0cR0J+zMHKFe9XPfX3dKQOc2TfWki3WhFTsA==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} hasBin: true peerDependencies: node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 @@ -3168,57 +3349,56 @@ packages: node-notifier: optional: true - jest-config@29.7.0: - resolution: {integrity: sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-config@30.0.3: + resolution: {integrity: sha512-j0L4oRCtJwNyZktXIqwzEiDVQXBbQ4dqXuLD/TZdn++hXIcIfZmjHgrViEy5s/+j4HvITmAXbexVZpQ/jnr0bg==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} peerDependencies: '@types/node': '*' + esbuild-register: '>=3.4.0' ts-node: '>=9.0.0' peerDependenciesMeta: '@types/node': optional: true + esbuild-register: + optional: true ts-node: optional: true - jest-diff@29.7.0: - resolution: {integrity: sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-docblock@29.7.0: - resolution: {integrity: sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-diff@30.0.3: + resolution: {integrity: sha512-Q1TAV0cUcBTic57SVnk/mug0/ASyAqtSIOkr7RAlxx97llRYsM74+E8N5WdGJUlwCKwgxPAkVjKh653h1+HA9A==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - jest-each@29.7.0: - resolution: {integrity: sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-docblock@30.0.1: + resolution: {integrity: sha512-/vF78qn3DYphAaIc3jy4gA7XSAz167n9Bm/wn/1XhTLW7tTBIzXtCJpb/vcmc73NIIeeohCbdL94JasyXUZsGA==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - jest-environment-node@29.7.0: - resolution: {integrity: sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-each@30.0.2: + resolution: {integrity: sha512-ZFRsTpe5FUWFQ9cWTMguCaiA6kkW5whccPy9JjD1ezxh+mJeqmz8naL8Fl/oSbNJv3rgB0x87WBIkA5CObIUZQ==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - jest-get-type@29.6.3: - resolution: {integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-environment-node@30.0.2: + resolution: {integrity: sha512-XsGtZ0H+a70RsxAQkKuIh0D3ZlASXdZdhpOSBq9WRPq6lhe0IoQHGW0w9ZUaPiZQ/CpkIdprvlfV1QcXcvIQLQ==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - jest-haste-map@29.7.0: - resolution: {integrity: sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-haste-map@30.0.2: + resolution: {integrity: sha512-telJBKpNLeCb4MaX+I5k496556Y2FiKR/QLZc0+MGBYl4k3OO0472drlV2LUe7c1Glng5HuAu+5GLYp//GpdOQ==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - jest-leak-detector@29.7.0: - resolution: {integrity: sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-leak-detector@30.0.2: + resolution: {integrity: sha512-U66sRrAYdALq+2qtKffBLDWsQ/XoNNs2Lcr83sc9lvE/hEpNafJlq2lXCPUBMNqamMECNxSIekLfe69qg4KMIQ==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - jest-matcher-utils@29.7.0: - resolution: {integrity: sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-matcher-utils@30.0.3: + resolution: {integrity: sha512-hMpVFGFOhYmIIRGJ0HgM9htC5qUiJ00famcc9sRFchJJiLZbbVKrAztcgE6VnXLRxA3XZ0bvNA7hQWh3oHXo/A==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - jest-message-util@29.7.0: - resolution: {integrity: sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-message-util@30.0.2: + resolution: {integrity: sha512-vXywcxmr0SsKXF/bAD7t7nMamRvPuJkras00gqYeB1V0WllxZrbZ0paRr3XqpFU2sYYjD0qAaG2fRyn/CGZ0aw==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - jest-mock@29.7.0: - resolution: {integrity: sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-mock@30.0.2: + resolution: {integrity: sha512-PnZOHmqup/9cT/y+pXIVbbi8ID6U1XHRmbvR7MvUy4SLqhCbwpkmXhLbsWbGewHrV5x/1bF7YDjs+x24/QSvFA==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} jest-pnp-resolver@1.2.3: resolution: {integrity: sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==} @@ -3229,53 +3409,53 @@ packages: jest-resolve: optional: true - jest-regex-util@29.6.3: - resolution: {integrity: sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-regex-util@30.0.1: + resolution: {integrity: sha512-jHEQgBXAgc+Gh4g0p3bCevgRCVRkB4VB70zhoAE48gxeSr1hfUOsM/C2WoJgVL7Eyg//hudYENbm3Ne+/dRVVA==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - jest-resolve-dependencies@29.7.0: - resolution: {integrity: sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-resolve-dependencies@30.0.3: + resolution: {integrity: sha512-FlL6u7LiHbF0Oe27k7DHYMq2T2aNpPhxnNo75F7lEtu4A6sSw+TKkNNUGNcVckdFoL0RCWREJsC1HsKDwKRZzQ==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - jest-resolve@29.7.0: - resolution: {integrity: sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-resolve@30.0.2: + resolution: {integrity: sha512-q/XT0XQvRemykZsvRopbG6FQUT6/ra+XV6rPijyjT6D0msOyCvR2A5PlWZLd+fH0U8XWKZfDiAgrUNDNX2BkCw==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - jest-runner@29.7.0: - resolution: {integrity: sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-runner@30.0.3: + resolution: {integrity: sha512-CxYBzu9WStOBBXAKkLXGoUtNOWsiS1RRmUQb6SsdUdTcqVncOau7m8AJ4cW3Mz+YL1O9pOGPSYLyvl8HBdFmkQ==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - jest-runtime@29.7.0: - resolution: {integrity: sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-runtime@30.0.3: + resolution: {integrity: sha512-Xjosq0C48G9XEQOtmgrjXJwPaUPaq3sPJwHDRaiC+5wi4ZWxO6Lx6jNkizK/0JmTulVNuxP8iYwt77LGnfg3/w==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - jest-snapshot@29.7.0: - resolution: {integrity: sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-snapshot@30.0.3: + resolution: {integrity: sha512-F05JCohd3OA1N9+5aEPXA6I0qOfZDGIx0zTq5Z4yMBg2i1p5ELfBusjYAWwTkC12c7dHcbyth4QAfQbS7cRjow==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - jest-util@29.7.0: - resolution: {integrity: sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-util@30.0.2: + resolution: {integrity: sha512-8IyqfKS4MqprBuUpZNlFB5l+WFehc8bfCe1HSZFHzft2mOuND8Cvi9r1musli+u6F3TqanCZ/Ik4H4pXUolZIg==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - jest-validate@29.7.0: - resolution: {integrity: sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-validate@30.0.2: + resolution: {integrity: sha512-noOvul+SFER4RIvNAwGn6nmV2fXqBq67j+hKGHKGFCmK4ks/Iy1FSrqQNBLGKlu4ZZIRL6Kg1U72N1nxuRCrGQ==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - jest-watcher@29.7.0: - resolution: {integrity: sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-watcher@30.0.2: + resolution: {integrity: sha512-vYO5+E7jJuF+XmONr6CrbXdlYrgvZqtkn6pdkgjt/dU64UAdc0v1cAVaAeWtAfUUMScxNmnUjKPUMdCpNVASwg==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} jest-worker@27.5.1: resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==} engines: {node: '>= 10.13.0'} - jest-worker@29.7.0: - resolution: {integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-worker@30.0.2: + resolution: {integrity: sha512-RN1eQmx7qSLFA+o9pfJKlqViwL5wt+OL3Vff/A+/cPsmuw7NPwfgl33AP+/agRmHzPOFgXviRycR9kYwlcRQXg==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - jest@29.7.0: - resolution: {integrity: sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest@30.0.3: + resolution: {integrity: sha512-Uy8xfeE/WpT2ZLGDXQmaYNzw2v8NUKuYeKGtkS6sDxwsdQihdgYCXaKIYnph1h95DN5H35ubFDm0dfmsQnjn4Q==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} hasBin: true peerDependencies: node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 @@ -3294,6 +3474,9 @@ packages: jose@5.10.0: resolution: {integrity: sha512-s+3Al/p9g32Iq+oqXxkW//7jk2Vig6FF1CFqzVXoTUXt2qz89YWbL+OwS17NFYEvxC35n0FKeGO2LGYSxeM2Gg==} + jose@6.0.11: + resolution: {integrity: sha512-QxG7EaliDARm1O1S8BGakqncGT9s25bKL1WSf6/oa17Tkqwi8D2ZNglqCF+DsYF88/rV66Q/Q2mFAy697E1DUg==} + js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} @@ -3347,10 +3530,6 @@ packages: resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} engines: {node: '>=0.10.0'} - kleur@3.0.3: - resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} - engines: {node: '>=6'} - leven@3.1.0: resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} engines: {node: '>=6'} @@ -3421,6 +3600,9 @@ packages: resolution: {integrity: sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + lru-cache@11.1.0: resolution: {integrity: sha512-QIXZUBJUx+2zHUdQujWejBkcD9+cs94tLn0+YL8UrCh+D5sCXZ4c7LaEH48pNwRY3MLDgqUFyhlCyjJPf1WP0A==} engines: {node: 20 || >=22} @@ -3554,9 +3736,9 @@ packages: ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - multer@1.4.5-lts.2: - resolution: {integrity: sha512-VzGiVigcG9zUAoCNU+xShztrlr1auZOlurXynNvO9GiWD1/mTBbUljOKY+qMeazBqXgRnjzeEgJI/wyjJUHg9A==} - engines: {node: '>= 6.0.0'} + multer@2.0.1: + resolution: {integrity: sha512-Ug8bXeTIUlxurg8xLTEskKShvcKDZALo1THEX5E41pYCD2sCVub5/kIRIGqWNoqV6szyLyQKV6mD4QUrWE5GCQ==} + engines: {node: '>= 10.16.0'} mute-stream@0.0.8: resolution: {integrity: sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==} @@ -3565,6 +3747,11 @@ packages: resolution: {integrity: sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==} engines: {node: ^18.17.0 || >=20.5.0} + napi-postinstall@0.2.4: + resolution: {integrity: sha512-ZEzHJwBhZ8qQSbknHqYcdtQVr8zUgGyM/q6h6qAyhtyVMNrSgDhrC4disf03dYW0e+czXyLnZINnCTEkWy0eJg==} + engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + hasBin: true + natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} @@ -3630,6 +3817,9 @@ packages: nullthrows@1.1.1: resolution: {integrity: sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==} + oauth4webapi@3.5.3: + resolution: {integrity: sha512-2bnHosmBLAQpXNBLOvaJMyMkr4Yya5ohE5Q9jqyxiN+aa7GFCzvDN1RRRMrp0NkfqRR2MTaQNkcSUCCjILD9oQ==} + object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} @@ -3653,6 +3843,9 @@ packages: resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} engines: {node: '>=6'} + openid-client@6.6.1: + resolution: {integrity: sha512-GmqoICGMI3IyFFjhvXxad8of4QWk2D0tm4vdJkldGm9nw7J3p1f7LPLWgGeFuKuw8HjDVe8Dd8QLGBe0NFvSSg==} + optionator@0.9.4: resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} engines: {node: '>= 0.8.0'} @@ -3741,9 +3934,6 @@ packages: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} - path-parse@1.0.7: - resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} - path-root-regex@0.1.2: resolution: {integrity: sha512-4GlJ6rZDhQZFE0DPVKh0e9jmZ5egZfxTkp7bcRDuPlJXbAwhxcl2dINPUAsjLdejqaLsCeg8axcLjIbvBjN4pQ==} engines: {node: '>=0.10.0'} @@ -3752,6 +3942,10 @@ packages: resolution: {integrity: sha512-QLcPegTHF11axjfojBIoDygmS2E3Lf+8+jI6wOVmNVenrKSo3mFdSGiIgdSHenczw3wPtlVMQaFVwGmM7BJdtg==} engines: {node: '>=0.10.0'} + path-scurry@1.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} + path-scurry@2.0.0: resolution: {integrity: sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==} engines: {node: 20 || >=22} @@ -3812,14 +4006,14 @@ packages: resolution: {integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==} engines: {node: '>=6.0.0'} - prettier@3.5.3: - resolution: {integrity: sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==} + prettier@3.6.1: + resolution: {integrity: sha512-5xGWRa90Sp2+x1dQtNpIpeOQpTDBs9cZDmA/qs2vDNN2i18PdapqY7CmBeyLlMuGqXJRIOPaCaVZTLNQRWUH/A==} engines: {node: '>=14'} hasBin: true - pretty-format@29.7.0: - resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + pretty-format@30.0.2: + resolution: {integrity: sha512-yC5/EBSOrTtqhCKfLHqoUIAXVRZnukHPwWBJWR7h84Q3Be1DRQZLncwcfLoPA5RPQ65qfiCMqgYwdUuQ//eVpg==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} prisma@6.8.2: resolution: {integrity: sha512-JNricTXQxzDtRS7lCGGOB4g5DJ91eg3nozdubXze3LpcMl1oWwcFddrj++Up3jnRE6X/3gB/xz3V+ecBk/eEGA==} @@ -3831,16 +4025,9 @@ packages: typescript: optional: true - process-nextick-args@2.0.1: - resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} - promise@7.3.1: resolution: {integrity: sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==} - prompts@2.4.2: - resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} - engines: {node: '>= 6'} - proxy-addr@2.0.7: resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} engines: {node: '>= 0.10'} @@ -3849,8 +4036,8 @@ packages: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} - pure-rand@6.1.0: - resolution: {integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==} + pure-rand@7.0.1: + resolution: {integrity: sha512-oTUZM/NAZS8p7ANR3SHh30kXB+zK2r2BPcEn/awJIbOvq82WoMN4p62AWWp3Hhw50G0xMsw1mhIBLqHw64EcNQ==} qs@6.14.0: resolution: {integrity: sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==} @@ -3881,9 +4068,6 @@ packages: react-is@18.3.1: resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} - readable-stream@2.3.8: - resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} - readable-stream@3.6.2: resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} engines: {node: '>= 6'} @@ -3937,15 +4121,6 @@ packages: resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} engines: {node: '>=8'} - resolve.exports@2.0.3: - resolution: {integrity: sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==} - engines: {node: '>=10'} - - resolve@1.22.10: - resolution: {integrity: sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==} - engines: {node: '>= 0.4'} - hasBin: true - responselike@3.0.0: resolution: {integrity: sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==} engines: {node: '>=14.16'} @@ -3978,9 +4153,6 @@ packages: rxjs@7.8.2: resolution: {integrity: sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==} - safe-buffer@5.1.2: - resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} - safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} @@ -4080,9 +4252,6 @@ packages: signedsource@1.0.0: resolution: {integrity: sha512-6+eerH9fEnNmi/hyM1DXcRK3pWdoMQtlkQ+ns0ntzunjKqp5i3sKCc80ym8Fib3iaYhdJUOPdhlJWj1tvge2Ww==} - sisteransi@1.0.5: - resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} - slash@3.0.0: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} @@ -4156,9 +4325,6 @@ packages: resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} engines: {node: '>=12'} - string_decoder@1.1.1: - resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} - string_decoder@1.3.0: resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} @@ -4213,10 +4379,6 @@ packages: resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} engines: {node: '>=10'} - supports-preserve-symlinks-flag@1.0.0: - resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} - engines: {node: '>= 0.4'} - swap-case@2.0.2: resolution: {integrity: sha512-kc6S2YS/2yXbtkSMunBtKdah4VFETZ8Oh6ONSmSd9bRxhqTrtARUCBUiWXH3xVPpvR7tz2CSnkuXVE42EcGnMw==} @@ -4228,8 +4390,8 @@ packages: resolution: {integrity: sha512-c7AfkZ9udatCuAy9RSfiGPpeOKKUAUK5e1cXadLOGUjasdxqYqAK0jTNkM/FSEyJ3a5Ra27j/tw/PS0qLmaF/A==} engines: {node: '>=18'} - synckit@0.11.5: - resolution: {integrity: sha512-frqvfWyDA5VPVdrWfH24uM6SI/O8NLpVbIIJxb8t/a3YGsp4AW9CYgSKC0OaSEfexnp7Y1pVh2Y6IHO8ggGDmA==} + synckit@0.11.8: + resolution: {integrity: sha512-+XZ+r1XGIJGeQk3VvXhT6xx/VpbHsRzsTkGgF6E5RX9TTXD0118l87puaEBZ566FhqblC6U0d4XnubznJDm30A==} engines: {node: ^14.18.0 || >=16.0.0} tapable@2.2.1: @@ -4309,17 +4471,18 @@ packages: peerDependencies: typescript: '>=4.8.4' - ts-jest@29.3.4: - resolution: {integrity: sha512-Iqbrm8IXOmV+ggWHOTEbjwyCf2xZlUMv5npExksXohL+tk8va4Fjhb+X2+Rt9NBmgO7bJ8WpnMLOwih/DnMlFA==} + ts-jest@29.4.0: + resolution: {integrity: sha512-d423TJMnJGu80/eSgfQ5w/R+0zFJvdtTxwtF9KzFFunOpSeD+79lHJQIiAhluJoyGRbvj9NZJsl9WjCUo0ND7Q==} engines: {node: ^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: '@babel/core': '>=7.0.0-beta.0 <8' - '@jest/transform': ^29.0.0 - '@jest/types': ^29.0.0 - babel-jest: ^29.0.0 + '@jest/transform': ^29.0.0 || ^30.0.0 + '@jest/types': ^29.0.0 || ^30.0.0 + babel-jest: ^29.0.0 || ^30.0.0 esbuild: '*' - jest: ^29.0.0 + jest: ^29.0.0 || ^30.0.0 + jest-util: ^29.0.0 || ^30.0.0 typescript: '>=4.3 <6' peerDependenciesMeta: '@babel/core': @@ -4332,6 +4495,8 @@ packages: optional: true esbuild: optional: true + jest-util: + optional: true ts-loader@9.5.2: resolution: {integrity: sha512-Qo4piXvOTWcMGIgRiuFa6nHNm+54HbYaZCKqc9eeZCLRy3XqafQgwX2F7mofrbJG3g7EEb+lkiR+z2Lic2s3Zw==} @@ -4401,8 +4566,8 @@ packages: typedarray@0.0.6: resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} - typescript-eslint@8.32.1: - resolution: {integrity: sha512-D7el+eaDHAmXvrZBy1zpzSNIRqnCOrkwTgZxTu3MUqRWk8k0q9m9Ho4+vPf7iHtgUfrK/o8IZaEApsxPlHTFCg==} + typescript-eslint@8.35.0: + resolution: {integrity: sha512-uEnz70b7kBz6eg/j0Czy6K5NivaYopgxRjsnAJ2Fx5oTLo3wefTHIbL7AkQr1+7tJCRVpTs/wiM8JR/11Loq9A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 @@ -4451,6 +4616,9 @@ packages: resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} engines: {node: '>= 0.8'} + unrs-resolver@1.9.2: + resolution: {integrity: sha512-VUyWiTNQD7itdiMuJy+EuLEErLj3uwX/EpHQF8EOf33Dq3Ju6VW1GXm+swk6+1h7a49uv9fKZ+dft9jU7esdLA==} + update-browserslist-db@1.1.3: resolution: {integrity: sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==} hasBin: true @@ -4556,9 +4724,9 @@ packages: wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} - write-file-atomic@4.0.2: - resolution: {integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==} - engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + write-file-atomic@5.0.1: + resolution: {integrity: sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} ws@8.18.2: resolution: {integrity: sha512-DMricUmwGZUVr++AEAe2uiVM7UoO9MAVZMDu05UQOaUII0lp+zOzLLU4Xqh/JvTqklB1T4uELaaPBKyjE1r4fQ==} @@ -4704,7 +4872,7 @@ snapshots: '@babel/parser': 7.27.2 '@babel/runtime': 7.27.3 '@babel/traverse': 7.27.1 - '@babel/types': 7.27.1 + '@babel/types': 7.27.3 babel-preset-fbjs: 3.4.0(@babel/core@7.27.1) chalk: 4.1.2 fb-watchman: 2.0.2 @@ -4756,7 +4924,27 @@ snapshots: '@babel/parser': 7.27.2 '@babel/template': 7.27.2 '@babel/traverse': 7.27.1 - '@babel/types': 7.27.1 + '@babel/types': 7.27.3 + convert-source-map: 2.0.0 + debug: 4.4.1 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/core@7.27.4': + dependencies: + '@ampproject/remapping': 2.3.0 + '@babel/code-frame': 7.27.1 + '@babel/generator': 7.27.5 + '@babel/helper-compilation-targets': 7.27.2 + '@babel/helper-module-transforms': 7.27.3(@babel/core@7.27.4) + '@babel/helpers': 7.27.6 + '@babel/parser': 7.27.5 + '@babel/template': 7.27.2 + '@babel/traverse': 7.27.4 + '@babel/types': 7.27.3 convert-source-map: 2.0.0 debug: 4.4.1 gensync: 1.0.0-beta.2 @@ -4773,6 +4961,14 @@ snapshots: '@jridgewell/trace-mapping': 0.3.25 jsesc: 3.1.0 + '@babel/generator@7.27.5': + dependencies: + '@babel/parser': 7.27.5 + '@babel/types': 7.27.3 + '@jridgewell/gen-mapping': 0.3.8 + '@jridgewell/trace-mapping': 0.3.25 + jsesc: 3.1.0 + '@babel/helper-annotate-as-pure@7.27.3': dependencies: '@babel/types': 7.27.3 @@ -4801,14 +4997,14 @@ snapshots: '@babel/helper-member-expression-to-functions@7.27.1': dependencies: '@babel/traverse': 7.27.1 - '@babel/types': 7.27.1 + '@babel/types': 7.27.3 transitivePeerDependencies: - supports-color '@babel/helper-module-imports@7.27.1': dependencies: '@babel/traverse': 7.27.1 - '@babel/types': 7.27.1 + '@babel/types': 7.27.3 transitivePeerDependencies: - supports-color @@ -4821,9 +5017,18 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/helper-module-transforms@7.27.3(@babel/core@7.27.4)': + dependencies: + '@babel/core': 7.27.4 + '@babel/helper-module-imports': 7.27.1 + '@babel/helper-validator-identifier': 7.27.1 + '@babel/traverse': 7.27.4 + transitivePeerDependencies: + - supports-color + '@babel/helper-optimise-call-expression@7.27.1': dependencies: - '@babel/types': 7.27.1 + '@babel/types': 7.27.3 '@babel/helper-plugin-utils@7.27.1': {} @@ -4839,7 +5044,7 @@ snapshots: '@babel/helper-skip-transparent-expression-wrappers@7.27.1': dependencies: '@babel/traverse': 7.27.1 - '@babel/types': 7.27.1 + '@babel/types': 7.27.3 transitivePeerDependencies: - supports-color @@ -4852,12 +5057,21 @@ snapshots: '@babel/helpers@7.27.1': dependencies: '@babel/template': 7.27.2 - '@babel/types': 7.27.1 + '@babel/types': 7.27.3 + + '@babel/helpers@7.27.6': + dependencies: + '@babel/template': 7.27.2 + '@babel/types': 7.27.6 '@babel/parser@7.27.2': dependencies: '@babel/types': 7.27.1 + '@babel/parser@7.27.5': + dependencies: + '@babel/types': 7.27.3 + '@babel/plugin-proposal-class-properties@7.18.6(@babel/core@7.27.1)': dependencies: '@babel/core': 7.27.1 @@ -4875,14 +5089,14 @@ snapshots: '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.27.1) '@babel/plugin-transform-parameters': 7.27.1(@babel/core@7.27.1) - '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.27.1)': + '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.27.1 + '@babel/core': 7.27.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.27.1)': + '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.27.1 + '@babel/core': 7.27.4 '@babel/helper-plugin-utils': 7.27.1 '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.27.1)': @@ -4890,9 +5104,14 @@ snapshots: '@babel/core': 7.27.1 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.27.1)': + '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.27.1 + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.27.4)': + dependencies: + '@babel/core': 7.27.4 '@babel/helper-plugin-utils': 7.27.1 '@babel/plugin-syntax-flow@7.27.1(@babel/core@7.27.1)': @@ -4905,19 +5124,19 @@ snapshots: '@babel/core': 7.27.1 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-import-attributes@7.27.1(@babel/core@7.27.1)': + '@babel/plugin-syntax-import-attributes@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.27.1 + '@babel/core': 7.27.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.27.1)': + '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.27.1 + '@babel/core': 7.27.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.27.1)': + '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.27.1 + '@babel/core': 7.27.4 '@babel/helper-plugin-utils': 7.27.1 '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.27.1)': @@ -4925,19 +5144,24 @@ snapshots: '@babel/core': 7.27.1 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.27.1)': + '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.27.1 + '@babel/core': 7.27.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.27.1)': + '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.27.1 + '@babel/core': 7.27.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.27.1)': + '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.27.1 + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.27.4)': + dependencies: + '@babel/core': 7.27.4 '@babel/helper-plugin-utils': 7.27.1 '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.27.1)': @@ -4945,29 +5169,34 @@ snapshots: '@babel/core': 7.27.1 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.27.1)': + '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.27.1 + '@babel/core': 7.27.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.27.1)': + '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.27.1 + '@babel/core': 7.27.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.27.1)': + '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.27.1 + '@babel/core': 7.27.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.27.1)': + '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.27.1 + '@babel/core': 7.27.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-typescript@7.27.1(@babel/core@7.27.1)': + '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.27.1 + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-typescript@7.27.1(@babel/core@7.27.4)': + dependencies: + '@babel/core': 7.27.4 '@babel/helper-plugin-utils': 7.27.1 '@babel/plugin-transform-arrow-functions@7.27.1(@babel/core@7.27.1)': @@ -5079,7 +5308,7 @@ snapshots: '@babel/helper-module-imports': 7.27.1 '@babel/helper-plugin-utils': 7.27.1 '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.27.1) - '@babel/types': 7.27.1 + '@babel/types': 7.27.3 transitivePeerDependencies: - supports-color @@ -5115,7 +5344,19 @@ snapshots: '@babel/generator': 7.27.1 '@babel/parser': 7.27.2 '@babel/template': 7.27.2 - '@babel/types': 7.27.1 + '@babel/types': 7.27.3 + debug: 4.4.1 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + + '@babel/traverse@7.27.4': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/generator': 7.27.5 + '@babel/parser': 7.27.5 + '@babel/template': 7.27.2 + '@babel/types': 7.27.3 debug: 4.4.1 globals: 11.12.0 transitivePeerDependencies: @@ -5131,6 +5372,11 @@ snapshots: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.27.1 + '@babel/types@7.27.6': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.27.1 + '@bcoe/v8-coverage@0.2.3': {} '@colors/colors@1.5.0': @@ -5140,6 +5386,22 @@ snapshots: dependencies: '@jridgewell/trace-mapping': 0.3.9 + '@emnapi/core@1.4.3': + dependencies: + '@emnapi/wasi-threads': 1.0.2 + tslib: 2.8.1 + optional: true + + '@emnapi/runtime@1.4.3': + dependencies: + tslib: 2.8.1 + optional: true + + '@emnapi/wasi-threads@1.0.2': + dependencies: + tslib: 2.8.1 + optional: true + '@envelop/core@5.2.3': dependencies: '@envelop/instrumentation': 1.0.0 @@ -5157,14 +5419,14 @@ snapshots: '@whatwg-node/promise-helpers': 1.3.2 tslib: 2.8.1 - '@eslint-community/eslint-utils@4.7.0(eslint@9.27.0(jiti@2.4.2))': + '@eslint-community/eslint-utils@4.7.0(eslint@9.29.0(jiti@2.4.2))': dependencies: - eslint: 9.27.0(jiti@2.4.2) + eslint: 9.29.0(jiti@2.4.2) eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.12.1': {} - '@eslint/config-array@0.20.0': + '@eslint/config-array@0.20.1': dependencies: '@eslint/object-schema': 2.1.6 debug: 4.4.1 @@ -5192,7 +5454,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@eslint/js@9.27.0': {} + '@eslint/js@9.29.0': {} '@eslint/object-schema@2.1.6': {} @@ -5211,18 +5473,18 @@ snapshots: '@graphql-codegen/add@5.0.3(graphql@16.11.0)': dependencies: - '@graphql-codegen/plugin-helpers': 5.1.0(graphql@16.11.0) + '@graphql-codegen/plugin-helpers': 5.1.1(graphql@16.11.0) graphql: 16.11.0 tslib: 2.6.3 - '@graphql-codegen/cli@5.0.6(@parcel/watcher@2.5.1)(@types/node@22.15.21)(graphql@16.11.0)(typescript@5.8.3)': + '@graphql-codegen/cli@5.0.7(@parcel/watcher@2.5.1)(@types/node@22.15.21)(graphql@16.11.0)(typescript@5.8.3)': dependencies: '@babel/generator': 7.27.1 '@babel/template': 7.27.2 - '@babel/types': 7.27.1 - '@graphql-codegen/client-preset': 4.8.1(graphql@16.11.0) + '@babel/types': 7.27.3 + '@graphql-codegen/client-preset': 4.8.3(graphql@16.11.0) '@graphql-codegen/core': 4.0.2(graphql@16.11.0) - '@graphql-codegen/plugin-helpers': 5.1.0(graphql@16.11.0) + '@graphql-codegen/plugin-helpers': 5.1.1(graphql@16.11.0) '@graphql-tools/apollo-engine-loader': 8.0.20(graphql@16.11.0) '@graphql-tools/code-file-loader': 8.1.20(graphql@16.11.0) '@graphql-tools/git-loader': 8.0.24(graphql@16.11.0) @@ -5269,14 +5531,14 @@ snapshots: - uWebSockets.js - utf-8-validate - '@graphql-codegen/client-preset@4.8.1(graphql@16.11.0)': + '@graphql-codegen/client-preset@4.8.3(graphql@16.11.0)': dependencies: '@babel/helper-plugin-utils': 7.27.1 '@babel/template': 7.27.2 '@graphql-codegen/add': 5.0.3(graphql@16.11.0) '@graphql-codegen/gql-tag-operations': 4.0.17(graphql@16.11.0) - '@graphql-codegen/plugin-helpers': 5.1.0(graphql@16.11.0) - '@graphql-codegen/typed-document-node': 5.1.1(graphql@16.11.0) + '@graphql-codegen/plugin-helpers': 5.1.1(graphql@16.11.0) + '@graphql-codegen/typed-document-node': 5.1.2(graphql@16.11.0) '@graphql-codegen/typescript': 4.1.6(graphql@16.11.0) '@graphql-codegen/typescript-operations': 4.6.1(graphql@16.11.0) '@graphql-codegen/visitor-plugin-common': 5.8.0(graphql@16.11.0) @@ -5290,7 +5552,7 @@ snapshots: '@graphql-codegen/core@4.0.2(graphql@16.11.0)': dependencies: - '@graphql-codegen/plugin-helpers': 5.1.0(graphql@16.11.0) + '@graphql-codegen/plugin-helpers': 5.1.1(graphql@16.11.0) '@graphql-tools/schema': 10.0.23(graphql@16.11.0) '@graphql-tools/utils': 10.8.6(graphql@16.11.0) graphql: 16.11.0 @@ -5298,7 +5560,7 @@ snapshots: '@graphql-codegen/gql-tag-operations@4.0.17(graphql@16.11.0)': dependencies: - '@graphql-codegen/plugin-helpers': 5.1.0(graphql@16.11.0) + '@graphql-codegen/plugin-helpers': 5.1.1(graphql@16.11.0) '@graphql-codegen/visitor-plugin-common': 5.8.0(graphql@16.11.0) '@graphql-tools/utils': 10.8.6(graphql@16.11.0) auto-bind: 4.0.0 @@ -5327,6 +5589,16 @@ snapshots: lodash: 4.17.21 tslib: 2.6.3 + '@graphql-codegen/plugin-helpers@5.1.1(graphql@16.11.0)': + dependencies: + '@graphql-tools/utils': 10.8.6(graphql@16.11.0) + change-case-all: 1.0.15 + common-tags: 1.8.2 + graphql: 16.11.0 + import-from: 4.0.0 + lodash: 4.17.21 + tslib: 2.6.3 + '@graphql-codegen/schema-ast@4.1.0(graphql@16.11.0)': dependencies: '@graphql-codegen/plugin-helpers': 5.1.0(graphql@16.11.0) @@ -5334,9 +5606,9 @@ snapshots: graphql: 16.11.0 tslib: 2.6.3 - '@graphql-codegen/typed-document-node@5.1.1(graphql@16.11.0)': + '@graphql-codegen/typed-document-node@5.1.2(graphql@16.11.0)': dependencies: - '@graphql-codegen/plugin-helpers': 5.1.0(graphql@16.11.0) + '@graphql-codegen/plugin-helpers': 5.1.1(graphql@16.11.0) '@graphql-codegen/visitor-plugin-common': 5.8.0(graphql@16.11.0) auto-bind: 4.0.0 change-case-all: 1.0.15 @@ -5562,7 +5834,7 @@ snapshots: '@babel/parser': 7.27.2 '@babel/plugin-syntax-import-assertions': 7.27.1(@babel/core@7.27.1) '@babel/traverse': 7.27.1 - '@babel/types': 7.27.1 + '@babel/types': 7.27.3 '@graphql-tools/utils': 10.8.6(graphql@16.11.0) graphql: 16.11.0 tslib: 2.8.1 @@ -5877,162 +6149,179 @@ snapshots: '@istanbuljs/schema@0.1.3': {} - '@jest/console@29.7.0': + '@jest/console@30.0.2': dependencies: - '@jest/types': 29.6.3 + '@jest/types': 30.0.1 '@types/node': 22.15.21 chalk: 4.1.2 - jest-message-util: 29.7.0 - jest-util: 29.7.0 + jest-message-util: 30.0.2 + jest-util: 30.0.2 slash: 3.0.0 - '@jest/core@29.7.0(ts-node@10.9.2(@swc/core@1.11.29)(@types/node@22.15.21)(typescript@5.8.3))': + '@jest/core@30.0.3(ts-node@10.9.2(@swc/core@1.11.29)(@types/node@22.15.21)(typescript@5.8.3))': dependencies: - '@jest/console': 29.7.0 - '@jest/reporters': 29.7.0 - '@jest/test-result': 29.7.0 - '@jest/transform': 29.7.0 - '@jest/types': 29.6.3 + '@jest/console': 30.0.2 + '@jest/pattern': 30.0.1 + '@jest/reporters': 30.0.2 + '@jest/test-result': 30.0.2 + '@jest/transform': 30.0.2 + '@jest/types': 30.0.1 '@types/node': 22.15.21 ansi-escapes: 4.3.2 chalk: 4.1.2 - ci-info: 3.9.0 - exit: 0.1.2 + ci-info: 4.2.0 + exit-x: 0.2.2 graceful-fs: 4.2.11 - jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@22.15.21)(ts-node@10.9.2(@swc/core@1.11.29)(@types/node@22.15.21)(typescript@5.8.3)) - jest-haste-map: 29.7.0 - jest-message-util: 29.7.0 - jest-regex-util: 29.6.3 - jest-resolve: 29.7.0 - jest-resolve-dependencies: 29.7.0 - jest-runner: 29.7.0 - jest-runtime: 29.7.0 - jest-snapshot: 29.7.0 - jest-util: 29.7.0 - jest-validate: 29.7.0 - jest-watcher: 29.7.0 + jest-changed-files: 30.0.2 + jest-config: 30.0.3(@types/node@22.15.21)(ts-node@10.9.2(@swc/core@1.11.29)(@types/node@22.15.21)(typescript@5.8.3)) + jest-haste-map: 30.0.2 + jest-message-util: 30.0.2 + jest-regex-util: 30.0.1 + jest-resolve: 30.0.2 + jest-resolve-dependencies: 30.0.3 + jest-runner: 30.0.3 + jest-runtime: 30.0.3 + jest-snapshot: 30.0.3 + jest-util: 30.0.2 + jest-validate: 30.0.2 + jest-watcher: 30.0.2 micromatch: 4.0.8 - pretty-format: 29.7.0 + pretty-format: 30.0.2 slash: 3.0.0 - strip-ansi: 6.0.1 transitivePeerDependencies: - babel-plugin-macros + - esbuild-register - supports-color - ts-node - '@jest/environment@29.7.0': + '@jest/diff-sequences@30.0.1': {} + + '@jest/environment@30.0.2': dependencies: - '@jest/fake-timers': 29.7.0 - '@jest/types': 29.6.3 + '@jest/fake-timers': 30.0.2 + '@jest/types': 30.0.1 '@types/node': 22.15.21 - jest-mock: 29.7.0 + jest-mock: 30.0.2 - '@jest/expect-utils@29.7.0': + '@jest/expect-utils@30.0.3': dependencies: - jest-get-type: 29.6.3 + '@jest/get-type': 30.0.1 - '@jest/expect@29.7.0': + '@jest/expect@30.0.3': dependencies: - expect: 29.7.0 - jest-snapshot: 29.7.0 + expect: 30.0.3 + jest-snapshot: 30.0.3 transitivePeerDependencies: - supports-color - '@jest/fake-timers@29.7.0': + '@jest/fake-timers@30.0.2': dependencies: - '@jest/types': 29.6.3 - '@sinonjs/fake-timers': 10.3.0 + '@jest/types': 30.0.1 + '@sinonjs/fake-timers': 13.0.5 '@types/node': 22.15.21 - jest-message-util: 29.7.0 - jest-mock: 29.7.0 - jest-util: 29.7.0 + jest-message-util: 30.0.2 + jest-mock: 30.0.2 + jest-util: 30.0.2 + + '@jest/get-type@30.0.1': {} - '@jest/globals@29.7.0': + '@jest/globals@30.0.3': dependencies: - '@jest/environment': 29.7.0 - '@jest/expect': 29.7.0 - '@jest/types': 29.6.3 - jest-mock: 29.7.0 + '@jest/environment': 30.0.2 + '@jest/expect': 30.0.3 + '@jest/types': 30.0.1 + jest-mock: 30.0.2 transitivePeerDependencies: - supports-color - '@jest/reporters@29.7.0': + '@jest/pattern@30.0.1': + dependencies: + '@types/node': 22.15.21 + jest-regex-util: 30.0.1 + + '@jest/reporters@30.0.2': dependencies: '@bcoe/v8-coverage': 0.2.3 - '@jest/console': 29.7.0 - '@jest/test-result': 29.7.0 - '@jest/transform': 29.7.0 - '@jest/types': 29.6.3 + '@jest/console': 30.0.2 + '@jest/test-result': 30.0.2 + '@jest/transform': 30.0.2 + '@jest/types': 30.0.1 '@jridgewell/trace-mapping': 0.3.25 '@types/node': 22.15.21 chalk: 4.1.2 collect-v8-coverage: 1.0.2 - exit: 0.1.2 - glob: 7.2.3 + exit-x: 0.2.2 + glob: 10.4.5 graceful-fs: 4.2.11 istanbul-lib-coverage: 3.2.2 istanbul-lib-instrument: 6.0.3 istanbul-lib-report: 3.0.1 - istanbul-lib-source-maps: 4.0.1 + istanbul-lib-source-maps: 5.0.6 istanbul-reports: 3.1.7 - jest-message-util: 29.7.0 - jest-util: 29.7.0 - jest-worker: 29.7.0 + jest-message-util: 30.0.2 + jest-util: 30.0.2 + jest-worker: 30.0.2 slash: 3.0.0 string-length: 4.0.2 - strip-ansi: 6.0.1 v8-to-istanbul: 9.3.0 transitivePeerDependencies: - supports-color - '@jest/schemas@29.6.3': + '@jest/schemas@30.0.1': dependencies: - '@sinclair/typebox': 0.27.8 + '@sinclair/typebox': 0.34.37 - '@jest/source-map@29.6.3': + '@jest/snapshot-utils@30.0.1': + dependencies: + '@jest/types': 30.0.1 + chalk: 4.1.2 + graceful-fs: 4.2.11 + natural-compare: 1.4.0 + + '@jest/source-map@30.0.1': dependencies: '@jridgewell/trace-mapping': 0.3.25 callsites: 3.1.0 graceful-fs: 4.2.11 - '@jest/test-result@29.7.0': + '@jest/test-result@30.0.2': dependencies: - '@jest/console': 29.7.0 - '@jest/types': 29.6.3 + '@jest/console': 30.0.2 + '@jest/types': 30.0.1 '@types/istanbul-lib-coverage': 2.0.6 collect-v8-coverage: 1.0.2 - '@jest/test-sequencer@29.7.0': + '@jest/test-sequencer@30.0.2': dependencies: - '@jest/test-result': 29.7.0 + '@jest/test-result': 30.0.2 graceful-fs: 4.2.11 - jest-haste-map: 29.7.0 + jest-haste-map: 30.0.2 slash: 3.0.0 - '@jest/transform@29.7.0': + '@jest/transform@30.0.2': dependencies: - '@babel/core': 7.27.1 - '@jest/types': 29.6.3 + '@babel/core': 7.27.4 + '@jest/types': 30.0.1 '@jridgewell/trace-mapping': 0.3.25 - babel-plugin-istanbul: 6.1.1 + babel-plugin-istanbul: 7.0.0 chalk: 4.1.2 convert-source-map: 2.0.0 fast-json-stable-stringify: 2.1.0 graceful-fs: 4.2.11 - jest-haste-map: 29.7.0 - jest-regex-util: 29.6.3 - jest-util: 29.7.0 + jest-haste-map: 30.0.2 + jest-regex-util: 30.0.1 + jest-util: 30.0.2 micromatch: 4.0.8 pirates: 4.0.7 slash: 3.0.0 - write-file-atomic: 4.0.2 + write-file-atomic: 5.0.1 transitivePeerDependencies: - supports-color - '@jest/types@29.6.3': + '@jest/types@30.0.1': dependencies: - '@jest/schemas': 29.6.3 + '@jest/pattern': 30.0.1 + '@jest/schemas': 30.0.1 '@types/istanbul-lib-coverage': 2.0.6 '@types/istanbul-reports': 3.0.4 '@types/node': 22.15.21 @@ -6136,6 +6425,13 @@ snapshots: '@napi-rs/nice-win32-x64-msvc': 1.0.1 optional: true + '@napi-rs/wasm-runtime@0.2.11': + dependencies: + '@emnapi/core': 1.4.3 + '@emnapi/runtime': 1.4.3 + '@tybys/wasm-util': 0.9.0 + optional: true + '@nestjs/cli@11.0.7(@swc/cli@0.6.0(@swc/core@1.11.29)(chokidar@4.0.3))(@swc/core@1.11.29)(@types/node@22.15.21)': dependencies: '@angular-devkit/core': 19.2.8(chokidar@4.0.3) @@ -6166,9 +6462,9 @@ snapshots: - uglify-js - webpack-cli - '@nestjs/common@11.1.1(reflect-metadata@0.2.2)(rxjs@7.8.2)': + '@nestjs/common@11.1.3(reflect-metadata@0.2.2)(rxjs@7.8.2)': dependencies: - file-type: 20.5.0 + file-type: 21.0.0 iterare: 1.2.1 load-esm: 1.0.2 reflect-metadata: 0.2.2 @@ -6178,17 +6474,17 @@ snapshots: transitivePeerDependencies: - supports-color - '@nestjs/config@4.0.2(@nestjs/common@11.1.1(reflect-metadata@0.2.2)(rxjs@7.8.2))(rxjs@7.8.2)': + '@nestjs/config@4.0.2(@nestjs/common@11.1.3(reflect-metadata@0.2.2)(rxjs@7.8.2))(rxjs@7.8.2)': dependencies: - '@nestjs/common': 11.1.1(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.3(reflect-metadata@0.2.2)(rxjs@7.8.2) dotenv: 16.4.7 dotenv-expand: 12.0.1 lodash: 4.17.21 rxjs: 7.8.2 - '@nestjs/core@11.1.1(@nestjs/common@11.1.1(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)': + '@nestjs/core@11.1.3(@nestjs/common@11.1.3(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.3)(reflect-metadata@0.2.2)(rxjs@7.8.2)': dependencies: - '@nestjs/common': 11.1.1(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.3(reflect-metadata@0.2.2)(rxjs@7.8.2) '@nuxt/opencollective': 0.4.1 fast-safe-stringify: 2.1.1 iterare: 1.2.1 @@ -6198,20 +6494,20 @@ snapshots: tslib: 2.8.1 uid: 2.0.2 optionalDependencies: - '@nestjs/platform-express': 11.1.1(@nestjs/common@11.1.1(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.1) + '@nestjs/platform-express': 11.1.3(@nestjs/common@11.1.3(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.3) - '@nestjs/passport@11.0.5(@nestjs/common@11.1.1(reflect-metadata@0.2.2)(rxjs@7.8.2))(passport@0.7.0)': + '@nestjs/passport@11.0.5(@nestjs/common@11.1.3(reflect-metadata@0.2.2)(rxjs@7.8.2))(passport@0.7.0)': dependencies: - '@nestjs/common': 11.1.1(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.3(reflect-metadata@0.2.2)(rxjs@7.8.2) passport: 0.7.0 - '@nestjs/platform-express@11.1.1(@nestjs/common@11.1.1(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.1)': + '@nestjs/platform-express@11.1.3(@nestjs/common@11.1.3(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.3)': dependencies: - '@nestjs/common': 11.1.1(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.1(@nestjs/common@11.1.1(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.3(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.3(@nestjs/common@11.1.3(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.3)(reflect-metadata@0.2.2)(rxjs@7.8.2) cors: 2.8.5 express: 5.1.0 - multer: 1.4.5-lts.2 + multer: 2.0.1 path-to-regexp: 8.2.0 tslib: 2.8.1 transitivePeerDependencies: @@ -6228,13 +6524,13 @@ snapshots: transitivePeerDependencies: - chokidar - '@nestjs/testing@11.1.1(@nestjs/common@11.1.1(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.1)(@nestjs/platform-express@11.1.1)': + '@nestjs/testing@11.1.3(@nestjs/common@11.1.3(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.3)(@nestjs/platform-express@11.1.3)': dependencies: - '@nestjs/common': 11.1.1(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.1(@nestjs/common@11.1.1(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.3(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.3(@nestjs/common@11.1.3(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.3)(reflect-metadata@0.2.2)(rxjs@7.8.2) tslib: 2.8.1 optionalDependencies: - '@nestjs/platform-express': 11.1.1(@nestjs/common@11.1.1(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.1) + '@nestjs/platform-express': 11.1.3(@nestjs/common@11.1.3(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.3) '@noble/hashes@1.8.0': {} @@ -6318,6 +6614,9 @@ snapshots: '@parcel/watcher-win32-ia32': 2.5.1 '@parcel/watcher-win32-x64': 2.5.1 + '@pkgjs/parseargs@0.11.0': + optional: true + '@pkgr/core@0.2.4': {} '@prisma/client@6.8.2(prisma@6.8.2(typescript@5.8.3))(typescript@5.8.3)': @@ -6354,7 +6653,7 @@ snapshots: '@sec-ant/readable-stream@0.4.1': {} - '@sinclair/typebox@0.27.8': {} + '@sinclair/typebox@0.34.37': {} '@sindresorhus/is@5.6.0': {} @@ -6362,7 +6661,7 @@ snapshots: dependencies: type-detect: 4.0.8 - '@sinonjs/fake-timers@10.3.0': + '@sinonjs/fake-timers@13.0.5': dependencies: '@sinonjs/commons': 3.0.1 @@ -6455,26 +6754,31 @@ snapshots: '@tsconfig/node16@1.0.4': {} + '@tybys/wasm-util@0.9.0': + dependencies: + tslib: 2.8.1 + optional: true + '@types/babel__core@7.20.5': dependencies: '@babel/parser': 7.27.2 - '@babel/types': 7.27.1 + '@babel/types': 7.27.3 '@types/babel__generator': 7.27.0 '@types/babel__template': 7.4.4 '@types/babel__traverse': 7.20.7 '@types/babel__generator@7.27.0': dependencies: - '@babel/types': 7.27.1 + '@babel/types': 7.27.3 '@types/babel__template@7.4.4': dependencies: '@babel/parser': 7.27.2 - '@babel/types': 7.27.1 + '@babel/types': 7.27.3 '@types/babel__traverse@7.20.7': dependencies: - '@babel/types': 7.27.1 + '@babel/types': 7.27.3 '@types/body-parser@1.19.5': dependencies: @@ -6506,20 +6810,16 @@ snapshots: '@types/range-parser': 1.2.7 '@types/send': 0.17.4 - '@types/express-session@1.18.1': + '@types/express-session@1.18.2': dependencies: - '@types/express': 5.0.2 + '@types/express': 5.0.3 - '@types/express@5.0.2': + '@types/express@5.0.3': dependencies: '@types/body-parser': 1.19.5 '@types/express-serve-static-core': 5.0.6 '@types/serve-static': 1.15.7 - '@types/graceful-fs@4.1.9': - dependencies: - '@types/node': 22.15.21 - '@types/http-cache-semantics@4.0.4': {} '@types/http-errors@2.0.4': {} @@ -6534,10 +6834,10 @@ snapshots: dependencies: '@types/istanbul-lib-report': 3.0.3 - '@types/jest@29.5.14': + '@types/jest@30.0.0': dependencies: - expect: 29.7.0 - pretty-format: 29.7.0 + expect: 30.0.3 + pretty-format: 30.0.2 '@types/js-yaml@4.0.9': {} @@ -6553,7 +6853,7 @@ snapshots: '@types/passport@1.0.17': dependencies: - '@types/express': 5.0.2 + '@types/express': 5.0.3 '@types/qs@6.14.0': {} @@ -6594,15 +6894,15 @@ snapshots: dependencies: '@types/yargs-parser': 21.0.3 - '@typescript-eslint/eslint-plugin@8.32.1(@typescript-eslint/parser@8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3)': + '@typescript-eslint/eslint-plugin@8.35.0(@typescript-eslint/parser@8.35.0(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3)': dependencies: '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3) - '@typescript-eslint/scope-manager': 8.32.1 - '@typescript-eslint/type-utils': 8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3) - '@typescript-eslint/utils': 8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3) - '@typescript-eslint/visitor-keys': 8.32.1 - eslint: 9.27.0(jiti@2.4.2) + '@typescript-eslint/parser': 8.35.0(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/scope-manager': 8.35.0 + '@typescript-eslint/type-utils': 8.35.0(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/utils': 8.35.0(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/visitor-keys': 8.35.0 + eslint: 9.29.0(jiti@2.4.2) graphemer: 1.4.0 ignore: 7.0.4 natural-compare: 1.4.0 @@ -6611,40 +6911,55 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3)': + '@typescript-eslint/parser@8.35.0(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3)': + dependencies: + '@typescript-eslint/scope-manager': 8.35.0 + '@typescript-eslint/types': 8.35.0 + '@typescript-eslint/typescript-estree': 8.35.0(typescript@5.8.3) + '@typescript-eslint/visitor-keys': 8.35.0 + debug: 4.4.1 + eslint: 9.29.0(jiti@2.4.2) + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/project-service@8.35.0(typescript@5.8.3)': dependencies: - '@typescript-eslint/scope-manager': 8.32.1 - '@typescript-eslint/types': 8.32.1 - '@typescript-eslint/typescript-estree': 8.32.1(typescript@5.8.3) - '@typescript-eslint/visitor-keys': 8.32.1 + '@typescript-eslint/tsconfig-utils': 8.35.0(typescript@5.8.3) + '@typescript-eslint/types': 8.35.0 debug: 4.4.1 - eslint: 9.27.0(jiti@2.4.2) typescript: 5.8.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@8.32.1': + '@typescript-eslint/scope-manager@8.35.0': dependencies: - '@typescript-eslint/types': 8.32.1 - '@typescript-eslint/visitor-keys': 8.32.1 + '@typescript-eslint/types': 8.35.0 + '@typescript-eslint/visitor-keys': 8.35.0 - '@typescript-eslint/type-utils@8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3)': + '@typescript-eslint/tsconfig-utils@8.35.0(typescript@5.8.3)': dependencies: - '@typescript-eslint/typescript-estree': 8.32.1(typescript@5.8.3) - '@typescript-eslint/utils': 8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3) + typescript: 5.8.3 + + '@typescript-eslint/type-utils@8.35.0(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3)': + dependencies: + '@typescript-eslint/typescript-estree': 8.35.0(typescript@5.8.3) + '@typescript-eslint/utils': 8.35.0(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3) debug: 4.4.1 - eslint: 9.27.0(jiti@2.4.2) + eslint: 9.29.0(jiti@2.4.2) ts-api-utils: 2.1.0(typescript@5.8.3) typescript: 5.8.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/types@8.32.1': {} + '@typescript-eslint/types@8.35.0': {} - '@typescript-eslint/typescript-estree@8.32.1(typescript@5.8.3)': + '@typescript-eslint/typescript-estree@8.35.0(typescript@5.8.3)': dependencies: - '@typescript-eslint/types': 8.32.1 - '@typescript-eslint/visitor-keys': 8.32.1 + '@typescript-eslint/project-service': 8.35.0(typescript@5.8.3) + '@typescript-eslint/tsconfig-utils': 8.35.0(typescript@5.8.3) + '@typescript-eslint/types': 8.35.0 + '@typescript-eslint/visitor-keys': 8.35.0 debug: 4.4.1 fast-glob: 3.3.3 is-glob: 4.0.3 @@ -6655,21 +6970,82 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3)': + '@typescript-eslint/utils@8.35.0(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3)': dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.27.0(jiti@2.4.2)) - '@typescript-eslint/scope-manager': 8.32.1 - '@typescript-eslint/types': 8.32.1 - '@typescript-eslint/typescript-estree': 8.32.1(typescript@5.8.3) - eslint: 9.27.0(jiti@2.4.2) + '@eslint-community/eslint-utils': 4.7.0(eslint@9.29.0(jiti@2.4.2)) + '@typescript-eslint/scope-manager': 8.35.0 + '@typescript-eslint/types': 8.35.0 + '@typescript-eslint/typescript-estree': 8.35.0(typescript@5.8.3) + eslint: 9.29.0(jiti@2.4.2) typescript: 5.8.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/visitor-keys@8.32.1': + '@typescript-eslint/visitor-keys@8.35.0': dependencies: - '@typescript-eslint/types': 8.32.1 - eslint-visitor-keys: 4.2.0 + '@typescript-eslint/types': 8.35.0 + eslint-visitor-keys: 4.2.1 + + '@ungap/structured-clone@1.3.0': {} + + '@unrs/resolver-binding-android-arm-eabi@1.9.2': + optional: true + + '@unrs/resolver-binding-android-arm64@1.9.2': + optional: true + + '@unrs/resolver-binding-darwin-arm64@1.9.2': + optional: true + + '@unrs/resolver-binding-darwin-x64@1.9.2': + optional: true + + '@unrs/resolver-binding-freebsd-x64@1.9.2': + optional: true + + '@unrs/resolver-binding-linux-arm-gnueabihf@1.9.2': + optional: true + + '@unrs/resolver-binding-linux-arm-musleabihf@1.9.2': + optional: true + + '@unrs/resolver-binding-linux-arm64-gnu@1.9.2': + optional: true + + '@unrs/resolver-binding-linux-arm64-musl@1.9.2': + optional: true + + '@unrs/resolver-binding-linux-ppc64-gnu@1.9.2': + optional: true + + '@unrs/resolver-binding-linux-riscv64-gnu@1.9.2': + optional: true + + '@unrs/resolver-binding-linux-riscv64-musl@1.9.2': + optional: true + + '@unrs/resolver-binding-linux-s390x-gnu@1.9.2': + optional: true + + '@unrs/resolver-binding-linux-x64-gnu@1.9.2': + optional: true + + '@unrs/resolver-binding-linux-x64-musl@1.9.2': + optional: true + + '@unrs/resolver-binding-wasm32-wasi@1.9.2': + dependencies: + '@napi-rs/wasm-runtime': 0.2.11 + optional: true + + '@unrs/resolver-binding-win32-arm64-msvc@1.9.2': + optional: true + + '@unrs/resolver-binding-win32-ia32-msvc@1.9.2': + optional: true + + '@unrs/resolver-binding-win32-x64-msvc@1.9.2': + optional: true '@webassemblyjs/ast@1.14.1': dependencies: @@ -6849,12 +7225,18 @@ snapshots: dependencies: acorn: 8.14.1 + acorn-jsx@5.3.2(acorn@8.15.0): + dependencies: + acorn: 8.15.0 + acorn-walk@8.3.4: dependencies: acorn: 8.14.1 acorn@8.14.1: {} + acorn@8.15.0: {} + agent-base@7.1.3: {} aggregate-error@3.1.0: @@ -6946,56 +7328,55 @@ snapshots: b4a@1.6.7: {} - babel-jest@29.7.0(@babel/core@7.27.1): + babel-jest@30.0.2(@babel/core@7.27.4): dependencies: - '@babel/core': 7.27.1 - '@jest/transform': 29.7.0 + '@babel/core': 7.27.4 + '@jest/transform': 30.0.2 '@types/babel__core': 7.20.5 - babel-plugin-istanbul: 6.1.1 - babel-preset-jest: 29.6.3(@babel/core@7.27.1) + babel-plugin-istanbul: 7.0.0 + babel-preset-jest: 30.0.1(@babel/core@7.27.4) chalk: 4.1.2 graceful-fs: 4.2.11 slash: 3.0.0 transitivePeerDependencies: - supports-color - babel-plugin-istanbul@6.1.1: + babel-plugin-istanbul@7.0.0: dependencies: '@babel/helper-plugin-utils': 7.27.1 '@istanbuljs/load-nyc-config': 1.1.0 '@istanbuljs/schema': 0.1.3 - istanbul-lib-instrument: 5.2.1 + istanbul-lib-instrument: 6.0.3 test-exclude: 6.0.0 transitivePeerDependencies: - supports-color - babel-plugin-jest-hoist@29.6.3: + babel-plugin-jest-hoist@30.0.1: dependencies: '@babel/template': 7.27.2 - '@babel/types': 7.27.1 + '@babel/types': 7.27.3 '@types/babel__core': 7.20.5 - '@types/babel__traverse': 7.20.7 babel-plugin-syntax-trailing-function-commas@7.0.0-beta.0: {} - babel-preset-current-node-syntax@1.1.0(@babel/core@7.27.1): - dependencies: - '@babel/core': 7.27.1 - '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.27.1) - '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.27.1) - '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.27.1) - '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.27.1) - '@babel/plugin-syntax-import-attributes': 7.27.1(@babel/core@7.27.1) - '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.27.1) - '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.27.1) - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.27.1) - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.27.1) - '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.27.1) - '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.27.1) - '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.27.1) - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.27.1) - '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.27.1) - '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.27.1) + babel-preset-current-node-syntax@1.1.0(@babel/core@7.27.4): + dependencies: + '@babel/core': 7.27.4 + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.27.4) + '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.27.4) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.27.4) + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.27.4) + '@babel/plugin-syntax-import-attributes': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.27.4) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.27.4) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.27.4) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.27.4) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.27.4) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.27.4) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.27.4) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.27.4) + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.27.4) + '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.27.4) babel-preset-fbjs@3.4.0(@babel/core@7.27.1): dependencies: @@ -7030,11 +7411,11 @@ snapshots: transitivePeerDependencies: - supports-color - babel-preset-jest@29.6.3(@babel/core@7.27.1): + babel-preset-jest@30.0.1(@babel/core@7.27.4): dependencies: - '@babel/core': 7.27.1 - babel-plugin-jest-hoist: 29.6.3 - babel-preset-current-node-syntax: 1.1.0(@babel/core@7.27.1) + '@babel/core': 7.27.4 + babel-plugin-jest-hoist: 30.0.1 + babel-preset-current-node-syntax: 1.1.0(@babel/core@7.27.4) balanced-match@1.0.2: {} @@ -7201,9 +7582,9 @@ snapshots: chrome-trace-event@1.0.4: {} - ci-info@3.9.0: {} + ci-info@4.2.0: {} - cjs-module-lexer@1.4.3: {} + cjs-module-lexer@2.1.0: {} clean-stack@2.2.0: {} @@ -7280,11 +7661,11 @@ snapshots: concat-map@0.0.1: {} - concat-stream@1.6.2: + concat-stream@2.0.0: dependencies: buffer-from: 1.1.2 inherits: 2.0.4 - readable-stream: 2.3.8 + readable-stream: 3.6.2 typedarray: 0.0.6 consola@3.4.2: {} @@ -7311,8 +7692,6 @@ snapshots: cookie-signature@1.2.2: {} - cookie@0.7.1: {} - cookie@0.7.2: {} cookiejar@2.1.4: {} @@ -7333,21 +7712,6 @@ snapshots: optionalDependencies: typescript: 5.8.3 - create-jest@29.7.0(@types/node@22.15.21)(ts-node@10.9.2(@swc/core@1.11.29)(@types/node@22.15.21)(typescript@5.8.3)): - dependencies: - '@jest/types': 29.6.3 - chalk: 4.1.2 - exit: 0.1.2 - graceful-fs: 4.2.11 - jest-config: 29.7.0(@types/node@22.15.21)(ts-node@10.9.2(@swc/core@1.11.29)(@types/node@22.15.21)(typescript@5.8.3)) - jest-util: 29.7.0 - prompts: 2.4.2 - transitivePeerDependencies: - - '@types/node' - - babel-plugin-macros - - supports-color - - ts-node - create-require@1.1.1: {} cross-fetch@3.2.0: @@ -7417,8 +7781,6 @@ snapshots: asap: 2.0.6 wrappy: 1.0.2 - diff-sequences@29.6.3: {} - diff@4.0.2: {} dir-glob@3.0.1: @@ -7498,26 +7860,26 @@ snapshots: escape-string-regexp@4.0.0: {} - eslint-config-prettier@10.1.5(eslint@9.27.0(jiti@2.4.2)): + eslint-config-prettier@10.1.5(eslint@9.29.0(jiti@2.4.2)): dependencies: - eslint: 9.27.0(jiti@2.4.2) + eslint: 9.29.0(jiti@2.4.2) - eslint-plugin-prettier@5.4.0(@types/eslint@9.6.1)(eslint-config-prettier@10.1.5(eslint@9.27.0(jiti@2.4.2)))(eslint@9.27.0(jiti@2.4.2))(prettier@3.5.3): + eslint-plugin-prettier@5.5.1(@types/eslint@9.6.1)(eslint-config-prettier@10.1.5(eslint@9.29.0(jiti@2.4.2)))(eslint@9.29.0(jiti@2.4.2))(prettier@3.6.1): dependencies: - eslint: 9.27.0(jiti@2.4.2) - prettier: 3.5.3 + eslint: 9.29.0(jiti@2.4.2) + prettier: 3.6.1 prettier-linter-helpers: 1.0.0 - synckit: 0.11.5 + synckit: 0.11.8 optionalDependencies: '@types/eslint': 9.6.1 - eslint-config-prettier: 10.1.5(eslint@9.27.0(jiti@2.4.2)) + eslint-config-prettier: 10.1.5(eslint@9.29.0(jiti@2.4.2)) eslint-scope@5.1.1: dependencies: esrecurse: 4.3.0 estraverse: 4.3.0 - eslint-scope@8.3.0: + eslint-scope@8.4.0: dependencies: esrecurse: 4.3.0 estraverse: 5.3.0 @@ -7526,15 +7888,17 @@ snapshots: eslint-visitor-keys@4.2.0: {} - eslint@9.27.0(jiti@2.4.2): + eslint-visitor-keys@4.2.1: {} + + eslint@9.29.0(jiti@2.4.2): dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.27.0(jiti@2.4.2)) + '@eslint-community/eslint-utils': 4.7.0(eslint@9.29.0(jiti@2.4.2)) '@eslint-community/regexpp': 4.12.1 - '@eslint/config-array': 0.20.0 + '@eslint/config-array': 0.20.1 '@eslint/config-helpers': 0.2.2 '@eslint/core': 0.14.0 '@eslint/eslintrc': 3.3.1 - '@eslint/js': 9.27.0 + '@eslint/js': 9.29.0 '@eslint/plugin-kit': 0.3.1 '@humanfs/node': 0.16.6 '@humanwhocodes/module-importer': 1.0.1 @@ -7546,9 +7910,9 @@ snapshots: cross-spawn: 7.0.6 debug: 4.4.1 escape-string-regexp: 4.0.0 - eslint-scope: 8.3.0 - eslint-visitor-keys: 4.2.0 - espree: 10.3.0 + eslint-scope: 8.4.0 + eslint-visitor-keys: 4.2.1 + espree: 10.4.0 esquery: 1.6.0 esutils: 2.0.3 fast-deep-equal: 3.1.3 @@ -7574,6 +7938,12 @@ snapshots: acorn-jsx: 5.3.2(acorn@8.14.1) eslint-visitor-keys: 4.2.0 + espree@10.4.0: + dependencies: + acorn: 8.15.0 + acorn-jsx: 5.3.2(acorn@8.15.0) + eslint-visitor-keys: 4.2.1 + esprima@4.0.1: {} esquery@1.6.0: @@ -7606,15 +7976,16 @@ snapshots: signal-exit: 3.0.7 strip-final-newline: 2.0.0 - exit@0.1.2: {} + exit-x@0.2.2: {} - expect@29.7.0: + expect@30.0.3: dependencies: - '@jest/expect-utils': 29.7.0 - jest-get-type: 29.6.3 - jest-matcher-utils: 29.7.0 - jest-message-util: 29.7.0 - jest-util: 29.7.0 + '@jest/expect-utils': 30.0.3 + '@jest/get-type': 30.0.1 + jest-matcher-utils: 30.0.3 + jest-message-util: 30.0.2 + jest-mock: 30.0.2 + jest-util: 30.0.2 express-session@1.18.1: dependencies: @@ -7635,7 +8006,7 @@ snapshots: body-parser: 2.2.0 content-disposition: 1.0.0 content-type: 1.0.5 - cookie: 0.7.1 + cookie: 0.7.2 cookie-signature: 1.2.2 debug: 4.4.1 encodeurl: 2.0.0 @@ -7742,7 +8113,7 @@ snapshots: token-types: 6.0.0 uint8array-extras: 1.4.0 - file-type@20.5.0: + file-type@21.0.0: dependencies: '@tokenizer/inflate': 0.2.7 strtok3: 10.2.2 @@ -7898,6 +8269,15 @@ snapshots: glob-to-regexp@0.4.1: {} + glob@10.4.5: + dependencies: + foreground-child: 3.3.1 + jackspeak: 3.4.3 + minimatch: 9.0.5 + minipass: 7.1.2 + package-json-from-dist: 1.0.1 + path-scurry: 1.11.1 + glob@11.0.1: dependencies: foreground-child: 3.3.1 @@ -8126,10 +8506,6 @@ snapshots: is-arrayish@0.2.1: {} - is-core-module@2.16.1: - dependencies: - hasown: 2.0.2 - is-extglob@2.1.1: {} is-fullwidth-code-point@3.0.0: {} @@ -8172,8 +8548,6 @@ snapshots: is-windows@1.0.2: {} - isarray@1.0.0: {} - isexe@2.0.0: {} isomorphic-ws@5.0.0(ws@8.18.2): @@ -8182,16 +8556,6 @@ snapshots: istanbul-lib-coverage@3.2.2: {} - istanbul-lib-instrument@5.2.1: - dependencies: - '@babel/core': 7.27.1 - '@babel/parser': 7.27.2 - '@istanbuljs/schema': 0.1.3 - istanbul-lib-coverage: 3.2.2 - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - istanbul-lib-instrument@6.0.3: dependencies: '@babel/core': 7.27.1 @@ -8208,11 +8572,11 @@ snapshots: make-dir: 4.0.0 supports-color: 7.2.0 - istanbul-lib-source-maps@4.0.1: + istanbul-lib-source-maps@5.0.6: dependencies: + '@jridgewell/trace-mapping': 0.3.25 debug: 4.4.1 istanbul-lib-coverage: 3.2.2 - source-map: 0.6.1 transitivePeerDependencies: - supports-color @@ -8223,6 +8587,12 @@ snapshots: iterare@1.2.1: {} + jackspeak@3.4.3: + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + jackspeak@4.1.0: dependencies: '@isaacs/cliui': 8.0.2 @@ -8234,79 +8604,81 @@ snapshots: filelist: 1.0.4 minimatch: 3.1.2 - jest-changed-files@29.7.0: + jest-changed-files@30.0.2: dependencies: execa: 5.1.1 - jest-util: 29.7.0 + jest-util: 30.0.2 p-limit: 3.1.0 - jest-circus@29.7.0: + jest-circus@30.0.3: dependencies: - '@jest/environment': 29.7.0 - '@jest/expect': 29.7.0 - '@jest/test-result': 29.7.0 - '@jest/types': 29.6.3 + '@jest/environment': 30.0.2 + '@jest/expect': 30.0.3 + '@jest/test-result': 30.0.2 + '@jest/types': 30.0.1 '@types/node': 22.15.21 chalk: 4.1.2 co: 4.6.0 dedent: 1.6.0 is-generator-fn: 2.1.0 - jest-each: 29.7.0 - jest-matcher-utils: 29.7.0 - jest-message-util: 29.7.0 - jest-runtime: 29.7.0 - jest-snapshot: 29.7.0 - jest-util: 29.7.0 + jest-each: 30.0.2 + jest-matcher-utils: 30.0.3 + jest-message-util: 30.0.2 + jest-runtime: 30.0.3 + jest-snapshot: 30.0.3 + jest-util: 30.0.2 p-limit: 3.1.0 - pretty-format: 29.7.0 - pure-rand: 6.1.0 + pretty-format: 30.0.2 + pure-rand: 7.0.1 slash: 3.0.0 stack-utils: 2.0.6 transitivePeerDependencies: - babel-plugin-macros - supports-color - jest-cli@29.7.0(@types/node@22.15.21)(ts-node@10.9.2(@swc/core@1.11.29)(@types/node@22.15.21)(typescript@5.8.3)): + jest-cli@30.0.3(@types/node@22.15.21)(ts-node@10.9.2(@swc/core@1.11.29)(@types/node@22.15.21)(typescript@5.8.3)): dependencies: - '@jest/core': 29.7.0(ts-node@10.9.2(@swc/core@1.11.29)(@types/node@22.15.21)(typescript@5.8.3)) - '@jest/test-result': 29.7.0 - '@jest/types': 29.6.3 + '@jest/core': 30.0.3(ts-node@10.9.2(@swc/core@1.11.29)(@types/node@22.15.21)(typescript@5.8.3)) + '@jest/test-result': 30.0.2 + '@jest/types': 30.0.1 chalk: 4.1.2 - create-jest: 29.7.0(@types/node@22.15.21)(ts-node@10.9.2(@swc/core@1.11.29)(@types/node@22.15.21)(typescript@5.8.3)) - exit: 0.1.2 + exit-x: 0.2.2 import-local: 3.2.0 - jest-config: 29.7.0(@types/node@22.15.21)(ts-node@10.9.2(@swc/core@1.11.29)(@types/node@22.15.21)(typescript@5.8.3)) - jest-util: 29.7.0 - jest-validate: 29.7.0 + jest-config: 30.0.3(@types/node@22.15.21)(ts-node@10.9.2(@swc/core@1.11.29)(@types/node@22.15.21)(typescript@5.8.3)) + jest-util: 30.0.2 + jest-validate: 30.0.2 yargs: 17.7.2 transitivePeerDependencies: - '@types/node' - babel-plugin-macros + - esbuild-register - supports-color - ts-node - jest-config@29.7.0(@types/node@22.15.21)(ts-node@10.9.2(@swc/core@1.11.29)(@types/node@22.15.21)(typescript@5.8.3)): + jest-config@30.0.3(@types/node@22.15.21)(ts-node@10.9.2(@swc/core@1.11.29)(@types/node@22.15.21)(typescript@5.8.3)): dependencies: - '@babel/core': 7.27.1 - '@jest/test-sequencer': 29.7.0 - '@jest/types': 29.6.3 - babel-jest: 29.7.0(@babel/core@7.27.1) + '@babel/core': 7.27.4 + '@jest/get-type': 30.0.1 + '@jest/pattern': 30.0.1 + '@jest/test-sequencer': 30.0.2 + '@jest/types': 30.0.1 + babel-jest: 30.0.2(@babel/core@7.27.4) chalk: 4.1.2 - ci-info: 3.9.0 + ci-info: 4.2.0 deepmerge: 4.3.1 - glob: 7.2.3 + glob: 10.4.5 graceful-fs: 4.2.11 - jest-circus: 29.7.0 - jest-environment-node: 29.7.0 - jest-get-type: 29.6.3 - jest-regex-util: 29.6.3 - jest-resolve: 29.7.0 - jest-runner: 29.7.0 - jest-util: 29.7.0 - jest-validate: 29.7.0 + jest-circus: 30.0.3 + jest-docblock: 30.0.1 + jest-environment-node: 30.0.2 + jest-regex-util: 30.0.1 + jest-resolve: 30.0.2 + jest-runner: 30.0.3 + jest-util: 30.0.2 + jest-validate: 30.0.2 micromatch: 4.0.8 parse-json: 5.2.0 - pretty-format: 29.7.0 + pretty-format: 30.0.2 slash: 3.0.0 strip-json-comments: 3.1.1 optionalDependencies: @@ -8316,212 +8688,211 @@ snapshots: - babel-plugin-macros - supports-color - jest-diff@29.7.0: + jest-diff@30.0.3: dependencies: + '@jest/diff-sequences': 30.0.1 + '@jest/get-type': 30.0.1 chalk: 4.1.2 - diff-sequences: 29.6.3 - jest-get-type: 29.6.3 - pretty-format: 29.7.0 + pretty-format: 30.0.2 - jest-docblock@29.7.0: + jest-docblock@30.0.1: dependencies: detect-newline: 3.1.0 - jest-each@29.7.0: + jest-each@30.0.2: dependencies: - '@jest/types': 29.6.3 + '@jest/get-type': 30.0.1 + '@jest/types': 30.0.1 chalk: 4.1.2 - jest-get-type: 29.6.3 - jest-util: 29.7.0 - pretty-format: 29.7.0 + jest-util: 30.0.2 + pretty-format: 30.0.2 - jest-environment-node@29.7.0: + jest-environment-node@30.0.2: dependencies: - '@jest/environment': 29.7.0 - '@jest/fake-timers': 29.7.0 - '@jest/types': 29.6.3 + '@jest/environment': 30.0.2 + '@jest/fake-timers': 30.0.2 + '@jest/types': 30.0.1 '@types/node': 22.15.21 - jest-mock: 29.7.0 - jest-util: 29.7.0 - - jest-get-type@29.6.3: {} + jest-mock: 30.0.2 + jest-util: 30.0.2 + jest-validate: 30.0.2 - jest-haste-map@29.7.0: + jest-haste-map@30.0.2: dependencies: - '@jest/types': 29.6.3 - '@types/graceful-fs': 4.1.9 + '@jest/types': 30.0.1 '@types/node': 22.15.21 anymatch: 3.1.3 fb-watchman: 2.0.2 graceful-fs: 4.2.11 - jest-regex-util: 29.6.3 - jest-util: 29.7.0 - jest-worker: 29.7.0 + jest-regex-util: 30.0.1 + jest-util: 30.0.2 + jest-worker: 30.0.2 micromatch: 4.0.8 walker: 1.0.8 optionalDependencies: fsevents: 2.3.3 - jest-leak-detector@29.7.0: + jest-leak-detector@30.0.2: dependencies: - jest-get-type: 29.6.3 - pretty-format: 29.7.0 + '@jest/get-type': 30.0.1 + pretty-format: 30.0.2 - jest-matcher-utils@29.7.0: + jest-matcher-utils@30.0.3: dependencies: + '@jest/get-type': 30.0.1 chalk: 4.1.2 - jest-diff: 29.7.0 - jest-get-type: 29.6.3 - pretty-format: 29.7.0 + jest-diff: 30.0.3 + pretty-format: 30.0.2 - jest-message-util@29.7.0: + jest-message-util@30.0.2: dependencies: '@babel/code-frame': 7.27.1 - '@jest/types': 29.6.3 + '@jest/types': 30.0.1 '@types/stack-utils': 2.0.3 chalk: 4.1.2 graceful-fs: 4.2.11 micromatch: 4.0.8 - pretty-format: 29.7.0 + pretty-format: 30.0.2 slash: 3.0.0 stack-utils: 2.0.6 - jest-mock@29.7.0: + jest-mock@30.0.2: dependencies: - '@jest/types': 29.6.3 + '@jest/types': 30.0.1 '@types/node': 22.15.21 - jest-util: 29.7.0 + jest-util: 30.0.2 - jest-pnp-resolver@1.2.3(jest-resolve@29.7.0): + jest-pnp-resolver@1.2.3(jest-resolve@30.0.2): optionalDependencies: - jest-resolve: 29.7.0 + jest-resolve: 30.0.2 - jest-regex-util@29.6.3: {} + jest-regex-util@30.0.1: {} - jest-resolve-dependencies@29.7.0: + jest-resolve-dependencies@30.0.3: dependencies: - jest-regex-util: 29.6.3 - jest-snapshot: 29.7.0 + jest-regex-util: 30.0.1 + jest-snapshot: 30.0.3 transitivePeerDependencies: - supports-color - jest-resolve@29.7.0: + jest-resolve@30.0.2: dependencies: chalk: 4.1.2 graceful-fs: 4.2.11 - jest-haste-map: 29.7.0 - jest-pnp-resolver: 1.2.3(jest-resolve@29.7.0) - jest-util: 29.7.0 - jest-validate: 29.7.0 - resolve: 1.22.10 - resolve.exports: 2.0.3 + jest-haste-map: 30.0.2 + jest-pnp-resolver: 1.2.3(jest-resolve@30.0.2) + jest-util: 30.0.2 + jest-validate: 30.0.2 slash: 3.0.0 + unrs-resolver: 1.9.2 - jest-runner@29.7.0: + jest-runner@30.0.3: dependencies: - '@jest/console': 29.7.0 - '@jest/environment': 29.7.0 - '@jest/test-result': 29.7.0 - '@jest/transform': 29.7.0 - '@jest/types': 29.6.3 + '@jest/console': 30.0.2 + '@jest/environment': 30.0.2 + '@jest/test-result': 30.0.2 + '@jest/transform': 30.0.2 + '@jest/types': 30.0.1 '@types/node': 22.15.21 chalk: 4.1.2 emittery: 0.13.1 + exit-x: 0.2.2 graceful-fs: 4.2.11 - jest-docblock: 29.7.0 - jest-environment-node: 29.7.0 - jest-haste-map: 29.7.0 - jest-leak-detector: 29.7.0 - jest-message-util: 29.7.0 - jest-resolve: 29.7.0 - jest-runtime: 29.7.0 - jest-util: 29.7.0 - jest-watcher: 29.7.0 - jest-worker: 29.7.0 + jest-docblock: 30.0.1 + jest-environment-node: 30.0.2 + jest-haste-map: 30.0.2 + jest-leak-detector: 30.0.2 + jest-message-util: 30.0.2 + jest-resolve: 30.0.2 + jest-runtime: 30.0.3 + jest-util: 30.0.2 + jest-watcher: 30.0.2 + jest-worker: 30.0.2 p-limit: 3.1.0 source-map-support: 0.5.13 transitivePeerDependencies: - supports-color - jest-runtime@29.7.0: + jest-runtime@30.0.3: dependencies: - '@jest/environment': 29.7.0 - '@jest/fake-timers': 29.7.0 - '@jest/globals': 29.7.0 - '@jest/source-map': 29.6.3 - '@jest/test-result': 29.7.0 - '@jest/transform': 29.7.0 - '@jest/types': 29.6.3 + '@jest/environment': 30.0.2 + '@jest/fake-timers': 30.0.2 + '@jest/globals': 30.0.3 + '@jest/source-map': 30.0.1 + '@jest/test-result': 30.0.2 + '@jest/transform': 30.0.2 + '@jest/types': 30.0.1 '@types/node': 22.15.21 chalk: 4.1.2 - cjs-module-lexer: 1.4.3 + cjs-module-lexer: 2.1.0 collect-v8-coverage: 1.0.2 - glob: 7.2.3 + glob: 10.4.5 graceful-fs: 4.2.11 - jest-haste-map: 29.7.0 - jest-message-util: 29.7.0 - jest-mock: 29.7.0 - jest-regex-util: 29.6.3 - jest-resolve: 29.7.0 - jest-snapshot: 29.7.0 - jest-util: 29.7.0 + jest-haste-map: 30.0.2 + jest-message-util: 30.0.2 + jest-mock: 30.0.2 + jest-regex-util: 30.0.1 + jest-resolve: 30.0.2 + jest-snapshot: 30.0.3 + jest-util: 30.0.2 slash: 3.0.0 strip-bom: 4.0.0 transitivePeerDependencies: - supports-color - jest-snapshot@29.7.0: + jest-snapshot@30.0.3: dependencies: - '@babel/core': 7.27.1 - '@babel/generator': 7.27.1 - '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.27.1) - '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.27.1) - '@babel/types': 7.27.1 - '@jest/expect-utils': 29.7.0 - '@jest/transform': 29.7.0 - '@jest/types': 29.6.3 - babel-preset-current-node-syntax: 1.1.0(@babel/core@7.27.1) + '@babel/core': 7.27.4 + '@babel/generator': 7.27.5 + '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.27.4) + '@babel/types': 7.27.3 + '@jest/expect-utils': 30.0.3 + '@jest/get-type': 30.0.1 + '@jest/snapshot-utils': 30.0.1 + '@jest/transform': 30.0.2 + '@jest/types': 30.0.1 + babel-preset-current-node-syntax: 1.1.0(@babel/core@7.27.4) chalk: 4.1.2 - expect: 29.7.0 + expect: 30.0.3 graceful-fs: 4.2.11 - jest-diff: 29.7.0 - jest-get-type: 29.6.3 - jest-matcher-utils: 29.7.0 - jest-message-util: 29.7.0 - jest-util: 29.7.0 - natural-compare: 1.4.0 - pretty-format: 29.7.0 + jest-diff: 30.0.3 + jest-matcher-utils: 30.0.3 + jest-message-util: 30.0.2 + jest-util: 30.0.2 + pretty-format: 30.0.2 semver: 7.7.2 + synckit: 0.11.8 transitivePeerDependencies: - supports-color - jest-util@29.7.0: + jest-util@30.0.2: dependencies: - '@jest/types': 29.6.3 + '@jest/types': 30.0.1 '@types/node': 22.15.21 chalk: 4.1.2 - ci-info: 3.9.0 + ci-info: 4.2.0 graceful-fs: 4.2.11 - picomatch: 2.3.1 + picomatch: 4.0.2 - jest-validate@29.7.0: + jest-validate@30.0.2: dependencies: - '@jest/types': 29.6.3 + '@jest/get-type': 30.0.1 + '@jest/types': 30.0.1 camelcase: 6.3.0 chalk: 4.1.2 - jest-get-type: 29.6.3 leven: 3.1.0 - pretty-format: 29.7.0 + pretty-format: 30.0.2 - jest-watcher@29.7.0: + jest-watcher@30.0.2: dependencies: - '@jest/test-result': 29.7.0 - '@jest/types': 29.6.3 + '@jest/test-result': 30.0.2 + '@jest/types': 30.0.1 '@types/node': 22.15.21 ansi-escapes: 4.3.2 chalk: 4.1.2 emittery: 0.13.1 - jest-util: 29.7.0 + jest-util: 30.0.2 string-length: 4.0.2 jest-worker@27.5.1: @@ -8530,22 +8901,24 @@ snapshots: merge-stream: 2.0.0 supports-color: 8.1.1 - jest-worker@29.7.0: + jest-worker@30.0.2: dependencies: '@types/node': 22.15.21 - jest-util: 29.7.0 + '@ungap/structured-clone': 1.3.0 + jest-util: 30.0.2 merge-stream: 2.0.0 supports-color: 8.1.1 - jest@29.7.0(@types/node@22.15.21)(ts-node@10.9.2(@swc/core@1.11.29)(@types/node@22.15.21)(typescript@5.8.3)): + jest@30.0.3(@types/node@22.15.21)(ts-node@10.9.2(@swc/core@1.11.29)(@types/node@22.15.21)(typescript@5.8.3)): dependencies: - '@jest/core': 29.7.0(ts-node@10.9.2(@swc/core@1.11.29)(@types/node@22.15.21)(typescript@5.8.3)) - '@jest/types': 29.6.3 + '@jest/core': 30.0.3(ts-node@10.9.2(@swc/core@1.11.29)(@types/node@22.15.21)(typescript@5.8.3)) + '@jest/types': 30.0.1 import-local: 3.2.0 - jest-cli: 29.7.0(@types/node@22.15.21)(ts-node@10.9.2(@swc/core@1.11.29)(@types/node@22.15.21)(typescript@5.8.3)) + jest-cli: 30.0.3(@types/node@22.15.21)(ts-node@10.9.2(@swc/core@1.11.29)(@types/node@22.15.21)(typescript@5.8.3)) transitivePeerDependencies: - '@types/node' - babel-plugin-macros + - esbuild-register - supports-color - ts-node @@ -8555,6 +8928,8 @@ snapshots: jose@5.10.0: {} + jose@6.0.11: {} + js-tokens@4.0.0: {} js-yaml@3.14.1: @@ -8599,8 +8974,6 @@ snapshots: kind-of@6.0.3: {} - kleur@3.0.3: {} - leven@3.1.0: {} levn@0.4.1: @@ -8667,6 +9040,8 @@ snapshots: lowercase-keys@3.0.0: {} + lru-cache@10.4.3: {} + lru-cache@11.1.0: {} lru-cache@5.1.1: @@ -8764,11 +9139,11 @@ snapshots: ms@2.1.3: {} - multer@1.4.5-lts.2: + multer@2.0.1: dependencies: append-field: 1.0.0 busboy: 1.6.0 - concat-stream: 1.6.2 + concat-stream: 2.0.0 mkdirp: 0.5.6 object-assign: 4.1.1 type-is: 1.6.18 @@ -8778,6 +9153,8 @@ snapshots: mute-stream@2.0.0: {} + napi-postinstall@0.2.4: {} + natural-compare@1.4.0: {} negotiator@1.0.0: {} @@ -8827,6 +9204,8 @@ snapshots: nullthrows@1.1.1: {} + oauth4webapi@3.5.3: {} + object-assign@4.1.1: {} object-inspect@1.13.4: {} @@ -8845,6 +9224,11 @@ snapshots: dependencies: mimic-fn: 2.1.0 + openid-client@6.6.1: + dependencies: + jose: 6.0.11 + oauth4webapi: 3.5.3 + optionator@0.9.4: dependencies: deep-is: 0.1.4 @@ -8942,14 +9326,17 @@ snapshots: path-key@3.1.1: {} - path-parse@1.0.7: {} - path-root-regex@0.1.2: {} path-root@0.1.1: dependencies: path-root-regex: 0.1.2 + path-scurry@1.11.1: + dependencies: + lru-cache: 10.4.3 + minipass: 7.1.2 + path-scurry@2.0.0: dependencies: lru-cache: 11.1.0 @@ -8991,11 +9378,11 @@ snapshots: dependencies: fast-diff: 1.3.0 - prettier@3.5.3: {} + prettier@3.6.1: {} - pretty-format@29.7.0: + pretty-format@30.0.2: dependencies: - '@jest/schemas': 29.6.3 + '@jest/schemas': 30.0.1 ansi-styles: 5.2.0 react-is: 18.3.1 @@ -9006,17 +9393,10 @@ snapshots: optionalDependencies: typescript: 5.8.3 - process-nextick-args@2.0.1: {} - promise@7.3.1: dependencies: asap: 2.0.6 - prompts@2.4.2: - dependencies: - kleur: 3.0.3 - sisteransi: 1.0.5 - proxy-addr@2.0.7: dependencies: forwarded: 0.2.0 @@ -9024,7 +9404,7 @@ snapshots: punycode@2.3.1: {} - pure-rand@6.1.0: {} + pure-rand@7.0.1: {} qs@6.14.0: dependencies: @@ -9051,16 +9431,6 @@ snapshots: react-is@18.3.1: {} - readable-stream@2.3.8: - dependencies: - core-util-is: 1.0.3 - inherits: 2.0.4 - isarray: 1.0.0 - process-nextick-args: 2.0.1 - safe-buffer: 5.1.2 - string_decoder: 1.1.1 - util-deprecate: 1.0.2 - readable-stream@3.6.2: dependencies: inherits: 2.0.4 @@ -9103,14 +9473,6 @@ snapshots: resolve-from@5.0.0: {} - resolve.exports@2.0.3: {} - - resolve@1.22.10: - dependencies: - is-core-module: 2.16.1 - path-parse: 1.0.7 - supports-preserve-symlinks-flag: 1.0.0 - responselike@3.0.0: dependencies: lowercase-keys: 3.0.0 @@ -9148,8 +9510,6 @@ snapshots: dependencies: tslib: 2.8.1 - safe-buffer@5.1.2: {} - safe-buffer@5.2.1: {} safer-buffer@2.1.2: {} @@ -9266,8 +9626,6 @@ snapshots: signedsource@1.0.0: {} - sisteransi@1.0.5: {} - slash@3.0.0: {} slice-ansi@3.0.0: @@ -9349,10 +9707,6 @@ snapshots: emoji-regex: 9.2.2 strip-ansi: 7.1.0 - string_decoder@1.1.1: - dependencies: - safe-buffer: 5.1.2 - string_decoder@1.3.0: dependencies: safe-buffer: 5.2.1 @@ -9417,8 +9771,6 @@ snapshots: dependencies: has-flag: 4.0.0 - supports-preserve-symlinks-flag@1.0.0: {} - swap-case@2.0.2: dependencies: tslib: 2.8.1 @@ -9431,10 +9783,9 @@ snapshots: timeout-signal: 2.0.0 whatwg-mimetype: 4.0.0 - synckit@0.11.5: + synckit@0.11.8: dependencies: '@pkgr/core': 0.2.4 - tslib: 2.8.1 tapable@2.2.1: {} @@ -9505,13 +9856,12 @@ snapshots: dependencies: typescript: 5.8.3 - ts-jest@29.3.4(@babel/core@7.27.1)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.27.1))(jest@29.7.0(@types/node@22.15.21)(ts-node@10.9.2(@swc/core@1.11.29)(@types/node@22.15.21)(typescript@5.8.3)))(typescript@5.8.3): + ts-jest@29.4.0(@babel/core@7.27.4)(@jest/transform@30.0.2)(@jest/types@30.0.1)(babel-jest@30.0.2(@babel/core@7.27.4))(jest-util@30.0.2)(jest@30.0.3(@types/node@22.15.21)(ts-node@10.9.2(@swc/core@1.11.29)(@types/node@22.15.21)(typescript@5.8.3)))(typescript@5.8.3): dependencies: bs-logger: 0.2.6 ejs: 3.1.10 fast-json-stable-stringify: 2.1.0 - jest: 29.7.0(@types/node@22.15.21)(ts-node@10.9.2(@swc/core@1.11.29)(@types/node@22.15.21)(typescript@5.8.3)) - jest-util: 29.7.0 + jest: 30.0.3(@types/node@22.15.21)(ts-node@10.9.2(@swc/core@1.11.29)(@types/node@22.15.21)(typescript@5.8.3)) json5: 2.2.3 lodash.memoize: 4.1.2 make-error: 1.3.6 @@ -9520,10 +9870,11 @@ snapshots: typescript: 5.8.3 yargs-parser: 21.1.1 optionalDependencies: - '@babel/core': 7.27.1 - '@jest/transform': 29.7.0 - '@jest/types': 29.6.3 - babel-jest: 29.7.0(@babel/core@7.27.1) + '@babel/core': 7.27.4 + '@jest/transform': 30.0.2 + '@jest/types': 30.0.1 + babel-jest: 30.0.2(@babel/core@7.27.4) + jest-util: 30.0.2 ts-loader@9.5.2(typescript@5.8.3)(webpack@5.99.6(@swc/core@1.11.29)): dependencies: @@ -9599,12 +9950,12 @@ snapshots: typedarray@0.0.6: {} - typescript-eslint@8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3): + typescript-eslint@8.35.0(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3): dependencies: - '@typescript-eslint/eslint-plugin': 8.32.1(@typescript-eslint/parser@8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3) - '@typescript-eslint/parser': 8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3) - '@typescript-eslint/utils': 8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3) - eslint: 9.27.0(jiti@2.4.2) + '@typescript-eslint/eslint-plugin': 8.35.0(@typescript-eslint/parser@8.35.0(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/parser': 8.35.0(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/utils': 8.35.0(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3) + eslint: 9.29.0(jiti@2.4.2) typescript: 5.8.3 transitivePeerDependencies: - supports-color @@ -9640,6 +9991,30 @@ snapshots: unpipe@1.0.0: {} + unrs-resolver@1.9.2: + dependencies: + napi-postinstall: 0.2.4 + optionalDependencies: + '@unrs/resolver-binding-android-arm-eabi': 1.9.2 + '@unrs/resolver-binding-android-arm64': 1.9.2 + '@unrs/resolver-binding-darwin-arm64': 1.9.2 + '@unrs/resolver-binding-darwin-x64': 1.9.2 + '@unrs/resolver-binding-freebsd-x64': 1.9.2 + '@unrs/resolver-binding-linux-arm-gnueabihf': 1.9.2 + '@unrs/resolver-binding-linux-arm-musleabihf': 1.9.2 + '@unrs/resolver-binding-linux-arm64-gnu': 1.9.2 + '@unrs/resolver-binding-linux-arm64-musl': 1.9.2 + '@unrs/resolver-binding-linux-ppc64-gnu': 1.9.2 + '@unrs/resolver-binding-linux-riscv64-gnu': 1.9.2 + '@unrs/resolver-binding-linux-riscv64-musl': 1.9.2 + '@unrs/resolver-binding-linux-s390x-gnu': 1.9.2 + '@unrs/resolver-binding-linux-x64-gnu': 1.9.2 + '@unrs/resolver-binding-linux-x64-musl': 1.9.2 + '@unrs/resolver-binding-wasm32-wasi': 1.9.2 + '@unrs/resolver-binding-win32-arm64-msvc': 1.9.2 + '@unrs/resolver-binding-win32-ia32-msvc': 1.9.2 + '@unrs/resolver-binding-win32-x64-msvc': 1.9.2 + update-browserslist-db@1.1.3(browserslist@4.24.5): dependencies: browserslist: 4.24.5 @@ -9760,10 +10135,10 @@ snapshots: wrappy@1.0.2: {} - write-file-atomic@4.0.2: + write-file-atomic@5.0.1: dependencies: imurmurhash: 0.1.4 - signal-exit: 3.0.7 + signal-exit: 4.1.0 ws@8.18.2: {} diff --git a/server/pnpm-workspace.yaml b/server/pnpm-workspace.yaml index 5dd3de53c..d24ecf9b2 100644 --- a/server/pnpm-workspace.yaml +++ b/server/pnpm-workspace.yaml @@ -5,3 +5,4 @@ onlyBuiltDependencies: - '@prisma/engines' - '@swc/core' - prisma + - unrs-resolver diff --git a/server/src/app.module.ts b/server/src/app.module.ts index dbd7bc8c9..78eafda57 100644 --- a/server/src/app.module.ts +++ b/server/src/app.module.ts @@ -4,6 +4,7 @@ import { AppService } from './app.service'; import { ConfigModule } from '@nestjs/config'; import config from './config'; import { UserModule } from './user/user.module'; +import { AuthModule } from './auth/auth.module'; @Module({ imports: [ @@ -13,6 +14,7 @@ import { UserModule } from './user/user.module'; expandVariables: true, }), UserModule, + AuthModule, ], controllers: [AppController], providers: [AppService], diff --git a/server/src/auth/auth.controller.ts b/server/src/auth/auth.controller.ts new file mode 100644 index 000000000..0bf6eaaac --- /dev/null +++ b/server/src/auth/auth.controller.ts @@ -0,0 +1,18 @@ +import { Controller, Get, Req, UseGuards } from '@nestjs/common'; +import { AuthGuard } from '@nestjs/passport'; +import { Request } from 'express'; + +@Controller('auth') +export class AuthController { + @Get('login') + @UseGuards(AuthGuard('oidc')) + login() { + // Handled by Passport redirect + } + + @Get('callback/csesoc') + @UseGuards(AuthGuard('oidc')) + callback(@Req() req: Request) { + return req.user; // user from validate() + } +} diff --git a/server/src/auth/auth.module.ts b/server/src/auth/auth.module.ts new file mode 100644 index 000000000..6f2dabf42 --- /dev/null +++ b/server/src/auth/auth.module.ts @@ -0,0 +1,23 @@ +import { Module } from '@nestjs/common'; +import { AuthService } from './auth.service'; +import { getConfig, OidcStrategy } from './oidc.strategy'; +import { PassportModule } from '@nestjs/passport'; +import { AuthController } from './auth.controller'; + +const OidcStrategyFactory = { + provide: 'OidcStrategy', + useFactory: async (authService: AuthService) => { + const config = await getConfig(); + return new OidcStrategy(authService, config); + }, + inject: [AuthService], +}; + +@Module({ + imports: [ + PassportModule.register({ session: true, defaultStrategy: 'oidc' }), + ], + controllers: [AuthController], + providers: [AuthService, OidcStrategyFactory], +}) +export class AuthModule {} diff --git a/server/src/auth/auth.service.ts b/server/src/auth/auth.service.ts new file mode 100644 index 000000000..a41c649f9 --- /dev/null +++ b/server/src/auth/auth.service.ts @@ -0,0 +1,4 @@ +import { Injectable } from '@nestjs/common'; + +@Injectable() +export class AuthService {} diff --git a/server/src/auth/oidc.strategy.ts b/server/src/auth/oidc.strategy.ts new file mode 100644 index 000000000..b984a117b --- /dev/null +++ b/server/src/auth/oidc.strategy.ts @@ -0,0 +1,42 @@ +import { Injectable } from '@nestjs/common'; +import { PassportStrategy } from '@nestjs/passport'; +import { discovery, Configuration, UserInfoResponse } from 'openid-client'; +import { AuthService } from './auth.service'; +const { Strategy } = + // eslint-disable-next-line @typescript-eslint/no-require-imports + require('openid-client/passport') as typeof import('openid-client/build/passport'); + +export const getConfig = async (): Promise => { + return await discovery( + new URL( + `${process.env.OAUTH2_CLIENT_PROVIDER_OIDC_ISSUER}/.well-known/openid-configuration`, + ), + process.env.OAUTH2_CLIENT_REGISTRATION_LOGIN_CLIENT_ID!, + process.env.OAUTH2_CLIENT_REGISTRATION_LOGIN_CLIENT_SECRET, + ); +}; + +@Injectable() +export class OidcStrategy extends PassportStrategy(Strategy, 'oidc') { + constructor( + private authService: AuthService, + config: Configuration, + ) { + super({ + config, + scope: process.env.OAUTH2_CLIENT_REGISTRATION_LOGIN_SCOPE!, + callbackURL: process.env.OAUTH2_CLIENT_REGISTRATION_LOGIN_REDIRECT_URI!, + // passReqToCallback: true, + }); + } + + validate(tokenset: any, userinfo: UserInfoResponse) { + return { + id: userinfo.sub, + email: userinfo.email, + name: userinfo.name, + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + tokenset, + }; + } +} diff --git a/server/src/graphql/queries.ts b/server/src/graphql/queries.ts index 7e890c98f..076906af0 100644 --- a/server/src/graphql/queries.ts +++ b/server/src/graphql/queries.ts @@ -1,6 +1,6 @@ -import { graphql } from '../generated/graphql/gql'; +import { gql } from 'graphql-tag'; -export const COURSE_EXISTS = graphql(` +export const COURSE_EXISTS = gql(` query CourseExists($courseId: String!, $term: String!) { courseExists: classes_aggregate( where: { course_id: { _eq: $courseId }, term: { _eq: $term } } diff --git a/server/src/prisma/prisma.service.ts b/server/src/prisma/prisma.service.ts index 27b13025f..ef197de4c 100644 --- a/server/src/prisma/prisma.service.ts +++ b/server/src/prisma/prisma.service.ts @@ -1,5 +1,5 @@ import { Injectable, OnModuleInit } from '@nestjs/common'; -import { PrismaClient } from '../generated/prisma'; +import { PrismaClient } from '../generated/prisma/client'; @Injectable() export class PrismaService extends PrismaClient implements OnModuleInit { From 54991eb47edbb0e33e1124e32845163958ca62b0 Mon Sep 17 00:00:00 2001 From: Lucas Date: Mon, 30 Jun 2025 14:14:00 +1000 Subject: [PATCH 07/33] Implement OIDC --- server/src/auth/auth.controller.ts | 14 ++--- server/src/auth/auth.module.ts | 15 +++-- server/src/auth/oidc.strategy.ts | 83 +++++++++++++++++++++++---- server/src/auth/session.serializer.ts | 31 ++++++++++ server/src/types/express.d.ts | 9 --- server/src/user/user.controller.ts | 31 +++++++--- 6 files changed, 142 insertions(+), 41 deletions(-) create mode 100644 server/src/auth/session.serializer.ts delete mode 100644 server/src/types/express.d.ts diff --git a/server/src/auth/auth.controller.ts b/server/src/auth/auth.controller.ts index 0bf6eaaac..3209d65d6 100644 --- a/server/src/auth/auth.controller.ts +++ b/server/src/auth/auth.controller.ts @@ -1,18 +1,16 @@ -import { Controller, Get, Req, UseGuards } from '@nestjs/common'; +import { Controller, Get, Res, UseGuards } from '@nestjs/common'; import { AuthGuard } from '@nestjs/passport'; -import { Request } from 'express'; +import { Response } from 'express'; @Controller('auth') export class AuthController { @Get('login') @UseGuards(AuthGuard('oidc')) - login() { - // Handled by Passport redirect - } + login() {} - @Get('callback/csesoc') + @Get('callback/devsoc') @UseGuards(AuthGuard('oidc')) - callback(@Req() req: Request) { - return req.user; // user from validate() + callback(@Res() res: Response) { + res.redirect('http://localhost:3001/api/user/profile'); } } diff --git a/server/src/auth/auth.module.ts b/server/src/auth/auth.module.ts index 6f2dabf42..f9bcd6a26 100644 --- a/server/src/auth/auth.module.ts +++ b/server/src/auth/auth.module.ts @@ -3,14 +3,16 @@ import { AuthService } from './auth.service'; import { getConfig, OidcStrategy } from './oidc.strategy'; import { PassportModule } from '@nestjs/passport'; import { AuthController } from './auth.controller'; +import { SessionSerializer } from './session.serializer'; +import { PrismaService } from 'src/prisma/prisma.service'; const OidcStrategyFactory = { provide: 'OidcStrategy', - useFactory: async (authService: AuthService) => { + useFactory: async (prismaService: PrismaService) => { const config = await getConfig(); - return new OidcStrategy(authService, config); + return new OidcStrategy(config, prismaService); }, - inject: [AuthService], + inject: [PrismaService], }; @Module({ @@ -18,6 +20,11 @@ const OidcStrategyFactory = { PassportModule.register({ session: true, defaultStrategy: 'oidc' }), ], controllers: [AuthController], - providers: [AuthService, OidcStrategyFactory], + providers: [ + AuthService, + PrismaService, + OidcStrategyFactory, + SessionSerializer, + ], }) export class AuthModule {} diff --git a/server/src/auth/oidc.strategy.ts b/server/src/auth/oidc.strategy.ts index b984a117b..e7fbbcb9b 100644 --- a/server/src/auth/oidc.strategy.ts +++ b/server/src/auth/oidc.strategy.ts @@ -1,7 +1,18 @@ -import { Injectable } from '@nestjs/common'; +import { HttpException, HttpStatus, Injectable } from '@nestjs/common'; import { PassportStrategy } from '@nestjs/passport'; -import { discovery, Configuration, UserInfoResponse } from 'openid-client'; -import { AuthService } from './auth.service'; +import { Request } from 'express'; +import { + Configuration, + discovery, + fetchUserInfo, + randomState, + TokenEndpointResponse, + TokenEndpointResponseHelpers, + UserInfoResponse, +} from 'openid-client'; +import { AuthenticateOptions } from 'openid-client/build/passport'; +import { promisify } from 'util'; +import { PrismaService } from 'src/prisma/prisma.service'; const { Strategy } = // eslint-disable-next-line @typescript-eslint/no-require-imports require('openid-client/passport') as typeof import('openid-client/build/passport'); @@ -19,24 +30,72 @@ export const getConfig = async (): Promise => { @Injectable() export class OidcStrategy extends PassportStrategy(Strategy, 'oidc') { constructor( - private authService: AuthService, - config: Configuration, + private readonly config: Configuration, + private readonly prisma: PrismaService, ) { super({ config, scope: process.env.OAUTH2_CLIENT_REGISTRATION_LOGIN_SCOPE!, callbackURL: process.env.OAUTH2_CLIENT_REGISTRATION_LOGIN_REDIRECT_URI!, - // passReqToCallback: true, + name: 'oidc', + passReqToCallback: true, }); } - validate(tokenset: any, userinfo: UserInfoResponse) { + authorizationRequestParams( + req: Request, + options: TOptions, + ): URLSearchParams | Record | undefined { + const params = super.authorizationRequestParams(req, options); return { - id: userinfo.sub, - email: userinfo.email, - name: userinfo.name, - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment - tokenset, + ...params, + state: randomState(), }; } + + async validate( + req: Request, + tokenset: TokenEndpointResponse & TokenEndpointResponseHelpers, + ) { + const claims = tokenset.claims(); + if (!claims) { + throw new HttpException( + 'No claims found in tokenset', + HttpStatus.INTERNAL_SERVER_ERROR, + ); + } + + const userInfo: UserInfoResponse = await fetchUserInfo( + this.config, + tokenset.access_token, + claims.sub, + ); + + const userData = userInfo.userData as { + firstName: string; + lastName: string; + zid: string; + department: string; + program: number; + }; + + const user = await this.prisma.user.upsert({ + where: { + oidcId: userInfo.sub, + }, + update: { + lastLogin: new Date(), + }, + create: { + oidcId: userInfo.sub, + firstName: userData.firstName, + lastName: userData.lastName, + isGuest: false, + }, + }); + + const login = promisify(req.login.bind(req)); + await login(user); + return user; + } } diff --git a/server/src/auth/session.serializer.ts b/server/src/auth/session.serializer.ts new file mode 100644 index 000000000..22490450b --- /dev/null +++ b/server/src/auth/session.serializer.ts @@ -0,0 +1,31 @@ +import { Injectable } from '@nestjs/common'; +import { PassportSerializer } from '@nestjs/passport'; + +type SessionUser = { + id: string; + oidcId: string; + isGuest: boolean; +}; + +@Injectable() +export class SessionSerializer extends PassportSerializer { + serializeUser( + user: SessionUser, + done: (err: Error | null, payload?: SessionUser) => void, + ): void { + // Only cache the minimal required fields in session + done(null, { + id: user.id, + oidcId: user.oidcId, + isGuest: user.isGuest, + }); + } + + deserializeUser( + payload: SessionUser, + done: (err: Error | null, user?: SessionUser) => void, + ): void { + // No DB lookup — just return cached data + done(null, payload); + } +} diff --git a/server/src/types/express.d.ts b/server/src/types/express.d.ts deleted file mode 100644 index dd9f6a58b..000000000 --- a/server/src/types/express.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -declare module 'express' { - interface Request { - user?: { - id: string; - isGuest: boolean; - }; - isAuthenticated(): boolean; - } -} diff --git a/server/src/user/user.controller.ts b/server/src/user/user.controller.ts index 4085751d4..4a187a585 100644 --- a/server/src/user/user.controller.ts +++ b/server/src/user/user.controller.ts @@ -4,35 +4,50 @@ import { AuthenticatedGuard } from 'src/auth/authenticated.guard'; import { Request } from 'express'; import { UserSettings } from './types'; +interface AuthenticatedRequest extends Request { + user: { + id: string; + oidcId?: string; + isGuest: boolean; + }; +} + @Controller('user') export class UserController { constructor(private userService: UserService) {} @Get('profile') @UseGuards(AuthenticatedGuard) - async getProfile(@Req() req: Request) { - const userInfo = await this.userService.getUserInfo(req.user!.id); + async getProfile(@Req() req: AuthenticatedRequest) { + console.log(req.user); + const userInfo = await this.userService.getUserInfo(req.user.id); return userInfo; } @Post('profile/picture') @UseGuards(AuthenticatedGuard) - async setProfilePicture(@Req() req: Request, @Body('url') url: string) { - await this.userService.setProfilePicture(req.user!.id, url); + async setProfilePicture( + @Req() req: AuthenticatedRequest, + @Body('url') url: string, + ) { + await this.userService.setProfilePicture(req.user.id, url); return; } @Get('settings') @UseGuards(AuthenticatedGuard) - async getSettings(@Req() req: Request) { - const settings = await this.userService.getSettings(req.user!.id); + async getSettings(@Req() req: AuthenticatedRequest) { + const settings = await this.userService.getSettings(req.user.id); return settings; } @Post('settings') @UseGuards(AuthenticatedGuard) - async setSettings(@Req() req: Request, @Body() settings: UserSettings) { - await this.userService.setSettings(req.user!.id, settings); + async setSettings( + @Req() req: AuthenticatedRequest, + @Body() settings: UserSettings, + ) { + await this.userService.setSettings(req.user.id, settings); return; } } From 4d7e11d3c38ea1712e7e44035fe357a5e1a8aeed Mon Sep 17 00:00:00 2001 From: Lucas Date: Mon, 30 Jun 2025 15:02:15 +1000 Subject: [PATCH 08/33] Remove debug log --- server/src/user/user.controller.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/server/src/user/user.controller.ts b/server/src/user/user.controller.ts index 4a187a585..9dee9e9db 100644 --- a/server/src/user/user.controller.ts +++ b/server/src/user/user.controller.ts @@ -19,7 +19,6 @@ export class UserController { @Get('profile') @UseGuards(AuthenticatedGuard) async getProfile(@Req() req: AuthenticatedRequest) { - console.log(req.user); const userInfo = await this.userService.getUserInfo(req.user.id); return userInfo; } From 9ea51605cbb96b9f9b5055661463cd72dc3573ec Mon Sep 17 00:00:00 2001 From: Lucas Date: Thu, 3 Jul 2025 20:35:49 +1000 Subject: [PATCH 09/33] Bump backend deps --- server/package.json | 28 +- server/pnpm-lock.yaml | 811 ++++++++++++++++++++++-------------------- 2 files changed, 441 insertions(+), 398 deletions(-) diff --git a/server/package.json b/server/package.json index fd97bf6c5..654d4b2bd 100644 --- a/server/package.json +++ b/server/package.json @@ -26,20 +26,20 @@ "@nestjs/core": "11.1.3", "@nestjs/passport": "11.0.5", "@nestjs/platform-express": "11.1.3", - "@prisma/client": "6.8.2", + "@prisma/client": "6.11.0", "express-session": "1.18.1", "graphql": "16.11.0", "graphql-request": "7.2.0", "graphql-tag": "2.12.6", - "openid-client": "6.6.1", + "openid-client": "6.6.2", "passport": "0.7.0", "reflect-metadata": "0.2.2", "rxjs": "7.8.2" }, "devDependencies": { - "@0no-co/graphqlsp": "1.12.16", + "@0no-co/graphqlsp": "1.13.0", "@eslint/eslintrc": "3.3.1", - "@eslint/js": "9.29.0", + "@eslint/js": "9.30.1", "@graphql-codegen/cli": "5.0.7", "@graphql-codegen/client-preset": "4.8.3", "@graphql-codegen/typescript": "4.1.6", @@ -50,21 +50,21 @@ "@nestjs/schematics": "11.0.5", "@nestjs/testing": "11.1.3", "@parcel/watcher": "2.5.1", - "@swc/cli": "0.6.0", - "@swc/core": "1.11.29", + "@swc/cli": "0.7.7", + "@swc/core": "1.12.9", "@types/express": "5.0.3", "@types/express-session": "1.18.2", "@types/jest": "30.0.0", - "@types/node": "22.15.21", + "@types/node": "22", "@types/passport": "1.0.17", "@types/supertest": "6.0.3", - "eslint": "9.29.0", + "eslint": "9.30.1", "eslint-config-prettier": "10.1.5", "eslint-plugin-prettier": "5.5.1", - "globals": "16.1.0", - "jest": "30.0.3", - "prettier": "3.6.1", - "prisma": "6.8.2", + "globals": "16.3.0", + "jest": "30.0.4", + "prettier": "3.6.2", + "prisma": "6.11.0", "source-map-support": "0.5.21", "supertest": "7.1.1", "ts-jest": "29.4.0", @@ -72,7 +72,7 @@ "ts-node": "10.9.2", "tsconfig-paths": "4.2.0", "typescript": "5.8.3", - "typescript-eslint": "8.35.0" + "typescript-eslint": "8.35.1" }, "jest": { "moduleFileExtensions": [ @@ -91,5 +91,5 @@ "coverageDirectory": "../coverage", "testEnvironment": "node" }, - "packageManager": "pnpm@10.12.3+sha512.467df2c586056165580ad6dfb54ceaad94c5a30f80893ebdec5a44c5aa73c205ae4a5bb9d5ed6bb84ea7c249ece786642bbb49d06a307df218d03da41c317417" + "packageManager": "pnpm@10.12.4+sha512.5ea8b0deed94ed68691c9bad4c955492705c5eeb8a87ef86bc62c74a26b037b08ff9570f108b2e4dbd1dd1a9186fea925e527f141c648e85af45631074680184" } diff --git a/server/pnpm-lock.yaml b/server/pnpm-lock.yaml index eba35752d..b14f18e4a 100644 --- a/server/pnpm-lock.yaml +++ b/server/pnpm-lock.yaml @@ -24,8 +24,8 @@ importers: specifier: 11.1.3 version: 11.1.3(@nestjs/common@11.1.3(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.3) '@prisma/client': - specifier: 6.8.2 - version: 6.8.2(prisma@6.8.2(typescript@5.8.3))(typescript@5.8.3) + specifier: 6.11.0 + version: 6.11.0(prisma@6.11.0(typescript@5.8.3))(typescript@5.8.3) express-session: specifier: 1.18.1 version: 1.18.1 @@ -39,8 +39,8 @@ importers: specifier: 2.12.6 version: 2.12.6(graphql@16.11.0) openid-client: - specifier: 6.6.1 - version: 6.6.1 + specifier: 6.6.2 + version: 6.6.2 passport: specifier: 0.7.0 version: 0.7.0 @@ -52,14 +52,14 @@ importers: version: 7.8.2 devDependencies: '@0no-co/graphqlsp': - specifier: 1.12.16 - version: 1.12.16(graphql@16.11.0)(typescript@5.8.3) + specifier: 1.13.0 + version: 1.13.0(graphql@16.11.0)(typescript@5.8.3) '@eslint/eslintrc': specifier: 3.3.1 version: 3.3.1 '@eslint/js': - specifier: 9.29.0 - version: 9.29.0 + specifier: 9.30.1 + version: 9.30.1 '@graphql-codegen/cli': specifier: 5.0.7 version: 5.0.7(@parcel/watcher@2.5.1)(@types/node@22.15.21)(graphql@16.11.0)(typescript@5.8.3) @@ -80,7 +80,7 @@ importers: version: 8.3.19(graphql@16.11.0) '@nestjs/cli': specifier: 11.0.7 - version: 11.0.7(@swc/cli@0.6.0(@swc/core@1.11.29)(chokidar@4.0.3))(@swc/core@1.11.29)(@types/node@22.15.21) + version: 11.0.7(@swc/cli@0.7.7(@swc/core@1.12.9)(chokidar@4.0.3))(@swc/core@1.12.9)(@types/node@22.15.21) '@nestjs/schematics': specifier: 11.0.5 version: 11.0.5(chokidar@4.0.3)(typescript@5.8.3) @@ -91,11 +91,11 @@ importers: specifier: 2.5.1 version: 2.5.1 '@swc/cli': - specifier: 0.6.0 - version: 0.6.0(@swc/core@1.11.29)(chokidar@4.0.3) + specifier: 0.7.7 + version: 0.7.7(@swc/core@1.12.9)(chokidar@4.0.3) '@swc/core': - specifier: 1.11.29 - version: 1.11.29 + specifier: 1.12.9 + version: 1.12.9 '@types/express': specifier: 5.0.3 version: 5.0.3 @@ -106,7 +106,7 @@ importers: specifier: 30.0.0 version: 30.0.0 '@types/node': - specifier: 22.15.21 + specifier: '22' version: 22.15.21 '@types/passport': specifier: 1.0.17 @@ -115,26 +115,26 @@ importers: specifier: 6.0.3 version: 6.0.3 eslint: - specifier: 9.29.0 - version: 9.29.0(jiti@2.4.2) + specifier: 9.30.1 + version: 9.30.1(jiti@2.4.2) eslint-config-prettier: specifier: 10.1.5 - version: 10.1.5(eslint@9.29.0(jiti@2.4.2)) + version: 10.1.5(eslint@9.30.1(jiti@2.4.2)) eslint-plugin-prettier: specifier: 5.5.1 - version: 5.5.1(@types/eslint@9.6.1)(eslint-config-prettier@10.1.5(eslint@9.29.0(jiti@2.4.2)))(eslint@9.29.0(jiti@2.4.2))(prettier@3.6.1) + version: 5.5.1(@types/eslint@9.6.1)(eslint-config-prettier@10.1.5(eslint@9.30.1(jiti@2.4.2)))(eslint@9.30.1(jiti@2.4.2))(prettier@3.6.2) globals: - specifier: 16.1.0 - version: 16.1.0 + specifier: 16.3.0 + version: 16.3.0 jest: - specifier: 30.0.3 - version: 30.0.3(@types/node@22.15.21)(ts-node@10.9.2(@swc/core@1.11.29)(@types/node@22.15.21)(typescript@5.8.3)) + specifier: 30.0.4 + version: 30.0.4(@types/node@22.15.21)(ts-node@10.9.2(@swc/core@1.12.9)(@types/node@22.15.21)(typescript@5.8.3)) prettier: - specifier: 3.6.1 - version: 3.6.1 + specifier: 3.6.2 + version: 3.6.2 prisma: - specifier: 6.8.2 - version: 6.8.2(typescript@5.8.3) + specifier: 6.11.0 + version: 6.11.0(typescript@5.8.3) source-map-support: specifier: 0.5.21 version: 0.5.21 @@ -143,13 +143,13 @@ importers: version: 7.1.1 ts-jest: specifier: 29.4.0 - version: 29.4.0(@babel/core@7.27.4)(@jest/transform@30.0.2)(@jest/types@30.0.1)(babel-jest@30.0.2(@babel/core@7.27.4))(jest-util@30.0.2)(jest@30.0.3(@types/node@22.15.21)(ts-node@10.9.2(@swc/core@1.11.29)(@types/node@22.15.21)(typescript@5.8.3)))(typescript@5.8.3) + version: 29.4.0(@babel/core@7.27.4)(@jest/transform@30.0.4)(@jest/types@30.0.1)(babel-jest@30.0.4(@babel/core@7.27.4))(jest-util@30.0.2)(jest@30.0.4(@types/node@22.15.21)(ts-node@10.9.2(@swc/core@1.12.9)(@types/node@22.15.21)(typescript@5.8.3)))(typescript@5.8.3) ts-loader: specifier: 9.5.2 - version: 9.5.2(typescript@5.8.3)(webpack@5.99.6(@swc/core@1.11.29)) + version: 9.5.2(typescript@5.8.3)(webpack@5.99.6(@swc/core@1.12.9)) ts-node: specifier: 10.9.2 - version: 10.9.2(@swc/core@1.11.29)(@types/node@22.15.21)(typescript@5.8.3) + version: 10.9.2(@swc/core@1.12.9)(@types/node@22.15.21)(typescript@5.8.3) tsconfig-paths: specifier: 4.2.0 version: 4.2.0 @@ -157,8 +157,8 @@ importers: specifier: 5.8.3 version: 5.8.3 typescript-eslint: - specifier: 8.35.0 - version: 8.35.0(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3) + specifier: 8.35.1 + version: 8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) packages: @@ -170,8 +170,8 @@ packages: graphql: optional: true - '@0no-co/graphqlsp@1.12.16': - resolution: {integrity: sha512-B5pyYVH93Etv7xjT6IfB7QtMBdaaC07yjbhN6v8H7KgFStMkPvi+oWYBTibMFRMY89qwc9H8YixXg8SXDVgYWw==} + '@0no-co/graphqlsp@1.13.0': + resolution: {integrity: sha512-I8HVJ19PeF0QMKCcxUXjsmbI6L26bmAuDHUFdLD8xjhaOi7XG2ZhlkhqTYNxzYJN58yvv0IfKfn8yVrVvPUmVw==} peerDependencies: graphql: ^15.5.0 || ^16.0.0 || ^17.0.0 typescript: ^5.0.0 @@ -636,12 +636,12 @@ packages: resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - '@eslint/config-array@0.20.1': - resolution: {integrity: sha512-OL0RJzC/CBzli0DrrR31qzj6d6i6Mm3HByuhflhl4LOBiWxN+3i6/t/ZQQNii4tjksXi8r2CRW1wMpWA2ULUEw==} + '@eslint/config-array@0.21.0': + resolution: {integrity: sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/config-helpers@0.2.2': - resolution: {integrity: sha512-+GPzk8PlG0sPpzdU5ZvIRMPidzAnZDl/s9L+y13iodqvb8leL53bTannOrQ/Im7UkpsmFU5Ily5U60LWixnmLg==} + '@eslint/config-helpers@0.3.0': + resolution: {integrity: sha512-ViuymvFmcJi04qdZeDc2whTHryouGcDlaxPqarTD0ZE10ISpxGUVZGZDx4w01upyIynL3iu6IXH2bS1NhclQMw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@eslint/core@0.14.0': @@ -652,8 +652,8 @@ packages: resolution: {integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/js@9.29.0': - resolution: {integrity: sha512-3PIF4cBw/y+1u2EazflInpV+lYsSG0aByVIQzAgb1m1MhHFSbqTyNqtBKHgWf/9Ykud+DhILS9EGkmekVhbKoQ==} + '@eslint/js@9.30.1': + resolution: {integrity: sha512-zXhuECFlyep42KZUhWjfvsmXGX39W8K8LFb8AWXM9gSV9dQB+MrJGLKvW6Zw0Ggnbpw0VHTtrhFXYe3Gym18jg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@eslint/object-schema@2.1.6': @@ -1109,12 +1109,12 @@ packages: resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} engines: {node: '>=8'} - '@jest/console@30.0.2': - resolution: {integrity: sha512-krGElPU0FipAqpVZ/BRZOy0MZh/ARdJ0Nj+PiH1ykFY1+VpBlYNLjdjVA5CFKxnKR6PFqFutO4Z7cdK9BlGiDA==} + '@jest/console@30.0.4': + resolution: {integrity: sha512-tMLCDvBJBwPqMm4OAiuKm2uF5y5Qe26KgcMn+nrDSWpEW+eeFmqA0iO4zJfL16GP7gE3bUUQ3hIuUJ22AqVRnw==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - '@jest/core@30.0.3': - resolution: {integrity: sha512-Mgs1N+NSHD3Fusl7bOq1jyxv1JDAUwjy+0DhVR93Q6xcBP9/bAQ+oZhXb5TTnP5sQzAHgb7ROCKQ2SnovtxYtg==} + '@jest/core@30.0.4': + resolution: {integrity: sha512-MWScSO9GuU5/HoWjpXAOBs6F/iobvK1XlioelgOM9St7S0Z5WTI9kjCQLPeo4eQRRYusyLW25/J7J5lbFkrYXw==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} peerDependencies: node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 @@ -1126,36 +1126,40 @@ packages: resolution: {integrity: sha512-n5H8QLDJ47QqbCNn5SuFjCRDrOLEZ0h8vAHCK5RL9Ls7Xa8AQLa/YxAc9UjFqoEDM48muwtBGjtMY5cr0PLDCw==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - '@jest/environment@30.0.2': - resolution: {integrity: sha512-hRLhZRJNxBiOhxIKSq2UkrlhMt3/zVFQOAi5lvS8T9I03+kxsbflwHJEF+eXEYXCrRGRhHwECT7CDk6DyngsRA==} + '@jest/environment@30.0.4': + resolution: {integrity: sha512-5NT+sr7ZOb8wW7C4r7wOKnRQ8zmRWQT2gW4j73IXAKp5/PX1Z8MCStBLQDYfIG3n1Sw0NRfYGdp0iIPVooBAFQ==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} '@jest/expect-utils@30.0.3': resolution: {integrity: sha512-SMtBvf2sfX2agcT0dA9pXwcUrKvOSDqBY4e4iRfT+Hya33XzV35YVg+98YQFErVGA/VR1Gto5Y2+A6G9LSQ3Yg==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - '@jest/expect@30.0.3': - resolution: {integrity: sha512-73BVLqfCeWjYWPEQoYjiRZ4xuQRhQZU0WdgvbyXGRHItKQqg5e6mt2y1kVhzLSuZpmUnccZHbGynoaL7IcLU3A==} + '@jest/expect-utils@30.0.4': + resolution: {integrity: sha512-EgXecHDNfANeqOkcak0DxsoVI4qkDUsR7n/Lr2vtmTBjwLPBnnPOF71S11Q8IObWzxm2QgQoY6f9hzrRD3gHRA==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - '@jest/fake-timers@30.0.2': - resolution: {integrity: sha512-jfx0Xg7l0gmphTY9UKm5RtH12BlLYj/2Plj6wXjVW5Era4FZKfXeIvwC67WX+4q8UCFxYS20IgnMcFBcEU0DtA==} + '@jest/expect@30.0.4': + resolution: {integrity: sha512-Z/DL7t67LBHSX4UzDyeYKqOxE/n7lbrrgEwWM3dGiH5Dgn35nk+YtgzKudmfIrBI8DRRrKYY5BCo3317HZV1Fw==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + '@jest/fake-timers@30.0.4': + resolution: {integrity: sha512-qZ7nxOcL5+gwBO6LErvwVy5k06VsX/deqo2XnVUSTV0TNC9lrg8FC3dARbi+5lmrr5VyX5drragK+xLcOjvjYw==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} '@jest/get-type@30.0.1': resolution: {integrity: sha512-AyYdemXCptSRFirI5EPazNxyPwAL0jXt3zceFjaj8NFiKP9pOi0bfXonf6qkf82z2t3QWPeLCWWw4stPBzctLw==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - '@jest/globals@30.0.3': - resolution: {integrity: sha512-fIduqNyYpMeeSr5iEAiMn15KxCzvrmxl7X7VwLDRGj7t5CoHtbF+7K3EvKk32mOUIJ4kIvFRlaixClMH2h/Vaw==} + '@jest/globals@30.0.4': + resolution: {integrity: sha512-avyZuxEHF2EUhFF6NEWVdxkRRV6iXXcIES66DLhuLlU7lXhtFG/ySq/a8SRZmEJSsLkNAFX6z6mm8KWyXe9OEA==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} '@jest/pattern@30.0.1': resolution: {integrity: sha512-gWp7NfQW27LaBQz3TITS8L7ZCQ0TLvtmI//4OwlQRx4rnWxcPNIYjxZpDcN4+UlGxgm3jS5QPz8IPTCkb59wZA==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - '@jest/reporters@30.0.2': - resolution: {integrity: sha512-l4QzS/oKf57F8WtPZK+vvF4Io6ukplc6XgNFu4Hd/QxaLEO9f+8dSFzUua62Oe0HKlCUjKHpltKErAgDiMJKsA==} + '@jest/reporters@30.0.4': + resolution: {integrity: sha512-6ycNmP0JSJEEys1FbIzHtjl9BP0tOZ/KN6iMeAKrdvGmUsa1qfRdlQRUDKJ4P84hJ3xHw1yTqJt4fvPNHhyE+g==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} peerDependencies: node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 @@ -1167,24 +1171,24 @@ packages: resolution: {integrity: sha512-+g/1TKjFuGrf1Hh0QPCv0gISwBxJ+MQSNXmG9zjHy7BmFhtoJ9fdNhWJp3qUKRi93AOZHXtdxZgJ1vAtz6z65w==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - '@jest/snapshot-utils@30.0.1': - resolution: {integrity: sha512-6Dpv7vdtoRiISEFwYF8/c7LIvqXD7xDXtLPNzC2xqAfBznKip0MQM+rkseKwUPUpv2PJ7KW/YsnwWXrIL2xF+A==} + '@jest/snapshot-utils@30.0.4': + resolution: {integrity: sha512-BEpX8M/Y5lG7MI3fmiO+xCnacOrVsnbqVrcDZIT8aSGkKV1w2WwvRQxSWw5SIS8ozg7+h8tSj5EO1Riqqxcdag==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} '@jest/source-map@30.0.1': resolution: {integrity: sha512-MIRWMUUR3sdbP36oyNyhbThLHyJ2eEDClPCiHVbrYAe5g3CHRArIVpBw7cdSB5fr+ofSfIb2Tnsw8iEHL0PYQg==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - '@jest/test-result@30.0.2': - resolution: {integrity: sha512-KKMuBKkkZYP/GfHMhI+cH2/P3+taMZS3qnqqiPC1UXZTJskkCS+YU/ILCtw5anw1+YsTulDHFpDo70mmCedW8w==} + '@jest/test-result@30.0.4': + resolution: {integrity: sha512-Mfpv8kjyKTHqsuu9YugB6z1gcdB3TSSOaKlehtVaiNlClMkEHY+5ZqCY2CrEE3ntpBMlstX/ShDAf84HKWsyIw==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - '@jest/test-sequencer@30.0.2': - resolution: {integrity: sha512-fbyU5HPka0rkalZ3MXVvq0hwZY8dx3Y6SCqR64zRmh+xXlDeFl0IdL4l9e7vp4gxEXTYHbwLFA1D+WW5CucaSw==} + '@jest/test-sequencer@30.0.4': + resolution: {integrity: sha512-bj6ePmqi4uxAE8EHE0Slmk5uBYd9Vd/PcVt06CsBxzH4bbA8nGsI1YbXl/NH+eii4XRtyrRx+Cikub0x8H4vDg==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - '@jest/transform@30.0.2': - resolution: {integrity: sha512-kJIuhLMTxRF7sc0gPzPtCDib/V9KwW3I2U25b+lYCYMVqHHSrcZopS8J8H+znx9yixuFv+Iozl8raLt/4MoxrA==} + '@jest/transform@30.0.4': + resolution: {integrity: sha512-atvy4hRph/UxdCIBp+UB2jhEA/jJiUeGZ7QPgBi9jUUKNgi3WEoMXGNG7zbbELG2+88PMabUNCDchmqgJy3ELg==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} '@jest/types@30.0.1': @@ -1516,8 +1520,8 @@ packages: resolution: {integrity: sha512-ROFF39F6ZrnzSUEmQQZUar0Jt4xVoP9WnDRdWwF4NNcXs3xBTLgBUDoOwW141y1jP+S8nahIbdxbFC7IShw9Iw==} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} - '@prisma/client@6.8.2': - resolution: {integrity: sha512-5II+vbyzv4si6Yunwgkj0qT/iY0zyspttoDrL3R4BYgLdp42/d2C8xdi9vqkrYtKt9H32oFIukvyw3Koz5JoDg==} + '@prisma/client@6.11.0': + resolution: {integrity: sha512-K9TkKepOYvCOg3qCuKz7ZHf6rf58BFKi08plKjU4qVv9y7/UxO6tLz7PlWcgODUZKURLPmRHjHERffIx/8az4w==} engines: {node: '>=18.18'} peerDependencies: prisma: '*' @@ -1528,23 +1532,23 @@ packages: typescript: optional: true - '@prisma/config@6.8.2': - resolution: {integrity: sha512-ZJY1fF4qRBPdLQ/60wxNtX+eu89c3AkYEcP7L3jkp0IPXCNphCYxikTg55kPJLDOG6P0X+QG5tCv6CmsBRZWFQ==} + '@prisma/config@6.11.0': + resolution: {integrity: sha512-icBfutMpdrwSf2ggo012zhQ4oianijXL/UPbv4PNVK3WUWbB3/F5Ltq8ZfElGrtwKC6XuFFPxU5qDC9x7vh8zQ==} - '@prisma/debug@6.8.2': - resolution: {integrity: sha512-4muBSSUwJJ9BYth5N8tqts8JtiLT8QI/RSAzEogwEfpbYGFo9mYsInsVo8dqXdPO2+Rm5OG5q0qWDDE3nyUbVg==} + '@prisma/debug@6.11.0': + resolution: {integrity: sha512-zo4oEZMWMt0BFWl+4NK9FUpaEOmjGR3y2/r0lkW/DK4BUBRgMj90s8QqK2K+vXG3xn0nAGg2kOSu+Swn60CFLg==} - '@prisma/engines-version@6.8.0-43.2060c79ba17c6bb9f5823312b6f6b7f4a845738e': - resolution: {integrity: sha512-Rkik9lMyHpFNGaLpPF3H5q5TQTkm/aE7DsGM5m92FZTvWQsvmi6Va8On3pWvqLHOt5aPUvFb/FeZTmphI4CPiQ==} + '@prisma/engines-version@6.11.0-18.9c30299f5a0ea26a96790e13f796dc6094db3173': + resolution: {integrity: sha512-M3vbyDICFIA1oJl0cFkM0omD4HsJZjFi0hu0f0UxyPABH8KEcZyUd5BToCrNl4B8lUeQn+L5+gfaQleOKp6Lrg==} - '@prisma/engines@6.8.2': - resolution: {integrity: sha512-XqAJ//LXjqYRQ1RRabs79KOY4+v6gZOGzbcwDQl0D6n9WBKjV7qdrbd042CwSK0v0lM9MSHsbcFnU2Yn7z8Zlw==} + '@prisma/engines@6.11.0': + resolution: {integrity: sha512-uqnYxvPKZPvYZA7F0q4gTR+fVWUJSY5bif7JAKBIOD5SoRRy0qEIaPy4Nna5WDLQaFGshaY/Bh8dLOQMfxhJJw==} - '@prisma/fetch-engine@6.8.2': - resolution: {integrity: sha512-lCvikWOgaLOfqXGacEKSNeenvj0n3qR5QvZUOmPE2e1Eh8cMYSobxonCg9rqM6FSdTfbpqp9xwhSAOYfNqSW0g==} + '@prisma/fetch-engine@6.11.0': + resolution: {integrity: sha512-ZHHSP7vJFo5hePH+MNovxhqXabIg38ZpCwQfUBON29kwPX3f1pjYnzGpgJLCJy4k7mKGOzTgrXPqH8+nJvq2fw==} - '@prisma/get-platform@6.8.2': - resolution: {integrity: sha512-vXSxyUgX3vm1Q70QwzwkjeYfRryIvKno1SXbIqwSptKwqKzskINnDUcx85oX+ys6ooN2ATGSD0xN2UTfg6Zcow==} + '@prisma/get-platform@6.11.0': + resolution: {integrity: sha512-yspBGvOfJQwuoApk5B4aBlHDy6YDXAOe4Ml8U2eZ+M2b7fDd10YDomS3Q4qrYHUUVYF3TJyN86NcnRMOvCMUrA==} '@repeaterjs/repeater@3.0.6': resolution: {integrity: sha512-Javneu5lsuhwNCryN+pXH93VPQ8g0dBX7wItHFgYiwQmzE1sVdg5tWHiOgHywzL2W21XQopa7IwIEnNbmeUJYA==} @@ -1565,8 +1569,8 @@ packages: '@sinonjs/fake-timers@13.0.5': resolution: {integrity: sha512-36/hTbH2uaWuGVERyC6da9YwGWnzUZXuPro/F2LfsdOsLnCojz/iSH8MxUt/FD2S5XBSVPhmArFUXcpCQ2Hkiw==} - '@swc/cli@0.6.0': - resolution: {integrity: sha512-Q5FsI3Cw0fGMXhmsg7c08i4EmXCrcl+WnAxb6LYOLHw4JFFC3yzmx9LaXZ7QMbA+JZXbigU2TirI7RAfO0Qlnw==} + '@swc/cli@0.7.7': + resolution: {integrity: sha512-j4yYm9bx3pxWofaJKX1BFwj/3ngUDynN4UIQ2Xd2h0h/7Gt7zkReBTpDN7g5S13mgAYxacaTHTOUsz18097E8w==} engines: {node: '>= 16.14.0'} hasBin: true peerDependencies: @@ -1576,68 +1580,68 @@ packages: chokidar: optional: true - '@swc/core-darwin-arm64@1.11.29': - resolution: {integrity: sha512-whsCX7URzbuS5aET58c75Dloby3Gtj/ITk2vc4WW6pSDQKSPDuONsIcZ7B2ng8oz0K6ttbi4p3H/PNPQLJ4maQ==} + '@swc/core-darwin-arm64@1.12.9': + resolution: {integrity: sha512-GACFEp4nD6V+TZNR2JwbMZRHB+Yyvp14FrcmB6UCUYmhuNWjkxi+CLnEvdbuiKyQYv0zA+TRpCHZ+whEs6gwfA==} engines: {node: '>=10'} cpu: [arm64] os: [darwin] - '@swc/core-darwin-x64@1.11.29': - resolution: {integrity: sha512-S3eTo/KYFk+76cWJRgX30hylN5XkSmjYtCBnM4jPLYn7L6zWYEPajsFLmruQEiTEDUg0gBEWLMNyUeghtswouw==} + '@swc/core-darwin-x64@1.12.9': + resolution: {integrity: sha512-hv2kls7Ilkm2EpeJz+I9MCil7pGS3z55ZAgZfxklEuYsxpICycxeH+RNRv4EraggN44ms+FWCjtZFu0LGg2V3g==} engines: {node: '>=10'} cpu: [x64] os: [darwin] - '@swc/core-linux-arm-gnueabihf@1.11.29': - resolution: {integrity: sha512-o9gdshbzkUMG6azldHdmKklcfrcMx+a23d/2qHQHPDLUPAN+Trd+sDQUYArK5Fcm7TlpG4sczz95ghN0DMkM7g==} + '@swc/core-linux-arm-gnueabihf@1.12.9': + resolution: {integrity: sha512-od9tDPiG+wMU9wKtd6y3nYJdNqgDOyLdgRRcrj1/hrbHoUPOM8wZQZdwQYGarw63iLXGgsw7t5HAF9Yc51ilFA==} engines: {node: '>=10'} cpu: [arm] os: [linux] - '@swc/core-linux-arm64-gnu@1.11.29': - resolution: {integrity: sha512-sLoaciOgUKQF1KX9T6hPGzvhOQaJn+3DHy4LOHeXhQqvBgr+7QcZ+hl4uixPKTzxk6hy6Hb0QOvQEdBAAR1gXw==} + '@swc/core-linux-arm64-gnu@1.12.9': + resolution: {integrity: sha512-6qx1ka9LHcLzxIgn2Mros+CZLkHK2TawlXzi/h7DJeNnzi8F1Hw0Yzjp8WimxNCg6s2n+o3jnmin1oXB7gg8rw==} engines: {node: '>=10'} cpu: [arm64] os: [linux] - '@swc/core-linux-arm64-musl@1.11.29': - resolution: {integrity: sha512-PwjB10BC0N+Ce7RU/L23eYch6lXFHz7r3NFavIcwDNa/AAqywfxyxh13OeRy+P0cg7NDpWEETWspXeI4Ek8otw==} + '@swc/core-linux-arm64-musl@1.12.9': + resolution: {integrity: sha512-yghFZWKPVVGbUdqiD7ft23G0JX6YFGDJPz9YbLLAwGuKZ9th3/jlWoQDAw1Naci31LQhVC+oIji6ozihSuwB2A==} engines: {node: '>=10'} cpu: [arm64] os: [linux] - '@swc/core-linux-x64-gnu@1.11.29': - resolution: {integrity: sha512-i62vBVoPaVe9A3mc6gJG07n0/e7FVeAvdD9uzZTtGLiuIfVfIBta8EMquzvf+POLycSk79Z6lRhGPZPJPYiQaA==} + '@swc/core-linux-x64-gnu@1.12.9': + resolution: {integrity: sha512-SFUxyhWLZRNL8QmgGNqdi2Q43PNyFVkRZ2zIif30SOGFSxnxcf2JNeSeBgKIGVgaLSuk6xFVVCtJ3KIeaStgRg==} engines: {node: '>=10'} cpu: [x64] os: [linux] - '@swc/core-linux-x64-musl@1.11.29': - resolution: {integrity: sha512-YER0XU1xqFdK0hKkfSVX1YIyCvMDI7K07GIpefPvcfyNGs38AXKhb2byySDjbVxkdl4dycaxxhRyhQ2gKSlsFQ==} + '@swc/core-linux-x64-musl@1.12.9': + resolution: {integrity: sha512-9FB0wM+6idCGTI20YsBNBg9xSWtkDBymnpaTCsZM3qDc0l4uOpJMqbfWhQvp17x7r/ulZfb2QY8RDvQmCL6AcQ==} engines: {node: '>=10'} cpu: [x64] os: [linux] - '@swc/core-win32-arm64-msvc@1.11.29': - resolution: {integrity: sha512-po+WHw+k9g6FAg5IJ+sMwtA/fIUL3zPQ4m/uJgONBATCVnDDkyW6dBA49uHNVtSEvjvhuD8DVWdFP847YTcITw==} + '@swc/core-win32-arm64-msvc@1.12.9': + resolution: {integrity: sha512-zHOusMVbOH9ik5RtRrMiGzLpKwxrPXgXkBm3SbUCa65HAdjV33NZ0/R9Rv1uPESALtEl2tzMYLUxYA5ECFDFhA==} engines: {node: '>=10'} cpu: [arm64] os: [win32] - '@swc/core-win32-ia32-msvc@1.11.29': - resolution: {integrity: sha512-h+NjOrbqdRBYr5ItmStmQt6x3tnhqgwbj9YxdGPepbTDamFv7vFnhZR0YfB3jz3UKJ8H3uGJ65Zw1VsC+xpFkg==} + '@swc/core-win32-ia32-msvc@1.12.9': + resolution: {integrity: sha512-aWZf0PqE0ot7tCuhAjRkDFf41AzzSQO0x2xRfTbnhpROp57BRJ/N5eee1VULO/UA2PIJRG7GKQky5bSGBYlFug==} engines: {node: '>=10'} cpu: [ia32] os: [win32] - '@swc/core-win32-x64-msvc@1.11.29': - resolution: {integrity: sha512-Q8cs2BDV9wqDvqobkXOYdC+pLUSEpX/KvI0Dgfun1F+LzuLotRFuDhrvkU9ETJA6OnD2+Fn/ieHgloiKA/Mn/g==} + '@swc/core-win32-x64-msvc@1.12.9': + resolution: {integrity: sha512-C25fYftXOras3P3anSUeXXIpxmEkdAcsIL9yrr0j1xepTZ/yKwpnQ6g3coj8UXdeJy4GTVlR6+Ow/QiBgZQNOg==} engines: {node: '>=10'} cpu: [x64] os: [win32] - '@swc/core@1.11.29': - resolution: {integrity: sha512-g4mThMIpWbNhV8G2rWp5a5/Igv8/2UFRJx2yImrLGMgrDDYZIopqZ/z0jZxDgqNA1QDx93rpwNF7jGsxVWcMlA==} + '@swc/core@1.12.9': + resolution: {integrity: sha512-O+LfT2JlVMsIMWG9x+rdxg8GzpzeGtCZQfXV7cKc1PjIKUkLFf1QJ7okuseA4f/9vncu37dQ2ZcRrPKy0Ndd5g==} engines: {node: '>=10'} peerDependencies: '@swc/helpers': '>=0.5.17' @@ -1648,8 +1652,8 @@ packages: '@swc/counter@0.1.3': resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} - '@swc/types@0.1.21': - resolution: {integrity: sha512-2YEtj5HJVbKivud9N4bpPBAyZhj4S2Ipe5LkUG94alTpr7in/GU/EARgPAd3BwU+YOmFVJC2+kjqhGRi3r0ZpQ==} + '@swc/types@0.1.23': + resolution: {integrity: sha512-u1iIVZV9Q0jxY+yM2vw/hZGDNudsN85bBpTqzAQ9rzkxW9D+e3aEM4Han+ow518gSewkXgjmEK0BD79ZcNVgPw==} '@szmarczak/http-timer@5.0.1': resolution: {integrity: sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==} @@ -1782,63 +1786,63 @@ packages: '@types/yargs@17.0.33': resolution: {integrity: sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==} - '@typescript-eslint/eslint-plugin@8.35.0': - resolution: {integrity: sha512-ijItUYaiWuce0N1SoSMrEd0b6b6lYkYt99pqCPfybd+HKVXtEvYhICfLdwp42MhiI5mp0oq7PKEL+g1cNiz/Eg==} + '@typescript-eslint/eslint-plugin@8.35.1': + resolution: {integrity: sha512-9XNTlo7P7RJxbVeICaIIIEipqxLKguyh+3UbXuT2XQuFp6d8VOeDEGuz5IiX0dgZo8CiI6aOFLg4e8cF71SFVg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.35.0 + '@typescript-eslint/parser': ^8.35.1 eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/parser@8.35.0': - resolution: {integrity: sha512-6sMvZePQrnZH2/cJkwRpkT7DxoAWh+g6+GFRK6bV3YQo7ogi3SX5rgF6099r5Q53Ma5qeT7LGmOmuIutF4t3lA==} + '@typescript-eslint/parser@8.35.1': + resolution: {integrity: sha512-3MyiDfrfLeK06bi/g9DqJxP5pV74LNv4rFTyvGDmT3x2p1yp1lOd+qYZfiRPIOf/oON+WRZR5wxxuF85qOar+w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/project-service@8.35.0': - resolution: {integrity: sha512-41xatqRwWZuhUMF/aZm2fcUsOFKNcG28xqRSS6ZVr9BVJtGExosLAm5A1OxTjRMagx8nJqva+P5zNIGt8RIgbQ==} + '@typescript-eslint/project-service@8.35.1': + resolution: {integrity: sha512-VYxn/5LOpVxADAuP3NrnxxHYfzVtQzLKeldIhDhzC8UHaiQvYlXvKuVho1qLduFbJjjy5U5bkGwa3rUGUb1Q6Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/scope-manager@8.35.0': - resolution: {integrity: sha512-+AgL5+mcoLxl1vGjwNfiWq5fLDZM1TmTPYs2UkyHfFhgERxBbqHlNjRzhThJqz+ktBqTChRYY6zwbMwy0591AA==} + '@typescript-eslint/scope-manager@8.35.1': + resolution: {integrity: sha512-s/Bpd4i7ht2934nG+UoSPlYXd08KYz3bmjLEb7Ye1UVob0d1ENiT3lY8bsCmik4RqfSbPw9xJJHbugpPpP5JUg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/tsconfig-utils@8.35.0': - resolution: {integrity: sha512-04k/7247kZzFraweuEirmvUj+W3bJLI9fX6fbo1Qm2YykuBvEhRTPl8tcxlYO8kZZW+HIXfkZNoasVb8EV4jpA==} + '@typescript-eslint/tsconfig-utils@8.35.1': + resolution: {integrity: sha512-K5/U9VmT9dTHoNowWZpz+/TObS3xqC5h0xAIjXPw+MNcKV9qg6eSatEnmeAwkjHijhACH0/N7bkhKvbt1+DXWQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/type-utils@8.35.0': - resolution: {integrity: sha512-ceNNttjfmSEoM9PW87bWLDEIaLAyR+E6BoYJQ5PfaDau37UGca9Nyq3lBk8Bw2ad0AKvYabz6wxc7DMTO2jnNA==} + '@typescript-eslint/type-utils@8.35.1': + resolution: {integrity: sha512-HOrUBlfVRz5W2LIKpXzZoy6VTZzMu2n8q9C2V/cFngIC5U1nStJgv0tMV4sZPzdf4wQm9/ToWUFPMN9Vq9VJQQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/types@8.35.0': - resolution: {integrity: sha512-0mYH3emanku0vHw2aRLNGqe7EXh9WHEhi7kZzscrMDf6IIRUQ5Jk4wp1QrledE/36KtdZrVfKnE32eZCf/vaVQ==} + '@typescript-eslint/types@8.35.1': + resolution: {integrity: sha512-q/O04vVnKHfrrhNAscndAn1tuQhIkwqnaW+eu5waD5IPts2eX1dgJxgqcPx5BX109/qAz7IG6VrEPTOYKCNfRQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@8.35.0': - resolution: {integrity: sha512-F+BhnaBemgu1Qf8oHrxyw14wq6vbL8xwWKKMwTMwYIRmFFY/1n/9T/jpbobZL8vp7QyEUcC6xGrnAO4ua8Kp7w==} + '@typescript-eslint/typescript-estree@8.35.1': + resolution: {integrity: sha512-Vvpuvj4tBxIka7cPs6Y1uvM7gJgdF5Uu9F+mBJBPY4MhvjrjWGK4H0lVgLJd/8PWZ23FTqsaJaLEkBCFUk8Y9g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/utils@8.35.0': - resolution: {integrity: sha512-nqoMu7WWM7ki5tPgLVsmPM8CkqtoPUG6xXGeefM5t4x3XumOEKMoUZPdi+7F+/EotukN4R9OWdmDxN80fqoZeg==} + '@typescript-eslint/utils@8.35.1': + resolution: {integrity: sha512-lhnwatFmOFcazAsUm3ZnZFpXSxiwoa1Lj50HphnDe1Et01NF4+hrdXONSUHIcbVu2eFb1bAf+5yjXkGVkXBKAQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/visitor-keys@8.35.0': - resolution: {integrity: sha512-zTh2+1Y8ZpmeQaQVIc/ZZxsx8UzgKJyNg1PTvjzC7WMhPSVS8bfDX34k1SrwOf016qd5RU3az2UxUNue3IfQ5g==} + '@typescript-eslint/visitor-keys@8.35.1': + resolution: {integrity: sha512-VRwixir4zBWCSTP/ljEo091lbpypz57PoeAQ9imjG+vbeof9LplljsL1mos4ccG6H9IjfrVGM359RozUnuFhpw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@ungap/structured-clone@1.3.0': @@ -2187,8 +2191,8 @@ packages: b4a@1.6.7: resolution: {integrity: sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg==} - babel-jest@30.0.2: - resolution: {integrity: sha512-A5kqR1/EUTidM2YC2YMEUDP2+19ppgOwK0IAd9Swc3q2KqFb5f9PtRUXVeZcngu0z5mDMyZ9zH2huJZSOMLiTQ==} + babel-jest@30.0.4: + resolution: {integrity: sha512-UjG2j7sAOqsp2Xua1mS/e+ekddkSu3wpf4nZUSvXNHuVWdaOUXQ77+uyjJLDE9i0atm5x4kds8K9yb5lRsRtcA==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} peerDependencies: '@babel/core': ^7.11.0 @@ -2740,8 +2744,8 @@ packages: resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - eslint@9.29.0: - resolution: {integrity: sha512-GsGizj2Y1rCWDu6XoEekL3RLilp0voSePurjZIkxL3wlm5o5EC9VpgaP7lrCvjnkuLvzFBQWB3vWB3K5KQTveQ==} + eslint@9.30.1: + resolution: {integrity: sha512-zmxXPNMOXmwm9E0yQLi5uqXHs7uq2UIiqEKo3Gq+3fwo1XrJ+hijAZImyF7hclW3E6oHz43Yk3RP8at6OTKflQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} hasBin: true peerDependencies: @@ -2803,6 +2807,10 @@ packages: resolution: {integrity: sha512-HXg6NvK35/cSYZCUKAtmlgCFyqKM4frEPbzrav5hRqb0GMz0E0lS5hfzYjSaiaE5ysnp/qI2aeZkeyeIAOeXzQ==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + expect@30.0.4: + resolution: {integrity: sha512-dDLGjnP2cKbEppxVICxI/Uf4YemmGMPNy0QytCbfafbpYk9AFQsxb8Uyrxii0RPK7FWgLGlSem+07WirwS3cFQ==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + express-session@1.18.1: resolution: {integrity: sha512-a5mtTqEaZvBCL9A9aqkrtfz+3SMDhOVUnjafjo+s7A9Txkq+SVX2DLvSp1Zrv4uCXa3lMSK3viWnh9Gg07PBUA==} engines: {node: '>= 0.8.0'} @@ -3034,8 +3042,8 @@ packages: resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} engines: {node: '>=18'} - globals@16.1.0: - resolution: {integrity: sha512-aibexHNbb/jiUSObBgpHLj+sIuUmJnYcgXBlrfsiDZ9rt4aF2TFRbyLgZ2iFQuVZ1K5Mx3FVkbKRSgKrbK3K2g==} + globals@16.3.0: + resolution: {integrity: sha512-bqWEnJ1Nt3neqx2q5SFfGS8r/ahumIakg3HcwtNlrVlwXIeNumWn/c7Pn/wKzGhf6SaW6H6uWXLqC30STCMchQ==} engines: {node: '>=18'} globby@11.1.0: @@ -3335,12 +3343,12 @@ packages: resolution: {integrity: sha512-Ius/iRST9FKfJI+I+kpiDh8JuUlAISnRszF9ixZDIqJF17FckH5sOzKC8a0wd0+D+8em5ADRHA5V5MnfeDk2WA==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - jest-circus@30.0.3: - resolution: {integrity: sha512-rD9qq2V28OASJHJWDRVdhoBdRs6k3u3EmBzDYcyuMby8XCO3Ll1uq9kyqM41ZcC4fMiPulMVh3qMw0cBvDbnyg==} + jest-circus@30.0.4: + resolution: {integrity: sha512-o6UNVfbXbmzjYgmVPtSQrr5xFZCtkDZGdTlptYvGFSN80RuOOlTe73djvMrs+QAuSERZWcHBNIOMH+OEqvjWuw==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - jest-cli@30.0.3: - resolution: {integrity: sha512-UWDSj0ayhumEAxpYRlqQLrssEi29kdQ+kddP94AuHhZknrE+mT0cR0J+zMHKFe9XPfX3dKQOc2TfWki3WhFTsA==} + jest-cli@30.0.4: + resolution: {integrity: sha512-3dOrP3zqCWBkjoVG1zjYJpD9143N9GUCbwaF2pFF5brnIgRLHmKcCIw+83BvF1LxggfMWBA0gxkn6RuQVuRhIQ==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} hasBin: true peerDependencies: @@ -3349,8 +3357,8 @@ packages: node-notifier: optional: true - jest-config@30.0.3: - resolution: {integrity: sha512-j0L4oRCtJwNyZktXIqwzEiDVQXBbQ4dqXuLD/TZdn++hXIcIfZmjHgrViEy5s/+j4HvITmAXbexVZpQ/jnr0bg==} + jest-config@30.0.4: + resolution: {integrity: sha512-3dzbO6sh34thAGEjJIW0fgT0GA0EVlkski6ZzMcbW6dzhenylXAE/Mj2MI4HonroWbkKc6wU6bLVQ8dvBSZ9lA==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} peerDependencies: '@types/node': '*' @@ -3368,6 +3376,10 @@ packages: resolution: {integrity: sha512-Q1TAV0cUcBTic57SVnk/mug0/ASyAqtSIOkr7RAlxx97llRYsM74+E8N5WdGJUlwCKwgxPAkVjKh653h1+HA9A==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + jest-diff@30.0.4: + resolution: {integrity: sha512-TSjceIf6797jyd+R64NXqicttROD+Qf98fex7CowmlSn7f8+En0da1Dglwr1AXxDtVizoxXYZBlUQwNhoOXkNw==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + jest-docblock@30.0.1: resolution: {integrity: sha512-/vF78qn3DYphAaIc3jy4gA7XSAz167n9Bm/wn/1XhTLW7tTBIzXtCJpb/vcmc73NIIeeohCbdL94JasyXUZsGA==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} @@ -3376,8 +3388,8 @@ packages: resolution: {integrity: sha512-ZFRsTpe5FUWFQ9cWTMguCaiA6kkW5whccPy9JjD1ezxh+mJeqmz8naL8Fl/oSbNJv3rgB0x87WBIkA5CObIUZQ==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - jest-environment-node@30.0.2: - resolution: {integrity: sha512-XsGtZ0H+a70RsxAQkKuIh0D3ZlASXdZdhpOSBq9WRPq6lhe0IoQHGW0w9ZUaPiZQ/CpkIdprvlfV1QcXcvIQLQ==} + jest-environment-node@30.0.4: + resolution: {integrity: sha512-p+rLEzC2eThXqiNh9GHHTC0OW5Ca4ZfcURp7scPjYBcmgpR9HG6750716GuUipYf2AcThU3k20B31USuiaaIEg==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} jest-haste-map@30.0.2: @@ -3392,6 +3404,10 @@ packages: resolution: {integrity: sha512-hMpVFGFOhYmIIRGJ0HgM9htC5qUiJ00famcc9sRFchJJiLZbbVKrAztcgE6VnXLRxA3XZ0bvNA7hQWh3oHXo/A==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + jest-matcher-utils@30.0.4: + resolution: {integrity: sha512-ubCewJ54YzeAZ2JeHHGVoU+eDIpQFsfPQs0xURPWoNiO42LGJ+QGgfSf+hFIRplkZDkhH5MOvuxHKXRTUU3dUQ==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + jest-message-util@30.0.2: resolution: {integrity: sha512-vXywcxmr0SsKXF/bAD7t7nMamRvPuJkras00gqYeB1V0WllxZrbZ0paRr3XqpFU2sYYjD0qAaG2fRyn/CGZ0aw==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} @@ -3413,24 +3429,24 @@ packages: resolution: {integrity: sha512-jHEQgBXAgc+Gh4g0p3bCevgRCVRkB4VB70zhoAE48gxeSr1hfUOsM/C2WoJgVL7Eyg//hudYENbm3Ne+/dRVVA==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - jest-resolve-dependencies@30.0.3: - resolution: {integrity: sha512-FlL6u7LiHbF0Oe27k7DHYMq2T2aNpPhxnNo75F7lEtu4A6sSw+TKkNNUGNcVckdFoL0RCWREJsC1HsKDwKRZzQ==} + jest-resolve-dependencies@30.0.4: + resolution: {integrity: sha512-EQBYow19B/hKr4gUTn+l8Z+YLlP2X0IoPyp0UydOtrcPbIOYzJ8LKdFd+yrbwztPQvmlBFUwGPPEzHH1bAvFAw==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} jest-resolve@30.0.2: resolution: {integrity: sha512-q/XT0XQvRemykZsvRopbG6FQUT6/ra+XV6rPijyjT6D0msOyCvR2A5PlWZLd+fH0U8XWKZfDiAgrUNDNX2BkCw==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - jest-runner@30.0.3: - resolution: {integrity: sha512-CxYBzu9WStOBBXAKkLXGoUtNOWsiS1RRmUQb6SsdUdTcqVncOau7m8AJ4cW3Mz+YL1O9pOGPSYLyvl8HBdFmkQ==} + jest-runner@30.0.4: + resolution: {integrity: sha512-mxY0vTAEsowJwvFJo5pVivbCpuu6dgdXRmt3v3MXjBxFly7/lTk3Td0PaMyGOeNQUFmSuGEsGYqhbn7PA9OekQ==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - jest-runtime@30.0.3: - resolution: {integrity: sha512-Xjosq0C48G9XEQOtmgrjXJwPaUPaq3sPJwHDRaiC+5wi4ZWxO6Lx6jNkizK/0JmTulVNuxP8iYwt77LGnfg3/w==} + jest-runtime@30.0.4: + resolution: {integrity: sha512-tUQrZ8+IzoZYIHoPDQEB4jZoPyzBjLjq7sk0KVyd5UPRjRDOsN7o6UlvaGF8ddpGsjznl9PW+KRgWqCNO+Hn7w==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - jest-snapshot@30.0.3: - resolution: {integrity: sha512-F05JCohd3OA1N9+5aEPXA6I0qOfZDGIx0zTq5Z4yMBg2i1p5ELfBusjYAWwTkC12c7dHcbyth4QAfQbS7cRjow==} + jest-snapshot@30.0.4: + resolution: {integrity: sha512-S/8hmSkeUib8WRUq9pWEb5zMfsOjiYWDWzFzKnjX7eDyKKgimsu9hcmsUEg8a7dPAw8s/FacxsXquq71pDgPjQ==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} jest-util@30.0.2: @@ -3441,8 +3457,8 @@ packages: resolution: {integrity: sha512-noOvul+SFER4RIvNAwGn6nmV2fXqBq67j+hKGHKGFCmK4ks/Iy1FSrqQNBLGKlu4ZZIRL6Kg1U72N1nxuRCrGQ==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - jest-watcher@30.0.2: - resolution: {integrity: sha512-vYO5+E7jJuF+XmONr6CrbXdlYrgvZqtkn6pdkgjt/dU64UAdc0v1cAVaAeWtAfUUMScxNmnUjKPUMdCpNVASwg==} + jest-watcher@30.0.4: + resolution: {integrity: sha512-YESbdHDs7aQOCSSKffG8jXqOKFqw4q4YqR+wHYpR5GWEQioGvL0BfbcjvKIvPEM0XGfsfJrka7jJz3Cc3gI4VQ==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} jest-worker@27.5.1: @@ -3453,8 +3469,8 @@ packages: resolution: {integrity: sha512-RN1eQmx7qSLFA+o9pfJKlqViwL5wt+OL3Vff/A+/cPsmuw7NPwfgl33AP+/agRmHzPOFgXviRycR9kYwlcRQXg==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - jest@30.0.3: - resolution: {integrity: sha512-Uy8xfeE/WpT2ZLGDXQmaYNzw2v8NUKuYeKGtkS6sDxwsdQihdgYCXaKIYnph1h95DN5H35ubFDm0dfmsQnjn4Q==} + jest@30.0.4: + resolution: {integrity: sha512-9QE0RS4WwTj/TtTC4h/eFVmFAhGNVerSB9XpJh8sqaXlP73ILcPcZ7JWjjEtJJe2m8QyBLKKfPQuK+3F+Xij/g==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} hasBin: true peerDependencies: @@ -3817,8 +3833,8 @@ packages: nullthrows@1.1.1: resolution: {integrity: sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==} - oauth4webapi@3.5.3: - resolution: {integrity: sha512-2bnHosmBLAQpXNBLOvaJMyMkr4Yya5ohE5Q9jqyxiN+aa7GFCzvDN1RRRMrp0NkfqRR2MTaQNkcSUCCjILD9oQ==} + oauth4webapi@3.5.5: + resolution: {integrity: sha512-1K88D2GiAydGblHo39NBro5TebGXa+7tYoyIbxvqv3+haDDry7CBE1eSYuNbOSsYCCU6y0gdynVZAkm4YPw4hg==} object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} @@ -3843,8 +3859,8 @@ packages: resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} engines: {node: '>=6'} - openid-client@6.6.1: - resolution: {integrity: sha512-GmqoICGMI3IyFFjhvXxad8of4QWk2D0tm4vdJkldGm9nw7J3p1f7LPLWgGeFuKuw8HjDVe8Dd8QLGBe0NFvSSg==} + openid-client@6.6.2: + resolution: {integrity: sha512-Xya5TNMnnZuTM6DbHdB4q0S3ig2NTAELnii/ASie1xDEr8iiB8zZbO871OWBdrw++sd3hW6bqWjgcmSy1RTWHA==} optionator@0.9.4: resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} @@ -4006,8 +4022,8 @@ packages: resolution: {integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==} engines: {node: '>=6.0.0'} - prettier@3.6.1: - resolution: {integrity: sha512-5xGWRa90Sp2+x1dQtNpIpeOQpTDBs9cZDmA/qs2vDNN2i18PdapqY7CmBeyLlMuGqXJRIOPaCaVZTLNQRWUH/A==} + prettier@3.6.2: + resolution: {integrity: sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==} engines: {node: '>=14'} hasBin: true @@ -4015,8 +4031,8 @@ packages: resolution: {integrity: sha512-yC5/EBSOrTtqhCKfLHqoUIAXVRZnukHPwWBJWR7h84Q3Be1DRQZLncwcfLoPA5RPQ65qfiCMqgYwdUuQ//eVpg==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - prisma@6.8.2: - resolution: {integrity: sha512-JNricTXQxzDtRS7lCGGOB4g5DJ91eg3nozdubXze3LpcMl1oWwcFddrj++Up3jnRE6X/3gB/xz3V+ecBk/eEGA==} + prisma@6.11.0: + resolution: {integrity: sha512-gI69E7fusgk32XALpXzdgR10xUx2aFnHiu/JaUo4O07G4JvFT0xNtD0Iy81p37iBLTYFEhWa9VrHKXaiyZ5fLQ==} engines: {node: '>=18.18'} hasBin: true peerDependencies: @@ -4566,8 +4582,8 @@ packages: typedarray@0.0.6: resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} - typescript-eslint@8.35.0: - resolution: {integrity: sha512-uEnz70b7kBz6eg/j0Czy6K5NivaYopgxRjsnAJ2Fx5oTLo3wefTHIbL7AkQr1+7tJCRVpTs/wiM8JR/11Loq9A==} + typescript-eslint@8.35.1: + resolution: {integrity: sha512-xslJjFzhOmHYQzSB/QTeASAHbjmxOGEP6Coh93TXmUBFQoJ1VU35UHIDmG06Jd6taf3wqqC1ntBnCMeymy5Ovw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 @@ -4800,7 +4816,7 @@ snapshots: optionalDependencies: graphql: 16.11.0 - '@0no-co/graphqlsp@1.12.16(graphql@16.11.0)(typescript@5.8.3)': + '@0no-co/graphqlsp@1.13.0(graphql@16.11.0)(typescript@5.8.3)': dependencies: '@gql.tada/internal': 1.0.8(graphql@16.11.0)(typescript@5.8.3) graphql: 16.11.0 @@ -4944,7 +4960,7 @@ snapshots: '@babel/parser': 7.27.5 '@babel/template': 7.27.2 '@babel/traverse': 7.27.4 - '@babel/types': 7.27.3 + '@babel/types': 7.27.6 convert-source-map: 2.0.0 debug: 4.4.1 gensync: 1.0.0-beta.2 @@ -4964,7 +4980,7 @@ snapshots: '@babel/generator@7.27.5': dependencies: '@babel/parser': 7.27.5 - '@babel/types': 7.27.3 + '@babel/types': 7.27.6 '@jridgewell/gen-mapping': 0.3.8 '@jridgewell/trace-mapping': 0.3.25 jsesc: 3.1.0 @@ -5070,7 +5086,7 @@ snapshots: '@babel/parser@7.27.5': dependencies: - '@babel/types': 7.27.3 + '@babel/types': 7.27.6 '@babel/plugin-proposal-class-properties@7.18.6(@babel/core@7.27.1)': dependencies: @@ -5356,7 +5372,7 @@ snapshots: '@babel/generator': 7.27.5 '@babel/parser': 7.27.5 '@babel/template': 7.27.2 - '@babel/types': 7.27.3 + '@babel/types': 7.27.6 debug: 4.4.1 globals: 11.12.0 transitivePeerDependencies: @@ -5419,14 +5435,14 @@ snapshots: '@whatwg-node/promise-helpers': 1.3.2 tslib: 2.8.1 - '@eslint-community/eslint-utils@4.7.0(eslint@9.29.0(jiti@2.4.2))': + '@eslint-community/eslint-utils@4.7.0(eslint@9.30.1(jiti@2.4.2))': dependencies: - eslint: 9.29.0(jiti@2.4.2) + eslint: 9.30.1(jiti@2.4.2) eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.12.1': {} - '@eslint/config-array@0.20.1': + '@eslint/config-array@0.21.0': dependencies: '@eslint/object-schema': 2.1.6 debug: 4.4.1 @@ -5434,7 +5450,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@eslint/config-helpers@0.2.2': {} + '@eslint/config-helpers@0.3.0': {} '@eslint/core@0.14.0': dependencies: @@ -5454,7 +5470,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@eslint/js@9.29.0': {} + '@eslint/js@9.30.1': {} '@eslint/object-schema@2.1.6': {} @@ -6149,7 +6165,7 @@ snapshots: '@istanbuljs/schema@0.1.3': {} - '@jest/console@30.0.2': + '@jest/console@30.0.4': dependencies: '@jest/types': 30.0.1 '@types/node': 22.15.21 @@ -6158,13 +6174,13 @@ snapshots: jest-util: 30.0.2 slash: 3.0.0 - '@jest/core@30.0.3(ts-node@10.9.2(@swc/core@1.11.29)(@types/node@22.15.21)(typescript@5.8.3))': + '@jest/core@30.0.4(ts-node@10.9.2(@swc/core@1.12.9)(@types/node@22.15.21)(typescript@5.8.3))': dependencies: - '@jest/console': 30.0.2 + '@jest/console': 30.0.4 '@jest/pattern': 30.0.1 - '@jest/reporters': 30.0.2 - '@jest/test-result': 30.0.2 - '@jest/transform': 30.0.2 + '@jest/reporters': 30.0.4 + '@jest/test-result': 30.0.4 + '@jest/transform': 30.0.4 '@jest/types': 30.0.1 '@types/node': 22.15.21 ansi-escapes: 4.3.2 @@ -6173,18 +6189,18 @@ snapshots: exit-x: 0.2.2 graceful-fs: 4.2.11 jest-changed-files: 30.0.2 - jest-config: 30.0.3(@types/node@22.15.21)(ts-node@10.9.2(@swc/core@1.11.29)(@types/node@22.15.21)(typescript@5.8.3)) + jest-config: 30.0.4(@types/node@22.15.21)(ts-node@10.9.2(@swc/core@1.12.9)(@types/node@22.15.21)(typescript@5.8.3)) jest-haste-map: 30.0.2 jest-message-util: 30.0.2 jest-regex-util: 30.0.1 jest-resolve: 30.0.2 - jest-resolve-dependencies: 30.0.3 - jest-runner: 30.0.3 - jest-runtime: 30.0.3 - jest-snapshot: 30.0.3 + jest-resolve-dependencies: 30.0.4 + jest-runner: 30.0.4 + jest-runtime: 30.0.4 + jest-snapshot: 30.0.4 jest-util: 30.0.2 jest-validate: 30.0.2 - jest-watcher: 30.0.2 + jest-watcher: 30.0.4 micromatch: 4.0.8 pretty-format: 30.0.2 slash: 3.0.0 @@ -6196,9 +6212,9 @@ snapshots: '@jest/diff-sequences@30.0.1': {} - '@jest/environment@30.0.2': + '@jest/environment@30.0.4': dependencies: - '@jest/fake-timers': 30.0.2 + '@jest/fake-timers': 30.0.4 '@jest/types': 30.0.1 '@types/node': 22.15.21 jest-mock: 30.0.2 @@ -6207,14 +6223,18 @@ snapshots: dependencies: '@jest/get-type': 30.0.1 - '@jest/expect@30.0.3': + '@jest/expect-utils@30.0.4': dependencies: - expect: 30.0.3 - jest-snapshot: 30.0.3 + '@jest/get-type': 30.0.1 + + '@jest/expect@30.0.4': + dependencies: + expect: 30.0.4 + jest-snapshot: 30.0.4 transitivePeerDependencies: - supports-color - '@jest/fake-timers@30.0.2': + '@jest/fake-timers@30.0.4': dependencies: '@jest/types': 30.0.1 '@sinonjs/fake-timers': 13.0.5 @@ -6225,10 +6245,10 @@ snapshots: '@jest/get-type@30.0.1': {} - '@jest/globals@30.0.3': + '@jest/globals@30.0.4': dependencies: - '@jest/environment': 30.0.2 - '@jest/expect': 30.0.3 + '@jest/environment': 30.0.4 + '@jest/expect': 30.0.4 '@jest/types': 30.0.1 jest-mock: 30.0.2 transitivePeerDependencies: @@ -6239,12 +6259,12 @@ snapshots: '@types/node': 22.15.21 jest-regex-util: 30.0.1 - '@jest/reporters@30.0.2': + '@jest/reporters@30.0.4': dependencies: '@bcoe/v8-coverage': 0.2.3 - '@jest/console': 30.0.2 - '@jest/test-result': 30.0.2 - '@jest/transform': 30.0.2 + '@jest/console': 30.0.4 + '@jest/test-result': 30.0.4 + '@jest/transform': 30.0.4 '@jest/types': 30.0.1 '@jridgewell/trace-mapping': 0.3.25 '@types/node': 22.15.21 @@ -6271,7 +6291,7 @@ snapshots: dependencies: '@sinclair/typebox': 0.34.37 - '@jest/snapshot-utils@30.0.1': + '@jest/snapshot-utils@30.0.4': dependencies: '@jest/types': 30.0.1 chalk: 4.1.2 @@ -6284,21 +6304,21 @@ snapshots: callsites: 3.1.0 graceful-fs: 4.2.11 - '@jest/test-result@30.0.2': + '@jest/test-result@30.0.4': dependencies: - '@jest/console': 30.0.2 + '@jest/console': 30.0.4 '@jest/types': 30.0.1 '@types/istanbul-lib-coverage': 2.0.6 collect-v8-coverage: 1.0.2 - '@jest/test-sequencer@30.0.2': + '@jest/test-sequencer@30.0.4': dependencies: - '@jest/test-result': 30.0.2 + '@jest/test-result': 30.0.4 graceful-fs: 4.2.11 jest-haste-map: 30.0.2 slash: 3.0.0 - '@jest/transform@30.0.2': + '@jest/transform@30.0.4': dependencies: '@babel/core': 7.27.4 '@jest/types': 30.0.1 @@ -6432,7 +6452,7 @@ snapshots: '@tybys/wasm-util': 0.9.0 optional: true - '@nestjs/cli@11.0.7(@swc/cli@0.6.0(@swc/core@1.11.29)(chokidar@4.0.3))(@swc/core@1.11.29)(@types/node@22.15.21)': + '@nestjs/cli@11.0.7(@swc/cli@0.7.7(@swc/core@1.12.9)(chokidar@4.0.3))(@swc/core@1.12.9)(@types/node@22.15.21)': dependencies: '@angular-devkit/core': 19.2.8(chokidar@4.0.3) '@angular-devkit/schematics': 19.2.8(chokidar@4.0.3) @@ -6443,7 +6463,7 @@ snapshots: chokidar: 4.0.3 cli-table3: 0.6.5 commander: 4.1.1 - fork-ts-checker-webpack-plugin: 9.1.0(typescript@5.8.3)(webpack@5.99.6(@swc/core@1.11.29)) + fork-ts-checker-webpack-plugin: 9.1.0(typescript@5.8.3)(webpack@5.99.6(@swc/core@1.12.9)) glob: 11.0.1 node-emoji: 1.11.0 ora: 5.4.1 @@ -6451,11 +6471,11 @@ snapshots: tsconfig-paths: 4.2.0 tsconfig-paths-webpack-plugin: 4.2.0 typescript: 5.8.3 - webpack: 5.99.6(@swc/core@1.11.29) + webpack: 5.99.6(@swc/core@1.12.9) webpack-node-externals: 3.0.0 optionalDependencies: - '@swc/cli': 0.6.0(@swc/core@1.11.29)(chokidar@4.0.3) - '@swc/core': 1.11.29 + '@swc/cli': 0.7.7(@swc/core@1.12.9)(chokidar@4.0.3) + '@swc/core': 1.12.9 transitivePeerDependencies: - '@types/node' - esbuild @@ -6619,35 +6639,35 @@ snapshots: '@pkgr/core@0.2.4': {} - '@prisma/client@6.8.2(prisma@6.8.2(typescript@5.8.3))(typescript@5.8.3)': + '@prisma/client@6.11.0(prisma@6.11.0(typescript@5.8.3))(typescript@5.8.3)': optionalDependencies: - prisma: 6.8.2(typescript@5.8.3) + prisma: 6.11.0(typescript@5.8.3) typescript: 5.8.3 - '@prisma/config@6.8.2': + '@prisma/config@6.11.0': dependencies: jiti: 2.4.2 - '@prisma/debug@6.8.2': {} + '@prisma/debug@6.11.0': {} - '@prisma/engines-version@6.8.0-43.2060c79ba17c6bb9f5823312b6f6b7f4a845738e': {} + '@prisma/engines-version@6.11.0-18.9c30299f5a0ea26a96790e13f796dc6094db3173': {} - '@prisma/engines@6.8.2': + '@prisma/engines@6.11.0': dependencies: - '@prisma/debug': 6.8.2 - '@prisma/engines-version': 6.8.0-43.2060c79ba17c6bb9f5823312b6f6b7f4a845738e - '@prisma/fetch-engine': 6.8.2 - '@prisma/get-platform': 6.8.2 + '@prisma/debug': 6.11.0 + '@prisma/engines-version': 6.11.0-18.9c30299f5a0ea26a96790e13f796dc6094db3173 + '@prisma/fetch-engine': 6.11.0 + '@prisma/get-platform': 6.11.0 - '@prisma/fetch-engine@6.8.2': + '@prisma/fetch-engine@6.11.0': dependencies: - '@prisma/debug': 6.8.2 - '@prisma/engines-version': 6.8.0-43.2060c79ba17c6bb9f5823312b6f6b7f4a845738e - '@prisma/get-platform': 6.8.2 + '@prisma/debug': 6.11.0 + '@prisma/engines-version': 6.11.0-18.9c30299f5a0ea26a96790e13f796dc6094db3173 + '@prisma/get-platform': 6.11.0 - '@prisma/get-platform@6.8.2': + '@prisma/get-platform@6.11.0': dependencies: - '@prisma/debug': 6.8.2 + '@prisma/debug': 6.11.0 '@repeaterjs/repeater@3.0.6': {} @@ -6665,9 +6685,9 @@ snapshots: dependencies: '@sinonjs/commons': 3.0.1 - '@swc/cli@0.6.0(@swc/core@1.11.29)(chokidar@4.0.3)': + '@swc/cli@0.7.7(@swc/core@1.12.9)(chokidar@4.0.3)': dependencies: - '@swc/core': 1.11.29 + '@swc/core': 1.12.9 '@swc/counter': 0.1.3 '@xhmikosr/bin-wrapper': 13.0.5 commander: 8.3.0 @@ -6680,55 +6700,55 @@ snapshots: optionalDependencies: chokidar: 4.0.3 - '@swc/core-darwin-arm64@1.11.29': + '@swc/core-darwin-arm64@1.12.9': optional: true - '@swc/core-darwin-x64@1.11.29': + '@swc/core-darwin-x64@1.12.9': optional: true - '@swc/core-linux-arm-gnueabihf@1.11.29': + '@swc/core-linux-arm-gnueabihf@1.12.9': optional: true - '@swc/core-linux-arm64-gnu@1.11.29': + '@swc/core-linux-arm64-gnu@1.12.9': optional: true - '@swc/core-linux-arm64-musl@1.11.29': + '@swc/core-linux-arm64-musl@1.12.9': optional: true - '@swc/core-linux-x64-gnu@1.11.29': + '@swc/core-linux-x64-gnu@1.12.9': optional: true - '@swc/core-linux-x64-musl@1.11.29': + '@swc/core-linux-x64-musl@1.12.9': optional: true - '@swc/core-win32-arm64-msvc@1.11.29': + '@swc/core-win32-arm64-msvc@1.12.9': optional: true - '@swc/core-win32-ia32-msvc@1.11.29': + '@swc/core-win32-ia32-msvc@1.12.9': optional: true - '@swc/core-win32-x64-msvc@1.11.29': + '@swc/core-win32-x64-msvc@1.12.9': optional: true - '@swc/core@1.11.29': + '@swc/core@1.12.9': dependencies: '@swc/counter': 0.1.3 - '@swc/types': 0.1.21 + '@swc/types': 0.1.23 optionalDependencies: - '@swc/core-darwin-arm64': 1.11.29 - '@swc/core-darwin-x64': 1.11.29 - '@swc/core-linux-arm-gnueabihf': 1.11.29 - '@swc/core-linux-arm64-gnu': 1.11.29 - '@swc/core-linux-arm64-musl': 1.11.29 - '@swc/core-linux-x64-gnu': 1.11.29 - '@swc/core-linux-x64-musl': 1.11.29 - '@swc/core-win32-arm64-msvc': 1.11.29 - '@swc/core-win32-ia32-msvc': 1.11.29 - '@swc/core-win32-x64-msvc': 1.11.29 + '@swc/core-darwin-arm64': 1.12.9 + '@swc/core-darwin-x64': 1.12.9 + '@swc/core-linux-arm-gnueabihf': 1.12.9 + '@swc/core-linux-arm64-gnu': 1.12.9 + '@swc/core-linux-arm64-musl': 1.12.9 + '@swc/core-linux-x64-gnu': 1.12.9 + '@swc/core-linux-x64-musl': 1.12.9 + '@swc/core-win32-arm64-msvc': 1.12.9 + '@swc/core-win32-ia32-msvc': 1.12.9 + '@swc/core-win32-x64-msvc': 1.12.9 '@swc/counter@0.1.3': {} - '@swc/types@0.1.21': + '@swc/types@0.1.23': dependencies: '@swc/counter': 0.1.3 @@ -6761,24 +6781,24 @@ snapshots: '@types/babel__core@7.20.5': dependencies: - '@babel/parser': 7.27.2 - '@babel/types': 7.27.3 + '@babel/parser': 7.27.5 + '@babel/types': 7.27.6 '@types/babel__generator': 7.27.0 '@types/babel__template': 7.4.4 '@types/babel__traverse': 7.20.7 '@types/babel__generator@7.27.0': dependencies: - '@babel/types': 7.27.3 + '@babel/types': 7.27.6 '@types/babel__template@7.4.4': dependencies: - '@babel/parser': 7.27.2 - '@babel/types': 7.27.3 + '@babel/parser': 7.27.5 + '@babel/types': 7.27.6 '@types/babel__traverse@7.20.7': dependencies: - '@babel/types': 7.27.3 + '@babel/types': 7.27.6 '@types/body-parser@1.19.5': dependencies: @@ -6894,15 +6914,15 @@ snapshots: dependencies: '@types/yargs-parser': 21.0.3 - '@typescript-eslint/eslint-plugin@8.35.0(@typescript-eslint/parser@8.35.0(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3)': + '@typescript-eslint/eslint-plugin@8.35.1(@typescript-eslint/parser@8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3)': dependencies: '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 8.35.0(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3) - '@typescript-eslint/scope-manager': 8.35.0 - '@typescript-eslint/type-utils': 8.35.0(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3) - '@typescript-eslint/utils': 8.35.0(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3) - '@typescript-eslint/visitor-keys': 8.35.0 - eslint: 9.29.0(jiti@2.4.2) + '@typescript-eslint/parser': 8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/scope-manager': 8.35.1 + '@typescript-eslint/type-utils': 8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/utils': 8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/visitor-keys': 8.35.1 + eslint: 9.30.1(jiti@2.4.2) graphemer: 1.4.0 ignore: 7.0.4 natural-compare: 1.4.0 @@ -6911,55 +6931,55 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.35.0(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3)': + '@typescript-eslint/parser@8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3)': dependencies: - '@typescript-eslint/scope-manager': 8.35.0 - '@typescript-eslint/types': 8.35.0 - '@typescript-eslint/typescript-estree': 8.35.0(typescript@5.8.3) - '@typescript-eslint/visitor-keys': 8.35.0 + '@typescript-eslint/scope-manager': 8.35.1 + '@typescript-eslint/types': 8.35.1 + '@typescript-eslint/typescript-estree': 8.35.1(typescript@5.8.3) + '@typescript-eslint/visitor-keys': 8.35.1 debug: 4.4.1 - eslint: 9.29.0(jiti@2.4.2) + eslint: 9.30.1(jiti@2.4.2) typescript: 5.8.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.35.0(typescript@5.8.3)': + '@typescript-eslint/project-service@8.35.1(typescript@5.8.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.35.0(typescript@5.8.3) - '@typescript-eslint/types': 8.35.0 + '@typescript-eslint/tsconfig-utils': 8.35.1(typescript@5.8.3) + '@typescript-eslint/types': 8.35.1 debug: 4.4.1 typescript: 5.8.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@8.35.0': + '@typescript-eslint/scope-manager@8.35.1': dependencies: - '@typescript-eslint/types': 8.35.0 - '@typescript-eslint/visitor-keys': 8.35.0 + '@typescript-eslint/types': 8.35.1 + '@typescript-eslint/visitor-keys': 8.35.1 - '@typescript-eslint/tsconfig-utils@8.35.0(typescript@5.8.3)': + '@typescript-eslint/tsconfig-utils@8.35.1(typescript@5.8.3)': dependencies: typescript: 5.8.3 - '@typescript-eslint/type-utils@8.35.0(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3)': + '@typescript-eslint/type-utils@8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3)': dependencies: - '@typescript-eslint/typescript-estree': 8.35.0(typescript@5.8.3) - '@typescript-eslint/utils': 8.35.0(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/typescript-estree': 8.35.1(typescript@5.8.3) + '@typescript-eslint/utils': 8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) debug: 4.4.1 - eslint: 9.29.0(jiti@2.4.2) + eslint: 9.30.1(jiti@2.4.2) ts-api-utils: 2.1.0(typescript@5.8.3) typescript: 5.8.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/types@8.35.0': {} + '@typescript-eslint/types@8.35.1': {} - '@typescript-eslint/typescript-estree@8.35.0(typescript@5.8.3)': + '@typescript-eslint/typescript-estree@8.35.1(typescript@5.8.3)': dependencies: - '@typescript-eslint/project-service': 8.35.0(typescript@5.8.3) - '@typescript-eslint/tsconfig-utils': 8.35.0(typescript@5.8.3) - '@typescript-eslint/types': 8.35.0 - '@typescript-eslint/visitor-keys': 8.35.0 + '@typescript-eslint/project-service': 8.35.1(typescript@5.8.3) + '@typescript-eslint/tsconfig-utils': 8.35.1(typescript@5.8.3) + '@typescript-eslint/types': 8.35.1 + '@typescript-eslint/visitor-keys': 8.35.1 debug: 4.4.1 fast-glob: 3.3.3 is-glob: 4.0.3 @@ -6970,20 +6990,20 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.35.0(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3)': + '@typescript-eslint/utils@8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3)': dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.29.0(jiti@2.4.2)) - '@typescript-eslint/scope-manager': 8.35.0 - '@typescript-eslint/types': 8.35.0 - '@typescript-eslint/typescript-estree': 8.35.0(typescript@5.8.3) - eslint: 9.29.0(jiti@2.4.2) + '@eslint-community/eslint-utils': 4.7.0(eslint@9.30.1(jiti@2.4.2)) + '@typescript-eslint/scope-manager': 8.35.1 + '@typescript-eslint/types': 8.35.1 + '@typescript-eslint/typescript-estree': 8.35.1(typescript@5.8.3) + eslint: 9.30.1(jiti@2.4.2) typescript: 5.8.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/visitor-keys@8.35.0': + '@typescript-eslint/visitor-keys@8.35.1': dependencies: - '@typescript-eslint/types': 8.35.0 + '@typescript-eslint/types': 8.35.1 eslint-visitor-keys: 4.2.1 '@ungap/structured-clone@1.3.0': {} @@ -7328,10 +7348,10 @@ snapshots: b4a@1.6.7: {} - babel-jest@30.0.2(@babel/core@7.27.4): + babel-jest@30.0.4(@babel/core@7.27.4): dependencies: '@babel/core': 7.27.4 - '@jest/transform': 30.0.2 + '@jest/transform': 30.0.4 '@types/babel__core': 7.20.5 babel-plugin-istanbul: 7.0.0 babel-preset-jest: 30.0.1(@babel/core@7.27.4) @@ -7354,7 +7374,7 @@ snapshots: babel-plugin-jest-hoist@30.0.1: dependencies: '@babel/template': 7.27.2 - '@babel/types': 7.27.3 + '@babel/types': 7.27.6 '@types/babel__core': 7.20.5 babel-plugin-syntax-trailing-function-commas@7.0.0-beta.0: {} @@ -7860,19 +7880,19 @@ snapshots: escape-string-regexp@4.0.0: {} - eslint-config-prettier@10.1.5(eslint@9.29.0(jiti@2.4.2)): + eslint-config-prettier@10.1.5(eslint@9.30.1(jiti@2.4.2)): dependencies: - eslint: 9.29.0(jiti@2.4.2) + eslint: 9.30.1(jiti@2.4.2) - eslint-plugin-prettier@5.5.1(@types/eslint@9.6.1)(eslint-config-prettier@10.1.5(eslint@9.29.0(jiti@2.4.2)))(eslint@9.29.0(jiti@2.4.2))(prettier@3.6.1): + eslint-plugin-prettier@5.5.1(@types/eslint@9.6.1)(eslint-config-prettier@10.1.5(eslint@9.30.1(jiti@2.4.2)))(eslint@9.30.1(jiti@2.4.2))(prettier@3.6.2): dependencies: - eslint: 9.29.0(jiti@2.4.2) - prettier: 3.6.1 + eslint: 9.30.1(jiti@2.4.2) + prettier: 3.6.2 prettier-linter-helpers: 1.0.0 synckit: 0.11.8 optionalDependencies: '@types/eslint': 9.6.1 - eslint-config-prettier: 10.1.5(eslint@9.29.0(jiti@2.4.2)) + eslint-config-prettier: 10.1.5(eslint@9.30.1(jiti@2.4.2)) eslint-scope@5.1.1: dependencies: @@ -7890,15 +7910,15 @@ snapshots: eslint-visitor-keys@4.2.1: {} - eslint@9.29.0(jiti@2.4.2): + eslint@9.30.1(jiti@2.4.2): dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.29.0(jiti@2.4.2)) + '@eslint-community/eslint-utils': 4.7.0(eslint@9.30.1(jiti@2.4.2)) '@eslint-community/regexpp': 4.12.1 - '@eslint/config-array': 0.20.1 - '@eslint/config-helpers': 0.2.2 + '@eslint/config-array': 0.21.0 + '@eslint/config-helpers': 0.3.0 '@eslint/core': 0.14.0 '@eslint/eslintrc': 3.3.1 - '@eslint/js': 9.29.0 + '@eslint/js': 9.30.1 '@eslint/plugin-kit': 0.3.1 '@humanfs/node': 0.16.6 '@humanwhocodes/module-importer': 1.0.1 @@ -7987,6 +8007,15 @@ snapshots: jest-mock: 30.0.2 jest-util: 30.0.2 + expect@30.0.4: + dependencies: + '@jest/expect-utils': 30.0.4 + '@jest/get-type': 30.0.1 + jest-matcher-utils: 30.0.4 + jest-message-util: 30.0.2 + jest-mock: 30.0.2 + jest-util: 30.0.2 + express-session@1.18.1: dependencies: cookie: 0.7.2 @@ -8173,7 +8202,7 @@ snapshots: cross-spawn: 7.0.6 signal-exit: 4.1.0 - fork-ts-checker-webpack-plugin@9.1.0(typescript@5.8.3)(webpack@5.99.6(@swc/core@1.11.29)): + fork-ts-checker-webpack-plugin@9.1.0(typescript@5.8.3)(webpack@5.99.6(@swc/core@1.12.9)): dependencies: '@babel/code-frame': 7.27.1 chalk: 4.1.2 @@ -8188,7 +8217,7 @@ snapshots: semver: 7.7.2 tapable: 2.2.1 typescript: 5.8.3 - webpack: 5.99.6(@swc/core@1.11.29) + webpack: 5.99.6(@swc/core@1.12.9) form-data-encoder@2.1.4: {} @@ -8300,7 +8329,7 @@ snapshots: globals@14.0.0: {} - globals@16.1.0: {} + globals@16.3.0: {} globby@11.1.0: dependencies: @@ -8558,8 +8587,8 @@ snapshots: istanbul-lib-instrument@6.0.3: dependencies: - '@babel/core': 7.27.1 - '@babel/parser': 7.27.2 + '@babel/core': 7.27.4 + '@babel/parser': 7.27.5 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.2 semver: 7.7.2 @@ -8610,11 +8639,11 @@ snapshots: jest-util: 30.0.2 p-limit: 3.1.0 - jest-circus@30.0.3: + jest-circus@30.0.4: dependencies: - '@jest/environment': 30.0.2 - '@jest/expect': 30.0.3 - '@jest/test-result': 30.0.2 + '@jest/environment': 30.0.4 + '@jest/expect': 30.0.4 + '@jest/test-result': 30.0.4 '@jest/types': 30.0.1 '@types/node': 22.15.21 chalk: 4.1.2 @@ -8622,10 +8651,10 @@ snapshots: dedent: 1.6.0 is-generator-fn: 2.1.0 jest-each: 30.0.2 - jest-matcher-utils: 30.0.3 + jest-matcher-utils: 30.0.4 jest-message-util: 30.0.2 - jest-runtime: 30.0.3 - jest-snapshot: 30.0.3 + jest-runtime: 30.0.4 + jest-snapshot: 30.0.4 jest-util: 30.0.2 p-limit: 3.1.0 pretty-format: 30.0.2 @@ -8636,15 +8665,15 @@ snapshots: - babel-plugin-macros - supports-color - jest-cli@30.0.3(@types/node@22.15.21)(ts-node@10.9.2(@swc/core@1.11.29)(@types/node@22.15.21)(typescript@5.8.3)): + jest-cli@30.0.4(@types/node@22.15.21)(ts-node@10.9.2(@swc/core@1.12.9)(@types/node@22.15.21)(typescript@5.8.3)): dependencies: - '@jest/core': 30.0.3(ts-node@10.9.2(@swc/core@1.11.29)(@types/node@22.15.21)(typescript@5.8.3)) - '@jest/test-result': 30.0.2 + '@jest/core': 30.0.4(ts-node@10.9.2(@swc/core@1.12.9)(@types/node@22.15.21)(typescript@5.8.3)) + '@jest/test-result': 30.0.4 '@jest/types': 30.0.1 chalk: 4.1.2 exit-x: 0.2.2 import-local: 3.2.0 - jest-config: 30.0.3(@types/node@22.15.21)(ts-node@10.9.2(@swc/core@1.11.29)(@types/node@22.15.21)(typescript@5.8.3)) + jest-config: 30.0.4(@types/node@22.15.21)(ts-node@10.9.2(@swc/core@1.12.9)(@types/node@22.15.21)(typescript@5.8.3)) jest-util: 30.0.2 jest-validate: 30.0.2 yargs: 17.7.2 @@ -8655,25 +8684,25 @@ snapshots: - supports-color - ts-node - jest-config@30.0.3(@types/node@22.15.21)(ts-node@10.9.2(@swc/core@1.11.29)(@types/node@22.15.21)(typescript@5.8.3)): + jest-config@30.0.4(@types/node@22.15.21)(ts-node@10.9.2(@swc/core@1.12.9)(@types/node@22.15.21)(typescript@5.8.3)): dependencies: '@babel/core': 7.27.4 '@jest/get-type': 30.0.1 '@jest/pattern': 30.0.1 - '@jest/test-sequencer': 30.0.2 + '@jest/test-sequencer': 30.0.4 '@jest/types': 30.0.1 - babel-jest: 30.0.2(@babel/core@7.27.4) + babel-jest: 30.0.4(@babel/core@7.27.4) chalk: 4.1.2 ci-info: 4.2.0 deepmerge: 4.3.1 glob: 10.4.5 graceful-fs: 4.2.11 - jest-circus: 30.0.3 + jest-circus: 30.0.4 jest-docblock: 30.0.1 - jest-environment-node: 30.0.2 + jest-environment-node: 30.0.4 jest-regex-util: 30.0.1 jest-resolve: 30.0.2 - jest-runner: 30.0.3 + jest-runner: 30.0.4 jest-util: 30.0.2 jest-validate: 30.0.2 micromatch: 4.0.8 @@ -8683,7 +8712,7 @@ snapshots: strip-json-comments: 3.1.1 optionalDependencies: '@types/node': 22.15.21 - ts-node: 10.9.2(@swc/core@1.11.29)(@types/node@22.15.21)(typescript@5.8.3) + ts-node: 10.9.2(@swc/core@1.12.9)(@types/node@22.15.21)(typescript@5.8.3) transitivePeerDependencies: - babel-plugin-macros - supports-color @@ -8695,6 +8724,13 @@ snapshots: chalk: 4.1.2 pretty-format: 30.0.2 + jest-diff@30.0.4: + dependencies: + '@jest/diff-sequences': 30.0.1 + '@jest/get-type': 30.0.1 + chalk: 4.1.2 + pretty-format: 30.0.2 + jest-docblock@30.0.1: dependencies: detect-newline: 3.1.0 @@ -8707,10 +8743,10 @@ snapshots: jest-util: 30.0.2 pretty-format: 30.0.2 - jest-environment-node@30.0.2: + jest-environment-node@30.0.4: dependencies: - '@jest/environment': 30.0.2 - '@jest/fake-timers': 30.0.2 + '@jest/environment': 30.0.4 + '@jest/fake-timers': 30.0.4 '@jest/types': 30.0.1 '@types/node': 22.15.21 jest-mock: 30.0.2 @@ -8744,6 +8780,13 @@ snapshots: jest-diff: 30.0.3 pretty-format: 30.0.2 + jest-matcher-utils@30.0.4: + dependencies: + '@jest/get-type': 30.0.1 + chalk: 4.1.2 + jest-diff: 30.0.4 + pretty-format: 30.0.2 + jest-message-util@30.0.2: dependencies: '@babel/code-frame': 7.27.1 @@ -8768,10 +8811,10 @@ snapshots: jest-regex-util@30.0.1: {} - jest-resolve-dependencies@30.0.3: + jest-resolve-dependencies@30.0.4: dependencies: jest-regex-util: 30.0.1 - jest-snapshot: 30.0.3 + jest-snapshot: 30.0.4 transitivePeerDependencies: - supports-color @@ -8786,12 +8829,12 @@ snapshots: slash: 3.0.0 unrs-resolver: 1.9.2 - jest-runner@30.0.3: + jest-runner@30.0.4: dependencies: - '@jest/console': 30.0.2 - '@jest/environment': 30.0.2 - '@jest/test-result': 30.0.2 - '@jest/transform': 30.0.2 + '@jest/console': 30.0.4 + '@jest/environment': 30.0.4 + '@jest/test-result': 30.0.4 + '@jest/transform': 30.0.4 '@jest/types': 30.0.1 '@types/node': 22.15.21 chalk: 4.1.2 @@ -8799,28 +8842,28 @@ snapshots: exit-x: 0.2.2 graceful-fs: 4.2.11 jest-docblock: 30.0.1 - jest-environment-node: 30.0.2 + jest-environment-node: 30.0.4 jest-haste-map: 30.0.2 jest-leak-detector: 30.0.2 jest-message-util: 30.0.2 jest-resolve: 30.0.2 - jest-runtime: 30.0.3 + jest-runtime: 30.0.4 jest-util: 30.0.2 - jest-watcher: 30.0.2 + jest-watcher: 30.0.4 jest-worker: 30.0.2 p-limit: 3.1.0 source-map-support: 0.5.13 transitivePeerDependencies: - supports-color - jest-runtime@30.0.3: + jest-runtime@30.0.4: dependencies: - '@jest/environment': 30.0.2 - '@jest/fake-timers': 30.0.2 - '@jest/globals': 30.0.3 + '@jest/environment': 30.0.4 + '@jest/fake-timers': 30.0.4 + '@jest/globals': 30.0.4 '@jest/source-map': 30.0.1 - '@jest/test-result': 30.0.2 - '@jest/transform': 30.0.2 + '@jest/test-result': 30.0.4 + '@jest/transform': 30.0.4 '@jest/types': 30.0.1 '@types/node': 22.15.21 chalk: 4.1.2 @@ -8833,31 +8876,31 @@ snapshots: jest-mock: 30.0.2 jest-regex-util: 30.0.1 jest-resolve: 30.0.2 - jest-snapshot: 30.0.3 + jest-snapshot: 30.0.4 jest-util: 30.0.2 slash: 3.0.0 strip-bom: 4.0.0 transitivePeerDependencies: - supports-color - jest-snapshot@30.0.3: + jest-snapshot@30.0.4: dependencies: '@babel/core': 7.27.4 '@babel/generator': 7.27.5 '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.27.4) '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.27.4) - '@babel/types': 7.27.3 - '@jest/expect-utils': 30.0.3 + '@babel/types': 7.27.6 + '@jest/expect-utils': 30.0.4 '@jest/get-type': 30.0.1 - '@jest/snapshot-utils': 30.0.1 - '@jest/transform': 30.0.2 + '@jest/snapshot-utils': 30.0.4 + '@jest/transform': 30.0.4 '@jest/types': 30.0.1 babel-preset-current-node-syntax: 1.1.0(@babel/core@7.27.4) chalk: 4.1.2 - expect: 30.0.3 + expect: 30.0.4 graceful-fs: 4.2.11 - jest-diff: 30.0.3 - jest-matcher-utils: 30.0.3 + jest-diff: 30.0.4 + jest-matcher-utils: 30.0.4 jest-message-util: 30.0.2 jest-util: 30.0.2 pretty-format: 30.0.2 @@ -8884,9 +8927,9 @@ snapshots: leven: 3.1.0 pretty-format: 30.0.2 - jest-watcher@30.0.2: + jest-watcher@30.0.4: dependencies: - '@jest/test-result': 30.0.2 + '@jest/test-result': 30.0.4 '@jest/types': 30.0.1 '@types/node': 22.15.21 ansi-escapes: 4.3.2 @@ -8909,12 +8952,12 @@ snapshots: merge-stream: 2.0.0 supports-color: 8.1.1 - jest@30.0.3(@types/node@22.15.21)(ts-node@10.9.2(@swc/core@1.11.29)(@types/node@22.15.21)(typescript@5.8.3)): + jest@30.0.4(@types/node@22.15.21)(ts-node@10.9.2(@swc/core@1.12.9)(@types/node@22.15.21)(typescript@5.8.3)): dependencies: - '@jest/core': 30.0.3(ts-node@10.9.2(@swc/core@1.11.29)(@types/node@22.15.21)(typescript@5.8.3)) + '@jest/core': 30.0.4(ts-node@10.9.2(@swc/core@1.12.9)(@types/node@22.15.21)(typescript@5.8.3)) '@jest/types': 30.0.1 import-local: 3.2.0 - jest-cli: 30.0.3(@types/node@22.15.21)(ts-node@10.9.2(@swc/core@1.11.29)(@types/node@22.15.21)(typescript@5.8.3)) + jest-cli: 30.0.4(@types/node@22.15.21)(ts-node@10.9.2(@swc/core@1.12.9)(@types/node@22.15.21)(typescript@5.8.3)) transitivePeerDependencies: - '@types/node' - babel-plugin-macros @@ -9204,7 +9247,7 @@ snapshots: nullthrows@1.1.1: {} - oauth4webapi@3.5.3: {} + oauth4webapi@3.5.5: {} object-assign@4.1.1: {} @@ -9224,10 +9267,10 @@ snapshots: dependencies: mimic-fn: 2.1.0 - openid-client@6.6.1: + openid-client@6.6.2: dependencies: jose: 6.0.11 - oauth4webapi: 3.5.3 + oauth4webapi: 3.5.5 optionator@0.9.4: dependencies: @@ -9378,7 +9421,7 @@ snapshots: dependencies: fast-diff: 1.3.0 - prettier@3.6.1: {} + prettier@3.6.2: {} pretty-format@30.0.2: dependencies: @@ -9386,10 +9429,10 @@ snapshots: ansi-styles: 5.2.0 react-is: 18.3.1 - prisma@6.8.2(typescript@5.8.3): + prisma@6.11.0(typescript@5.8.3): dependencies: - '@prisma/config': 6.8.2 - '@prisma/engines': 6.8.2 + '@prisma/config': 6.11.0 + '@prisma/engines': 6.11.0 optionalDependencies: typescript: 5.8.3 @@ -9795,16 +9838,16 @@ snapshots: fast-fifo: 1.3.2 streamx: 2.22.0 - terser-webpack-plugin@5.3.14(@swc/core@1.11.29)(webpack@5.99.6(@swc/core@1.11.29)): + terser-webpack-plugin@5.3.14(@swc/core@1.12.9)(webpack@5.99.6(@swc/core@1.12.9)): dependencies: '@jridgewell/trace-mapping': 0.3.25 jest-worker: 27.5.1 schema-utils: 4.3.2 serialize-javascript: 6.0.2 terser: 5.39.2 - webpack: 5.99.6(@swc/core@1.11.29) + webpack: 5.99.6(@swc/core@1.12.9) optionalDependencies: - '@swc/core': 1.11.29 + '@swc/core': 1.12.9 terser@5.39.2: dependencies: @@ -9856,12 +9899,12 @@ snapshots: dependencies: typescript: 5.8.3 - ts-jest@29.4.0(@babel/core@7.27.4)(@jest/transform@30.0.2)(@jest/types@30.0.1)(babel-jest@30.0.2(@babel/core@7.27.4))(jest-util@30.0.2)(jest@30.0.3(@types/node@22.15.21)(ts-node@10.9.2(@swc/core@1.11.29)(@types/node@22.15.21)(typescript@5.8.3)))(typescript@5.8.3): + ts-jest@29.4.0(@babel/core@7.27.4)(@jest/transform@30.0.4)(@jest/types@30.0.1)(babel-jest@30.0.4(@babel/core@7.27.4))(jest-util@30.0.2)(jest@30.0.4(@types/node@22.15.21)(ts-node@10.9.2(@swc/core@1.12.9)(@types/node@22.15.21)(typescript@5.8.3)))(typescript@5.8.3): dependencies: bs-logger: 0.2.6 ejs: 3.1.10 fast-json-stable-stringify: 2.1.0 - jest: 30.0.3(@types/node@22.15.21)(ts-node@10.9.2(@swc/core@1.11.29)(@types/node@22.15.21)(typescript@5.8.3)) + jest: 30.0.4(@types/node@22.15.21)(ts-node@10.9.2(@swc/core@1.12.9)(@types/node@22.15.21)(typescript@5.8.3)) json5: 2.2.3 lodash.memoize: 4.1.2 make-error: 1.3.6 @@ -9871,12 +9914,12 @@ snapshots: yargs-parser: 21.1.1 optionalDependencies: '@babel/core': 7.27.4 - '@jest/transform': 30.0.2 + '@jest/transform': 30.0.4 '@jest/types': 30.0.1 - babel-jest: 30.0.2(@babel/core@7.27.4) + babel-jest: 30.0.4(@babel/core@7.27.4) jest-util: 30.0.2 - ts-loader@9.5.2(typescript@5.8.3)(webpack@5.99.6(@swc/core@1.11.29)): + ts-loader@9.5.2(typescript@5.8.3)(webpack@5.99.6(@swc/core@1.12.9)): dependencies: chalk: 4.1.2 enhanced-resolve: 5.18.1 @@ -9884,11 +9927,11 @@ snapshots: semver: 7.7.2 source-map: 0.7.4 typescript: 5.8.3 - webpack: 5.99.6(@swc/core@1.11.29) + webpack: 5.99.6(@swc/core@1.12.9) ts-log@2.2.7: {} - ts-node@10.9.2(@swc/core@1.11.29)(@types/node@22.15.21)(typescript@5.8.3): + ts-node@10.9.2(@swc/core@1.12.9)(@types/node@22.15.21)(typescript@5.8.3): dependencies: '@cspotcode/source-map-support': 0.8.1 '@tsconfig/node10': 1.0.11 @@ -9906,7 +9949,7 @@ snapshots: v8-compile-cache-lib: 3.0.1 yn: 3.1.1 optionalDependencies: - '@swc/core': 1.11.29 + '@swc/core': 1.12.9 tsconfig-paths-webpack-plugin@4.2.0: dependencies: @@ -9950,12 +9993,12 @@ snapshots: typedarray@0.0.6: {} - typescript-eslint@8.35.0(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3): + typescript-eslint@8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3): dependencies: - '@typescript-eslint/eslint-plugin': 8.35.0(@typescript-eslint/parser@8.35.0(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3) - '@typescript-eslint/parser': 8.35.0(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3) - '@typescript-eslint/utils': 8.35.0(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3) - eslint: 9.29.0(jiti@2.4.2) + '@typescript-eslint/eslint-plugin': 8.35.1(@typescript-eslint/parser@8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/parser': 8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/utils': 8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) + eslint: 9.30.1(jiti@2.4.2) typescript: 5.8.3 transitivePeerDependencies: - supports-color @@ -10070,7 +10113,7 @@ snapshots: webpack-sources@3.2.3: {} - webpack@5.99.6(@swc/core@1.11.29): + webpack@5.99.6(@swc/core@1.12.9): dependencies: '@types/eslint-scope': 3.7.7 '@types/estree': 1.0.7 @@ -10092,7 +10135,7 @@ snapshots: neo-async: 2.6.2 schema-utils: 4.3.2 tapable: 2.2.1 - terser-webpack-plugin: 5.3.14(@swc/core@1.11.29)(webpack@5.99.6(@swc/core@1.11.29)) + terser-webpack-plugin: 5.3.14(@swc/core@1.12.9)(webpack@5.99.6(@swc/core@1.12.9)) watchpack: 2.4.2 webpack-sources: 3.2.3 transitivePeerDependencies: From e2a4698f27526cfcf34cef0a1373dd00fd3e99b9 Mon Sep 17 00:00:00 2001 From: Lucas Date: Tue, 15 Jul 2025 13:58:19 +1000 Subject: [PATCH 10/33] Add GraphQL types to server CI --- .github/workflows/ci.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9846c09a0..5f77423d1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -31,7 +31,12 @@ jobs: working-directory: ${{ matrix.component }} - name: Generate Prisma Types from Schema - run: npx prisma generate + run: pnpx prisma generate + if: ${{ matrix.component == 'server' }} + working-directory: server + + - name: Generate GraphQL Types + run: pnpm graphql if: ${{ matrix.component == 'server' }} working-directory: server From 9ae4bfb6f029914401eb4b8f3345ce6c4c39ccac Mon Sep 17 00:00:00 2001 From: jason4193 <100593637+jason4193@users.noreply.github.com> Date: Fri, 18 Jul 2025 02:54:49 +1000 Subject: [PATCH 11/33] Add backend routes for courses and classes (#1013) * Add routes for adding and removing course * Update routes by moving validation to controller * Add route for update course colour * add OpenAPI for api-docs for backend using swagger library * Add ApiProperty for user's route * Add get route for courses and classes with update of routing urls * Update PUT request for setCourseColour to PATCH request * Update user routes to using AuthenticatedRequest Type * Add selectClass & removeClass route * Remove OpenAPI and Swagger Library, switched to use Postman * Update route for select and remove class * Remove unwanted routes with forwarding functions * Resolve usage of null and undefined * Resolve PR review comments * Slim down the Course and Class detail for graphql, and add validation function for update and remove class * Update routes returning status code * Refactor user.controller, move all business validation into service level * Remove duplicate getCourse request in addSelectedClass * Resolve issues on the PR code review * Resolve minor issue on function call, optimise prisma call * Resolve function name typo * Update service level function name corresponds to control level --- server/src/graphql/graphql.service.ts | 6 + server/src/graphql/queries.ts | 9 + server/src/graphql/types.ts | 4 + server/src/user/types.ts | 9 + server/src/user/user.controller.ts | 113 ++++++++- server/src/user/user.module.ts | 3 +- server/src/user/user.service.ts | 335 +++++++++++++++++++++++++- server/src/utils/validate.ts | 11 + 8 files changed, 484 insertions(+), 6 deletions(-) create mode 100644 server/src/graphql/types.ts create mode 100644 server/src/utils/validate.ts diff --git a/server/src/graphql/graphql.service.ts b/server/src/graphql/graphql.service.ts index b8f687d6b..9c1aa453e 100644 --- a/server/src/graphql/graphql.service.ts +++ b/server/src/graphql/graphql.service.ts @@ -1,6 +1,7 @@ import { Injectable } from '@nestjs/common'; import { GraphQLClient } from 'graphql-request'; import { getSdk } from '../generated/graphql'; +import type { ClassDetails } from './types'; const HASURAGRES_GRAPHQL_API = 'https://graphql.csesoc.app/v1/graphql'; @@ -21,4 +22,9 @@ export class GraphqlService { return courseExists.aggregate != null && courseExists.aggregate.count > 0; } + + async getClassDetails(classId: string): Promise { + const { classDetails } = await this.sdk.ClassDetails({ classId }); + return classDetails ? classDetails : undefined; + } } diff --git a/server/src/graphql/queries.ts b/server/src/graphql/queries.ts index 076906af0..0c70ff204 100644 --- a/server/src/graphql/queries.ts +++ b/server/src/graphql/queries.ts @@ -11,3 +11,12 @@ export const COURSE_EXISTS = gql(` } } `); + +export const CLASS_DETAILS = gql(` + query ClassDetails($classId: String!) { + classDetails: classes_by_pk(class_id: $classId) { + activity + section + } + } +`); diff --git a/server/src/graphql/types.ts b/server/src/graphql/types.ts new file mode 100644 index 000000000..6efa3f7cc --- /dev/null +++ b/server/src/graphql/types.ts @@ -0,0 +1,4 @@ +export class ClassDetails { + activity: string; + section: string; +} diff --git a/server/src/user/types.ts b/server/src/user/types.ts index d7e12c64f..fc77654b4 100644 --- a/server/src/user/types.ts +++ b/server/src/user/types.ts @@ -15,3 +15,12 @@ export class UserSettings { unscheduleClassesByDefault: boolean; hideExamClasses: boolean; } + +export class AddCourseDto { + term: string; + colour: string; +} +export class CourseDetails { + id: string; + selectedClasses: string[]; +} diff --git a/server/src/user/user.controller.ts b/server/src/user/user.controller.ts index 9dee9e9db..0c055a289 100644 --- a/server/src/user/user.controller.ts +++ b/server/src/user/user.controller.ts @@ -1,8 +1,19 @@ -import { Body, Controller, Get, Post, Req, UseGuards } from '@nestjs/common'; +import { + Body, + Controller, + Delete, + Get, + HttpStatus, + Param, + Patch, + Post, + Req, + UseGuards, +} from '@nestjs/common'; import { UserService } from './user.service'; import { AuthenticatedGuard } from 'src/auth/authenticated.guard'; import { Request } from 'express'; -import { UserSettings } from './types'; +import { UserSettings, AddCourseDto } from './types'; interface AuthenticatedRequest extends Request { user: { @@ -49,4 +60,102 @@ export class UserController { await this.userService.setSettings(req.user.id, settings); return; } + + @Get('courses/:timetableId') + @UseGuards(AuthenticatedGuard) + async getCourseIds( + @Req() req: AuthenticatedRequest, + @Param('timetableId') timetableId: string, + ) { + return await this.userService.getCourseIds(req.user.id, timetableId); + } + + @Post('course/:timetableId/:courseId') + @UseGuards(AuthenticatedGuard) + async addCourse( + @Req() req: AuthenticatedRequest, + @Param('timetableId') timetableId: string, + @Param('courseId') courseId: string, + @Body() addCourseDto: AddCourseDto, + ) { + await this.userService.addCourse( + req.user.id, + timetableId, + courseId, + addCourseDto, + ); + return HttpStatus.CREATED; + } + + @Delete('course/:timetableId/:courseId') + @UseGuards(AuthenticatedGuard) + async removeCourse( + @Req() req: AuthenticatedRequest, + @Param('timetableId') timetableId: string, + @Param('courseId') courseId: string, + ) { + await this.userService.removeCourse(req.user.id, timetableId, courseId); + } + + @Patch('course/:timetableId/:courseId/colour') + @UseGuards(AuthenticatedGuard) + async setCourseColour( + @Req() req: AuthenticatedRequest, + @Param('timetableId') timetableId: string, + @Param('courseId') courseId: string, + @Body('colour') colour: string, + ) { + await this.userService.setCourseColour( + req.user.id, + timetableId, + courseId, + colour, + ); + } + + @Get('classes/:timetableId/:courseId') + @UseGuards(AuthenticatedGuard) + async getSelectedClassIds( + @Req() req: AuthenticatedRequest, + @Param('timetableId') timetableId: string, + @Param('courseId') courseId: string, + ) { + return await this.userService.getSelectedClassIds( + req.user.id, + timetableId, + courseId, + ); + } + + @Patch('class/:timetableId/:courseId') + @UseGuards(AuthenticatedGuard) + async updateSelectedClass( + @Req() req: AuthenticatedRequest, + @Param('timetableId') timetableId: string, + @Param('courseId') courseId: string, + @Body('classId') classId: string, + ) { + await this.userService.updateSelectedClass( + req.user.id, + timetableId, + courseId, + classId, + ); + } + + @Delete('class/:timetableId/:courseId/:classId') + @UseGuards(AuthenticatedGuard) + async removeSelectedClass( + @Req() req: AuthenticatedRequest, + @Param('timetableId') timetableId: string, + @Param('courseId') courseId: string, + @Param('classId') classId: string, + ) { + await this.userService.removeSelectedClass( + req.user.id, + timetableId, + courseId, + classId, + ); + } } diff --git a/server/src/user/user.module.ts b/server/src/user/user.module.ts index 7629f686f..e93cb4341 100644 --- a/server/src/user/user.module.ts +++ b/server/src/user/user.module.ts @@ -1,10 +1,11 @@ import { Module } from '@nestjs/common'; +import { GraphqlService } from 'src/graphql/graphql.service'; import { PrismaService } from 'src/prisma/prisma.service'; import { UserService } from './user.service'; import { UserController } from './user.controller'; @Module({ - providers: [UserService, PrismaService], + providers: [UserService, PrismaService, GraphqlService], controllers: [UserController], }) export class UserModule {} diff --git a/server/src/user/user.service.ts b/server/src/user/user.service.ts index 40c13e820..dee4e9190 100644 --- a/server/src/user/user.service.ts +++ b/server/src/user/user.service.ts @@ -1,10 +1,16 @@ -import { Injectable } from '@nestjs/common'; +import { HttpException, HttpStatus, Injectable } from '@nestjs/common'; +import { GraphqlService } from 'src/graphql/graphql.service'; import { PrismaService } from 'src/prisma/prisma.service'; -import { UserInfo, UserSettings } from './types'; +import { AddCourseDto, CourseDetails, UserInfo, UserSettings } from './types'; +import type { ClassDetails } from 'src/graphql/types'; +import { validate } from 'src/utils/validate'; @Injectable({}) export class UserService { - constructor(private readonly prisma: PrismaService) {} + constructor( + private readonly prisma: PrismaService, + private readonly graphqlService: GraphqlService, + ) {} async getUserInfo(userId: string): Promise { const data = await this.prisma.user.findUniqueOrThrow({ @@ -64,4 +70,327 @@ export class UserService { }, }); } + + async isTimetableOwnedByUser( + userId: string, + timetableId: string, + ): Promise { + const timetable = await this.prisma.timetable.findUnique({ + select: { + userId: true, + }, + where: { + id: timetableId, + }, + }); + return timetable?.userId === userId; + } + + async isCourseInTimetable( + timetableId: string, + courseId: string, + ): Promise { + const course = await this.prisma.course.findFirst({ + where: { + courseId: courseId, + timetableId: timetableId, + }, + select: { + id: true, + }, + }); + return course !== null; + } + + isColourCodeValid(colour: string): boolean { + const hexCodeRegex = /^#([0-9A-F]{3}|[0-9A-F]{6})$/i; + const defaultColoursRegex = /^default-[1-8]$/; + return hexCodeRegex.test(colour) || defaultColoursRegex.test(colour); + } + + async getCourseIds(userId: string, timetableId: string): Promise { + const timetableExists = await this.isTimetableOwnedByUser( + userId, + timetableId, + ); + validate(timetableExists, 'Timetable does not exist', HttpStatus.NOT_FOUND); + + const courses = await this.prisma.course.findMany({ + where: { + timetableId: timetableId, + }, + select: { + courseId: true, + }, + }); + return courses.map((course) => course.courseId); + } + + async getCourseIfExists( + timetableId: string, + courseId: string, + ): Promise { + try { + return await this.prisma.course.findFirstOrThrow({ + select: { + id: true, + selectedClasses: true, + }, + where: { + courseId: courseId, + timetableId: timetableId, + }, + }); + } catch { + throw new HttpException( + 'Course is not in timetable', + HttpStatus.NOT_FOUND, + ); + } + } + + async addCourse( + userId: string, + timetableId: string, + courseId: string, + addCourseDto: AddCourseDto, + ): Promise { + const courseExistsOnGraphQL = await this.graphqlService.courseExists( + courseId, + addCourseDto.term, + ); + validate( + courseExistsOnGraphQL, + 'Course does not exist', + HttpStatus.NOT_FOUND, + ); + const timetableExists = await this.isTimetableOwnedByUser( + userId, + timetableId, + ); + validate(timetableExists, 'Timetable does not exist', HttpStatus.NOT_FOUND); + const courseInTimetable = await this.isCourseInTimetable( + timetableId, + courseId, + ); + validate( + !courseInTimetable, + 'Course is in timetable already', + HttpStatus.CONFLICT, + ); + const colourValid = this.isColourCodeValid(addCourseDto.colour); + validate(colourValid, 'Colour code is not valid', HttpStatus.BAD_REQUEST); + + await this.prisma.course.create({ + data: { + courseId: courseId, + colour: addCourseDto.colour, + selectedClasses: [], + timetable: { + connect: { + id: timetableId, + }, + }, + }, + }); + } + + async removeCourse( + userId: string, + timetableId: string, + courseId: string, + ): Promise { + const timetableExists = await this.isTimetableOwnedByUser( + userId, + timetableId, + ); + validate(timetableExists, 'Timetable does not exist', HttpStatus.NOT_FOUND); + + const course = await this.getCourseIfExists(timetableId, courseId); + await this.prisma.course.delete({ + where: { + id: course.id, + }, + }); + } + + async setCourseColour( + userId: string, + timetableId: string, + courseId: string, + colour: string, + ): Promise { + const timetableExists = await this.isTimetableOwnedByUser( + userId, + timetableId, + ); + validate(timetableExists, 'Timetable does not exist', HttpStatus.NOT_FOUND); + const colourValid = this.isColourCodeValid(colour); + validate(colourValid, 'Colour code is not valid', HttpStatus.BAD_REQUEST); + const course = await this.getCourseIfExists(timetableId, courseId); + + await this.prisma.course.update({ + where: { + id: course.id, + }, + data: { + colour: colour, + }, + }); + } + + async getSelectedClassIds( + userId: string, + timetableId: string, + courseId: string, + ): Promise { + const timetableExists = await this.isTimetableOwnedByUser( + userId, + timetableId, + ); + validate(timetableExists, 'Timetable does not exist', HttpStatus.NOT_FOUND); + + const course = await this.getCourseIfExists(timetableId, courseId); + return course.selectedClasses; + } + + async differentTimeSlotsExist( + classData: ClassDetails, + existingClassIds: string[], + ): Promise { + try { + const existingClassDetails = await Promise.all( + existingClassIds.map(async (classId) => { + const details = await this.graphqlService.getClassDetails(classId); + return { + ...details, + class_id: classId, + }; + }), + ); + const differentTimeSlotsExist = existingClassDetails.filter( + (classDetails: ClassDetails & { class_id: string }) => + classDetails.activity === classData.activity && + classDetails.section !== classData.section, + ); + validate( + differentTimeSlotsExist.length <= 1, + 'Multiple different time slots found for the same activity', + HttpStatus.CONFLICT, + ); + if (differentTimeSlotsExist.length === 1 && differentTimeSlotsExist[0]) { + return differentTimeSlotsExist[0].class_id; + } else { + return undefined; + } + } catch (error) { + if (error instanceof HttpException) { + throw error; + } + throw new HttpException( + 'Failed to check for different time slots', + HttpStatus.INTERNAL_SERVER_ERROR, + ); + } + } + + async updateSelectedClass( + userId: string, + timetableId: string, + courseId: string, + classId: string, + ): Promise { + const classDetails = await this.graphqlService.getClassDetails(classId); + validate( + classDetails !== undefined, + 'Class does not exist', + HttpStatus.NOT_FOUND, + ); + validate( + classDetails!.activity !== undefined && + classDetails!.activity !== 'Course Enrollment', + 'Class is not a valid course class', + HttpStatus.BAD_REQUEST, + ); + const timetableExists = await this.isTimetableOwnedByUser( + userId, + timetableId, + ); + validate(timetableExists, 'Timetable does not exist', HttpStatus.NOT_FOUND); + const course = await this.getCourseIfExists(timetableId, courseId); + validate( + !course.selectedClasses.includes(classId), + 'Class is already in course', + HttpStatus.CONFLICT, + ); + + const differentTimeSlotClassId = await this.differentTimeSlotsExist( + classDetails!, + course.selectedClasses, + ); + if (differentTimeSlotClassId) { + await this.removeClassFromCourse(course, differentTimeSlotClassId); + } + await this.addSelectedClass(course, classId); + } + + private async addSelectedClass( + course: CourseDetails, + classId: string, + ): Promise { + await this.prisma.course.update({ + where: { + id: course.id, + }, + data: { + selectedClasses: { + push: classId, + }, + }, + }); + } + + private async removeClassFromCourse( + course: CourseDetails, + classId: string, + ): Promise { + const updatedClasses = course.selectedClasses.filter( + (existingClassId) => existingClassId !== classId, + ); + await this.prisma.course.update({ + where: { + id: course.id, + }, + data: { + selectedClasses: updatedClasses, + }, + }); + } + + async removeSelectedClass( + userId: string, + timetableId: string, + courseId: string, + classId: string, + ): Promise { + const classValidate = await this.graphqlService.getClassDetails(classId); + validate( + classValidate !== undefined, + 'Class does not exist', + HttpStatus.NOT_FOUND, + ); + const timetableExists = await this.isTimetableOwnedByUser( + userId, + timetableId, + ); + validate(timetableExists, 'Timetable does not exist', HttpStatus.NOT_FOUND); + const course = await this.getCourseIfExists(timetableId, courseId); + validate( + course.selectedClasses.includes(classId), + 'Class is not in course', + HttpStatus.NOT_FOUND, + ); + + await this.removeClassFromCourse(course, classId); + } } diff --git a/server/src/utils/validate.ts b/server/src/utils/validate.ts new file mode 100644 index 000000000..376bad1f0 --- /dev/null +++ b/server/src/utils/validate.ts @@ -0,0 +1,11 @@ +import { HttpException, HttpStatus } from '@nestjs/common'; + +export function validate( + condition: boolean, + errorMessage: string, + statusCode: HttpStatus = HttpStatus.BAD_REQUEST, +): void { + if (!condition) { + throw new HttpException(errorMessage, statusCode); + } +} From df889e8f04436f26535b4ecaa58ceaba2f41067b Mon Sep 17 00:00:00 2001 From: Lucas Date: Thu, 24 Jul 2025 18:41:47 +1000 Subject: [PATCH 12/33] Remove old account implementation (#1036) * Remove old account implementation * Delete group sidebar * Remove timetable syncing and groups --- client/src/App.tsx | 29 +- client/src/components/controls/History.tsx | 4 +- .../src/components/sidebar/FriendsButton.tsx | 7 +- client/src/components/sidebar/Sidebar.tsx | 32 +- client/src/components/sidebar/UserAccount.tsx | 32 +- .../friends/AddAFriendTab.tsx | 6 +- .../friends/FriendsDialog.tsx | 2 +- .../friends/FriendsTablist.tsx | 2 +- .../friends/RequestsTab.tsx | 6 +- client/src/components/sidebar/friends/User.ts | 16 + .../friends/UserProfile.tsx | 0 .../friends/YourFriendsTab.tsx | 8 +- .../groupsSidebar/AddOrEditGroupDialog.tsx | 123 ------- .../AddOrEditGroupDialogContent.tsx | 268 --------------- .../groupsSidebar/EditImagePopover.tsx | 80 ----- .../sidebar/groupsSidebar/GroupCircle.tsx | 202 ------------ .../sidebar/groupsSidebar/GroupsSidebar.tsx | 37 --- .../timetableShared.tsx/TimetableShared.tsx | 76 ----- client/src/context/UserContext.tsx | 179 ---------- client/src/index.tsx | 35 +- client/src/interfaces/Group.ts | 18 - client/src/interfaces/Periods.ts | 5 - client/src/utils/syncTimetables.ts | 309 ------------------ 23 files changed, 62 insertions(+), 1414 deletions(-) rename client/src/components/sidebar/{groupsSidebar => }/friends/AddAFriendTab.tsx (97%) rename client/src/components/sidebar/{groupsSidebar => }/friends/FriendsDialog.tsx (97%) rename client/src/components/sidebar/{groupsSidebar => }/friends/FriendsTablist.tsx (98%) rename client/src/components/sidebar/{groupsSidebar => }/friends/RequestsTab.tsx (95%) create mode 100644 client/src/components/sidebar/friends/User.ts rename client/src/components/sidebar/{groupsSidebar => }/friends/UserProfile.tsx (100%) rename client/src/components/sidebar/{groupsSidebar => }/friends/YourFriendsTab.tsx (90%) delete mode 100644 client/src/components/sidebar/groupsSidebar/AddOrEditGroupDialog.tsx delete mode 100644 client/src/components/sidebar/groupsSidebar/AddOrEditGroupDialogContent.tsx delete mode 100644 client/src/components/sidebar/groupsSidebar/EditImagePopover.tsx delete mode 100644 client/src/components/sidebar/groupsSidebar/GroupCircle.tsx delete mode 100644 client/src/components/sidebar/groupsSidebar/GroupsSidebar.tsx delete mode 100644 client/src/components/timetableShared.tsx/TimetableShared.tsx delete mode 100644 client/src/context/UserContext.tsx delete mode 100644 client/src/interfaces/Group.ts delete mode 100644 client/src/utils/syncTimetables.ts diff --git a/client/src/App.tsx b/client/src/App.tsx index 816e62ec1..252070418 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -17,7 +17,6 @@ import SubcomPromotion from './components/promotions/SubcomPromotion'; import Sidebar from './components/sidebar/Sidebar'; import Sponsors from './components/Sponsors'; import Timetable from './components/timetable/Timetable'; -import TimetableShared from './components/timetableShared.tsx/TimetableShared'; import { TimetableTabs } from './components/timetableTabs/TimetableTabs'; import { contentPadding, rightContentPadding, themes } from './constants/theme'; import { @@ -31,7 +30,6 @@ import { } from './constants/timetable'; import { AppContext } from './context/AppContext'; import { CourseContext } from './context/CourseContext'; -import { UserContext } from './context/UserContext'; import { useColorsDecoder } from './hooks/useColorDecoder'; import useColorMapper from './hooks/useColorMapper'; import useUpdateEffect from './hooks/useUpdateEffect'; @@ -49,7 +47,6 @@ import { import { setDropzoneRange, useDrag } from './utils/Drag'; import { downloadIcsFile } from './utils/generateICS'; import storage from './utils/storage'; -import { runSync } from './utils/syncTimetables'; import { createDefaultTimetable } from './utils/timetableHelpers'; const StyledApp = styled(Box)` @@ -148,7 +145,6 @@ const App: React.FC = () => { } = useContext(CourseContext); const decodedAssignedColors = useColorsDecoder(assignedColors, currentTheme); - const { user, setUser, groupsSidebarCollapsed, setGroupsSidebarCollapsed } = useContext(UserContext); setDropzoneRange(days.length, earliestStartTime, latestEndTime); @@ -200,7 +196,7 @@ const App: React.FC = () => { ...{ [termId]: Object.prototype.hasOwnProperty.call(oldData, termId) ? oldData[termId] - : createDefaultTimetable(user.userID), + : createDefaultTimetable(undefined), }, }; } @@ -446,14 +442,6 @@ const App: React.FC = () => { updateTimetableEvents(); }, [year, isConvertToLocalTimezone]); - const syncTimetables = () => { - if (!user.userID) { - return; - } - - runSync(user, setUser, displayTimetables, setDisplayTimetables); - }; - // The following three useUpdateEffects update local storage whenever a change is made to the timetable useUpdateEffect(() => { displayTimetables[term][selectedTimetable].selectedCourses = selectedCourses; @@ -462,7 +450,6 @@ const App: React.FC = () => { storage.set('timetables', displayTimetables); setDisplayTimetables(displayTimetables); - syncTimetables(); }, [selectedCourses]); useUpdateEffect(() => { @@ -470,7 +457,6 @@ const App: React.FC = () => { storage.set('timetables', displayTimetables); setDisplayTimetables(displayTimetables); - syncTimetables(); }, [selectedClasses]); useUpdateEffect(() => { @@ -478,7 +464,6 @@ const App: React.FC = () => { storage.set('timetables', displayTimetables); setDisplayTimetables(displayTimetables); - syncTimetables(); }, [createdEvents]); useUpdateEffect(() => { @@ -486,13 +471,11 @@ const App: React.FC = () => { storage.set('timetables', displayTimetables); setDisplayTimetables(displayTimetables); - syncTimetables(); }, [assignedColors]); // Update storage when dragging timetables useUpdateEffect(() => { storage.set('timetables', displayTimetables); - syncTimetables(); }, [displayTimetables]); /** @@ -649,14 +632,8 @@ const App: React.FC = () => { handleRemoveCourse={handleRemoveCourse} /> - {groupsSidebarCollapsed ? ( - <> - - - - ) : ( - - )} + + downloadIcsFile(selectedCourses, createdEvents, selectedClasses, firstDayOfTerm)} > diff --git a/client/src/components/controls/History.tsx b/client/src/components/controls/History.tsx index 4afb53420..6534a58cc 100644 --- a/client/src/components/controls/History.tsx +++ b/client/src/components/controls/History.tsx @@ -4,7 +4,6 @@ import React, { useCallback, useContext, useEffect, useRef, useState } from 'rea import { AppContext } from '../../context/AppContext'; import { CourseContext } from '../../context/CourseContext'; -import { UserContext } from '../../context/UserContext'; import { CourseData, CreatedEvents, DisplayTimetablesMap, SelectedClasses } from '../../interfaces/Periods'; import { ActionsPointer, @@ -31,7 +30,6 @@ const History: React.FC = () => { useContext(CourseContext); const { isDrag, setIsDrag, selectedTimetable, setSelectedTimetable, displayTimetables, setDisplayTimetables, term } = useContext(AppContext); - const { user } = useContext(UserContext); const timetableActions = useRef({}); const actionsPointer = useRef({}); @@ -207,7 +205,7 @@ const History: React.FC = () => { * Resets all timetables - leave one as default */ const clearAll = () => { - const newTimetables = createDefaultTimetable(user.userID); + const newTimetables = createDefaultTimetable(undefined); if (!term) return; const newDisplayTimetables: DisplayTimetablesMap = { diff --git a/client/src/components/sidebar/FriendsButton.tsx b/client/src/components/sidebar/FriendsButton.tsx index be5b4d209..1eb054273 100644 --- a/client/src/components/sidebar/FriendsButton.tsx +++ b/client/src/components/sidebar/FriendsButton.tsx @@ -3,8 +3,6 @@ import { IconButton, Tooltip, Typography } from '@mui/material'; import { styled } from '@mui/system'; import React, { useContext } from 'react'; -import { UserContext } from '../../context/UserContext'; - interface FriendsButtonProps { collapsed: boolean; } @@ -24,16 +22,15 @@ const IndividualComponentTypography = styled(Typography)` font-size: 16px; `; +// TODO: Repurpose using Sunny's design for friends const FriendsButton: React.FC = ({ collapsed }) => { - const { groupsSidebarCollapsed, setGroupsSidebarCollapsed } = useContext(UserContext); - return ( <> setGroupsSidebarCollapsed(!groupsSidebarCollapsed)} UNCOMMENT to see shared timetables - isSelected={!groupsSidebarCollapsed} + isSelected={false} > {collapsed ? '' : 'Shared Timetables'} diff --git a/client/src/components/sidebar/Sidebar.tsx b/client/src/components/sidebar/Sidebar.tsx index 82ad2a024..191d437c8 100644 --- a/client/src/components/sidebar/Sidebar.tsx +++ b/client/src/components/sidebar/Sidebar.tsx @@ -1,20 +1,17 @@ import { CalendarMonth, Description, Info, Security, Settings as SettingsIcon } from '@mui/icons-material'; -import { Divider, Drawer, Typography } from '@mui/material'; -import { useMediaQuery, useTheme } from '@mui/material'; +import { Divider, Drawer, Typography, useMediaQuery, useTheme } from '@mui/material'; import { styled } from '@mui/system'; -import React, { useContext, useMemo, useState } from 'react'; +import React, { useMemo, useState } from 'react'; import notanglesLogoGif from '../../assets/notangles.gif'; import notanglesLogo from '../../assets/notangles_1.png'; import { leftContentPadding } from '../../constants/theme'; -import { UserContext } from '../../context/UserContext'; import About from './About'; import Changelog from './Changelog'; import CollapseButton from './CollapseButton'; import CustomModal from './CustomModal'; import DarkModeButton from './DarkModeButton'; import FriendsButton from './FriendsButton'; -import GroupsSidebar from './groupsSidebar/GroupsSidebar'; import MobileMenuButton from './MobileMenuButton'; import Privacy from './Privacy'; import Settings from './Settings'; @@ -115,25 +112,6 @@ const SidebarFooterWrapper = styled('div')` flex-direction: row; `; -const StyledGroupContainer = styled('div')` - height: 100vh; - width: 60px; - background: ${({ theme }) => theme.palette.primary.main}; - display: flex; - align-items: center; - padding: 12px 2px; - flex-direction: column; - gap: 4px; - - overflow-y: auto; - max-height: calc(100vh - 24px); - - scrollbar-width: none; /* Firefox */ - &::-webkit-scrollbar { - display: none; /* Chrome, Safari, and Edge */ - } -`; - const modalData = [ { title: 'About', @@ -177,7 +155,6 @@ const Sidebar: React.FC = () => { const [currLogo, setCurrLogo] = useState(notanglesLogo); const [collapsed, setCollapsed] = useState(() => !isWide); - const { groupsSidebarCollapsed } = useContext(UserContext); const handleCollapse = (val: boolean) => { setCollapsed(val); @@ -216,11 +193,6 @@ const Sidebar: React.FC = () => { }} elevation={0} > - {!groupsSidebarCollapsed && ( - - - - )}
diff --git a/client/src/components/sidebar/UserAccount.tsx b/client/src/components/sidebar/UserAccount.tsx index 342bb3c7d..c8fd5d079 100644 --- a/client/src/components/sidebar/UserAccount.tsx +++ b/client/src/components/sidebar/UserAccount.tsx @@ -1,15 +1,12 @@ import { LoginRounded, LogoutRounded } from '@mui/icons-material'; import { Button, IconButton, Tooltip } from '@mui/material'; import { styled } from '@mui/system'; -import React, { useContext, useState } from 'react'; - +import React, { useState } from 'react'; import { API_URL } from '../../api/config'; -import { undefinedUser, UserContext } from '../../context/UserContext'; -import { DisplayTimetablesMap } from '../../interfaces/Periods'; import storage from '../../utils/storage'; import { createDefaultTimetable } from '../../utils/timetableHelpers'; import StyledDialog from '../StyledDialog'; -import UserProfile from './groupsSidebar/friends/UserProfile'; +import UserProfile from './friends/UserProfile'; interface UserAccountProps { collapsed: boolean; @@ -45,26 +42,10 @@ const ExpandedContainer = styled('div')` padding: 10px 12px; `; -export interface User { - userID: string; - firstname: string; - lastname: string; - email: string; - profileURL: string; - createdAt: string; - lastLogin: string; - loggedIn: boolean; - friends: User[]; - incoming: User[]; - outgoing: User[]; - timetables: DisplayTimetablesMap; -} - const UserAccount: React.FC = ({ collapsed }) => { const [windowLocation, setWindowLocation] = useState(''); const [logoutDialog, setLogoutDialog] = useState(false); - const { user, setUser } = useContext(UserContext); const loginCall = async () => { setWindowLocation(window.location.href); try { @@ -74,6 +55,14 @@ const UserAccount: React.FC = ({ collapsed }) => { } }; + const user = { + userID: '', + firstname: 'First', + lastname: 'Last', + email: 'example@user.com', + profileURL: '', + }; + const logoutCall = async () => { try { await fetch(`${API_URL.server}/auth/logout`, { @@ -83,7 +72,6 @@ const UserAccount: React.FC = ({ collapsed }) => { console.log(error); } window.location.replace(windowLocation); - setUser(undefinedUser); storage.set('timetables', createDefaultTimetable(undefined)); }; if (!user.userID) { diff --git a/client/src/components/sidebar/groupsSidebar/friends/AddAFriendTab.tsx b/client/src/components/sidebar/friends/AddAFriendTab.tsx similarity index 97% rename from client/src/components/sidebar/groupsSidebar/friends/AddAFriendTab.tsx rename to client/src/components/sidebar/friends/AddAFriendTab.tsx index 191fb8d7e..6bb2e4250 100644 --- a/client/src/components/sidebar/groupsSidebar/friends/AddAFriendTab.tsx +++ b/client/src/components/sidebar/friends/AddAFriendTab.tsx @@ -3,9 +3,9 @@ import { Add, Close } from '@mui/icons-material'; import { IconButton, TextField, Tooltip } from '@mui/material'; import { useEffect, useState } from 'react'; -import { API_URL } from '../../../../api/config'; -import NetworkError from '../../../../interfaces/NetworkError'; -import { User } from '../../UserAccount'; +import { API_URL } from '../../../api/config'; +import NetworkError from '../../../interfaces/NetworkError'; +import { User } from './User'; import UserProfile from './UserProfile'; const StyledContainer = styled('div')` diff --git a/client/src/components/sidebar/groupsSidebar/friends/FriendsDialog.tsx b/client/src/components/sidebar/friends/FriendsDialog.tsx similarity index 97% rename from client/src/components/sidebar/groupsSidebar/friends/FriendsDialog.tsx rename to client/src/components/sidebar/friends/FriendsDialog.tsx index 6d1a959c3..73719bc5e 100644 --- a/client/src/components/sidebar/groupsSidebar/friends/FriendsDialog.tsx +++ b/client/src/components/sidebar/friends/FriendsDialog.tsx @@ -3,7 +3,7 @@ import { Close as CloseIcon } from '@mui/icons-material'; import { Badge, Dialog, DialogTitle, IconButton, Paper, styled, Typography } from '@mui/material'; import React, { useState } from 'react'; -import { User } from '../../UserAccount'; +import { User } from './User'; import FriendsTablist from './FriendsTablist'; const StyledDialogTitle = styled(DialogTitle)` diff --git a/client/src/components/sidebar/groupsSidebar/friends/FriendsTablist.tsx b/client/src/components/sidebar/friends/FriendsTablist.tsx similarity index 98% rename from client/src/components/sidebar/groupsSidebar/friends/FriendsTablist.tsx rename to client/src/components/sidebar/friends/FriendsTablist.tsx index 900240e7f..c468ceb7d 100644 --- a/client/src/components/sidebar/groupsSidebar/friends/FriendsTablist.tsx +++ b/client/src/components/sidebar/friends/FriendsTablist.tsx @@ -5,7 +5,7 @@ import Tab from '@mui/material/Tab'; import Tabs from '@mui/material/Tabs'; import * as React from 'react'; -import { User } from '../../UserAccount'; +import { User } from './User'; import AddAFriendTab from './AddAFriendTab'; import RequestsTab from './RequestsTab'; import YourFriendsTab from './YourFriendsTab'; diff --git a/client/src/components/sidebar/groupsSidebar/friends/RequestsTab.tsx b/client/src/components/sidebar/friends/RequestsTab.tsx similarity index 95% rename from client/src/components/sidebar/groupsSidebar/friends/RequestsTab.tsx rename to client/src/components/sidebar/friends/RequestsTab.tsx index 490e62d99..d252dcd4b 100644 --- a/client/src/components/sidebar/groupsSidebar/friends/RequestsTab.tsx +++ b/client/src/components/sidebar/friends/RequestsTab.tsx @@ -3,9 +3,9 @@ import { Check, Close } from '@mui/icons-material'; import { IconButton, Tooltip } from '@mui/material'; import React from 'react'; -import { API_URL } from '../../../../api/config'; -import NetworkError from '../../../../interfaces/NetworkError'; -import { User } from '../../UserAccount'; +import { API_URL } from '../../../api/config'; +import NetworkError from '../../../interfaces/NetworkError'; +import { User } from './User'; import UserProfile from './UserProfile'; const StyledFriendsListContainer = styled('div')` diff --git a/client/src/components/sidebar/friends/User.ts b/client/src/components/sidebar/friends/User.ts new file mode 100644 index 000000000..92a368092 --- /dev/null +++ b/client/src/components/sidebar/friends/User.ts @@ -0,0 +1,16 @@ +import { DisplayTimetablesMap } from '../../../interfaces/Periods'; + +export interface User { + userID: string; + firstname: string; + lastname: string; + email: string; + profileURL: string; + createdAt: string; + lastLogin: string; + loggedIn: boolean; + friends: User[]; + incoming: User[]; + outgoing: User[]; + timetables: DisplayTimetablesMap; +} diff --git a/client/src/components/sidebar/groupsSidebar/friends/UserProfile.tsx b/client/src/components/sidebar/friends/UserProfile.tsx similarity index 100% rename from client/src/components/sidebar/groupsSidebar/friends/UserProfile.tsx rename to client/src/components/sidebar/friends/UserProfile.tsx diff --git a/client/src/components/sidebar/groupsSidebar/friends/YourFriendsTab.tsx b/client/src/components/sidebar/friends/YourFriendsTab.tsx similarity index 90% rename from client/src/components/sidebar/groupsSidebar/friends/YourFriendsTab.tsx rename to client/src/components/sidebar/friends/YourFriendsTab.tsx index db9f6bf9e..94d01c319 100644 --- a/client/src/components/sidebar/groupsSidebar/friends/YourFriendsTab.tsx +++ b/client/src/components/sidebar/friends/YourFriendsTab.tsx @@ -3,10 +3,10 @@ import DeleteOutlineIcon from '@mui/icons-material/DeleteOutline'; import { IconButton, Tooltip } from '@mui/material'; import React from 'react'; -import { API_URL } from '../../../../api/config'; -import NetworkError from '../../../../interfaces/NetworkError'; -import { User } from '../../UserAccount'; +import { API_URL } from '../../../api/config'; +import NetworkError from '../../../interfaces/NetworkError'; import UserProfile from './UserProfile'; +import { User } from './User'; const StyledContainer = styled('div')` display: flex; @@ -45,7 +45,7 @@ const YourFriendsTab: React.FC<{ user: User; fetchUserInfo: (userID: string) => return ( - {user.friends.map((friend: User, i) => ( + {user.friends.map((friend: User, i: number) => ( void; -} - -const StyledDialogTitle = styled(DialogTitle)` - background-color: ${({ theme }) => theme.palette.background.paper}; - padding: 30px; - display: flex; - flex-direction: row; - justify-content: space-between; -`; - -const AddOrEditGroupDialog: React.FC = ({ editGroupData, user, onClose }) => { - const emptyGroupData: Group = { - id: '', - name: '', - description: '', - visibility: Privacy.PRIVATE, - timetables: [], - members: [], - groupAdmins: [user], - imageURL: '', - }; - - const [isOpen, setIsOpen] = useState(false); - const [group, setGroup] = useState(emptyGroupData); - - useEffect(() => { - setGroup({ ...group, groupAdmins: [user] }); - }, [user.userID]); - - useEffect(() => { - setGroup(editGroupData ? editGroupData : emptyGroupData); - }, [editGroupData]); - - const handleClose = () => { - setIsOpen(false); - setGroup({ - id: '', - name: '', - description: '', - visibility: Privacy.PRIVATE, - timetables: [], - members: [], - groupAdmins: [user], - imageURL: '', - }); - onClose(user.userID); - }; - - return ( - <> -
- {editGroupData ? ( - { - setIsOpen(true); - }} - > - - - - Edit - - ) : ( - - { - setIsOpen(true); - }} - > - - - - )} -
- - - <> - - {editGroupData ? 'Edit Group Details' : 'Create a Group'} -
- - - -
-
- - -
- - ); -}; - -export default AddOrEditGroupDialog; diff --git a/client/src/components/sidebar/groupsSidebar/AddOrEditGroupDialogContent.tsx b/client/src/components/sidebar/groupsSidebar/AddOrEditGroupDialogContent.tsx deleted file mode 100644 index a78d6459b..000000000 --- a/client/src/components/sidebar/groupsSidebar/AddOrEditGroupDialogContent.tsx +++ /dev/null @@ -1,268 +0,0 @@ -import { CheckCircle as CheckCircleIcon, RadioButtonUnchecked as RadioButtonUncheckedIcon } from '@mui/icons-material'; -import { - Autocomplete, - Button, - Checkbox, - Chip, - DialogActions, - DialogContent, - FormControl, - InputLabel, - MenuItem, - Select, - TextField, - Tooltip, -} from '@mui/material'; -import { styled } from '@mui/system'; -import React, { useState } from 'react'; - -import { API_URL } from '../../../api/config'; -import NotanglesLogo from '../../../assets/notangles_1.png'; -import { Group, Privacy } from '../../../interfaces/Group'; -import NetworkError from '../../../interfaces/NetworkError'; -import { User } from '../UserAccount'; -import EditImagePopOver from './EditImagePopover'; - -const StyledDialogContent = styled(DialogContent)` - background-color: ${({ theme }) => theme.palette.background.paper}; - padding: 30px 30px; - gap: 20px; - display: flex; - flex-direction: column; - align-items: center; -`; - -const Circle = ` - width: 150px; - height: 150px; - border-radius: 999px; -`; - -const CircleOutline = styled('div')` - ${Circle} - border: 1px solid gray; -`; - -const CircleImage = styled('img')` - ${Circle} - object-fit: cover; -`; - -const StyledUploadImageContainer = styled('div')` - display: flex; - flex-direction: column; - align-items: flex-end; -`; - -const StyledDialogActions = styled(DialogActions)` - background-color: ${({ theme }) => theme.palette.background.paper}; - padding: 0px 30px 30px 0px; -`; - -interface AddGroupDialogContentProps { - user: User; - group: Group; - setGroup: (group: Group) => void; - handleClose: () => void; - isEditing: boolean; -} - -enum InputError { - GROUP_NAME = 'Group name must be at least 1 character', - GROUP_DESCRIPTION = 'Group description must be at least 1 character', - GROUP_MEMBERS = 'You must select at least 1 friend', -} - -const AddOrEditGroupDialogContent: React.FC = ({ - user, - group, - setGroup, - handleClose, - isEditing, -}) => { - const [errorMessage, setErrorMessage] = useState(''); - - const checkInputs = () => { - if (group.name.length < 1) { - setErrorMessage(InputError.GROUP_NAME); - } else if (group.description.length < 1) { - setErrorMessage(InputError.GROUP_DESCRIPTION); - } else if (group.members.length < 1) { - setErrorMessage(InputError.GROUP_MEMBERS); - } - return group.name.length >= 1 && group.description.length >= 1 && group.members.length >= 1; - }; - - const handleCreateGroup = async () => { - if (!checkInputs()) return; - - try { - const res = await fetch(`${API_URL.server}/group`, { - method: 'POST', - headers: { - Accept: 'application/json', - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - name: group.name, - description: group.description, - visibility: group.visibility, - timetableIDs: group.timetables.map((timetable) => timetable.id), - memberIDs: group.members.map((member) => member.userID), - groupAdminIDs: group.groupAdmins.map((groupAdmin) => groupAdmin.userID), - imageURL: group.imageURL, - }), - credentials: 'include', - }); - const groupCreationStatus = await res.json(); - console.log('group creation status', groupCreationStatus.data); // Can see the status of group creation here! - - if (res.status === 201) { - handleClose(); - } else { - throw new NetworkError("Couldn't get response"); - } - } catch (error) { - throw new NetworkError(`Couldn't get response cause encountered error: ${error}`); - } - }; - - const handleEditGroup = async (groupId: string) => { - if (!checkInputs()) return; - try { - const res = await fetch(`${API_URL.server}/group/${groupId}`, { - method: 'PUT', - headers: { - Accept: 'application/json', - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - name: group.name, - description: group.description, - visibility: group.visibility, - timetableIDs: group.timetables.map((timetable) => timetable.id), - memberIDs: group.members.map((member) => member.userID), - groupAdminIDs: group.groupAdmins.map((groupAdmin) => groupAdmin.userID), - imageURL: group.imageURL, - }), - credentials: 'include', - }); - const groupCreationStatus = await res.json(); - console.log('group update status', groupCreationStatus.data); // Can see the status of group creation here! - if (res.status === 200) { - handleClose(); - } else { - throw new NetworkError("Couldn't get response"); - } - } catch (error) { - throw new NetworkError(`Couldn't get response cause encountered error: ${error}`); - } - }; - - return ( - <> - - - - - - - { - setGroup({ ...group, name: e.target.value }); - }} - error={errorMessage === InputError.GROUP_NAME} - helperText={errorMessage === InputError.GROUP_NAME ? InputError.GROUP_NAME : ''} - /> - { - setGroup({ ...group, description: e.target.value }); - }} - error={errorMessage === InputError.GROUP_DESCRIPTION} - helperText={errorMessage === InputError.GROUP_DESCRIPTION ? InputError.GROUP_DESCRIPTION : ''} - /> - - { - setGroup({ ...group, members: value }); - }} - getOptionLabel={(option) => `${option.firstname} ${option.lastname} ${option.userID}`} // What the search query is based on - renderOption={(props, option, { selected }) => ( -
  • - } - checkedIcon={} - style={{ marginRight: 8 }} - checked={selected} - /> - {`${option.firstname} ${option.lastname}`} -
  • - )} - renderTags={(tagValue, getTagProps) => { - return tagValue.map((option, index) => ( - - - - )); - }} - renderInput={(params) => ( - - )} - /> - - - Group Privacy - - -
    - - - {isEditing ? ( - - ) : ( - - )} - - - ); -}; - -export default AddOrEditGroupDialogContent; diff --git a/client/src/components/sidebar/groupsSidebar/EditImagePopover.tsx b/client/src/components/sidebar/groupsSidebar/EditImagePopover.tsx deleted file mode 100644 index 70a1bff46..000000000 --- a/client/src/components/sidebar/groupsSidebar/EditImagePopover.tsx +++ /dev/null @@ -1,80 +0,0 @@ -import { Edit as EditIcon } from '@mui/icons-material'; -import { IconButton, Popover, TextField } from '@mui/material'; -import { styled } from '@mui/system'; -import React from 'react'; - -import { Group } from '../../../interfaces/Group'; - -const EditIconCircle = styled('div')` - background-color: ${({ theme }) => theme.palette.background.paper}; - border: 1px solid gray; - border-radius: 999px; - width: 35px; - height: 35px; - display: flex; - justify-content: center; - align-items: center; - position: relative; - top: -35px; - cursor: pointer; - &:hover { - border: ${({ theme }) => (theme.palette.mode === 'light' ? '1px solid black' : '1px solid white;')}; - } -`; - -const StyledPopoverContent = styled('div')` - width: 400px; -`; - -interface EditImagePopOverProps { - group: Group; - setGroup: (group: Group) => void; -} - -const EditImagePopOver: React.FC = ({ group, setGroup }) => { - const [anchorEl, setAnchorEl] = React.useState(null); - - return ( - -
    - { - setAnchorEl(e.currentTarget); - }} - > - - - - { - setAnchorEl(null); - }} - anchorOrigin={{ - vertical: 'bottom', - horizontal: 'left', - }} - transformOrigin={{ - vertical: 'top', - horizontal: 'center', - }} - > - - { - setGroup({ ...group, imageURL: e.target.value }); - }} - /> - - -
    -
    - ); -}; - -export default EditImagePopOver; diff --git a/client/src/components/sidebar/groupsSidebar/GroupCircle.tsx b/client/src/components/sidebar/groupsSidebar/GroupCircle.tsx deleted file mode 100644 index 766653392..000000000 --- a/client/src/components/sidebar/groupsSidebar/GroupCircle.tsx +++ /dev/null @@ -1,202 +0,0 @@ -import styled from '@emotion/styled'; -import { WavingHand } from '@mui/icons-material'; -import { ListItemIcon, Tooltip, Zoom } from '@mui/material'; -import MenuItem from '@mui/material/MenuItem'; -import React from 'react'; - -import { API_URL } from '../../../api/config'; -import NotanglesLogo from '../../../assets/notangles_1.png'; -import { Group } from '../../../interfaces/Group'; -import NetworkError from '../../../interfaces/NetworkError'; -import { RedDeleteIcon, RedListItemText, StyledMenu } from '../../../styles/CustomEventStyles'; -import { User } from '../UserAccount'; -import AddOrEditGroupDialog from './AddOrEditGroupDialog'; - -const AdminBorder = styled('div')<{ isAdmin: boolean }>(({ isAdmin }) => ({ - display: 'flex', - justifyContent: 'center', - alignItems: 'center', - borderRadius: 999, - width: 44, - height: 44, - border: isAdmin ? '2px solid gold' : '', -})); - -const GroupContainer = styled('div')` - display: flex; - align-items: center; - gap: 2px; -`; - -const GroupImage = styled('img')` - border-radius: 999px; - width: 40px; - height: 40px; - background-color: white; -`; - -const SelectedCircle = styled('div')` - border-radius: 999px; - width: 3px; - height: 36px; - background: white; -`; - -const AdminMenu: React.FC<{ - user: User; - group: Group; - fetchUserInfo: (userID: string) => void; - handleClose: () => void; -}> = ({ user, group, fetchUserInfo, handleClose }) => { - const editGroupDialogOnClose = () => { - fetchUserInfo(user.userID); - handleClose(); - }; - - const handleDeleteGroup = async () => { - try { - const res = await fetch(`${API_URL.server}/group/${group.id}`, { - method: 'DELETE', - headers: { - Accept: 'application/json', - 'Content-Type': 'application/json', - }, - credentials: 'include', - }); - const groupDeleteStatus = await res.json(); - console.log('group delete status', groupDeleteStatus); - if (res.status === 200) { - handleClose(); - fetchUserInfo(user.userID); - } else { - throw new NetworkError("Couldn't get response"); - } - } catch (error) { - throw new NetworkError(`Couldn't get response cause encountered error: ${error}`); - } - }; - - return ( - <> - - - - - - Delete - - - ); -}; - -const MemberMenu: React.FC<{ userID: string; group: Group; fetchUserInfo: (userID: string) => void }> = ({ - userID, - group, - fetchUserInfo, -}) => { - const handleLeaveGroup = async () => { - try { - const res = await fetch(`${API_URL.server}/group/${group.id}`, { - method: 'PUT', - headers: { - Accept: 'application/json', - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - name: group.name, - description: group.description, - visibility: group.visibility, - timetableIDs: group.timetables.map((timetable) => timetable.id), - memberIDs: group.members.map((member) => { - if (member.userID !== userID) { - member.userID; - } - }), - groupAdminIDs: group.groupAdmins.map((groupAdmins) => groupAdmins.userID), - imageURL: group.imageURL, - }), - credentials: 'include', - }); - const leaveGroupStatus = await res.json(); - console.log('leave group status', leaveGroupStatus.data); - if (res.status === 200) { - fetchUserInfo(userID); - } else { - throw new NetworkError("Couldn't get response"); - } - } catch (error) { - throw new NetworkError(`Couldn't get response cause encountered error: ${error}`); - } - }; - - return ( - - - - - Leave Group - - ); -}; - -const GroupCircle: React.FC<{ - group: Group; - fetchUserInfo: (userID: string) => void; - user: User; - isSelected: boolean; - onClick: () => void; -}> = ({ group, fetchUserInfo, user, isSelected, onClick }) => { - const isAdmin = group.groupAdmins.map((groupAdmin) => groupAdmin.userID).includes(user.userID); - - const [contextMenu, setContextMenu] = React.useState<{ - mouseX: number; - mouseY: number; - } | null>(null); - - const handleContextMenu = (event: React.MouseEvent) => { - event.preventDefault(); - setContextMenu( - contextMenu === null - ? { - mouseX: event.clientX + 2, - mouseY: event.clientY - 6, - } - : null, - ); - }; - - const handleClose = () => { - setContextMenu(null); - }; - - return ( -
    - - - {isSelected && ( - - - - )} - - - - - - - {isAdmin ? ( - - ) : ( - - )} - -
    - ); -}; - -export default GroupCircle; diff --git a/client/src/components/sidebar/groupsSidebar/GroupsSidebar.tsx b/client/src/components/sidebar/groupsSidebar/GroupsSidebar.tsx deleted file mode 100644 index 2b20389c0..000000000 --- a/client/src/components/sidebar/groupsSidebar/GroupsSidebar.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import React, { useContext } from 'react'; - -import { UserContext } from '../../../context/UserContext'; -import AddOrEditGroupDialog from './AddOrEditGroupDialog'; -import FriendsDialog from './friends/FriendsDialog'; -import GroupCircle from './GroupCircle'; - -const GroupsSidebar: React.FC = () => { - const { user, groups, fetchUserInfo, selectedGroupIndex, setSelectedGroupIndex } = useContext(UserContext); - - const handleChangeSelectedGroup = (newIndex: number) => { - setSelectedGroupIndex(newIndex); - }; - - return ( - <> - - - {groups.map((group, i) => { - return ( - { - handleChangeSelectedGroup(i); - }} - /> - ); - })} - - ); -}; - -export default GroupsSidebar; diff --git a/client/src/components/timetableShared.tsx/TimetableShared.tsx b/client/src/components/timetableShared.tsx/TimetableShared.tsx deleted file mode 100644 index f31463465..000000000 --- a/client/src/components/timetableShared.tsx/TimetableShared.tsx +++ /dev/null @@ -1,76 +0,0 @@ -import styled from '@emotion/styled'; -import { Tooltip } from '@mui/material'; -import React, { useContext } from 'react'; - -import { UserContext } from '../../context/UserContext'; -import { TimetableProps } from '../../interfaces/PropTypes'; -import { emptyProfile } from '../sidebar/groupsSidebar/friends/UserProfile'; -import Timetable from '../timetable/Timetable'; - -const Container = styled('div')` - display: flex; - flex-direction: column; - gap: 12px; -`; - -const Legend = styled('div')` - display: flex; - gap: 24px; - align-items: center; - padding: 12px 32px; - border-radius: 12px; - border: 1px dotted grey; - width: fit-content; - margin: 12px; - align-self: center; -`; - -const Members = styled('div')` - display: flex; - gap: 2px; -`; - -const MemberText = styled('div')` - display: flex; - gap: 2px; - flex-direction: column; - align-items: start; -`; -const GroupName = styled('div')` - font-size: 18px; - font-weight: 600; -`; -const GroupDescription = styled('div')` - font-size: 14px; -`; -const TimetableShared: React.FC = ({ assignedColors, handleSelectClass }) => { - const { groups, selectedGroupIndex } = useContext(UserContext); - if (groups.length === 0) return <>; - const group = groups[selectedGroupIndex]; - - return ( - - - - {group.name} - {group.description} - - - {group.members.map((member, i) => ( - - - - ))} - - - - - ); -}; - -export default TimetableShared; diff --git a/client/src/context/UserContext.tsx b/client/src/context/UserContext.tsx deleted file mode 100644 index 5d35e36e5..000000000 --- a/client/src/context/UserContext.tsx +++ /dev/null @@ -1,179 +0,0 @@ -import { createContext, useContext, useEffect, useMemo, useState } from 'react'; - -import { API_URL } from '../api/config'; -import { User } from '../components/sidebar/UserAccount'; -import { Group } from '../interfaces/Group'; -import NetworkError from '../interfaces/NetworkError'; -import { DisplayTimetablesMap, TimetableDTO } from '../interfaces/Periods'; -import { UserContextProviderProps } from '../interfaces/PropTypes'; -import { parseTimetableDTO } from '../utils/syncTimetables'; -import { createDefaultTimetable } from '../utils/timetableHelpers'; -import { AppContext } from './AppContext'; -import { CourseContext } from './CourseContext'; - -export const undefinedUser = { - userID: '', - firstname: '', - lastname: '', - email: '', - profileURL: '', - createdAt: '', - lastLogin: '', - loggedIn: false, - friends: [], - incoming: [], - outgoing: [], - timetables: {}, -}; - -export interface IUserContext { - user: User; - setUser: (newUser: User) => void; - groups: Group[]; - setGroups: (newGroups: Group[]) => void; - fetchUserInfo: (userID: string) => void; - selectedGroupIndex: number; // selected group is the index of groups; - setSelectedGroupIndex: (newSelectedGroupIndex: number) => void; - groupsSidebarCollapsed: boolean; - setGroupsSidebarCollapsed: (isCollapsed: boolean) => void; -} - -export const UserContext = createContext({ - user: undefinedUser, - setUser: () => {}, - groups: [], - setGroups: () => {}, - fetchUserInfo: () => {}, - selectedGroupIndex: -1, - setSelectedGroupIndex: () => {}, - groupsSidebarCollapsed: true, - setGroupsSidebarCollapsed: () => {}, -}); - -const UserContextProvider = ({ children }: UserContextProviderProps) => { - const [user, setUser] = useState(undefinedUser); - const [groups, setGroups] = useState([]); - const [selectedGroupIndex, setSelectedGroupIndex] = useState(-1); - const [groupsSidebarCollapsed, setGroupsSidebarCollapsed] = useState(true); - const { setDisplayTimetables, setSelectedTimetable, term, year } = useContext(AppContext); - const { setSelectedClasses, setSelectedCourses, setCreatedEvents, setAssignedColors } = useContext(CourseContext); - - const getUserInfo = async (userID: string) => { - try { - const response = await fetch(`${API_URL.server}/user/profile/${userID}`, { - method: 'GET', - headers: { - Accept: 'application/json', - 'Content-Type': 'application/json', - }, - credentials: 'include', - }); - const res = await response.json(); - const timetables = await Promise.all( - res.data.timetables.map((timetable: TimetableDTO) => parseTimetableDTO(timetable, year)), - ); - // Unpack timetables based on key - const timetableMap: DisplayTimetablesMap = {}; - - timetables.forEach(({ mapKey, timetable }) => { - if (!timetableMap[mapKey]) { - timetableMap[mapKey] = []; - } - timetableMap[mapKey].push(timetable); - }); - - const userResponse = { ...res.data, timetables: structuredClone(timetableMap) }; - setUser(userResponse); - - // Check current term exists. If not, create default timetable for this term - // NOTE: This is AFTER setting the timetableMap for user.timetable. By doing this, we allow the runSync - // function to pick up that there's a difference, and sync the default timetable with the backend. - if (!Object.keys(timetableMap).includes(term)) { - timetableMap[term] = createDefaultTimetable(res.data.userID); - } - setDisplayTimetables({ ...timetableMap }); - - Object.keys(timetableMap).forEach(() => { - if (timetableMap[term].every((t) => !t.isPrimary)) timetableMap[term][0].isPrimary = true; - }); - - // TODO: check if this conditional is necessary - if (timetableMap[term] && timetableMap[term][0]) { - const { selectedCourses, selectedClasses, createdEvents, assignedColors } = timetableMap[term][0]; - setSelectedCourses(selectedCourses); - setSelectedClasses(selectedClasses); - setCreatedEvents(createdEvents); - setAssignedColors(assignedColors); - setSelectedTimetable(0); - } - } catch (error) { - console.log(error); - } - }; - - const getGroups = async (userID: string) => { - try { - const res = await fetch(`${API_URL.server}/user/group/${userID}`, { - method: 'GET', - headers: { - Accept: 'application/json', - 'Content-Type': 'application/json', - }, - credentials: 'include', - }); - if (res.status !== 200) throw new NetworkError("Couldn't get response"); - const jsonData = await res.json(); - const groups = jsonData.data.groups; - setGroups(groups); - setSelectedGroupIndex(groups.length === 0 ? -1 : 0); - } catch (error) { - throw new NetworkError(`Couldn't get response cause encountered error: ${error}`); - } - }; - - const fetchUserInfo = (userID: string) => { - if (term !== 'T0') getUserInfo(userID); - getGroups(userID); - }; - - useEffect(() => { - const getZid = async () => { - try { - const response = await fetch(`${API_URL.server}/auth/user`, { - credentials: 'include', - }); - const userResponse = await response.text(); - if (userResponse !== '') { - const userID = JSON.parse(userResponse); - fetchUserInfo(userID); - } else { - setUser(undefinedUser); - console.log('user is not logged in'); - throw new NetworkError("Couldn't get response for user information!"); - } - } catch (error) { - console.log(error); - } - }; - getZid(); - }, [term]); - - const initialContext = useMemo( - () => ({ - user, - setUser, - groups, - setGroups, - fetchUserInfo, - selectedGroupIndex, - setSelectedGroupIndex, - groupsSidebarCollapsed, - setGroupsSidebarCollapsed, - }), - [user, groups, selectedGroupIndex, groupsSidebarCollapsed], - ); - - return {children}; -}; - -export default UserContextProvider; diff --git a/client/src/index.tsx b/client/src/index.tsx index ec3b11717..0b6291eca 100644 --- a/client/src/index.tsx +++ b/client/src/index.tsx @@ -14,7 +14,6 @@ import EventShareModal from './components/EventShareModal'; import LandingPage from './components/landingPage/LandingPage'; import AppContextProvider from './context/AppContext'; import CourseContextProvider from './context/CourseContext'; -import UserContextProvider from './context/UserContext'; import * as swRegistration from './serviceWorkerRegistration'; Sentry.init({ @@ -30,24 +29,22 @@ const Root: React.FC = () => { - - - - {hasVisited ? ( - } path="/"> - } /> - - ) : ( - } path="/" /> - )} - - - + + + {hasVisited ? ( + } path="/"> + } /> + + ) : ( + } path="/" /> + )} + + diff --git a/client/src/interfaces/Group.ts b/client/src/interfaces/Group.ts deleted file mode 100644 index 0fcba6d00..000000000 --- a/client/src/interfaces/Group.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { User } from '../components/sidebar/UserAccount'; -import { TimetableData } from './Periods'; - -export enum Privacy { - PRIVATE = 'PRIVATE', - PUBLIC = 'PUBLIC', -} - -export interface Group { - id: string; - name: string; - description: string; - visibility: Privacy; - timetables: TimetableData[]; - members: User[]; - groupAdmins: User[]; - imageURL: string; -} diff --git a/client/src/interfaces/Periods.ts b/client/src/interfaces/Periods.ts index d051a4b5b..d01847b67 100644 --- a/client/src/interfaces/Periods.ts +++ b/client/src/interfaces/Periods.ts @@ -1,6 +1,3 @@ -import { User } from '../components/sidebar/UserAccount'; -import { Group } from './Group'; - export type CourseCode = string; export type Activity = string; export type InInventory = null; @@ -105,8 +102,6 @@ export interface TimetableDTO { selectedCourses: string[]; selectedClasses: ScrapedClassDTO[]; createdEvents: EventDTO[]; - user: User[]; - groups: Group[]; mapKey: string; } diff --git a/client/src/utils/syncTimetables.ts b/client/src/utils/syncTimetables.ts deleted file mode 100644 index eb25c4db7..000000000 --- a/client/src/utils/syncTimetables.ts +++ /dev/null @@ -1,309 +0,0 @@ -import { v4 as uuidv4 } from 'uuid'; - -import { API_URL } from '../api/config'; -import getCourseInfo from '../api/getCourseInfo'; -import { User } from '../components/sidebar/UserAccount'; -import useColorMapper from '../hooks/useColorMapper'; -import { - ClassData, - CourseData, - CreatedEvents, - DisplayTimetablesMap, - EventPeriod, - ScrapedClassDTO, - SelectedClasses, - TimetableData, - TimetableDTO, -} from '../interfaces/Periods'; - -interface DiffID { - delete: Set; - update: Set; - add: Set; -} - -let timeoutID: NodeJS.Timeout; - -const convertClassToDTO = (selectedClasses: SelectedClasses) => { - const courseCodes = Object.keys(selectedClasses); - - const res = courseCodes.map((courseCode) => { - const activityNames = Object.keys(selectedClasses[courseCode]); - return activityNames.map((activity) => { - const activityData = selectedClasses[courseCode][activity]; - if (activityData) { - const { id, classNo, year, term, courseCode, activity } = activityData; - return { id, classNo: String(classNo), year, term, courseCode, activity }; - } else { - // if activityData === null, then it is in inventory. - return { id: uuidv4(), classNo: '', year: '', term: '', courseCode, activity }; - } - }); - }); - - return res.reduce((prev, curr) => prev.concat(curr), []); - - // const a = Object.values(selectedClasses); - // const b = a.map((c) => { - // const d = Object.values(c); - - // return d.map((c2) => { - // const { id, classNo, year, term, courseCode, activity } = c2 as ClassData; - // return { id, classNo: String(classNo), year, term, courseCode, activity }; - // }); - // }); - - // return b.reduce((prev, curr) => prev.concat(curr), []); -}; - -const convertEventToDTO = (createdEvents: CreatedEvents, timetableId?: string) => { - return Object.values(createdEvents).map((period) => { - const { subtype, event, time } = period; - - const eventDTO = { - id: event.id, - name: event.name, - location: event.location, - description: event.description, - colour: event.color, - day: Number(time.day), - start: Number(time.start), - end: Number(time.end), - subtype: subtype, - }; - - return { - ...eventDTO, - ...(timetableId && { timetableId }), - }; - }); -}; - -const convertTimetableToDTO = (timetable: TimetableData) => { - return { - ...timetable, - selectedCourses: timetable.selectedCourses.map((t) => t.code), - selectedClasses: convertClassToDTO(timetable.selectedClasses), - createdEvents: convertEventToDTO(timetable.createdEvents, timetable.id), - }; -}; - -// DATABASE TO FRONTEND PARSING of a timetable. TODO: change type later -const parseTimetableDTO = async (timetableDTO: TimetableDTO, currentYear: string) => { - // First, recover course information from course info API - const courseInfo: CourseData[] = await Promise.all( - timetableDTO.selectedCourses.map((code: string) => { - // TODO: populate with year and term dynamically (is convert to local timezone is a setting to recover) - return getCourseInfo(timetableDTO.mapKey.slice(0, 2), code, currentYear, true); - }), - ); - - // Next, reverse the selected classes info from class data - const classDataMap: Record = {}; // k (course code): v (ClassData[]) - courseInfo.forEach((course) => { - classDataMap[course.code] = Object.values(course.activities).reduce((prev, curr) => prev.concat(curr), []); - }); - - const selectedClasses: SelectedClasses = {}; - timetableDTO.selectedClasses.forEach((scrapedClassDTO: ScrapedClassDTO) => { - const classID = scrapedClassDTO.classID; - - const courseCode: string = scrapedClassDTO.courseCode; - - if (!selectedClasses[courseCode]) { - selectedClasses[courseCode] = {}; - } - - selectedClasses[courseCode][scrapedClassDTO.activity] = - classDataMap[courseCode].find((clz) => clz.classNo === classID) || null; - }); - - // Finally, reverse created events - const eventsList: EventPeriod[] = timetableDTO.createdEvents.map((eventDTO: any) => { - return { - type: 'event', - subtype: eventDTO.subtype, - time: { - day: eventDTO.day, - start: eventDTO.start, - end: eventDTO.end, - }, - event: { - id: eventDTO.id, - name: eventDTO.name, - location: eventDTO.location, - description: eventDTO.description || '', - color: eventDTO.colour, - }, - }; - }); - const createdEvents = eventsList.reduce((prev: CreatedEvents, curr) => { - const id = curr.event.id; - prev[id] = curr; - return prev; - }, {}); - - const parsedTimetable: TimetableData = { - id: timetableDTO.id, - name: timetableDTO.name, - isPrimary: timetableDTO.isPrimary, - selectedCourses: courseInfo, - selectedClasses: selectedClasses, - createdEvents: createdEvents, - assignedColors: useColorMapper(timetableDTO.selectedCourses, {}), - }; - - return { mapKey: timetableDTO.mapKey, timetable: parsedTimetable }; -}; - -export const syncAddTimetable = async (userId: string, newTimetable: TimetableData, term: string) => { - try { - if (!userId) { - console.log('User is not logged in'); - return; - } - const { selectedCourses, selectedClasses, createdEvents, name } = newTimetable; - const res = await fetch(`${API_URL.server}/user/timetable`, { - method: 'POST', - headers: { - Accept: 'application/json', - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - userId, - selectedCourses: selectedCourses.map((t) => t.code), - selectedClasses: convertClassToDTO(selectedClasses), - createdEvents: convertEventToDTO(createdEvents), - name, - mapKey: term, - }), - credentials: 'include', - }); - - const json = await res.json(); - return json.data; // This is the new ID of timetable - } catch (e) { - console.log(e); - } -}; - -const syncDeleteTimetable = async (timetableId: string) => { - try { - await fetch(`${API_URL.server}/user/timetable/${timetableId}`, { - method: 'DELETE', - headers: { - Accept: 'application/json', - 'Content-Type': 'application/json', - }, - credentials: 'include', - }); - } catch (e) { - console.log(e); - } -}; - -const syncEditTimetable = async (userId: string, editedTimetable: TimetableData) => { - try { - if (!userId) { - console.log('User is not logged in'); - return; - } - - await fetch(`${API_URL.server}/user/timetable`, { - method: 'PUT', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - userId: userId, - timetable: convertTimetableToDTO(editedTimetable), - }), - credentials: 'include', - }); - } catch (e) { - console.log(e); - } -}; - -/** - * Between two term timetables - find new timetables, deleted timetables, and updated timetable ids - */ -const getTimetableDiffs = (oldTimetables: TimetableData[], newTimetables: TimetableData[]) => { - const diffIds: DiffID = { - delete: new Set(), - update: new Set(), - add: new Set(), - }; - - const oldIds = new Set(oldTimetables.map((t) => t.id)); - const newIds = new Set(newTimetables.map((t) => t.id)); - - diffIds.delete = oldIds.difference(newIds); - diffIds.add = newIds.difference(oldIds); - - oldIds.intersection(newIds).forEach((id) => { - const oldTarget = oldTimetables.find((t) => t.id === id); - const newTarget = newTimetables.find((t) => t.id === id); - - if (JSON.stringify(oldTarget) !== JSON.stringify(newTarget)) { - diffIds.update.add(id); - } - }); - - return diffIds; -}; - -const updateTimetableDiffs = async ( - zid: string, - newTimetables: TimetableData[], - diffIds: DiffID, - term: string, -): Promise => { - diffIds.delete.forEach((id) => { - syncDeleteTimetable(id); - }); - - return Promise.all( - newTimetables.map(async (t) => { - if (diffIds.add.has(t.id)) { - const newId = await syncAddTimetable(zid, t, term); - return { ...t, id: newId }; - } else if (diffIds.update.has(t.id)) { - syncEditTimetable(zid, t); - } - return { ...t }; - }), - ); -}; - -const runSync = ( - user: User, - setUser: (user: User) => void, - newMap: DisplayTimetablesMap, - setMap: (m: DisplayTimetablesMap) => void, -) => { - clearTimeout(timeoutID); - timeoutID = setTimeout(async () => { - const oldMap = { ...user.timetables }; - const trueMap: DisplayTimetablesMap = {}; - - if (JSON.stringify(oldMap) === JSON.stringify(newMap)) { - return; - } - - for (const key of Object.keys(newMap)) { - const oldTimetables = oldMap[key] || []; - const newTimetables = newMap[key]; - - const diffs = getTimetableDiffs(oldTimetables, newTimetables); - - trueMap[key] = await updateTimetableDiffs(user.userID, newTimetables, diffs, key); - } - - // Save to user timetable - setMap(trueMap); - setUser({ ...user, timetables: structuredClone(trueMap) }); - }, 5000); -}; - -export { parseTimetableDTO, runSync }; From 50df370ea1d7786b424e26fc4d69c44ed09e309b Mon Sep 17 00:00:00 2001 From: Lucas Date: Thu, 31 Jul 2025 19:24:15 +1000 Subject: [PATCH 13/33] Add authentication guard and login modal (#1039) * Add authentication guard and login modal * Fix login redirect * Fix casing on pathname of png --- client/src/assets/notanglesWithBg.png | Bin 0 -> 443669 bytes .../landingPage/HeroSection/HeroSection.tsx | 21 ++-- .../components/landingPage/LandingPage.tsx | 56 ++++++---- client/src/components/login/AuthGuard.tsx | 11 ++ client/src/components/login/AuthModal.tsx | 104 ++++++++++++++++++ .../components/pageLoading/PageLoading.tsx | 33 ++++++ client/src/hooks/useAuth.tsx | 39 +++++++ client/src/index.tsx | 52 +++++---- client/src/interfaces/User.ts | 6 + server/package.json | 2 +- server/src/auth/auth.controller.ts | 7 +- 11 files changed, 278 insertions(+), 53 deletions(-) create mode 100644 client/src/assets/notanglesWithBg.png create mode 100644 client/src/components/login/AuthGuard.tsx create mode 100644 client/src/components/login/AuthModal.tsx create mode 100644 client/src/components/pageLoading/PageLoading.tsx create mode 100644 client/src/hooks/useAuth.tsx create mode 100644 client/src/interfaces/User.ts diff --git a/client/src/assets/notanglesWithBg.png b/client/src/assets/notanglesWithBg.png new file mode 100644 index 0000000000000000000000000000000000000000..85bf6dbb262e0c21856b6bb838dceebcc72e46f6 GIT binary patch literal 443669 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 z z!FhQ)nikl?)%>D&7`$2ynZ7kQnCqZ9Q@YRKZg}M5pKdKTF?{2~#E{g|OdEzRv&N<7 z<-xxs4Lq`VT@F7d+^^83N_kc-kiV9j!yf6cT~=9lvC{CVGDuOR#B5u)9q6)9aQn2# z93}@`U=g*OC~*$orF8&P-@u-mYyWpZLBckh?-xBOxKyh5B_>dn>hG2>jMBsy@j>uf}~y!-;tSdE-uJn8BBi&fABV+Gi;Zl&sVb0-Z+1A}#n$!&;`v ziNf?Jj^5Kofh|207Av!_jVVY>MfNOuIUh@Nb!a+|Rr9W0tjgLxFh?0+5TfCX{_?~_DcA9?R+z_I!9;-1*J}&W1w2YIsBRQ=_3uN$c2h@kIjc*E{D0o6|E6Bvo)9PD$Xn>7=}g^_gvi)!zQ8zMYlaU4 zN03)Mpn=HfEE~}mS8V!d%BA|X>ESJK8uT2EEXD6=_+5M0@{pj{v+I!GlDl&_9%Rf^ zzWk%*bpOpxF z%a!pMKdq6p9GV~X5N;zcVfehdf4^aoJ|3q+;xbl9NB8P4Ubx!r6_MCVH`8!3`4LbC z02oT)R74P|@}wx5kVZ}_|3^aB8hn)+;`&f$pmV+4A{SO*`I*dKh;7%0CemX<(&BdF zU`0#{LuF2MZ}3*^8P8!p0AmnJR8#S#3{;?SD1Zk(37I-c(>!dTL(wWR>@;WlYGQTxVKfY1EEE&B0w3*NqPq0@h;;%Gein%7T5fe;E;q zerJXr2Z^W$EY4mZ$-1vh*>C63IIZ%VwOgpsU)4C_&{xZb64Gaxc0cLF!>+!GDH8l+ zt7*W4IZ%BPMYpXc|9Ps;I3jkRUAtII+_MD*3#e52E;P~_0q0PTcTbdaV*-?zw&`gw z0NK|}Q%z2KXylQ$J{MRDL8H$;@5uhq&Xah?fe0Aj?jGdw8->x)FuA>38FE@xP*{0t z9dGBCmm=PFHSGXuS!CT@{zaSWA4QwftrQcMd2!)U0DSoZWYD%s^a)&~lUeMdz`es2CB zUn(|ZlP8<$P`g)DTuG zf1cs;khwWYfbS{Iq4Ze$COfqL=dXk`ZK{6wJLUECBH9qF&>GL6oyz)aBO*#ci%G}O{Q~nJ<1a!l*3Hkj8;&zx z5w*+%*a}SXy~l}UEa>rT^8$M=B0T;X6oT>?vgqZ*CkWA_J1?+O(%b$Y^Gh^}^j3$b z&?xNo<#7A%mGplut?2)KAGa>irX~vwIA!k$Wf|<*2gy^lFR`d5AU)oasaT2NFd0mfwyetSo%iqZ{+0e1!I;IXzW{BH=MSX0e99a>A zjK;CM`*k2zMZCJlzB8I`t)Srd_l2`J+hHaacqs+` zO+7f%0-=Xit1C?+0o>Rj^`%q#dns_(r^>(WWC&IC1CVo8~9h+0J|fxMcE^L5wOei3ImFYcW7!4-qm zIq>a3c9*%Q;PV67#nzSQ^mB-5vAZTctSNjn`=0_c>%D4GVpPtt`w{oOb66=##>#J) zJhr=E;CA`jfwR=`qc=U1H}ik&fosT1O_IM#qbO^v3=6>Ah5-)SzC{LtfyA*A-q6QTNjP`VVLrE zmRi9yWZ9kcl~V&nmS`Phq)_o~Rs-?m@H7oW;5-YPYEy4qg!CjE;(8`8hxc>3bM~*B zl0Kep`+V+kjcDjQ`fYGY;^^qf^?sa!F=;+p#`MLb8 zK!-i}iL35abk1Dvet3ukZL-vF?TTnUHv>VLHDzI}jwy+l7Am`wG&$G9W25f%= zFCH}jp8+a9tUUPzPpo+?uoqt%zw*a4-K;bZCPc$q%G+t{(~C5&-*003kz$YuEm+dM|Edpl ziGhEw#;c$wi3REAoP$0>Ao=v(;8La+tVW;O2i;hHSogItVqy!A+q773#jFX9srm}V zSszK1Rc4y;2w5O3?dckvMA8F?N z`$J#!vqiH&Yh16j&AQiC=hVfm^Zv#|MBPQQzaXHxj|#5gx-r6}wHXvVJSp~jcXAbT z3$ZFbc0WnCi(~MJF`ICiVT12DhKBMFFaQ10?V(S0|%QN?aNunb@f+iWePkf~9h^5Kt!>ikQe}TkRbFK*u zthAO%$h1kTs?yq3JCe8$z?8;j8WcPf=cuPzkJ_vv0J6qgA`{QhQp`uI#&lJPl zY+yA0dIO&rb&OeXhl$MKOrATd>&P7PB+3!7 z{;b3$7K5gDJ*!G?PXzoeE@-Kx>2H$Cd;ip@b{Mim&p9?Z+(l# zG{iEAWXQ6fd}7jxb*D~%U?t7i{&JN%hh~23K=ox>ES~wS0eN&uPfu?KR(miD*yOI) z9RPEBt5tDFg%Lma?lB?=n4u=4Cf8)LIcCzMUrr2^BOPIJfW*bu^r%c=ud-jb-jW4lJ4vA?@4q zn{nmz52z1Q8Rjk^C#RG@Fuog?Z!fwnLIEowtQF{?(qQG>`B?73*p% zblS?_GfXYz3!#EJfHA(4ck&{2s!gWh_~pc2%bltQg=h5sMbaGdv}&Lht*;S zMqlpP3nrfn?akZJnF!VH#@WS4K`K0;v2A+Tv>j}_wNK%*e-w_08~>Rq)V7D9+o6(= zpGw{$r4%Azx)r&+!{$MwN9FDEPH2!}Ep2D_OA1sg(BnGmEf@Znl)rX-kZX)kkujV{ogucu4meo;uSSvIQ>yYq(RhQpQiXh!65oPFe<@8Q`q`c19 z0*qOnyO0Zh9RqlcFeiHdzQ|YyB6Ui8PRrxPH`-4OTQW)xh3rqnF7%|_>srZkI2j-f_|IPe{KVUVgFW72$>ZfGbwkN3Br?=c0} zIB68~%XYWr%_3|9s0<7v^>D)_n1IUt&fj*jYeRkSM}&`Z4(5fL3!Ur!1<}3ryJX`5Xdr^5Yf!zjj}kt^6%p5(nt*0Ac8Mu7zP`iDB210Ec} z3ZcnC8V5v&fy?9ft@|MrlH8d)67`$wF-3(A#Fl79(aCp^&1G#=9KdlL2zm+^W${fxiCa6Y?n_iP^m0gw_B8TUwyR}fOpU}`_>8&#ocQVSCXB`#O}#jL*O#J6;jm!+PR&Eg*4svy zGINm|NE*CI-@F7DoB~ayqHSsC#NjPRHS$&wE48cz0 zDOGQZc`o~IOz0 z#@ngBHl8uc`t6v;Y0HQuZ=!`2xOCsUylc-lfa+Ru%6ooPzB5;;by^~?JkgdfT1DM> zw#?3T(fP=&bXw5yBxQr%<@tZ}INnOnD5f9l;))qL(~#e5fbD zdJWr7E6iiAX&uJ#OcP|rDHxvfuldLJzqLVN6>9#4k4=8u-1WW+q)BiC#LfB=T&8jO zmm>Nb>&k-7qlZH4pZm0fd5szBqOHJp8gEHMt>&)M$~(fzU3IRkXgFzpQe*FeUkxuW z*9E$ZfUW1ESfV!L<6rCLXZ^UjOU6EC<7{h#;>9Z8hSSzR!`%9hy91xW+t-kCw!&?= z4N?YMX1kaF$iIsMAQKDOQ~-Q3yUVevp9bFGjTkd6&8Zxn-&w}A?HGto4cHju`pb0; zMcz{z<}OOpPc>9&Cy5`HGu5N|xIL9olBWo@F!Wn|t&l%TyR7)Zlt)Z><(C{_HXL4n zINv<&d?hk_5^yShy4!fcu{rjQl_lqoc&LgCM4+ z7AYw%$}imgN4Co(DmJaewM^{rPCW!@i^kZKpPDBtU5#Q}knl9&=AfeED)eZIFe_9r z>f<|KB~`P@teF)-xT;_|@Qxx5L*u3eK|(9C5F(2EZ+PKzqgs-}{G; zPqkrv#T+ZP*GXcKiUME*O$~o+&z4K*rg^)0>gF#S{}duxR|f1;6uc7;p=H)_=ef$-p+ zztmg6aG{D9nF$-xc-H&8Fcu?V)=Dq%by1Wms%i3reG&%W67+5N6DdS6RBr8YL)I>> zYd86ZayebrIQdxHEEoQB+1r3|&kh7D*Z5nr{;y#bSl+M8ag2A89u$E^x`eh z8)^ey8_FYz5j(}-RuwBMy$DcZri{M=2kH=9H^V53vl0hN)U?SDBQ8A_=4#nnQe>3? z2xZw$k%$bLdVBwj9TRsSo`9;Jv~d{3Sy<)ycE|`AlSpQ9r~zXSuvZ{Mcy*HJPHM=9 zf}$O;Igah&t>eXvif0odsKYeOH0i}cnD_n|DRc@tyZdOorwLpTcB_a=IZhK0@9eqHgVbI~Z{b)pO^NL=lG_kCvvJ&h}10F0oC{#n*v4Xf3-X9+; zd8*O>*t-rwnovE)wil4HE|NU=+$AYzdBus>e9_IF**_)H-XMB&oVDcslHjH=zkI4T z(?e0G9b3E{a%AshElJkn&bVU`@UvT@v>S}Q=5KIv!!}i%v;DB4-J#uID z9I9-cWU&X@x|q~J)p*{Cs9QJ2Si-1tb2Sl|@$cjbzd1A`y_V#aAP@5!UaDH;_8M4k z5zm6x7S#a66J4{eW3Fz6c3Q77$VAzBATV(?)AguI|KEY?|B?%uGFgy5%5MyLkD6j6 zcpln-pHewJWmOWG>%*WZjJ@S)e{eM{UiD*3>a1gee7Yk`n-b*&y=6?VvpRfLvLLx( zXO^m?v&6^WIRNQt61?HOL3EDz%ew{oVgYrH;3NX~)Cky?Gbs5KVlKx$;43S1FBu+e zjfz;E-@+c>qJ(d02L3ja>Q*f-i^5wrTf}y?D)u&~f7GI4vM)}tJ5D@~v#G6+tK>_tbY7=bp@bhDvRQP+2T5G5Ll^X!Y5?vF}LsOe9xua{9(OE-I z{ydW`7`rT>wQ}S{{q%JwXWV?sk6@wLb*8ck5Ea~MoyX^zLjDd9d$&q)s2Ho{@)xl-`5oZ(dM?abX@2o$ z9_eB2?C9Aw&B%$5Ls9^eUf}eYQ}OLcz`FFX{z!2^+~(MKT&N8(YWy9CdBo?*l~TQ_ zV#4>K&8qW(Dw`wSft>EjUE7PpRu<})#^=$fsHJ>A4K6(EvwzJd|9fZMt7}-MaLxW+ z2_Zybk$VoPs2(R*s*bnF62$?8YF;#Uzh>^pMG_C^^&Y@BLG4%2ws7n ze}lg|y1^&S(2()yX>d|hCnO=k7+_+k<11J&%dR=x78~#*1FG?9N?g8s?4AvU>g~=_wy1o3V_xbt40Fe+1g|hg}--1Q+S-wfi z#)1lpIzWMd8m@XJaWa^NNmAf!!AD5!`;MV}nQ1J0_YV>Y`3HI&jv>H#?G9GfTca{q zEy+8JD(_{brD+p|QXfTdnuGhMu>q@gbr--1l0hvR3M~jb%Ga`{-cj-U+5Xj;NVE;n z-Xxe96t5n`Sh;MJLqV?ak%x>SG!R{I3K+T`&Q>T`u(^Kb)70waU?Z}(`0z$Z=a%ng zi>54ljhQHPeFxus;0HNbVhg|ZoQ^%D#xnOUJu`D}5DlpoCnwlQfG}D5&g4ge z)zoGU8Pks3Feb67+Soj_RHhLUHKgUfez|mvgJ9Cw!UT)44F91N$G9hg+4DVgQM&hi zHiG?tC|kTt?Cb@S9kbMREAt!_rSsNJeWd(J5fRJiYrXm!kxy5D3+{TK^{&-~mM&>9SNutLZ*u|K&EbG6? zhw@JFNFHZ-Qe4maN5&X5^!Mq^~ zZkBXexElTZf$R@`t(|&9wF$gu&@2uERE`sX?SPfUmzVn;2r40iY@VYyUMZ-p#*{a( ztuihkU5nH0>GN5wBonfU2fim1Ma#|i2Vz?L6q$TZH4*pmNpRl!Ui}eT06R5emoI^l zUY|35nLZl3()NuF*&@99Xe8)>18CK01A;Xh^#{NHx(b|u47N2a+1km;$yqbR!oFeP zS1={gs<3fKx6bIIPeYvA6H3NK*Ga!CoX^h|90i1>1ctk8*h5ko?RgB+&P>SFy?yH! zdHpL_zATnD<=ceKZ_+>CpS1SKXm+>x09STp+`QOQ-+G@MK!T-TW`Nq4{?@=DF^BBtPAEs6U_IIHbt1-5~c zWSIX`qs753)bGbw8}S(hkf{t1QF;VGe$9VqZhmd877wh0FEM}Ln-)J-&8~5s%0e1Z zWE8hI+04fri-}hLM(6L=h>Gq6ks8-%Uq16dOGVh4veK@i-yO$Wwb%9PSK9r9$XmSm zKf42(cbn6gyf%@G|T~EKR zU!uN3wp$Dl^Aj`;em}s=rn2qs^K&%0u%rwsyEFRs5g8mnfqcYSf0cD1=~eQ&4wNF7 z@*GCZw5OULPiDOUdN4oN4-a2rh~AEiRHhXhe;Civz5VRe11VKjR>4Jpt=2nUY1R-B z-DI{ncj?IY?*2)Bv0)-Gmux@0X*-lyP=IJ3(W1$blCdBj) zEERZRjT`1^{(+R~qvrKf5X@Dc>+3`z;uz{HwBP3T%(4i?j3Q|qb zV>fdew%D;kM88h(N%Q?i1IO!43wvUaF->O!yb+1K9#l4Z5w$8I6*pjGEH2pQjqrH0 z_2T2-$Tgk+soNnD?tcZNTpYghYS`HU!L$3mfy3$xh(uxcoUi(D$!O3t7Sc`N@7zEEAO0$E?`|`2Ir$p|0T-mRo46Hp& z{OR-{WvF&(9OR+|!d2RVQYr_gXTNR+YxXpsF!h8VyPxg#f_wa$c({^=i38Osxu!yd z_$%5;0bs|PSwWZ6-}yw-ur{RfQS;+vt@JIdg$$cCyRAd8!B)4r_~bp0bC}Y6R^1bs zjGHp??X%C4r<$hgn%x;z(Vg_C={v(L&wT@51P$4w7+~$1pXMi^R_j0#@A7t58%)MS z5|U>lD`{*Jl^B$`wkZD8y6vRE~fe0`k8RM9Gur-|3Yt==cEE;U4NfOUpljqX+jHpQlj#7sVSjCK- zn}WYFDVBk(s3e`en}ZMnygqB)k(QL>uT4+udd!W^6s|p^&U3T19_s){R1DsRFP07% z??(dvJpcwXK7MH*sO&5@KfEz{F^wZqBsY8aQ1J2dGG zs@(3yyZI;aFj_mtZ+!S;7m+3t`gJk}Z=MfJv)zLRlc+a)pqUEl<`dq#_{fpw4BdQj zb5N8e=(3AF;Sc4^ygiU5v>bN?FCm##OEs~QBqJPG#InR7A*`N(->%{Hn9V2`!DTzw z<)^H6e)yPF0XqYq4Kfx?mSwUjC#7`b>4^bKIoMa~cE8kn*jutK`Q}3FQ|ek1zf66b zN1s0M*-m)U0++(-8w1jMJ}UTL8-g&zg+q5|J80jWLH^P_-O!`uN(au?BPp>mF6(2C84KK4C`LY!%(}dA@~2>PwqWM0codh9p%7+( zxe8-c83QjY+JBHZ?%d;8s-E-A(8*J2xgzes>D(XYgyA=#`orGAoBe6+G-X>2xHI@( zzJ$1&Cd=e|XGjF+C+*e{;kOkcerXM!@K9!ve)ZbYr#O6&M5lVWmy$-dWDR zC8>#crbn|Jzu8JX5$|H~XicFiGswyK=PR_qAK3`E%E=J7%89p~?xY9>9I}FWcKX

    TKt%_mw4Y#C$p`~@l;{(jT;VTq&*ZkQ}lp9z$<`GwCz8#dwk zA6xuq8IrLEckvtseIo;Qs!zHx3_9$e8Onx_&>V!NE$l#loZ2jAKleo%dHwPDjL9GL zzu@1({~S<4M?aLCRFWQS9H|RF0>kVcB+D$345sQYtZaYdi5OTBX48<*)2)MEORE$P z5`&Eu@sj#(!?z+`N*Xl(KzU0U-jX79#nIw&aee2n4!Y%N=K}IE78+X3!YSemHPpI3GQgk3iEppJL4!G^tqX~r? zJ^1Jd`=pm0UXJi_QY@an$9_rFAM3e&o^TQeSn4?RYBl{IYz%d;6U1HPdSA)P##vfh zv(qV`asjyb6JjtBP&q<|0&!%A5)+cz8oF&Nxr>5>_4(YYhg0;j^EkWhfNOzWJGLn) z-Glg>wtm7Fnu0z@P7RzH71&i#@VC@cCL#9iv17owhi&dIUwKWbVl0tfY6sQJq-l@3 z0^3=V25uj9K;#M_Iq?(LPX4<8qj!*nhPl}k5}>sPSGwk&!W>ae>EUChl=L8kUVD3S1Gv+_Wm#o|Ei^iZEvoa*^BoTYUS=rsfd6)(4|&H98N{ zlWA!icKmw?f-#I00g*-hX)ao_Q%@cv`!;J|ygdLvS67_yU1XbQCpI1CN}4@j>ZPJF}?((X-;dnz}ui>4&#u{COn^+vYvZ zgs;@bcc2OtLFMIACe^NFT6YFmj}69l9yp?RrBt8LJo7OtxdWyw2@iR&kxL`v5&t~2 zog(QKLo}?zFgrKA!*p$qqqMbUX4tA1vK7OCYR11kS zO)(+;3=;&D0awhuM#cOWKz-Nr5r_&^USQ)qB(F!3uO=-_+RS88jKX$J<2(!%%}b^% z{qvh`6`MI|45#(;)CwcneSNB|t6hWed9 zbQ3c)J(dT&I0rU+gEU75r5~q$9FXG95LmZ1K1MYENiE59X(~Yv*u9g7MEJ1gCfl>+ zZFP>fJW#V?7o;BjOk6iV%(BrG@H{nwNG<$pCHTLBxtV6}glklf#;A3yv}yUMd}H`P z7FRo=Yh7#z8VN~Cp4!9n>TwDhH^hhg&Ke{(X9=V>BPm}|d2j(FHu0JKOZSkV*T=x~!x@)Nwx2X=UX$Egc=e*P2Nm7k&FhEpSM~@3*d{dJx;Otf)Tc zAk4r{*do=RV3#jU?GC`IY?~}&438a;5HZbX!fkN8ZJWK}@l!b-kO}1R*66~*wbCP! z%K@iZ`r;g<%su&O?-7Fs*RFtDO1QtHt07b;TYS(RrC;_l8s;}XK|G#a z?3~>mU1BqJvirGNCztY$t*r&tf>Vnlvjp}=Cf|bN6mDgpWycF_d}Eu<&J&U=_ZKUWzo&fUPAels zd+moFkylXE|I1_I`EL`hl9xc-r6TJ3EN3!<4(}xt?hg@ra;@c{MF`3xx1t1^BCQ2O{qis>F(1U((&aR0gH%@^5qHr$8hEu@;u^qsk?nurN` zL_OZMf74Rd>FQGNeBiUpMVB<`NK##812egT3CGu*88JP2$&Wlo=T|GJ9^&)&>9>C_ zQUk)t%tZB_!`y(q`l^fb%9+EhS)d<|Wg;RdVvm*P9d0l>u<+b*UNFeQh&|Js>%p>y zSbV_ihiQW@rn?E}BZ9ude^`rF4(;Bxco?DVWmDU3zq)>}IKnoD1+qj>c+;Sc-NOHle=qTeT*+XgK9}*&L?UAPE8&Rsup?6zPTA_V~ zCHGBK!&16^n9Z$1QBD&@8ET{Zsj5cHtH<`V1b>Rf*(VhU&6>I&_75gLgCT*W65(i) zmJEAcrwYF8@e+Gq=Bc;C8A`~T@7DE2a9cxiXyUhuLk3AY5Y1t&lEUUq`UoAR_IqZ2 z)=*^FeT7zco2xSQgk0y13O}F=E$C5l*Bly=Rt=Sfn?sNA!1rQ4fE=yg*NtP#%Q%ko1RT>Y&Qq8|mHFD~A-$dU}* zcJC$>lO>~%^F5NY2WiJ1B$r{F2PF+n@*0EtV1@xP&Al{;{z&t}e^-~0{|!+$W-{f$ zVzk$eEnT+A30zLKbdPJ|~GIpzy zBC)%x|ISNxC)CH)={;Jo#MQ6S74sED3YPKMXjn3Fxg`6%OMc1w1Lq~z=zPvRDt>hJ zb7r-@{MoKm*>d~~P5ET}=L5iN4|FhD0i+OPV`Fb(bLDIh#bhXR{gSr#)O+Ua7(G{- zAbpgXGRw^3XU?M!;>QIS&`QWB%_f73g%p+5;!^?eAa{x>i6m2A|4}Gc1S9E2ScI2= z6BX1=p{(I)V$53kid%MpR5V3k{x2#5EAsf0{b4Ewbw&ATGwH{?AX?VV^+RX+d%QTP z!T61mHBgJdC_}M1GfbHjKIZ@ZO3TXgrdsVjCEu!fQ_@9acNk2T$YIM$e#w*s?ZW76 z#B*8tx2){=3M5cnUB4P+p?Y*Z<8s7^i7=ya*UOv!QoVt}K$rRh}C!uehnkU8Z%^6PKGa9&6@)a!?RTXxU^~>VGCfeT%|aXp|qU8{B$q<0wF* zs!Dwq50Xn_1l{VrIqkXqD0n|zklpL7y6syVP2TG8RHuz2t7sg89~P|Hn%Mo_>=O- zXx8{}E(m5s(MTk_iBvQ)75e@8-DC;8bqM@jc%Rh6c|jMyZpONz?N!Ed z9Uk^P?0O&UP$sdMx`nOSBd#7bC6-n7$< zosXJ}j%xW!1Y2I7mdnu!2aGrfC#a)lsJ%}+{qqVVoX^)ZKv@t|KM?xRct5L17`)EI zb`rF6#W(Y-<;@V#J=G#flJOKiSfm>b!8m=W_H=w=w=u-u)QJN6*HnN*D((kO@Mg1c z7qDFUL9Zq4In72>bDEk;@pUy)kHHUg)BEt;)L8{NX1qIivkuZDhanC~Q;@U+#-wds~K zg0(l*uF?6D`|5eEkKn|k+HgDBL8PgjOBXJVuRJUhu&GHPo=%n-A8KC%3 zs<`-D+>CF4wt7XcJu(ZvBe-6=iy4QY+ZoKZ6&re^3ZX9rXlgTl)ip$|`TGrQ z9_Zv0Qq#Sw$f_Lcm>s<-+}r&dq0k06nxqpfy}T$6CfsBucar|;{-$o9r2?1{C(7nS zO{!sJRH3}5^-}7AB*Q-S@!=O#B3etr1S67`=!l+G<&$}vr5)&Vr&uB>=eZ*40#i71xB#S& z9^Yl#M83&YSrN3%5a3L<_0LdO=f9Q%|FL>+mZWZX>%Qh>+b#_fQVsqYabtq!waL}} z5*|O_?4gs@&pkRUzuzj3zYBcN9u@`94Gh7W(y6e6NPb21q`u!GZjreb1HsLj0`sv1 zi#vFE0mmc4Nj^((Ql=fDR%C;5qS;G$AxtiUT{(;zNE2i^`Ceg_X|WPlqZX|+<}yC1 zxV!g9U-cr<+;xwCQs0S^YN?{>nS!fG?CL#lA3avJw)r@1*Mv0oq_O)JW5wI-x|~Q` zQjWHUpO)5kx&<5X-w}Dm-7E0j+Fio^tYQn-<>o7*`gl8~yn&j~_G_k0=;oTs@;$i8 zRP?iGG!9QP#4~F0|Es<<4}(*o{IM2~;+LHb;`h_%qg-h+82Y}|QE}mYqaIe>Z`?s# zTQZ@|?$EAheqE64ep4Z{8_uQ0IaoX>hT)8=xRo8(YDxu@>wl*z zN4>_&e(h#GgCx2r)@cAv#kcq40etT1IF#!fTu@Ss81GJeKlEfRdU59nJDiJ;B~PB9 zi&r%Aa4Zi3R$C+T?0cLlEr*ubnbyxm!bS|uc;VeAedp)kzlp!|Q^V8w##50Azs-cd zeYihg-T}s{7xaA<{pZij?XBQZ_V$IH3=TqC=X>cUq@;ocDh;nhL@^=P809)L0N=&nnyaj$Slx znJnLGe%5!b5OPJWTAVkf9_e56y{I_4fx_d3Cg~3ZYg79hkO{bocP)I?*z=6a_-R%4 zM?#*LNH|FWxQ>oca?_Uz1Sw<-?AlMPYnMZNimTzv4NR3nsYOp;f2}>@F)+oqI8>mA zd#8O1uT-WvU%9K^D{C@eG@P|_Ch(FYW4cdPuYn&;hZbqa2Ku}+?_yR_pRjg}G5zz!LF=9;?)J7dc|TK8=E046HJ_D-r9$wJaiQ+m z0wwuIvmxUk$G@51(@nnr1eN#XO01|D#}XfoL^uk5RhtA`XL1|OixWtMy!LD`sjBxa zw=EF{zw%K8`g3&IIW^U{@3*{2!pwX+1%kSfxqMpJs4-&>|Jen`UM07_kN~&UU%P4O zG%zW_rL|AnYw4;JcV3r#ik3}A@!=U1Js!ZQ^xUTM+}wYbjL2_ZnyRL$QHtw~9nI

    EYI{$ZnR-n_5dlE{h8hzHOieMwpdGd<}y^~S4ymEC(Q%p3v&q-FLu z)n(uGz3o(ty6n$}kK9?6rbRN+rZRM`+$W5}yAdhY@|>VMq8Es^R+5BnE{{izj53-+ z{N3iz=Ot;+8}{+vqih28eHsKJQ&4P$T6;a`xPb>W|DMTXlKOKb5)`ypQ2^0LOQ{Iber3rKNtzK?b zFxFzru^Al(f%Y^Pr*FD1j9eBaSm01693p6myIGqu_Rbt48*Q33bFf<4vo13_*^#!G z&S>c+w}MZ&nZnHLKzFFnO9~dap7Z_!^K{F)Xlwg|o%hr<(OD)m=+ye9SQI7lVDBDJ z=gd!>u9Dip>wB5Ei$sEuLUZ%g>6&joUecY-i5`uQR_sDMf%-H6hmpwy58(%mpacZ$T&jY#*<9YZK73@}I|T|=kub>GkLdH&n>e&XBk z<=oEeIM=b(zU~Hm(#*Fp2H*MD1-u;7`I_fC6FnR^k7(fZecs0;fH4R!9XD&8(R!&> zHM+5MMq?klTVy+k_C@|nP3-xvnq-t4&Ap}&yDzKeoi8z+(RF^OTV z9=C;1h+u{qp4;Ar9H;{`?sPp-c9H7p!o>i6J&2Ma`QYtatYMRA&H4&i0VNP~<6NgA zUbl=Aj_*v#wFD-mo15^_li;{Bv{Em+?G%EvKOl?B6pr&m1NrVTszZnB&_u@eRDfxki)a8}|_Q1n&@@QAA@aj#6 z@4+A#!Qs~&39?($+zXPED-6h{GkRga$qDexxnEPc8Af~fJ+I2+iyM7f-sHa5YPqR3 z>-*Qrf+y=jign99krCVVhMa$Za){%U3^oZm;;uZgFnlxno36Lx=|{=fvs?JUjR2eY z#AiF2vYUrXVO_MO0+;kYPC}<9k;Opzp+HK8W2hF-dO`l$A$DnAn%GGR&%aBkUaaK< zQ&Rk2_sB<8{~kCOxBm$UKJ>Fo0WMuufuq4}McuOH46@P54As%4$)rf0D(rTAs<#_VA$ ze!X)%f|V;be5((_Tw?Udi}MOum^>H*2qe1A?zm~KMZkM2pO z!vUwU!-M|RMdc368GAw%E-`t*Hz*FwOa%UMk78IQ6)@z@WIRz98m^qcTM^5xh6&gsvJBBjG6DGH0GSqZS6nM+vAC#xJwRgO4P)~zbb{;q!r z;vn#&sK?}t00)U~og{063+o}6Yq1bWm9g>&v;bmmR%?i9#;8zDGj(|6y*GB_Y7VT#Y&711UjW6RfTD7~+g^u9XBf!SPUbV60A&=nze{21| zQC7HEv02fWlCS37*13S43VON(LNw33G~X*44hRqb{O&&$uZ`{dt^Y!N0j9=;`#Mxabpiy9%ll-rTtH0M?(yw-ivUf{a$_>yplNAJL4XP2_b;(m(BXy5{JM0lCJ1fc>}DWh2i-Cn

    Start

    +

    + {loggedIn ? 'Goto Timetable' : 'Get Started'} +

    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ⅇQ7S@R!USOV>T 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 X%z63Sch`e3K?ImP;+Rp%$Yga> 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 z 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%0A+c{Bm%%58x)LU(v5KGtX`p+6R_{!& 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 O%FEs7AZh>EtN#Z%x^cGv literal 0 HcmV?d00001 diff --git a/client/src/components/landingPage/HeroSection/HeroSection.tsx b/client/src/components/landingPage/HeroSection/HeroSection.tsx index 1b9e8453a..04a2ac6ab 100644 --- a/client/src/components/landingPage/HeroSection/HeroSection.tsx +++ b/client/src/components/landingPage/HeroSection/HeroSection.tsx @@ -1,14 +1,19 @@ import { NavigateNext } from '@mui/icons-material'; - +import { useNavigate } from 'react-router-dom'; import notangles from '../../../assets/notangles_1.png'; import { FlipWords } from '../flip-words'; +import { useAuth } from '../../../hooks/useAuth'; -const handleStartClick = () => { - localStorage.setItem('visited', 'true'); - window.location.href = '/'; -}; +const HeroSection = ({ handleStartClick }: { handleStartClick: () => void }) => { + const { loggedIn } = useAuth(); + const navigate = useNavigate(); + + // const handleStartClick = () => { + // // TODO: Phase out the visited item + // localStorage.setItem('visited', 'true'); + // navigate('/home', { replace: true }); + // }; -const HeroSection = () => { const words = ['plan', 'create', 'organise', 'optimise', 'design']; return ( @@ -36,7 +41,9 @@ const HeroSection = () => { className="flex justify-center items-center shadow-[0_4px_14px_0_rgb(0,118,255,39%)] hover:shadow-[0_6px_20px_rgba(0,118,255,23%)] hover:bg-[rgba(0,118,255,0.9)] hover:scale-105 px-6 sm:px-8 py-2 sm:py-3 bg-[#0070f3] rounded-3xl text-white font-light transition duration-200 ease-linear mt-5" onClick={handleStartClick} > -

    diff --git a/client/src/components/landingPage/LandingPage.tsx b/client/src/components/landingPage/LandingPage.tsx index f1f3abaef..34cc189da 100644 --- a/client/src/components/landingPage/LandingPage.tsx +++ b/client/src/components/landingPage/LandingPage.tsx @@ -1,36 +1,52 @@ +import { useState } from 'react'; import notangles from '../../assets/notangles_1.png'; +import { useAuth } from '../../hooks/useAuth'; +import AuthModal, { AuthModalProps } from '../login/AuthModal'; import FeedbackSection from './FeedbackSection'; import Footer from './Footer'; import HeroSection from './HeroSection/HeroSection'; import FeaturesSection from './KeyFeaturesSection/FeaturesSection'; import ScrollingFeaturesSection from './ScrollingFeaturesSection'; import SponsorsSection from './SponsorsSection'; +import { useNavigate } from 'react-router-dom'; +import { API_URL } from '../../api/config'; const LandingPage = () => { + const [authModalOpen, setAuthModalOpen] = useState(false); + const { loading } = useAuth(); + const onSignIn: AuthModalProps['onSignIn'] = (provider) => { + localStorage.setItem('visited', 'true'); + setAuthModalOpen(false); + window.location.href = `${API_URL.server}/auth/login/${provider}`; + }; + return ( -
    -
    -
    - -

    Notangles

    + <> +
    +
    +
    + +

    Notangles

    +
    +
    +
    + setAuthModalOpen(true)} />
    -
    -
    - -
    -
    -
    - - +
    +
    + + +
    +
    + +
    + + {/* Sticky Footer */} +
    - -
    - - {/* Sticky Footer */} -
    -
    -
    + setAuthModalOpen(false)} loading={loading} onSignIn={onSignIn} /> + ); }; diff --git a/client/src/components/login/AuthGuard.tsx b/client/src/components/login/AuthGuard.tsx new file mode 100644 index 000000000..02f3c3bef --- /dev/null +++ b/client/src/components/login/AuthGuard.tsx @@ -0,0 +1,11 @@ +import { Navigate } from 'react-router-dom'; +import { useAuth } from '../../hooks/useAuth'; +import PageLoading from '../pageLoading/PageLoading'; + +export function AuthGuard({ children }: { children: JSX.Element }) { + const { loading, loggedIn } = useAuth(); + + if (loading) return ; + if (!loggedIn) return ; + return children; +} diff --git a/client/src/components/login/AuthModal.tsx b/client/src/components/login/AuthModal.tsx new file mode 100644 index 000000000..74e564d9f --- /dev/null +++ b/client/src/components/login/AuthModal.tsx @@ -0,0 +1,104 @@ +import React from 'react'; +import { Dialog, DialogContent, Grid, Box, Typography, Button, IconButton, Skeleton, useTheme } from '@mui/material'; +import GitHubIcon from '@mui/icons-material/GitHub'; +import GoogleIcon from '@mui/icons-material/Google'; +import AccountCircleIcon from '@mui/icons-material/AccountCircle'; +import CloseIcon from '@mui/icons-material/Close'; + +export interface AuthModalProps { + open: boolean; + onClose: () => void; + onSignIn: (provider: 'devsoc' | 'google' | 'github' | 'guest') => void; + loading?: boolean; +} + +export default function LoginDialog({ open, onClose, onSignIn, loading = false }: AuthModalProps) { + return ( + + + + + + + + {/* ◀ Illustration Panel */} + + + + notangles + + timetable planner + + + + {/* ▶ Form Panel */} + + {loading ? ( + <> + {/* Header skeletons */} + + + + {/* Button skeletons */} + + + + + {/* Guest text skeleton */} + + + ) : ( + <> + + Welcome back + + + Sign in to continue + + + + + + + + + + + )} + + + + + ); +} diff --git a/client/src/components/pageLoading/PageLoading.tsx b/client/src/components/pageLoading/PageLoading.tsx new file mode 100644 index 000000000..fea7ef1ad --- /dev/null +++ b/client/src/components/pageLoading/PageLoading.tsx @@ -0,0 +1,33 @@ +import { keyframes, styled } from '@mui/system'; +import logo from '../../assets/notanglesWithBg.png'; + +const PageWrapper = styled('div')` + height: 100vh; + display: flex; + align-items: center; + justify-content: center; + flex-direction: column; +`; + +const pulse = keyframes` + 0% { + box-shadow: 0 0 0 0px rgba(84, 72, 91, 0.2); + } + 100% { + box-shadow: 0 0 0 40px rgba(17, 3, 52, 0); + } +`; + +const LoadingLogo = styled('img')` + width: 200px; + border-radius: 50%; + animation: ${pulse} 1.5s infinite; +`; + +const PageLoading = () => ( + + + +); + +export default PageLoading; diff --git a/client/src/hooks/useAuth.tsx b/client/src/hooks/useAuth.tsx new file mode 100644 index 000000000..cd6ab5af0 --- /dev/null +++ b/client/src/hooks/useAuth.tsx @@ -0,0 +1,39 @@ +import { createContext, useContext, useState, useEffect } from 'react'; +import { UserInfo } from '../interfaces/User'; +import { API_URL } from '../api/config'; + +type AuthContextType = { + loading: boolean; + loggedIn: boolean; + user: UserInfo | null; +}; + +const AuthContext = createContext({ + loading: true, + loggedIn: false, + user: null, +}); + +export function AuthProvider({ children }: { children: React.ReactNode }) { + const [state, setState] = useState({ + loading: true, + loggedIn: false, + user: null, + }); + + useEffect(() => { + fetch(`${API_URL.server}/user/profile`, { credentials: 'include' }) + .then((res) => { + if (!res.ok) throw new Error('not logged in'); + return res.json(); + }) + .then((data) => setState({ loading: false, loggedIn: true, user: data })) + .catch(() => setState({ loading: false, loggedIn: false, user: null })); + }, []); + + return {children}; +} + +export function useAuth() { + return useContext(AuthContext); +} diff --git a/client/src/index.tsx b/client/src/index.tsx index 0b6291eca..7a5856a2b 100644 --- a/client/src/index.tsx +++ b/client/src/index.tsx @@ -15,6 +15,8 @@ import LandingPage from './components/landingPage/LandingPage'; import AppContextProvider from './context/AppContext'; import CourseContextProvider from './context/CourseContext'; import * as swRegistration from './serviceWorkerRegistration'; +import { AuthGuard } from './components/login/AuthGuard'; +import { AuthProvider } from './hooks/useAuth'; Sentry.init({ dsn: import.meta.env.VITE_APP_SENTRY_INGEST_CLIENT, @@ -23,31 +25,35 @@ Sentry.init({ }); const Root: React.FC = () => { - const hasVisited = localStorage.getItem('visited'); - return ( - - - - - - {hasVisited ? ( - } path="/"> - } /> - - ) : ( + + + + + + } path="/" /> - )} - - - - - + + + + } + path="/home" + > + } /> + + + + + + + ); }; diff --git a/client/src/interfaces/User.ts b/client/src/interfaces/User.ts new file mode 100644 index 000000000..831b0befc --- /dev/null +++ b/client/src/interfaces/User.ts @@ -0,0 +1,6 @@ +export type UserInfo = { + id: string; + firstName: string; + lastName: string; + profilePictureUrl?: string; +}; diff --git a/server/package.json b/server/package.json index 654d4b2bd..551b832a8 100644 --- a/server/package.json +++ b/server/package.json @@ -91,5 +91,5 @@ "coverageDirectory": "../coverage", "testEnvironment": "node" }, - "packageManager": "pnpm@10.12.4+sha512.5ea8b0deed94ed68691c9bad4c955492705c5eeb8a87ef86bc62c74a26b037b08ff9570f108b2e4dbd1dd1a9186fea925e527f141c648e85af45631074680184" + "packageManager": "pnpm@10.13.1+sha512.37ebf1a5c7a30d5fabe0c5df44ee8da4c965ca0c5af3dbab28c3a1681b70a256218d05c81c9c0dcf767ef6b8551eb5b960042b9ed4300c59242336377e01cfad" } diff --git a/server/src/auth/auth.controller.ts b/server/src/auth/auth.controller.ts index 3209d65d6..e3ddc59ac 100644 --- a/server/src/auth/auth.controller.ts +++ b/server/src/auth/auth.controller.ts @@ -4,13 +4,16 @@ import { Response } from 'express'; @Controller('auth') export class AuthController { - @Get('login') + @Get('login/devsoc') @UseGuards(AuthGuard('oidc')) login() {} @Get('callback/devsoc') @UseGuards(AuthGuard('oidc')) callback(@Res() res: Response) { - res.redirect('http://localhost:3001/api/user/profile'); + res.redirect( + (process.env.NODE_ENV === 'dev' ? `http://` : `https://`) + + `${process.env.CLIENT_HOST_NAME}:${process.env.CLIENT_HOST_PORT}`, + ); } } From ad36bb444b550b5b2bb0f2a4122c7d5c05ee0916 Mon Sep 17 00:00:00 2001 From: jason4193 Date: Fri, 8 Aug 2025 20:25:16 +1000 Subject: [PATCH 14/33] Autofix lint error for FE --- .../landingPage/HeroSection/HeroSection.tsx | 3 +- .../components/landingPage/LandingPage.tsx | 19 ++++++-- client/src/components/login/AuthGuard.tsx | 1 + client/src/components/login/AuthModal.tsx | 45 +++++++++++++++---- .../components/pageLoading/PageLoading.tsx | 1 + .../src/components/sidebar/FriendsButton.tsx | 2 +- client/src/components/sidebar/UserAccount.tsx | 1 + .../sidebar/friends/FriendsDialog.tsx | 2 +- .../sidebar/friends/FriendsTablist.tsx | 2 +- .../sidebar/friends/YourFriendsTab.tsx | 2 +- client/src/hooks/useAuth.tsx | 17 ++++--- client/src/index.tsx | 4 +- client/src/interfaces/User.ts | 4 +- 13 files changed, 76 insertions(+), 27 deletions(-) diff --git a/client/src/components/landingPage/HeroSection/HeroSection.tsx b/client/src/components/landingPage/HeroSection/HeroSection.tsx index 04a2ac6ab..410471108 100644 --- a/client/src/components/landingPage/HeroSection/HeroSection.tsx +++ b/client/src/components/landingPage/HeroSection/HeroSection.tsx @@ -1,8 +1,9 @@ import { NavigateNext } from '@mui/icons-material'; import { useNavigate } from 'react-router-dom'; + import notangles from '../../../assets/notangles_1.png'; -import { FlipWords } from '../flip-words'; import { useAuth } from '../../../hooks/useAuth'; +import { FlipWords } from '../flip-words'; const HeroSection = ({ handleStartClick }: { handleStartClick: () => void }) => { const { loggedIn } = useAuth(); diff --git a/client/src/components/landingPage/LandingPage.tsx b/client/src/components/landingPage/LandingPage.tsx index 34cc189da..1e4b8b790 100644 --- a/client/src/components/landingPage/LandingPage.tsx +++ b/client/src/components/landingPage/LandingPage.tsx @@ -1,4 +1,6 @@ import { useState } from 'react'; + +import { API_URL } from '../../api/config'; import notangles from '../../assets/notangles_1.png'; import { useAuth } from '../../hooks/useAuth'; import AuthModal, { AuthModalProps } from '../login/AuthModal'; @@ -8,8 +10,6 @@ import HeroSection from './HeroSection/HeroSection'; import FeaturesSection from './KeyFeaturesSection/FeaturesSection'; import ScrollingFeaturesSection from './ScrollingFeaturesSection'; import SponsorsSection from './SponsorsSection'; -import { useNavigate } from 'react-router-dom'; -import { API_URL } from '../../api/config'; const LandingPage = () => { const [authModalOpen, setAuthModalOpen] = useState(false); @@ -30,7 +30,11 @@ const LandingPage = () => {
    - setAuthModalOpen(true)} /> + { + setAuthModalOpen(true); + }} + />
    @@ -45,7 +49,14 @@ const LandingPage = () => {
    - setAuthModalOpen(false)} loading={loading} onSignIn={onSignIn} /> + { + setAuthModalOpen(false); + }} + loading={loading} + onSignIn={onSignIn} + /> ); }; diff --git a/client/src/components/login/AuthGuard.tsx b/client/src/components/login/AuthGuard.tsx index 02f3c3bef..ce55e9c7c 100644 --- a/client/src/components/login/AuthGuard.tsx +++ b/client/src/components/login/AuthGuard.tsx @@ -1,4 +1,5 @@ import { Navigate } from 'react-router-dom'; + import { useAuth } from '../../hooks/useAuth'; import PageLoading from '../pageLoading/PageLoading'; diff --git a/client/src/components/login/AuthModal.tsx b/client/src/components/login/AuthModal.tsx index 74e564d9f..3d39ba8d6 100644 --- a/client/src/components/login/AuthModal.tsx +++ b/client/src/components/login/AuthModal.tsx @@ -1,9 +1,8 @@ -import React from 'react'; -import { Dialog, DialogContent, Grid, Box, Typography, Button, IconButton, Skeleton, useTheme } from '@mui/material'; -import GitHubIcon from '@mui/icons-material/GitHub'; -import GoogleIcon from '@mui/icons-material/Google'; import AccountCircleIcon from '@mui/icons-material/AccountCircle'; import CloseIcon from '@mui/icons-material/Close'; +import GitHubIcon from '@mui/icons-material/GitHub'; +import GoogleIcon from '@mui/icons-material/Google'; +import { Box, Button, Dialog, DialogContent, Grid, IconButton, Skeleton, Typography } from '@mui/material'; export interface AuthModalProps { open: boolean; @@ -79,19 +78,49 @@ export default function LoginDialog({ open, onClose, onSignIn, loading = false } Sign in to continue - - - - diff --git a/client/src/components/pageLoading/PageLoading.tsx b/client/src/components/pageLoading/PageLoading.tsx index fea7ef1ad..f1961b4ce 100644 --- a/client/src/components/pageLoading/PageLoading.tsx +++ b/client/src/components/pageLoading/PageLoading.tsx @@ -1,4 +1,5 @@ import { keyframes, styled } from '@mui/system'; + import logo from '../../assets/notanglesWithBg.png'; const PageWrapper = styled('div')` diff --git a/client/src/components/sidebar/FriendsButton.tsx b/client/src/components/sidebar/FriendsButton.tsx index 1eb054273..cb4378ce3 100644 --- a/client/src/components/sidebar/FriendsButton.tsx +++ b/client/src/components/sidebar/FriendsButton.tsx @@ -1,7 +1,7 @@ import { SwitchAccount } from '@mui/icons-material'; import { IconButton, Tooltip, Typography } from '@mui/material'; import { styled } from '@mui/system'; -import React, { useContext } from 'react'; +import React from 'react'; interface FriendsButtonProps { collapsed: boolean; diff --git a/client/src/components/sidebar/UserAccount.tsx b/client/src/components/sidebar/UserAccount.tsx index c8fd5d079..92d6f1bb3 100644 --- a/client/src/components/sidebar/UserAccount.tsx +++ b/client/src/components/sidebar/UserAccount.tsx @@ -2,6 +2,7 @@ import { LoginRounded, LogoutRounded } from '@mui/icons-material'; import { Button, IconButton, Tooltip } from '@mui/material'; import { styled } from '@mui/system'; import React, { useState } from 'react'; + import { API_URL } from '../../api/config'; import storage from '../../utils/storage'; import { createDefaultTimetable } from '../../utils/timetableHelpers'; diff --git a/client/src/components/sidebar/friends/FriendsDialog.tsx b/client/src/components/sidebar/friends/FriendsDialog.tsx index 73719bc5e..061a34701 100644 --- a/client/src/components/sidebar/friends/FriendsDialog.tsx +++ b/client/src/components/sidebar/friends/FriendsDialog.tsx @@ -3,8 +3,8 @@ import { Close as CloseIcon } from '@mui/icons-material'; import { Badge, Dialog, DialogTitle, IconButton, Paper, styled, Typography } from '@mui/material'; import React, { useState } from 'react'; -import { User } from './User'; import FriendsTablist from './FriendsTablist'; +import { User } from './User'; const StyledDialogTitle = styled(DialogTitle)` background-color: ${({ theme }) => theme.palette.background.paper}; diff --git a/client/src/components/sidebar/friends/FriendsTablist.tsx b/client/src/components/sidebar/friends/FriendsTablist.tsx index c468ceb7d..c12985682 100644 --- a/client/src/components/sidebar/friends/FriendsTablist.tsx +++ b/client/src/components/sidebar/friends/FriendsTablist.tsx @@ -5,9 +5,9 @@ import Tab from '@mui/material/Tab'; import Tabs from '@mui/material/Tabs'; import * as React from 'react'; -import { User } from './User'; import AddAFriendTab from './AddAFriendTab'; import RequestsTab from './RequestsTab'; +import { User } from './User'; import YourFriendsTab from './YourFriendsTab'; interface TabPanelProps { diff --git a/client/src/components/sidebar/friends/YourFriendsTab.tsx b/client/src/components/sidebar/friends/YourFriendsTab.tsx index 94d01c319..e23efc13a 100644 --- a/client/src/components/sidebar/friends/YourFriendsTab.tsx +++ b/client/src/components/sidebar/friends/YourFriendsTab.tsx @@ -5,8 +5,8 @@ import React from 'react'; import { API_URL } from '../../../api/config'; import NetworkError from '../../../interfaces/NetworkError'; -import UserProfile from './UserProfile'; import { User } from './User'; +import UserProfile from './UserProfile'; const StyledContainer = styled('div')` display: flex; diff --git a/client/src/hooks/useAuth.tsx b/client/src/hooks/useAuth.tsx index cd6ab5af0..6961086e4 100644 --- a/client/src/hooks/useAuth.tsx +++ b/client/src/hooks/useAuth.tsx @@ -1,12 +1,13 @@ -import { createContext, useContext, useState, useEffect } from 'react'; -import { UserInfo } from '../interfaces/User'; +import { createContext, useContext, useEffect, useState } from 'react'; + import { API_URL } from '../api/config'; +import { UserInfo } from '../interfaces/User'; -type AuthContextType = { +interface AuthContextType { loading: boolean; loggedIn: boolean; user: UserInfo | null; -}; +} const AuthContext = createContext({ loading: true, @@ -27,8 +28,12 @@ export function AuthProvider({ children }: { children: React.ReactNode }) { if (!res.ok) throw new Error('not logged in'); return res.json(); }) - .then((data) => setState({ loading: false, loggedIn: true, user: data })) - .catch(() => setState({ loading: false, loggedIn: false, user: null })); + .then((data) => { + setState({ loading: false, loggedIn: true, user: data }); + }) + .catch(() => { + setState({ loading: false, loggedIn: false, user: null }); + }); }, []); return {children}; diff --git a/client/src/index.tsx b/client/src/index.tsx index 7a5856a2b..7c8433ded 100644 --- a/client/src/index.tsx +++ b/client/src/index.tsx @@ -12,11 +12,11 @@ import { client } from './api/config'; import App from './App'; import EventShareModal from './components/EventShareModal'; import LandingPage from './components/landingPage/LandingPage'; +import { AuthGuard } from './components/login/AuthGuard'; import AppContextProvider from './context/AppContext'; import CourseContextProvider from './context/CourseContext'; -import * as swRegistration from './serviceWorkerRegistration'; -import { AuthGuard } from './components/login/AuthGuard'; import { AuthProvider } from './hooks/useAuth'; +import * as swRegistration from './serviceWorkerRegistration'; Sentry.init({ dsn: import.meta.env.VITE_APP_SENTRY_INGEST_CLIENT, diff --git a/client/src/interfaces/User.ts b/client/src/interfaces/User.ts index 831b0befc..9dfcc8793 100644 --- a/client/src/interfaces/User.ts +++ b/client/src/interfaces/User.ts @@ -1,6 +1,6 @@ -export type UserInfo = { +export interface UserInfo { id: string; firstName: string; lastName: string; profilePictureUrl?: string; -}; +} From a68f39b6f3480cf2a349b2a02df1555a409887cb Mon Sep 17 00:00:00 2001 From: Lucas Date: Tue, 19 Aug 2025 19:19:39 +1000 Subject: [PATCH 15/33] Fix Prisma in CI and add linting to server CI --- .github/workflows/ci.yml | 8 +++++++- server/package.json | 4 +++- server/src/main.ts | 2 +- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5f77423d1..58690276f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -31,7 +31,7 @@ jobs: working-directory: ${{ matrix.component }} - name: Generate Prisma Types from Schema - run: pnpx prisma generate + run: pnpm prisma generate if: ${{ matrix.component == 'server' }} working-directory: server @@ -40,6 +40,12 @@ jobs: if: ${{ matrix.component == 'server' }} working-directory: server + - name: Lint + run: pnpm run lint + # Only running in server currently - need to fix more linting issues in client first + if: ${{ matrix.component == 'server' }} + working-directory: ${{ matrix.component }} + - name: Build run: pnpm run build working-directory: ${{ matrix.component }} diff --git a/server/package.json b/server/package.json index 551b832a8..345066b6c 100644 --- a/server/package.json +++ b/server/package.json @@ -12,12 +12,14 @@ "start:dev": "nest start --watch", "start:debug": "nest start --debug --watch", "start:prod": "node dist/main", - "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix", + "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --ignore-pattern src/generated", + "lint:fix": "eslint --fix \"{src,apps,libs,test}/**/*.ts\" --ignore-pattern src/generated", "test": "jest", "test:watch": "jest --watch", "test:cov": "jest --coverage", "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand", "test:e2e": "jest --config ./test/jest-e2e.json", + "prisma": "prisma", "graphql": "graphql-codegen --config codegen.ts" }, "dependencies": { diff --git a/server/src/main.ts b/server/src/main.ts index 212351b4a..eef748ee9 100644 --- a/server/src/main.ts +++ b/server/src/main.ts @@ -32,4 +32,4 @@ async function bootstrap() { await app.listen(configService.get('port') ?? 3001); } -bootstrap(); +void bootstrap(); From d7a291e131f34221fdca86471dcb4e8b97fc3e00 Mon Sep 17 00:00:00 2001 From: sunny Date: Wed, 27 Aug 2025 13:17:05 +1000 Subject: [PATCH 16/33] Restructure backend routes add timetable routes (#1042) * created routes for user timetables * fixed returns * separarted timetable and course routes into the new structure * removed redundant imports * fix redundant assert --------- Co-authored-by: sunny chen --- server/src/timetable/timetable.controller.ts | 109 +++++ server/src/timetable/timetable.module.ts | 9 + server/src/timetable/timetable.service.ts | 439 +++++++++++++++++++ server/src/timetable/types.ts | 16 + server/src/user/types.ts | 9 - server/src/user/user.controller.ts | 115 +---- server/src/user/user.service.ts | 335 +------------- 7 files changed, 578 insertions(+), 454 deletions(-) create mode 100644 server/src/timetable/timetable.controller.ts create mode 100644 server/src/timetable/timetable.module.ts create mode 100644 server/src/timetable/timetable.service.ts create mode 100644 server/src/timetable/types.ts diff --git a/server/src/timetable/timetable.controller.ts b/server/src/timetable/timetable.controller.ts new file mode 100644 index 000000000..7ac33afac --- /dev/null +++ b/server/src/timetable/timetable.controller.ts @@ -0,0 +1,109 @@ +import { + Body, + Controller, + Delete, + Get, + Param, + Patch, + Post, + Query, + Req, + UseGuards, +} from '@nestjs/common'; +import { TimetableService } from './timetable.service'; +import { AuthenticatedGuard } from 'src/auth/authenticated.guard'; +import { Request } from 'express'; + +interface AuthenticatedRequest extends Request { + user: { + id: string; + oidcId?: string; + isGuest: boolean; + }; +} + +@Controller('user/timetables') +export class TimetableController { + constructor(private timetableService: TimetableService) {} + + @Get(':id') + @UseGuards(AuthenticatedGuard) + async getTimetable( + @Req() req: AuthenticatedRequest, + @Param('id') timetableId: string, + ) { + const timetable = await this.timetableService.getTimetable( + req.user.id, + timetableId, + ); + return timetable; + } + + @Get() + @UseGuards(AuthenticatedGuard) + async getUserTimetables( + @Req() req: AuthenticatedRequest, + @Query('year') year: string, + @Query('term') term: string, + ) { + const timetables = await this.timetableService.getUserTimetables( + req.user.id, + Number(year), + term, + ); + return timetables; + } + + @Post() + @UseGuards(AuthenticatedGuard) + async createTimetable( + @Req() req: AuthenticatedRequest, + @Body() data: { name: string; year: number; term: string }, + ) { + const timetable = await this.timetableService.createTimetable( + req.user.id, + data, + ); + return timetable; + } + + @Delete(':id') + @UseGuards(AuthenticatedGuard) + async deleteTimetable( + @Req() req: AuthenticatedRequest, + @Param('id') timetableId: string, + @Query('year') year: string, + @Query('term') term: string, + ) { + await this.timetableService.deleteTimetable( + req.user.id, + timetableId, + Number(year), + term, + ); + } + + @Patch(':id/rename') + @UseGuards(AuthenticatedGuard) + async renameTimetable( + @Req() req: AuthenticatedRequest, + @Param('id') timetableId: string, + @Body('name') newName: string, + ) { + await this.timetableService.renameTimetable( + req.user.id, + timetableId, + newName, + ); + } + + @Patch(':id/change-primary') + @UseGuards(AuthenticatedGuard) + async makePrimary( + @Req() req: AuthenticatedRequest, + @Param('id') timetableId: string, + @Body() data: { year: number; term: string }, + ) { + await this.timetableService.makePrimary(req.user.id, timetableId, data); + } +} diff --git a/server/src/timetable/timetable.module.ts b/server/src/timetable/timetable.module.ts new file mode 100644 index 000000000..c9cb7f54a --- /dev/null +++ b/server/src/timetable/timetable.module.ts @@ -0,0 +1,9 @@ +import { Module } from '@nestjs/common'; +import { TimetableController } from './timetable.controller'; +import { TimetableService } from './timetable.service'; + +@Module({ + controllers: [TimetableController], + providers: [TimetableService], +}) +export class TimetableModule {} diff --git a/server/src/timetable/timetable.service.ts b/server/src/timetable/timetable.service.ts new file mode 100644 index 000000000..b04b87b32 --- /dev/null +++ b/server/src/timetable/timetable.service.ts @@ -0,0 +1,439 @@ +import { HttpException, HttpStatus, Injectable } from '@nestjs/common'; +import { PrismaService } from 'src/prisma/prisma.service'; +import { GraphqlService } from 'src/graphql/graphql.service'; +import { validate } from 'src/utils/validate'; +import { AddCourseDto, CourseDetails, UserTimetable } from './types'; +import type { ClassDetails } from 'src/graphql/types'; + +@Injectable() +export class TimetableService { + constructor( + private readonly prisma: PrismaService, + private readonly graphqlService: GraphqlService, + ) {} + + async isTimetableOwnedByUser( + userId: string, + timetableId: string, + ): Promise { + const timetable = await this.prisma.timetable.findUnique({ + select: { userId: true }, + where: { id: timetableId }, + }); + return timetable?.userId === userId; + } + + async isCourseInTimetable( + timetableId: string, + courseId: string, + ): Promise { + const course = await this.prisma.course.findFirst({ + where: { courseId, timetableId }, + select: { id: true }, + }); + return course !== null; + } + + isColourCodeValid(colour: string): boolean { + const hexCodeRegex = /^#([0-9A-F]{3}|[0-9A-F]{6})$/i; + const defaultColoursRegex = /^default-[1-8]$/; + return hexCodeRegex.test(colour) || defaultColoursRegex.test(colour); + } + + async getCourseIds(userId: string, timetableId: string): Promise { + const timetableExists = await this.isTimetableOwnedByUser( + userId, + timetableId, + ); + validate(timetableExists, 'Timetable does not exist', HttpStatus.NOT_FOUND); + + const courses = await this.prisma.course.findMany({ + where: { timetableId }, + select: { courseId: true }, + }); + return courses.map((course) => course.courseId); + } + + async getCourseIfExists( + timetableId: string, + courseId: string, + ): Promise { + try { + return await this.prisma.course.findFirstOrThrow({ + select: { id: true, selectedClasses: true }, + where: { courseId, timetableId }, + }); + } catch { + throw new HttpException( + 'Course is not in timetable', + HttpStatus.NOT_FOUND, + ); + } + } + + async addCourse( + userId: string, + timetableId: string, + courseId: string, + addCourseDto: AddCourseDto, + ): Promise { + const courseExistsOnGraphQL = await this.graphqlService.courseExists( + courseId, + addCourseDto.term, + ); + validate( + courseExistsOnGraphQL, + 'Course does not exist', + HttpStatus.NOT_FOUND, + ); + + const timetableExists = await this.isTimetableOwnedByUser( + userId, + timetableId, + ); + validate(timetableExists, 'Timetable does not exist', HttpStatus.NOT_FOUND); + + const courseInTimetable = await this.isCourseInTimetable( + timetableId, + courseId, + ); + validate( + !courseInTimetable, + 'Course is in timetable already', + HttpStatus.CONFLICT, + ); + + const colourValid = this.isColourCodeValid(addCourseDto.colour); + validate(colourValid, 'Colour code is not valid', HttpStatus.BAD_REQUEST); + + await this.prisma.course.create({ + data: { + courseId, + colour: addCourseDto.colour, + selectedClasses: [], + timetable: { connect: { id: timetableId } }, + }, + }); + } + + async removeCourse( + userId: string, + timetableId: string, + courseId: string, + ): Promise { + const timetableExists = await this.isTimetableOwnedByUser( + userId, + timetableId, + ); + validate(timetableExists, 'Timetable does not exist', HttpStatus.NOT_FOUND); + + const course = await this.getCourseIfExists(timetableId, courseId); + await this.prisma.course.delete({ where: { id: course.id } }); + } + + async setCourseColour( + userId: string, + timetableId: string, + courseId: string, + colour: string, + ): Promise { + const timetableExists = await this.isTimetableOwnedByUser( + userId, + timetableId, + ); + validate(timetableExists, 'Timetable does not exist', HttpStatus.NOT_FOUND); + + const colourValid = this.isColourCodeValid(colour); + validate(colourValid, 'Colour code is not valid', HttpStatus.BAD_REQUEST); + + const course = await this.getCourseIfExists(timetableId, courseId); + + await this.prisma.course.update({ + where: { id: course.id }, + data: { colour }, + }); + } + + async getSelectedClassIds( + userId: string, + timetableId: string, + courseId: string, + ): Promise { + const timetableExists = await this.isTimetableOwnedByUser( + userId, + timetableId, + ); + validate(timetableExists, 'Timetable does not exist', HttpStatus.NOT_FOUND); + + const course = await this.getCourseIfExists(timetableId, courseId); + return course.selectedClasses; + } + + async differentTimeSlotsExist( + classData: ClassDetails, + existingClassIds: string[], + ): Promise { + try { + const existingClassDetails = await Promise.all( + existingClassIds.map(async (classId) => { + const details = await this.graphqlService.getClassDetails(classId); + return { ...details, class_id: classId }; + }), + ); + const differentTimeSlotsExist = existingClassDetails.filter( + (classDetails: ClassDetails & { class_id: string }) => + classDetails.activity === classData.activity && + classDetails.section !== classData.section, + ); + validate( + differentTimeSlotsExist.length <= 1, + 'Multiple different time slots found for the same activity', + HttpStatus.CONFLICT, + ); + if (differentTimeSlotsExist.length === 1 && differentTimeSlotsExist[0]) { + return differentTimeSlotsExist[0].class_id; + } else { + return undefined; + } + } catch (error) { + if (error instanceof HttpException) throw error; + throw new HttpException( + 'Failed to check for different time slots', + HttpStatus.INTERNAL_SERVER_ERROR, + ); + } + } + + async updateSelectedClass( + userId: string, + timetableId: string, + courseId: string, + classId: string, + ): Promise { + const classDetails = await this.graphqlService.getClassDetails(classId); + validate( + classDetails !== undefined, + 'Class does not exist', + HttpStatus.NOT_FOUND, + ); + validate( + classDetails!.activity !== undefined && + classDetails!.activity !== 'Course Enrollment', + 'Class is not a valid course class', + HttpStatus.BAD_REQUEST, + ); + const timetableExists = await this.isTimetableOwnedByUser( + userId, + timetableId, + ); + validate(timetableExists, 'Timetable does not exist', HttpStatus.NOT_FOUND); + + const course = await this.getCourseIfExists(timetableId, courseId); + validate( + !course.selectedClasses.includes(classId), + 'Class is already in course', + HttpStatus.CONFLICT, + ); + + const differentTimeSlotClassId = await this.differentTimeSlotsExist( + classDetails!, + course.selectedClasses, + ); + if (differentTimeSlotClassId) { + await this.removeClassFromCourse(course, differentTimeSlotClassId); + } + await this.addSelectedClass(course, classId); + } + + private async addSelectedClass( + course: CourseDetails, + classId: string, + ): Promise { + await this.prisma.course.update({ + where: { id: course.id }, + data: { selectedClasses: { push: classId } }, + }); + } + + private async removeClassFromCourse( + course: CourseDetails, + classId: string, + ): Promise { + const updatedClasses = course.selectedClasses.filter( + (existingClassId) => existingClassId !== classId, + ); + await this.prisma.course.update({ + where: { id: course.id }, + data: { selectedClasses: updatedClasses }, + }); + } + + async removeSelectedClass( + userId: string, + timetableId: string, + courseId: string, + classId: string, + ): Promise { + const classValidate = await this.graphqlService.getClassDetails(classId); + validate( + classValidate !== undefined, + 'Class does not exist', + HttpStatus.NOT_FOUND, + ); + + const timetableExists = await this.isTimetableOwnedByUser( + userId, + timetableId, + ); + validate(timetableExists, 'Timetable does not exist', HttpStatus.NOT_FOUND); + + const course = await this.getCourseIfExists(timetableId, courseId); + validate( + course.selectedClasses.includes(classId), + 'Class is not in course', + HttpStatus.NOT_FOUND, + ); + + await this.removeClassFromCourse(course, classId); + } + + async getTimetable( + userId: string, + timetableId: string, + ): Promise { + const timetableExists = await this.isTimetableOwnedByUser( + userId, + timetableId, + ); + validate(timetableExists, 'Timetable does not exist', HttpStatus.NOT_FOUND); + + const data = await this.prisma.timetable.findFirstOrThrow({ + where: { id: timetableId }, + }); + + return { + id: data.id, + name: data.name, + year: data.year, + term: data.term, + primary: data.primary, + }; + } + + async getUserTimetables( + userId: string, + year: number, + term: string, + ): Promise { + const timetables = await this.prisma.timetable.findMany({ + where: { userId, year, term }, + select: { id: true }, + }); + + return timetables.map((t) => t.id); + } + + async createTimetable( + userId: string, + data: { name: string; year: number; term: string }, + ): Promise { + const numTimetables = await this.prisma.timetable.count({ + where: { userId, year: data.year, term: data.term }, + }); + + const timetable = await this.prisma.timetable.create({ + data: { + userId, + name: data.name, + year: data.year, + term: data.term, + primary: numTimetables === 0, + }, + select: { id: true }, + }); + + return timetable.id; + } + + async deleteTimetable( + userId: string, + timetableId: string, + year: number, + term: string, + ): Promise { + const numTimetables = await this.prisma.timetable.count({ + where: { userId, year, term }, + }); + + if (numTimetables <= 1) { + throw new HttpException( + 'Cannot delete the last timetable.', + HttpStatus.NOT_FOUND, + ); + } + + const timetable = await this.prisma.timetable.findFirst({ + where: { id: timetableId, userId }, + }); + + if (!timetable) { + throw new HttpException( + 'Timetable does not belong to this user.', + HttpStatus.NOT_FOUND, + ); + } + + if (timetable.primary) { + throw new HttpException( + 'Cannot delete the primary timetable.', + HttpStatus.NOT_FOUND, + ); + } + + await this.prisma.timetable.delete({ where: { id: timetableId } }); + } + + async renameTimetable( + userId: string, + timetableId: string, + newName: string, + ): Promise { + await this.prisma.timetable.updateMany({ + where: { userId, id: timetableId }, + data: { name: newName }, + }); + } + + async makePrimary( + userId: string, + timetableId: string, + data: { year: number; term: string }, + ): Promise { + const timetable = await this.prisma.timetable.findFirst({ + where: { id: timetableId, userId }, + }); + + if (!timetable) { + throw new HttpException( + 'Timetable does not belong to this user.', + HttpStatus.NOT_FOUND, + ); + } + + await this.prisma.$transaction([ + this.prisma.timetable.updateMany({ + where: { + userId, + primary: true, + year: data.year, + term: data.term, + }, + data: { primary: false }, + }), + this.prisma.timetable.update({ + where: { id: timetableId }, + data: { primary: true }, + }), + ]); + } +} diff --git a/server/src/timetable/types.ts b/server/src/timetable/types.ts new file mode 100644 index 000000000..a94f50160 --- /dev/null +++ b/server/src/timetable/types.ts @@ -0,0 +1,16 @@ +export class AddCourseDto { + term: string; + colour: string; +} +export class CourseDetails { + id: string; + selectedClasses: string[]; +} + +export class UserTimetable { + id: string; + name: string; + year: number; + term: string; + primary: boolean; +} diff --git a/server/src/user/types.ts b/server/src/user/types.ts index fc77654b4..d7e12c64f 100644 --- a/server/src/user/types.ts +++ b/server/src/user/types.ts @@ -15,12 +15,3 @@ export class UserSettings { unscheduleClassesByDefault: boolean; hideExamClasses: boolean; } - -export class AddCourseDto { - term: string; - colour: string; -} -export class CourseDetails { - id: string; - selectedClasses: string[]; -} diff --git a/server/src/user/user.controller.ts b/server/src/user/user.controller.ts index 0c055a289..7fa6f2bed 100644 --- a/server/src/user/user.controller.ts +++ b/server/src/user/user.controller.ts @@ -1,19 +1,8 @@ -import { - Body, - Controller, - Delete, - Get, - HttpStatus, - Param, - Patch, - Post, - Req, - UseGuards, -} from '@nestjs/common'; +import { Body, Controller, Get, Post, Req, UseGuards } from '@nestjs/common'; import { UserService } from './user.service'; import { AuthenticatedGuard } from 'src/auth/authenticated.guard'; import { Request } from 'express'; -import { UserSettings, AddCourseDto } from './types'; +import { UserSettings } from './types'; interface AuthenticatedRequest extends Request { user: { @@ -41,7 +30,6 @@ export class UserController { @Body('url') url: string, ) { await this.userService.setProfilePicture(req.user.id, url); - return; } @Get('settings') @@ -58,104 +46,5 @@ export class UserController { @Body() settings: UserSettings, ) { await this.userService.setSettings(req.user.id, settings); - return; - } - - @Get('courses/:timetableId') - @UseGuards(AuthenticatedGuard) - async getCourseIds( - @Req() req: AuthenticatedRequest, - @Param('timetableId') timetableId: string, - ) { - return await this.userService.getCourseIds(req.user.id, timetableId); - } - - @Post('course/:timetableId/:courseId') - @UseGuards(AuthenticatedGuard) - async addCourse( - @Req() req: AuthenticatedRequest, - @Param('timetableId') timetableId: string, - @Param('courseId') courseId: string, - @Body() addCourseDto: AddCourseDto, - ) { - await this.userService.addCourse( - req.user.id, - timetableId, - courseId, - addCourseDto, - ); - return HttpStatus.CREATED; - } - - @Delete('course/:timetableId/:courseId') - @UseGuards(AuthenticatedGuard) - async removeCourse( - @Req() req: AuthenticatedRequest, - @Param('timetableId') timetableId: string, - @Param('courseId') courseId: string, - ) { - await this.userService.removeCourse(req.user.id, timetableId, courseId); - } - - @Patch('course/:timetableId/:courseId/colour') - @UseGuards(AuthenticatedGuard) - async setCourseColour( - @Req() req: AuthenticatedRequest, - @Param('timetableId') timetableId: string, - @Param('courseId') courseId: string, - @Body('colour') colour: string, - ) { - await this.userService.setCourseColour( - req.user.id, - timetableId, - courseId, - colour, - ); - } - - @Get('classes/:timetableId/:courseId') - @UseGuards(AuthenticatedGuard) - async getSelectedClassIds( - @Req() req: AuthenticatedRequest, - @Param('timetableId') timetableId: string, - @Param('courseId') courseId: string, - ) { - return await this.userService.getSelectedClassIds( - req.user.id, - timetableId, - courseId, - ); - } - - @Patch('class/:timetableId/:courseId') - @UseGuards(AuthenticatedGuard) - async updateSelectedClass( - @Req() req: AuthenticatedRequest, - @Param('timetableId') timetableId: string, - @Param('courseId') courseId: string, - @Body('classId') classId: string, - ) { - await this.userService.updateSelectedClass( - req.user.id, - timetableId, - courseId, - classId, - ); - } - - @Delete('class/:timetableId/:courseId/:classId') - @UseGuards(AuthenticatedGuard) - async removeSelectedClass( - @Req() req: AuthenticatedRequest, - @Param('timetableId') timetableId: string, - @Param('courseId') courseId: string, - @Param('classId') classId: string, - ) { - await this.userService.removeSelectedClass( - req.user.id, - timetableId, - courseId, - classId, - ); } } diff --git a/server/src/user/user.service.ts b/server/src/user/user.service.ts index dee4e9190..40c13e820 100644 --- a/server/src/user/user.service.ts +++ b/server/src/user/user.service.ts @@ -1,16 +1,10 @@ -import { HttpException, HttpStatus, Injectable } from '@nestjs/common'; -import { GraphqlService } from 'src/graphql/graphql.service'; +import { Injectable } from '@nestjs/common'; import { PrismaService } from 'src/prisma/prisma.service'; -import { AddCourseDto, CourseDetails, UserInfo, UserSettings } from './types'; -import type { ClassDetails } from 'src/graphql/types'; -import { validate } from 'src/utils/validate'; +import { UserInfo, UserSettings } from './types'; @Injectable({}) export class UserService { - constructor( - private readonly prisma: PrismaService, - private readonly graphqlService: GraphqlService, - ) {} + constructor(private readonly prisma: PrismaService) {} async getUserInfo(userId: string): Promise { const data = await this.prisma.user.findUniqueOrThrow({ @@ -70,327 +64,4 @@ export class UserService { }, }); } - - async isTimetableOwnedByUser( - userId: string, - timetableId: string, - ): Promise { - const timetable = await this.prisma.timetable.findUnique({ - select: { - userId: true, - }, - where: { - id: timetableId, - }, - }); - return timetable?.userId === userId; - } - - async isCourseInTimetable( - timetableId: string, - courseId: string, - ): Promise { - const course = await this.prisma.course.findFirst({ - where: { - courseId: courseId, - timetableId: timetableId, - }, - select: { - id: true, - }, - }); - return course !== null; - } - - isColourCodeValid(colour: string): boolean { - const hexCodeRegex = /^#([0-9A-F]{3}|[0-9A-F]{6})$/i; - const defaultColoursRegex = /^default-[1-8]$/; - return hexCodeRegex.test(colour) || defaultColoursRegex.test(colour); - } - - async getCourseIds(userId: string, timetableId: string): Promise { - const timetableExists = await this.isTimetableOwnedByUser( - userId, - timetableId, - ); - validate(timetableExists, 'Timetable does not exist', HttpStatus.NOT_FOUND); - - const courses = await this.prisma.course.findMany({ - where: { - timetableId: timetableId, - }, - select: { - courseId: true, - }, - }); - return courses.map((course) => course.courseId); - } - - async getCourseIfExists( - timetableId: string, - courseId: string, - ): Promise { - try { - return await this.prisma.course.findFirstOrThrow({ - select: { - id: true, - selectedClasses: true, - }, - where: { - courseId: courseId, - timetableId: timetableId, - }, - }); - } catch { - throw new HttpException( - 'Course is not in timetable', - HttpStatus.NOT_FOUND, - ); - } - } - - async addCourse( - userId: string, - timetableId: string, - courseId: string, - addCourseDto: AddCourseDto, - ): Promise { - const courseExistsOnGraphQL = await this.graphqlService.courseExists( - courseId, - addCourseDto.term, - ); - validate( - courseExistsOnGraphQL, - 'Course does not exist', - HttpStatus.NOT_FOUND, - ); - const timetableExists = await this.isTimetableOwnedByUser( - userId, - timetableId, - ); - validate(timetableExists, 'Timetable does not exist', HttpStatus.NOT_FOUND); - const courseInTimetable = await this.isCourseInTimetable( - timetableId, - courseId, - ); - validate( - !courseInTimetable, - 'Course is in timetable already', - HttpStatus.CONFLICT, - ); - const colourValid = this.isColourCodeValid(addCourseDto.colour); - validate(colourValid, 'Colour code is not valid', HttpStatus.BAD_REQUEST); - - await this.prisma.course.create({ - data: { - courseId: courseId, - colour: addCourseDto.colour, - selectedClasses: [], - timetable: { - connect: { - id: timetableId, - }, - }, - }, - }); - } - - async removeCourse( - userId: string, - timetableId: string, - courseId: string, - ): Promise { - const timetableExists = await this.isTimetableOwnedByUser( - userId, - timetableId, - ); - validate(timetableExists, 'Timetable does not exist', HttpStatus.NOT_FOUND); - - const course = await this.getCourseIfExists(timetableId, courseId); - await this.prisma.course.delete({ - where: { - id: course.id, - }, - }); - } - - async setCourseColour( - userId: string, - timetableId: string, - courseId: string, - colour: string, - ): Promise { - const timetableExists = await this.isTimetableOwnedByUser( - userId, - timetableId, - ); - validate(timetableExists, 'Timetable does not exist', HttpStatus.NOT_FOUND); - const colourValid = this.isColourCodeValid(colour); - validate(colourValid, 'Colour code is not valid', HttpStatus.BAD_REQUEST); - const course = await this.getCourseIfExists(timetableId, courseId); - - await this.prisma.course.update({ - where: { - id: course.id, - }, - data: { - colour: colour, - }, - }); - } - - async getSelectedClassIds( - userId: string, - timetableId: string, - courseId: string, - ): Promise { - const timetableExists = await this.isTimetableOwnedByUser( - userId, - timetableId, - ); - validate(timetableExists, 'Timetable does not exist', HttpStatus.NOT_FOUND); - - const course = await this.getCourseIfExists(timetableId, courseId); - return course.selectedClasses; - } - - async differentTimeSlotsExist( - classData: ClassDetails, - existingClassIds: string[], - ): Promise { - try { - const existingClassDetails = await Promise.all( - existingClassIds.map(async (classId) => { - const details = await this.graphqlService.getClassDetails(classId); - return { - ...details, - class_id: classId, - }; - }), - ); - const differentTimeSlotsExist = existingClassDetails.filter( - (classDetails: ClassDetails & { class_id: string }) => - classDetails.activity === classData.activity && - classDetails.section !== classData.section, - ); - validate( - differentTimeSlotsExist.length <= 1, - 'Multiple different time slots found for the same activity', - HttpStatus.CONFLICT, - ); - if (differentTimeSlotsExist.length === 1 && differentTimeSlotsExist[0]) { - return differentTimeSlotsExist[0].class_id; - } else { - return undefined; - } - } catch (error) { - if (error instanceof HttpException) { - throw error; - } - throw new HttpException( - 'Failed to check for different time slots', - HttpStatus.INTERNAL_SERVER_ERROR, - ); - } - } - - async updateSelectedClass( - userId: string, - timetableId: string, - courseId: string, - classId: string, - ): Promise { - const classDetails = await this.graphqlService.getClassDetails(classId); - validate( - classDetails !== undefined, - 'Class does not exist', - HttpStatus.NOT_FOUND, - ); - validate( - classDetails!.activity !== undefined && - classDetails!.activity !== 'Course Enrollment', - 'Class is not a valid course class', - HttpStatus.BAD_REQUEST, - ); - const timetableExists = await this.isTimetableOwnedByUser( - userId, - timetableId, - ); - validate(timetableExists, 'Timetable does not exist', HttpStatus.NOT_FOUND); - const course = await this.getCourseIfExists(timetableId, courseId); - validate( - !course.selectedClasses.includes(classId), - 'Class is already in course', - HttpStatus.CONFLICT, - ); - - const differentTimeSlotClassId = await this.differentTimeSlotsExist( - classDetails!, - course.selectedClasses, - ); - if (differentTimeSlotClassId) { - await this.removeClassFromCourse(course, differentTimeSlotClassId); - } - await this.addSelectedClass(course, classId); - } - - private async addSelectedClass( - course: CourseDetails, - classId: string, - ): Promise { - await this.prisma.course.update({ - where: { - id: course.id, - }, - data: { - selectedClasses: { - push: classId, - }, - }, - }); - } - - private async removeClassFromCourse( - course: CourseDetails, - classId: string, - ): Promise { - const updatedClasses = course.selectedClasses.filter( - (existingClassId) => existingClassId !== classId, - ); - await this.prisma.course.update({ - where: { - id: course.id, - }, - data: { - selectedClasses: updatedClasses, - }, - }); - } - - async removeSelectedClass( - userId: string, - timetableId: string, - courseId: string, - classId: string, - ): Promise { - const classValidate = await this.graphqlService.getClassDetails(classId); - validate( - classValidate !== undefined, - 'Class does not exist', - HttpStatus.NOT_FOUND, - ); - const timetableExists = await this.isTimetableOwnedByUser( - userId, - timetableId, - ); - validate(timetableExists, 'Timetable does not exist', HttpStatus.NOT_FOUND); - const course = await this.getCourseIfExists(timetableId, courseId); - validate( - course.selectedClasses.includes(classId), - 'Class is not in course', - HttpStatus.NOT_FOUND, - ); - - await this.removeClassFromCourse(course, classId); - } } From 5a6860d2863d1570597d527b8c6601ed23ac87cc Mon Sep 17 00:00:00 2001 From: jason4193 <100593637+jason4193@users.noreply.github.com> Date: Wed, 27 Aug 2025 16:10:51 +0800 Subject: [PATCH 17/33] Migrate settings to Tanstack Query (#1040) * Install TankStack library with corresponding devtool, integrate into App.tsx * Integrate react query in to setting page * Connect settings.useSquareEdge,useDarkMode,preferredTheme with FE components * Remove use of QueryContext to direct suspense query calling to avoid re-rendering of whole App component * Update all settings to use React Query * Fix FE build error by removing removed AppContext states on components * Remove redudant comments * Add Error Boundary for handling unintented error, resolve packages version and dependecies issue * Remove unwanted comments and resolve naming issues * Resolve setting item destructing before used, and other dependecies issues * Migrate JS fetch to Axios * Remove unwanted library import * Update ErrorBoundary to handle any unknown errors * Resolve build error * Rebase from server-rewrite * Rebase from server-rewrite, with autofix eslint * Refactor Settings component to fit the feat of profile picture * Remove unneccssary commnets * Resolved dropcard shadow logic with react query * Resolve CI build error and lint warnings from drag.ts * Resolve review errors from lucas * Resolve use-prefix issue for settings parameter with minor changes * Resolve review comments from mark * Update the prisma schema for user settings * Update the prisma schema for user settings * Resolve naming error --- client/package.json | 3 + client/pnpm-lock.yaml | 3125 +++++++++++------ client/src/App.tsx | 82 +- client/src/api/timetable/mutations.ts | 0 client/src/api/timetable/queries.ts | 0 client/src/api/timetable/routes.ts | 0 client/src/api/user/mutations.ts | 12 + client/src/api/user/queries.ts | 9 + client/src/api/user/routes.ts | 24 + client/src/components/ErrorBoundary.tsx | 34 + client/src/components/ErrorPage/ErrorPage.tsx | 111 + client/src/components/Sponsors.tsx | 5 +- .../src/components/controls/ColorOptions.tsx | 36 +- .../src/components/controls/ColorPicker.tsx | 77 +- .../src/components/controls/CustomEvent.tsx | 6 +- .../components/sidebar/ColorThemeOptions.tsx | 15 +- .../src/components/sidebar/DarkModeButton.tsx | 19 +- client/src/components/sidebar/Settings.tsx | 141 +- .../src/components/timetable/DroppedCards.tsx | 6 +- .../src/components/timetable/DroppedClass.tsx | 20 +- .../src/components/timetable/DroppedEvent.tsx | 20 +- client/src/components/timetable/Dropzones.tsx | 14 +- .../timetable/ExpandedClassView.tsx | 4 +- .../timetable/ExpandedEventView.tsx | 4 +- .../components/timetable/TimetableLayout.tsx | 19 +- .../timetableTabs/TimetableTabs.tsx | 21 +- client/src/constants/theme.ts | 8 +- client/src/context/AppContext.tsx | 91 +- client/src/hooks/useAuth.tsx | 8 +- client/src/index.tsx | 99 +- client/src/interfaces/User.ts | 12 + client/src/styles/CustomEventStyles.tsx | 4 +- client/src/utils/Drag.ts | 81 +- .../migration.sql | 2 + .../migration.sql | 2 + .../migration.sql | 2 + .../migration.sql | 15 + server/prisma/schema.prisma | 9 +- server/src/auth/auth.controller.ts | 2 +- server/src/auth/oidc.strategy.ts | 8 + server/src/main.ts | 1 + server/src/user/types.ts | 6 +- 42 files changed, 2577 insertions(+), 1580 deletions(-) create mode 100644 client/src/api/timetable/mutations.ts create mode 100644 client/src/api/timetable/queries.ts create mode 100644 client/src/api/timetable/routes.ts create mode 100644 client/src/api/user/mutations.ts create mode 100644 client/src/api/user/queries.ts create mode 100644 client/src/api/user/routes.ts create mode 100644 client/src/components/ErrorBoundary.tsx create mode 100644 client/src/components/ErrorPage/ErrorPage.tsx create mode 100644 server/prisma/migrations/20250726163527_add_convert_to_local_timezone/migration.sql create mode 100644 server/prisma/migrations/20250827031550_set_covert_to_local_time_default_false/migration.sql create mode 100644 server/prisma/migrations/20250827041847_rename_preferred_theme_default_name/migration.sql create mode 100644 server/prisma/migrations/20250827072638_rename_use_prefix_settings_parameters/migration.sql diff --git a/client/package.json b/client/package.json index 15621bb9d..19a19f44f 100644 --- a/client/package.json +++ b/client/package.json @@ -30,7 +30,9 @@ "@sentry/browser": "9.38.0", "@sentry/node": "9.38.0", "@sentry/react": "9.38.0", + "@tanstack/react-query": "5.84.1", "@uiw/react-color": "2.7.1", + "axios": "1.11.0", "clsx": "2.1.1", "colorizr": "3.0.8", "date-fns": "2.30.0", @@ -78,6 +80,7 @@ "@eslint/js": "9.31.0", "@tailwindcss/postcss": "4.1.11", "@tanstack/eslint-plugin-query": "5.83.1", + "@tanstack/react-query-devtools": "5.84.1", "@types/file-saver": "2.0.7", "@types/is-base64": "1.1.3", "@types/lodash-es": "4.17.12", diff --git a/client/pnpm-lock.yaml b/client/pnpm-lock.yaml index 8b4fc360f..cc9cd5187 100644 --- a/client/pnpm-lock.yaml +++ b/client/pnpm-lock.yaml @@ -5,7 +5,6 @@ settings: excludeLinksFromLockfile: false importers: - .: dependencies: '@apollo/client': @@ -50,9 +49,15 @@ importers: '@sentry/react': specifier: 9.38.0 version: 9.38.0(react@18.3.1) + '@tanstack/react-query': + specifier: 5.84.1 + version: 5.84.1(react@18.3.1) '@uiw/react-color': specifier: 2.7.1 version: 2.7.1(@babel/runtime@7.27.6)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + axios: + specifier: 1.11.0 + version: 1.11.0 clsx: specifier: 2.1.1 version: 2.1.1 @@ -153,6 +158,9 @@ importers: '@tanstack/eslint-plugin-query': specifier: 5.83.1 version: 5.83.1(eslint@9.31.0(jiti@2.4.2))(typescript@5.8.3) + '@tanstack/react-query-devtools': + specifier: 5.84.1 + version: 5.84.1(@tanstack/react-query@5.84.1(react@18.3.1))(react@18.3.1) '@types/file-saver': specifier: 2.0.7 version: 2.0.7 @@ -242,17 +250,19 @@ importers: version: 3.2.4(@types/node@22.15.30)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(yaml@2.7.1) packages: - '@alloc/quick-lru@5.2.0': - resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} - engines: {node: '>=10'} + resolution: + { integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw== } + engines: { node: '>=10' } '@ampproject/remapping@2.3.0': - resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} - engines: {node: '>=6.0.0'} + resolution: + { integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw== } + engines: { node: '>=6.0.0' } '@apollo/client@3.13.8': - resolution: {integrity: sha512-YM9lQpm0VfVco4DSyKooHS/fDTiKQcCHfxr7i3iL6a0kP/jNO5+4NFK6vtRDxaYisd5BrwOZHLJpPBnvRVpKPg==} + resolution: + { integrity: sha512-YM9lQpm0VfVco4DSyKooHS/fDTiKQcCHfxr7i3iL6a0kP/jNO5+4NFK6vtRDxaYisd5BrwOZHLJpPBnvRVpKPg== } peerDependencies: graphql: ^15.0.0 || ^16.0.0 graphql-ws: ^5.5.5 || ^6.0.3 @@ -270,98 +280,121 @@ packages: optional: true '@asamuzakjp/css-color@3.2.0': - resolution: {integrity: sha512-K1A6z8tS3XsmCMM86xoWdn7Fkdn9m6RSVtocUrJYIwZnFVkng/PvkEoWtOWmP+Scc6saYWHWZYbndEEXxl24jw==} + resolution: + { integrity: sha512-K1A6z8tS3XsmCMM86xoWdn7Fkdn9m6RSVtocUrJYIwZnFVkng/PvkEoWtOWmP+Scc6saYWHWZYbndEEXxl24jw== } '@babel/code-frame@7.27.1': - resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} - engines: {node: '>=6.9.0'} + resolution: + { integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg== } + engines: { node: '>=6.9.0' } '@babel/generator@7.28.0': - resolution: {integrity: sha512-lJjzvrbEeWrhB4P3QBsH7tey117PjLZnDbLiQEKjQ/fNJTjuq4HSqgFA+UNSwZT8D7dxxbnuSBMsa1lrWzKlQg==} - engines: {node: '>=6.9.0'} + resolution: + { integrity: sha512-lJjzvrbEeWrhB4P3QBsH7tey117PjLZnDbLiQEKjQ/fNJTjuq4HSqgFA+UNSwZT8D7dxxbnuSBMsa1lrWzKlQg== } + engines: { node: '>=6.9.0' } '@babel/helper-globals@7.28.0': - resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} - engines: {node: '>=6.9.0'} + resolution: + { integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw== } + engines: { node: '>=6.9.0' } '@babel/helper-module-imports@7.27.1': - resolution: {integrity: sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==} - engines: {node: '>=6.9.0'} + resolution: + { integrity: sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w== } + engines: { node: '>=6.9.0' } '@babel/helper-string-parser@7.27.1': - resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} - engines: {node: '>=6.9.0'} + resolution: + { integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA== } + engines: { node: '>=6.9.0' } '@babel/helper-validator-identifier@7.27.1': - resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==} - engines: {node: '>=6.9.0'} + resolution: + { integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow== } + engines: { node: '>=6.9.0' } '@babel/parser@7.28.0': - resolution: {integrity: sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g==} - engines: {node: '>=6.0.0'} + resolution: + { integrity: sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g== } + engines: { node: '>=6.0.0' } hasBin: true '@babel/runtime@7.27.6': - resolution: {integrity: sha512-vbavdySgbTTrmFE+EsiqUTzlOr5bzlnJtUv9PynGCAKvfQqjIXbvFdumPM/GxMDfyuGMJaJAU6TO4zc1Jf1i8Q==} - engines: {node: '>=6.9.0'} + resolution: + { integrity: sha512-vbavdySgbTTrmFE+EsiqUTzlOr5bzlnJtUv9PynGCAKvfQqjIXbvFdumPM/GxMDfyuGMJaJAU6TO4zc1Jf1i8Q== } + engines: { node: '>=6.9.0' } '@babel/template@7.27.2': - resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==} - engines: {node: '>=6.9.0'} + resolution: + { integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw== } + engines: { node: '>=6.9.0' } '@babel/traverse@7.28.0': - resolution: {integrity: sha512-mGe7UK5wWyh0bKRfupsUchrQGqvDbZDbKJw+kcRGSmdHVYrv+ltd0pnpDTVpiTqnaBru9iEvA8pz8W46v0Amwg==} - engines: {node: '>=6.9.0'} + resolution: + { integrity: sha512-mGe7UK5wWyh0bKRfupsUchrQGqvDbZDbKJw+kcRGSmdHVYrv+ltd0pnpDTVpiTqnaBru9iEvA8pz8W46v0Amwg== } + engines: { node: '>=6.9.0' } '@babel/types@7.28.1': - resolution: {integrity: sha512-x0LvFTekgSX+83TI28Y9wYPUfzrnl2aT5+5QLnO6v7mSJYtEEevuDRN0F0uSHRk1G1IWZC43o00Y0xDDrpBGPQ==} - engines: {node: '>=6.9.0'} + resolution: + { integrity: sha512-x0LvFTekgSX+83TI28Y9wYPUfzrnl2aT5+5QLnO6v7mSJYtEEevuDRN0F0uSHRk1G1IWZC43o00Y0xDDrpBGPQ== } + engines: { node: '>=6.9.0' } '@csstools/color-helpers@5.0.2': - resolution: {integrity: sha512-JqWH1vsgdGcw2RR6VliXXdA0/59LttzlU8UlRT/iUUsEeWfYq8I+K0yhihEUTTHLRm1EXvpsCx3083EU15ecsA==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-JqWH1vsgdGcw2RR6VliXXdA0/59LttzlU8UlRT/iUUsEeWfYq8I+K0yhihEUTTHLRm1EXvpsCx3083EU15ecsA== } + engines: { node: '>=18' } '@csstools/css-calc@2.1.4': - resolution: {integrity: sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ== } + engines: { node: '>=18' } peerDependencies: '@csstools/css-parser-algorithms': ^3.0.5 '@csstools/css-tokenizer': ^3.0.4 '@csstools/css-color-parser@3.0.10': - resolution: {integrity: sha512-TiJ5Ajr6WRd1r8HSiwJvZBiJOqtH86aHpUjq5aEKWHiII2Qfjqd/HCWKPOW8EP4vcspXbHnXrwIDlu5savQipg==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-TiJ5Ajr6WRd1r8HSiwJvZBiJOqtH86aHpUjq5aEKWHiII2Qfjqd/HCWKPOW8EP4vcspXbHnXrwIDlu5savQipg== } + engines: { node: '>=18' } peerDependencies: '@csstools/css-parser-algorithms': ^3.0.5 '@csstools/css-tokenizer': ^3.0.4 '@csstools/css-parser-algorithms@3.0.5': - resolution: {integrity: sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ== } + engines: { node: '>=18' } peerDependencies: '@csstools/css-tokenizer': ^3.0.4 '@csstools/css-tokenizer@3.0.4': - resolution: {integrity: sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw== } + engines: { node: '>=18' } '@emotion/babel-plugin@11.13.5': - resolution: {integrity: sha512-pxHCpT2ex+0q+HH91/zsdHkw/lXd468DIN2zvfvLtPKLLMo6gQj7oLObq8PhkrxOZb/gGCq03S3Z7PDhS8pduQ==} + resolution: + { integrity: sha512-pxHCpT2ex+0q+HH91/zsdHkw/lXd468DIN2zvfvLtPKLLMo6gQj7oLObq8PhkrxOZb/gGCq03S3Z7PDhS8pduQ== } '@emotion/cache@11.14.0': - resolution: {integrity: sha512-L/B1lc/TViYk4DcpGxtAVbx0ZyiKM5ktoIyafGkH6zg/tj+mA+NE//aPYKG0k8kCHSHVJrpLpcAlOBEXQ3SavA==} + resolution: + { integrity: sha512-L/B1lc/TViYk4DcpGxtAVbx0ZyiKM5ktoIyafGkH6zg/tj+mA+NE//aPYKG0k8kCHSHVJrpLpcAlOBEXQ3SavA== } '@emotion/hash@0.9.2': - resolution: {integrity: sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==} + resolution: + { integrity: sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g== } '@emotion/is-prop-valid@1.3.1': - resolution: {integrity: sha512-/ACwoqx7XQi9knQs/G0qKvv5teDMhD7bXYns9N/wM8ah8iNb8jZ2uNO0YOgiq2o2poIvVtJS2YALasQuMSQ7Kw==} + resolution: + { integrity: sha512-/ACwoqx7XQi9knQs/G0qKvv5teDMhD7bXYns9N/wM8ah8iNb8jZ2uNO0YOgiq2o2poIvVtJS2YALasQuMSQ7Kw== } '@emotion/memoize@0.9.0': - resolution: {integrity: sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==} + resolution: + { integrity: sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ== } '@emotion/react@11.14.0': - resolution: {integrity: sha512-O000MLDBDdk/EohJPFUqvnp4qnHeYkVP5B0xEG0D/L7cOKP9kefu2DXn8dj74cQfsEzUqh+sr1RzFqiL1o+PpA==} + resolution: + { integrity: sha512-O000MLDBDdk/EohJPFUqvnp4qnHeYkVP5B0xEG0D/L7cOKP9kefu2DXn8dj74cQfsEzUqh+sr1RzFqiL1o+PpA== } peerDependencies: '@types/react': '*' react: '>=16.8.0' @@ -370,13 +403,16 @@ packages: optional: true '@emotion/serialize@1.3.3': - resolution: {integrity: sha512-EISGqt7sSNWHGI76hC7x1CksiXPahbxEOrC5RjmFRJTqLyEK9/9hZvBbiYn70dw4wuwMKiEMCUlR6ZXTSWQqxA==} + resolution: + { integrity: sha512-EISGqt7sSNWHGI76hC7x1CksiXPahbxEOrC5RjmFRJTqLyEK9/9hZvBbiYn70dw4wuwMKiEMCUlR6ZXTSWQqxA== } '@emotion/sheet@1.4.0': - resolution: {integrity: sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==} + resolution: + { integrity: sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg== } '@emotion/styled@11.14.1': - resolution: {integrity: sha512-qEEJt42DuToa3gurlH4Qqc1kVpNq8wO8cJtDzU46TjlzWjDlsVyevtYCRijVq3SrHsROS+gVQ8Fnea108GnKzw==} + resolution: + { integrity: sha512-qEEJt42DuToa3gurlH4Qqc1kVpNq8wO8cJtDzU46TjlzWjDlsVyevtYCRijVq3SrHsROS+gVQ8Fnea108GnKzw== } peerDependencies: '@emotion/react': ^11.0.0-rc.0 '@types/react': '*' @@ -386,287 +422,345 @@ packages: optional: true '@emotion/unitless@0.10.0': - resolution: {integrity: sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg==} + resolution: + { integrity: sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg== } '@emotion/use-insertion-effect-with-fallbacks@1.2.0': - resolution: {integrity: sha512-yJMtVdH59sxi/aVJBpk9FQq+OR8ll5GT8oWd57UpeaKEVGab41JWaCFA7FRLoMLloOZF/c/wsPoe+bfGmRKgDg==} + resolution: + { integrity: sha512-yJMtVdH59sxi/aVJBpk9FQq+OR8ll5GT8oWd57UpeaKEVGab41JWaCFA7FRLoMLloOZF/c/wsPoe+bfGmRKgDg== } peerDependencies: react: '>=16.8.0' '@emotion/utils@1.4.2': - resolution: {integrity: sha512-3vLclRofFziIa3J2wDh9jjbkUz9qk5Vi3IZ/FSTKViB0k+ef0fPV7dYrUIugbgupYDx7v9ud/SjrtEP8Y4xLoA==} + resolution: + { integrity: sha512-3vLclRofFziIa3J2wDh9jjbkUz9qk5Vi3IZ/FSTKViB0k+ef0fPV7dYrUIugbgupYDx7v9ud/SjrtEP8Y4xLoA== } '@emotion/weak-memoize@0.4.0': - resolution: {integrity: sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==} + resolution: + { integrity: sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg== } '@esbuild/aix-ppc64@0.25.6': - resolution: {integrity: sha512-ShbM/3XxwuxjFiuVBHA+d3j5dyac0aEVVq1oluIDf71hUw0aRF59dV/efUsIwFnR6m8JNM2FjZOzmaZ8yG61kw==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-ShbM/3XxwuxjFiuVBHA+d3j5dyac0aEVVq1oluIDf71hUw0aRF59dV/efUsIwFnR6m8JNM2FjZOzmaZ8yG61kw== } + engines: { node: '>=18' } cpu: [ppc64] os: [aix] '@esbuild/android-arm64@0.25.6': - resolution: {integrity: sha512-hd5zdUarsK6strW+3Wxi5qWws+rJhCCbMiC9QZyzoxfk5uHRIE8T287giQxzVpEvCwuJ9Qjg6bEjcRJcgfLqoA==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-hd5zdUarsK6strW+3Wxi5qWws+rJhCCbMiC9QZyzoxfk5uHRIE8T287giQxzVpEvCwuJ9Qjg6bEjcRJcgfLqoA== } + engines: { node: '>=18' } cpu: [arm64] os: [android] '@esbuild/android-arm@0.25.6': - resolution: {integrity: sha512-S8ToEOVfg++AU/bHwdksHNnyLyVM+eMVAOf6yRKFitnwnbwwPNqKr3srzFRe7nzV69RQKb5DgchIX5pt3L53xg==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-S8ToEOVfg++AU/bHwdksHNnyLyVM+eMVAOf6yRKFitnwnbwwPNqKr3srzFRe7nzV69RQKb5DgchIX5pt3L53xg== } + engines: { node: '>=18' } cpu: [arm] os: [android] '@esbuild/android-x64@0.25.6': - resolution: {integrity: sha512-0Z7KpHSr3VBIO9A/1wcT3NTy7EB4oNC4upJ5ye3R7taCc2GUdeynSLArnon5G8scPwaU866d3H4BCrE5xLW25A==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-0Z7KpHSr3VBIO9A/1wcT3NTy7EB4oNC4upJ5ye3R7taCc2GUdeynSLArnon5G8scPwaU866d3H4BCrE5xLW25A== } + engines: { node: '>=18' } cpu: [x64] os: [android] '@esbuild/darwin-arm64@0.25.6': - resolution: {integrity: sha512-FFCssz3XBavjxcFxKsGy2DYK5VSvJqa6y5HXljKzhRZ87LvEi13brPrf/wdyl/BbpbMKJNOr1Sd0jtW4Ge1pAA==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-FFCssz3XBavjxcFxKsGy2DYK5VSvJqa6y5HXljKzhRZ87LvEi13brPrf/wdyl/BbpbMKJNOr1Sd0jtW4Ge1pAA== } + engines: { node: '>=18' } cpu: [arm64] os: [darwin] '@esbuild/darwin-x64@0.25.6': - resolution: {integrity: sha512-GfXs5kry/TkGM2vKqK2oyiLFygJRqKVhawu3+DOCk7OxLy/6jYkWXhlHwOoTb0WqGnWGAS7sooxbZowy+pK9Yg==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-GfXs5kry/TkGM2vKqK2oyiLFygJRqKVhawu3+DOCk7OxLy/6jYkWXhlHwOoTb0WqGnWGAS7sooxbZowy+pK9Yg== } + engines: { node: '>=18' } cpu: [x64] os: [darwin] '@esbuild/freebsd-arm64@0.25.6': - resolution: {integrity: sha512-aoLF2c3OvDn2XDTRvn8hN6DRzVVpDlj2B/F66clWd/FHLiHaG3aVZjxQX2DYphA5y/evbdGvC6Us13tvyt4pWg==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-aoLF2c3OvDn2XDTRvn8hN6DRzVVpDlj2B/F66clWd/FHLiHaG3aVZjxQX2DYphA5y/evbdGvC6Us13tvyt4pWg== } + engines: { node: '>=18' } cpu: [arm64] os: [freebsd] '@esbuild/freebsd-x64@0.25.6': - resolution: {integrity: sha512-2SkqTjTSo2dYi/jzFbU9Plt1vk0+nNg8YC8rOXXea+iA3hfNJWebKYPs3xnOUf9+ZWhKAaxnQNUf2X9LOpeiMQ==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-2SkqTjTSo2dYi/jzFbU9Plt1vk0+nNg8YC8rOXXea+iA3hfNJWebKYPs3xnOUf9+ZWhKAaxnQNUf2X9LOpeiMQ== } + engines: { node: '>=18' } cpu: [x64] os: [freebsd] '@esbuild/linux-arm64@0.25.6': - resolution: {integrity: sha512-b967hU0gqKd9Drsh/UuAm21Khpoh6mPBSgz8mKRq4P5mVK8bpA+hQzmm/ZwGVULSNBzKdZPQBRT3+WuVavcWsQ==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-b967hU0gqKd9Drsh/UuAm21Khpoh6mPBSgz8mKRq4P5mVK8bpA+hQzmm/ZwGVULSNBzKdZPQBRT3+WuVavcWsQ== } + engines: { node: '>=18' } cpu: [arm64] os: [linux] '@esbuild/linux-arm@0.25.6': - resolution: {integrity: sha512-SZHQlzvqv4Du5PrKE2faN0qlbsaW/3QQfUUc6yO2EjFcA83xnwm91UbEEVx4ApZ9Z5oG8Bxz4qPE+HFwtVcfyw==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-SZHQlzvqv4Du5PrKE2faN0qlbsaW/3QQfUUc6yO2EjFcA83xnwm91UbEEVx4ApZ9Z5oG8Bxz4qPE+HFwtVcfyw== } + engines: { node: '>=18' } cpu: [arm] os: [linux] '@esbuild/linux-ia32@0.25.6': - resolution: {integrity: sha512-aHWdQ2AAltRkLPOsKdi3xv0mZ8fUGPdlKEjIEhxCPm5yKEThcUjHpWB1idN74lfXGnZ5SULQSgtr5Qos5B0bPw==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-aHWdQ2AAltRkLPOsKdi3xv0mZ8fUGPdlKEjIEhxCPm5yKEThcUjHpWB1idN74lfXGnZ5SULQSgtr5Qos5B0bPw== } + engines: { node: '>=18' } cpu: [ia32] os: [linux] '@esbuild/linux-loong64@0.25.6': - resolution: {integrity: sha512-VgKCsHdXRSQ7E1+QXGdRPlQ/e08bN6WMQb27/TMfV+vPjjTImuT9PmLXupRlC90S1JeNNW5lzkAEO/McKeJ2yg==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-VgKCsHdXRSQ7E1+QXGdRPlQ/e08bN6WMQb27/TMfV+vPjjTImuT9PmLXupRlC90S1JeNNW5lzkAEO/McKeJ2yg== } + engines: { node: '>=18' } cpu: [loong64] os: [linux] '@esbuild/linux-mips64el@0.25.6': - resolution: {integrity: sha512-WViNlpivRKT9/py3kCmkHnn44GkGXVdXfdc4drNmRl15zVQ2+D2uFwdlGh6IuK5AAnGTo2qPB1Djppj+t78rzw==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-WViNlpivRKT9/py3kCmkHnn44GkGXVdXfdc4drNmRl15zVQ2+D2uFwdlGh6IuK5AAnGTo2qPB1Djppj+t78rzw== } + engines: { node: '>=18' } cpu: [mips64el] os: [linux] '@esbuild/linux-ppc64@0.25.6': - resolution: {integrity: sha512-wyYKZ9NTdmAMb5730I38lBqVu6cKl4ZfYXIs31Baf8aoOtB4xSGi3THmDYt4BTFHk7/EcVixkOV2uZfwU3Q2Jw==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-wyYKZ9NTdmAMb5730I38lBqVu6cKl4ZfYXIs31Baf8aoOtB4xSGi3THmDYt4BTFHk7/EcVixkOV2uZfwU3Q2Jw== } + engines: { node: '>=18' } cpu: [ppc64] os: [linux] '@esbuild/linux-riscv64@0.25.6': - resolution: {integrity: sha512-KZh7bAGGcrinEj4qzilJ4hqTY3Dg2U82c8bv+e1xqNqZCrCyc+TL9AUEn5WGKDzm3CfC5RODE/qc96OcbIe33w==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-KZh7bAGGcrinEj4qzilJ4hqTY3Dg2U82c8bv+e1xqNqZCrCyc+TL9AUEn5WGKDzm3CfC5RODE/qc96OcbIe33w== } + engines: { node: '>=18' } cpu: [riscv64] os: [linux] '@esbuild/linux-s390x@0.25.6': - resolution: {integrity: sha512-9N1LsTwAuE9oj6lHMyyAM+ucxGiVnEqUdp4v7IaMmrwb06ZTEVCIs3oPPplVsnjPfyjmxwHxHMF8b6vzUVAUGw==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-9N1LsTwAuE9oj6lHMyyAM+ucxGiVnEqUdp4v7IaMmrwb06ZTEVCIs3oPPplVsnjPfyjmxwHxHMF8b6vzUVAUGw== } + engines: { node: '>=18' } cpu: [s390x] os: [linux] '@esbuild/linux-x64@0.25.6': - resolution: {integrity: sha512-A6bJB41b4lKFWRKNrWoP2LHsjVzNiaurf7wyj/XtFNTsnPuxwEBWHLty+ZE0dWBKuSK1fvKgrKaNjBS7qbFKig==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-A6bJB41b4lKFWRKNrWoP2LHsjVzNiaurf7wyj/XtFNTsnPuxwEBWHLty+ZE0dWBKuSK1fvKgrKaNjBS7qbFKig== } + engines: { node: '>=18' } cpu: [x64] os: [linux] '@esbuild/netbsd-arm64@0.25.6': - resolution: {integrity: sha512-IjA+DcwoVpjEvyxZddDqBY+uJ2Snc6duLpjmkXm/v4xuS3H+3FkLZlDm9ZsAbF9rsfP3zeA0/ArNDORZgrxR/Q==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-IjA+DcwoVpjEvyxZddDqBY+uJ2Snc6duLpjmkXm/v4xuS3H+3FkLZlDm9ZsAbF9rsfP3zeA0/ArNDORZgrxR/Q== } + engines: { node: '>=18' } cpu: [arm64] os: [netbsd] '@esbuild/netbsd-x64@0.25.6': - resolution: {integrity: sha512-dUXuZr5WenIDlMHdMkvDc1FAu4xdWixTCRgP7RQLBOkkGgwuuzaGSYcOpW4jFxzpzL1ejb8yF620UxAqnBrR9g==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-dUXuZr5WenIDlMHdMkvDc1FAu4xdWixTCRgP7RQLBOkkGgwuuzaGSYcOpW4jFxzpzL1ejb8yF620UxAqnBrR9g== } + engines: { node: '>=18' } cpu: [x64] os: [netbsd] '@esbuild/openbsd-arm64@0.25.6': - resolution: {integrity: sha512-l8ZCvXP0tbTJ3iaqdNf3pjaOSd5ex/e6/omLIQCVBLmHTlfXW3zAxQ4fnDmPLOB1x9xrcSi/xtCWFwCZRIaEwg==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-l8ZCvXP0tbTJ3iaqdNf3pjaOSd5ex/e6/omLIQCVBLmHTlfXW3zAxQ4fnDmPLOB1x9xrcSi/xtCWFwCZRIaEwg== } + engines: { node: '>=18' } cpu: [arm64] os: [openbsd] '@esbuild/openbsd-x64@0.25.6': - resolution: {integrity: sha512-hKrmDa0aOFOr71KQ/19JC7az1P0GWtCN1t2ahYAf4O007DHZt/dW8ym5+CUdJhQ/qkZmI1HAF8KkJbEFtCL7gw==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-hKrmDa0aOFOr71KQ/19JC7az1P0GWtCN1t2ahYAf4O007DHZt/dW8ym5+CUdJhQ/qkZmI1HAF8KkJbEFtCL7gw== } + engines: { node: '>=18' } cpu: [x64] os: [openbsd] '@esbuild/openharmony-arm64@0.25.6': - resolution: {integrity: sha512-+SqBcAWoB1fYKmpWoQP4pGtx+pUUC//RNYhFdbcSA16617cchuryuhOCRpPsjCblKukAckWsV+aQ3UKT/RMPcA==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-+SqBcAWoB1fYKmpWoQP4pGtx+pUUC//RNYhFdbcSA16617cchuryuhOCRpPsjCblKukAckWsV+aQ3UKT/RMPcA== } + engines: { node: '>=18' } cpu: [arm64] os: [openharmony] '@esbuild/sunos-x64@0.25.6': - resolution: {integrity: sha512-dyCGxv1/Br7MiSC42qinGL8KkG4kX0pEsdb0+TKhmJZgCUDBGmyo1/ArCjNGiOLiIAgdbWgmWgib4HoCi5t7kA==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-dyCGxv1/Br7MiSC42qinGL8KkG4kX0pEsdb0+TKhmJZgCUDBGmyo1/ArCjNGiOLiIAgdbWgmWgib4HoCi5t7kA== } + engines: { node: '>=18' } cpu: [x64] os: [sunos] '@esbuild/win32-arm64@0.25.6': - resolution: {integrity: sha512-42QOgcZeZOvXfsCBJF5Afw73t4veOId//XD3i+/9gSkhSV6Gk3VPlWncctI+JcOyERv85FUo7RxuxGy+z8A43Q==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-42QOgcZeZOvXfsCBJF5Afw73t4veOId//XD3i+/9gSkhSV6Gk3VPlWncctI+JcOyERv85FUo7RxuxGy+z8A43Q== } + engines: { node: '>=18' } cpu: [arm64] os: [win32] '@esbuild/win32-ia32@0.25.6': - resolution: {integrity: sha512-4AWhgXmDuYN7rJI6ORB+uU9DHLq/erBbuMoAuB4VWJTu5KtCgcKYPynF0YI1VkBNuEfjNlLrFr9KZPJzrtLkrQ==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-4AWhgXmDuYN7rJI6ORB+uU9DHLq/erBbuMoAuB4VWJTu5KtCgcKYPynF0YI1VkBNuEfjNlLrFr9KZPJzrtLkrQ== } + engines: { node: '>=18' } cpu: [ia32] os: [win32] '@esbuild/win32-x64@0.25.6': - resolution: {integrity: sha512-NgJPHHbEpLQgDH2MjQu90pzW/5vvXIZ7KOnPyNBm92A6WgZ/7b6fJyUBjoumLqeOQQGqY2QjQxRo97ah4Sj0cA==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-NgJPHHbEpLQgDH2MjQu90pzW/5vvXIZ7KOnPyNBm92A6WgZ/7b6fJyUBjoumLqeOQQGqY2QjQxRo97ah4Sj0cA== } + engines: { node: '>=18' } cpu: [x64] os: [win32] '@eslint-community/eslint-utils@4.7.0': - resolution: {integrity: sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + resolution: + { integrity: sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw== } + engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 } peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 '@eslint-community/regexpp@4.12.1': - resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} - engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + resolution: + { integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ== } + engines: { node: ^12.0.0 || ^14.0.0 || >=16.0.0 } '@eslint/config-array@0.21.0': - resolution: {integrity: sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + resolution: + { integrity: sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } '@eslint/config-helpers@0.3.0': - resolution: {integrity: sha512-ViuymvFmcJi04qdZeDc2whTHryouGcDlaxPqarTD0ZE10ISpxGUVZGZDx4w01upyIynL3iu6IXH2bS1NhclQMw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + resolution: + { integrity: sha512-ViuymvFmcJi04qdZeDc2whTHryouGcDlaxPqarTD0ZE10ISpxGUVZGZDx4w01upyIynL3iu6IXH2bS1NhclQMw== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } '@eslint/core@0.15.1': - resolution: {integrity: sha512-bkOp+iumZCCbt1K1CmWf0R9pM5yKpDv+ZXtvSyQpudrI9kuFLp+bM2WOPXImuD/ceQuaa8f5pj93Y7zyECIGNA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + resolution: + { integrity: sha512-bkOp+iumZCCbt1K1CmWf0R9pM5yKpDv+ZXtvSyQpudrI9kuFLp+bM2WOPXImuD/ceQuaa8f5pj93Y7zyECIGNA== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } '@eslint/eslintrc@3.3.1': - resolution: {integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + resolution: + { integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } '@eslint/js@9.31.0': - resolution: {integrity: sha512-LOm5OVt7D4qiKCqoiPbA7LWmI+tbw1VbTUowBcUMgQSuM6poJufkFkYDcQpo5KfgD39TnNySV26QjOh7VFpSyw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + resolution: + { integrity: sha512-LOm5OVt7D4qiKCqoiPbA7LWmI+tbw1VbTUowBcUMgQSuM6poJufkFkYDcQpo5KfgD39TnNySV26QjOh7VFpSyw== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } '@eslint/object-schema@2.1.6': - resolution: {integrity: sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + resolution: + { integrity: sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } '@eslint/plugin-kit@0.3.3': - resolution: {integrity: sha512-1+WqvgNMhmlAambTvT3KPtCl/Ibr68VldY2XY40SL1CE0ZXiakFR/cbTspaF5HsnpDMvcYYoJHfl4980NBjGag==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + resolution: + { integrity: sha512-1+WqvgNMhmlAambTvT3KPtCl/Ibr68VldY2XY40SL1CE0ZXiakFR/cbTspaF5HsnpDMvcYYoJHfl4980NBjGag== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } '@floating-ui/core@1.7.2': - resolution: {integrity: sha512-wNB5ooIKHQc+Kui96jE/n69rHFWAVoxn5CAzL1Xdd8FG03cgY3MLO+GF9U3W737fYDSgPWA6MReKhBQBop6Pcw==} + resolution: + { integrity: sha512-wNB5ooIKHQc+Kui96jE/n69rHFWAVoxn5CAzL1Xdd8FG03cgY3MLO+GF9U3W737fYDSgPWA6MReKhBQBop6Pcw== } '@floating-ui/dom@1.7.2': - resolution: {integrity: sha512-7cfaOQuCS27HD7DX+6ib2OrnW+b4ZBwDNnCcT0uTyidcmyWb03FnQqJybDBoCnpdxwBSfA94UAYlRCt7mV+TbA==} + resolution: + { integrity: sha512-7cfaOQuCS27HD7DX+6ib2OrnW+b4ZBwDNnCcT0uTyidcmyWb03FnQqJybDBoCnpdxwBSfA94UAYlRCt7mV+TbA== } '@floating-ui/react-dom@2.1.4': - resolution: {integrity: sha512-JbbpPhp38UmXDDAu60RJmbeme37Jbgsm7NrHGgzYYFKmblzRUh6Pa641dII6LsjwF4XlScDrde2UAzDo/b9KPw==} + resolution: + { integrity: sha512-JbbpPhp38UmXDDAu60RJmbeme37Jbgsm7NrHGgzYYFKmblzRUh6Pa641dII6LsjwF4XlScDrde2UAzDo/b9KPw== } peerDependencies: react: '>=16.8.0' react-dom: '>=16.8.0' '@floating-ui/utils@0.2.10': - resolution: {integrity: sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==} + resolution: + { integrity: sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ== } '@fontsource-variable/roboto-flex@5.2.6': - resolution: {integrity: sha512-8jUDGkb6gRUexJkdUz1GThB9fshF7ENe/vVmtf+nz2MxQZZsrrYT92tST3xM+xf/BnoqL6yRkGdv9zNITiyYCw==} + resolution: + { integrity: sha512-8jUDGkb6gRUexJkdUz1GThB9fshF7ENe/vVmtf+nz2MxQZZsrrYT92tST3xM+xf/BnoqL6yRkGdv9zNITiyYCw== } '@graphql-typed-document-node/core@3.2.0': - resolution: {integrity: sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ==} + resolution: + { integrity: sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ== } 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 '@hello-pangea/dnd@18.0.1': - resolution: {integrity: sha512-xojVWG8s/TGrKT1fC8K2tIWeejJYTAeJuj36zM//yEm/ZrnZUSFGS15BpO+jGZT1ybWvyXmeDJwPYb4dhWlbZQ==} + resolution: + { integrity: sha512-xojVWG8s/TGrKT1fC8K2tIWeejJYTAeJuj36zM//yEm/ZrnZUSFGS15BpO+jGZT1ybWvyXmeDJwPYb4dhWlbZQ== } peerDependencies: react: ^18.0.0 || ^19.0.0 react-dom: ^18.0.0 || ^19.0.0 '@heroicons/react@2.2.0': - resolution: {integrity: sha512-LMcepvRaS9LYHJGsF0zzmgKCUim/X3N/DQKc4jepAXJ7l8QxJ1PmxJzqplF2Z3FE4PqBAIGyJAQ/w4B5dsqbtQ==} + resolution: + { integrity: sha512-LMcepvRaS9LYHJGsF0zzmgKCUim/X3N/DQKc4jepAXJ7l8QxJ1PmxJzqplF2Z3FE4PqBAIGyJAQ/w4B5dsqbtQ== } peerDependencies: react: '>= 16 || ^19.0.0-rc' '@humanfs/core@0.19.1': - resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} - engines: {node: '>=18.18.0'} + resolution: + { integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA== } + engines: { node: '>=18.18.0' } '@humanfs/node@0.16.6': - resolution: {integrity: sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==} - engines: {node: '>=18.18.0'} + resolution: + { integrity: sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw== } + engines: { node: '>=18.18.0' } '@humanwhocodes/module-importer@1.0.1': - resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} - engines: {node: '>=12.22'} + resolution: + { integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== } + engines: { node: '>=12.22' } '@humanwhocodes/retry@0.3.1': - resolution: {integrity: sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==} - engines: {node: '>=18.18'} + resolution: + { integrity: sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA== } + engines: { node: '>=18.18' } '@humanwhocodes/retry@0.4.3': - resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} - engines: {node: '>=18.18'} + resolution: + { integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ== } + engines: { node: '>=18.18' } '@isaacs/fs-minipass@4.0.1': - resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==} - engines: {node: '>=18.0.0'} + resolution: + { integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w== } + engines: { node: '>=18.0.0' } '@jridgewell/gen-mapping@0.3.12': - resolution: {integrity: sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==} + resolution: + { integrity: sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg== } '@jridgewell/resolve-uri@3.1.2': - resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} - engines: {node: '>=6.0.0'} + resolution: + { integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw== } + engines: { node: '>=6.0.0' } '@jridgewell/sourcemap-codec@1.5.4': - resolution: {integrity: sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==} + resolution: + { integrity: sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw== } '@jridgewell/trace-mapping@0.3.29': - resolution: {integrity: sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==} + resolution: + { integrity: sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ== } '@mui/base@5.0.0-beta.40-1': - resolution: {integrity: sha512-agKXuNNy0bHUmeU7pNmoZwNFr7Hiyhojkb9+2PVyDG5+6RafYuyMgbrav8CndsB7KUc/U51JAw9vKNDLYBzaUA==} - engines: {node: '>=12.0.0'} + resolution: + { integrity: sha512-agKXuNNy0bHUmeU7pNmoZwNFr7Hiyhojkb9+2PVyDG5+6RafYuyMgbrav8CndsB7KUc/U51JAw9vKNDLYBzaUA== } + engines: { node: '>=12.0.0' } deprecated: This package has been replaced by @base-ui-components/react peerDependencies: '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 @@ -677,8 +771,9 @@ packages: optional: true '@mui/base@5.0.0-beta.70': - resolution: {integrity: sha512-Tb/BIhJzb0pa5zv/wu7OdokY9ZKEDqcu1BDFnohyvGCoHuSXbEr90rPq1qeNW3XvTBIbNWHEF7gqge+xpUo6tQ==} - engines: {node: '>=14.0.0'} + resolution: + { integrity: sha512-Tb/BIhJzb0pa5zv/wu7OdokY9ZKEDqcu1BDFnohyvGCoHuSXbEr90rPq1qeNW3XvTBIbNWHEF7gqge+xpUo6tQ== } + engines: { node: '>=14.0.0' } deprecated: This package has been replaced by @base-ui-components/react peerDependencies: '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 @@ -689,11 +784,13 @@ packages: optional: true '@mui/core-downloads-tracker@5.18.0': - resolution: {integrity: sha512-jbhwoQ1AY200PSSOrNXmrFCaSDSJWP7qk6urkTmIirvRXDROkqe+QwcLlUiw/PrREwsIF/vm3/dAXvjlMHF0RA==} + resolution: + { integrity: sha512-jbhwoQ1AY200PSSOrNXmrFCaSDSJWP7qk6urkTmIirvRXDROkqe+QwcLlUiw/PrREwsIF/vm3/dAXvjlMHF0RA== } '@mui/icons-material@5.17.1': - resolution: {integrity: sha512-CN86LocjkunFGG0yPlO4bgqHkNGgaEOEc3X/jG5Bzm401qYw79/SaLrofA7yAKCCXAGdIGnLoMHohc3+ubs95A==} - engines: {node: '>=12.0.0'} + resolution: + { integrity: sha512-CN86LocjkunFGG0yPlO4bgqHkNGgaEOEc3X/jG5Bzm401qYw79/SaLrofA7yAKCCXAGdIGnLoMHohc3+ubs95A== } + engines: { node: '>=12.0.0' } peerDependencies: '@mui/material': ^5.0.0 '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 @@ -703,8 +800,9 @@ packages: optional: true '@mui/lab@5.0.0-alpha.176': - resolution: {integrity: sha512-DcZt1BAz4CDMUFGUvKqRh6W0sehmPj5luVHPx4vzSNnXj8xFvOdHwvNZ0bzNXy/Ol+81bkxcHQoIG2VOJuLnbw==} - engines: {node: '>=12.0.0'} + resolution: + { integrity: sha512-DcZt1BAz4CDMUFGUvKqRh6W0sehmPj5luVHPx4vzSNnXj8xFvOdHwvNZ0bzNXy/Ol+81bkxcHQoIG2VOJuLnbw== } + engines: { node: '>=12.0.0' } peerDependencies: '@emotion/react': ^11.5.0 '@emotion/styled': ^11.3.0 @@ -721,8 +819,9 @@ packages: optional: true '@mui/material@5.17.1': - resolution: {integrity: sha512-2B33kQf+GmPnrvXXweWAx+crbiUEsxCdCN979QDYnlH9ox4pd+0/IBriWLV+l6ORoBF60w39cWjFnJYGFdzXcw==} - engines: {node: '>=12.0.0'} + resolution: + { integrity: sha512-2B33kQf+GmPnrvXXweWAx+crbiUEsxCdCN979QDYnlH9ox4pd+0/IBriWLV+l6ORoBF60w39cWjFnJYGFdzXcw== } + engines: { node: '>=12.0.0' } peerDependencies: '@emotion/react': ^11.5.0 '@emotion/styled': ^11.3.0 @@ -738,8 +837,9 @@ packages: optional: true '@mui/private-theming@5.17.1': - resolution: {integrity: sha512-XMxU0NTYcKqdsG8LRmSoxERPXwMbp16sIXPcLVgLGII/bVNagX0xaheWAwFv8+zDK7tI3ajllkuD3GZZE++ICQ==} - engines: {node: '>=12.0.0'} + resolution: + { integrity: sha512-XMxU0NTYcKqdsG8LRmSoxERPXwMbp16sIXPcLVgLGII/bVNagX0xaheWAwFv8+zDK7tI3ajllkuD3GZZE++ICQ== } + engines: { node: '>=12.0.0' } peerDependencies: '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 react: ^17.0.0 || ^18.0.0 || ^19.0.0 @@ -748,8 +848,9 @@ packages: optional: true '@mui/styled-engine@5.18.0': - resolution: {integrity: sha512-BN/vKV/O6uaQh2z5rXV+MBlVrEkwoS/TK75rFQ2mjxA7+NBo8qtTAOA4UaM0XeJfn7kh2wZ+xQw2HAx0u+TiBg==} - engines: {node: '>=12.0.0'} + resolution: + { integrity: sha512-BN/vKV/O6uaQh2z5rXV+MBlVrEkwoS/TK75rFQ2mjxA7+NBo8qtTAOA4UaM0XeJfn7kh2wZ+xQw2HAx0u+TiBg== } + engines: { node: '>=12.0.0' } peerDependencies: '@emotion/react': ^11.4.1 '@emotion/styled': ^11.3.0 @@ -761,8 +862,9 @@ packages: optional: true '@mui/system@5.17.1': - resolution: {integrity: sha512-aJrmGfQpyF0U4D4xYwA6ueVtQcEMebET43CUmKMP7e7iFh3sMIF3sBR0l8Urb4pqx1CBjHAaWgB0ojpND4Q3Jg==} - engines: {node: '>=12.0.0'} + resolution: + { integrity: sha512-aJrmGfQpyF0U4D4xYwA6ueVtQcEMebET43CUmKMP7e7iFh3sMIF3sBR0l8Urb4pqx1CBjHAaWgB0ojpND4Q3Jg== } + engines: { node: '>=12.0.0' } peerDependencies: '@emotion/react': ^11.5.0 '@emotion/styled': ^11.3.0 @@ -777,7 +879,8 @@ packages: optional: true '@mui/types@7.2.24': - resolution: {integrity: sha512-3c8tRt/CbWZ+pEg7QpSwbdxOk36EfmhbKf6AGZsD1EcLDLTSZoxxJ86FVtcjxvjuhdyBiWKSTGZFaXCnidO2kw==} + resolution: + { integrity: sha512-3c8tRt/CbWZ+pEg7QpSwbdxOk36EfmhbKf6AGZsD1EcLDLTSZoxxJ86FVtcjxvjuhdyBiWKSTGZFaXCnidO2kw== } peerDependencies: '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 peerDependenciesMeta: @@ -785,8 +888,9 @@ packages: optional: true '@mui/utils@5.17.1': - resolution: {integrity: sha512-jEZ8FTqInt2WzxDV8bhImWBqeQRD99c/id/fq83H0ER9tFl+sfZlaAoCdznGvbSQQ9ividMxqSV2c7cC1vBcQg==} - engines: {node: '>=12.0.0'} + resolution: + { integrity: sha512-jEZ8FTqInt2WzxDV8bhImWBqeQRD99c/id/fq83H0ER9tFl+sfZlaAoCdznGvbSQQ9ividMxqSV2c7cC1vBcQg== } + engines: { node: '>=12.0.0' } peerDependencies: '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 react: ^17.0.0 || ^18.0.0 || ^19.0.0 @@ -795,8 +899,9 @@ packages: optional: true '@mui/utils@6.4.9': - resolution: {integrity: sha512-Y12Q9hbK9g+ZY0T3Rxrx9m2m10gaphDuUMgWxyV5kNJevVxXYCLclYUCC9vXaIk1/NdNDTcW2Yfr2OGvNFNmHg==} - engines: {node: '>=14.0.0'} + resolution: + { integrity: sha512-Y12Q9hbK9g+ZY0T3Rxrx9m2m10gaphDuUMgWxyV5kNJevVxXYCLclYUCC9vXaIk1/NdNDTcW2Yfr2OGvNFNmHg== } + engines: { node: '>=14.0.0' } peerDependencies: '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 react: ^17.0.0 || ^18.0.0 || ^19.0.0 @@ -805,8 +910,9 @@ packages: optional: true '@mui/x-date-pickers@6.20.2': - resolution: {integrity: sha512-x1jLg8R+WhvkmUETRfX2wC+xJreMii78EXKLl6r3G+ggcAZlPyt0myID1Amf6hvJb9CtR7CgUo8BwR+1Vx9Ggw==} - engines: {node: '>=14.0.0'} + resolution: + { integrity: sha512-x1jLg8R+WhvkmUETRfX2wC+xJreMii78EXKLl6r3G+ggcAZlPyt0myID1Amf6hvJb9CtR7CgUo8BwR+1Vx9Ggw== } + engines: { node: '>=14.0.0' } peerDependencies: '@emotion/react': ^11.9.0 '@emotion/styled': ^11.8.1 @@ -842,351 +948,419 @@ packages: optional: true '@nodelib/fs.scandir@2.1.5': - resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} - engines: {node: '>= 8'} + resolution: + { integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== } + engines: { node: '>= 8' } '@nodelib/fs.stat@2.0.5': - resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} - engines: {node: '>= 8'} + resolution: + { integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== } + engines: { node: '>= 8' } '@nodelib/fs.walk@1.2.8': - resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} - engines: {node: '>= 8'} + resolution: + { integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== } + engines: { node: '>= 8' } '@opentelemetry/api-logs@0.57.2': - resolution: {integrity: sha512-uIX52NnTM0iBh84MShlpouI7UKqkZ7MrUszTmaypHBu4r7NofznSnQRfJ+uUeDtQDj6w8eFGg5KBLDAwAPz1+A==} - engines: {node: '>=14'} + resolution: + { integrity: sha512-uIX52NnTM0iBh84MShlpouI7UKqkZ7MrUszTmaypHBu4r7NofznSnQRfJ+uUeDtQDj6w8eFGg5KBLDAwAPz1+A== } + engines: { node: '>=14' } '@opentelemetry/api@1.9.0': - resolution: {integrity: sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==} - engines: {node: '>=8.0.0'} + resolution: + { integrity: sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg== } + engines: { node: '>=8.0.0' } '@opentelemetry/context-async-hooks@1.30.1': - resolution: {integrity: sha512-s5vvxXPVdjqS3kTLKMeBMvop9hbWkwzBpu+mUO2M7sZtlkyDJGwFe33wRKnbaYDo8ExRVBIIdwIGrqpxHuKttA==} - engines: {node: '>=14'} + resolution: + { integrity: sha512-s5vvxXPVdjqS3kTLKMeBMvop9hbWkwzBpu+mUO2M7sZtlkyDJGwFe33wRKnbaYDo8ExRVBIIdwIGrqpxHuKttA== } + engines: { node: '>=14' } peerDependencies: '@opentelemetry/api': '>=1.0.0 <1.10.0' '@opentelemetry/core@1.30.1': - resolution: {integrity: sha512-OOCM2C/QIURhJMuKaekP3TRBxBKxG/TWWA0TL2J6nXUtDnuCtccy49LUJF8xPFXMX+0LMcxFpCo8M9cGY1W6rQ==} - engines: {node: '>=14'} + resolution: + { integrity: sha512-OOCM2C/QIURhJMuKaekP3TRBxBKxG/TWWA0TL2J6nXUtDnuCtccy49LUJF8xPFXMX+0LMcxFpCo8M9cGY1W6rQ== } + engines: { node: '>=14' } peerDependencies: '@opentelemetry/api': '>=1.0.0 <1.10.0' '@opentelemetry/instrumentation-amqplib@0.46.1': - resolution: {integrity: sha512-AyXVnlCf/xV3K/rNumzKxZqsULyITJH6OVLiW6730JPRqWA7Zc9bvYoVNpN6iOpTU8CasH34SU/ksVJmObFibQ==} - engines: {node: '>=14'} + resolution: + { integrity: sha512-AyXVnlCf/xV3K/rNumzKxZqsULyITJH6OVLiW6730JPRqWA7Zc9bvYoVNpN6iOpTU8CasH34SU/ksVJmObFibQ== } + engines: { node: '>=14' } peerDependencies: '@opentelemetry/api': ^1.3.0 '@opentelemetry/instrumentation-connect@0.43.1': - resolution: {integrity: sha512-ht7YGWQuV5BopMcw5Q2hXn3I8eG8TH0J/kc/GMcW4CuNTgiP6wCu44BOnucJWL3CmFWaRHI//vWyAhaC8BwePw==} - engines: {node: '>=14'} + resolution: + { integrity: sha512-ht7YGWQuV5BopMcw5Q2hXn3I8eG8TH0J/kc/GMcW4CuNTgiP6wCu44BOnucJWL3CmFWaRHI//vWyAhaC8BwePw== } + engines: { node: '>=14' } peerDependencies: '@opentelemetry/api': ^1.3.0 '@opentelemetry/instrumentation-dataloader@0.16.1': - resolution: {integrity: sha512-K/qU4CjnzOpNkkKO4DfCLSQshejRNAJtd4esgigo/50nxCB6XCyi1dhAblUHM9jG5dRm8eu0FB+t87nIo99LYQ==} - engines: {node: '>=14'} + resolution: + { integrity: sha512-K/qU4CjnzOpNkkKO4DfCLSQshejRNAJtd4esgigo/50nxCB6XCyi1dhAblUHM9jG5dRm8eu0FB+t87nIo99LYQ== } + engines: { node: '>=14' } peerDependencies: '@opentelemetry/api': ^1.3.0 '@opentelemetry/instrumentation-express@0.47.1': - resolution: {integrity: sha512-QNXPTWteDclR2B4pDFpz0TNghgB33UMjUt14B+BZPmtH1MwUFAfLHBaP5If0Z5NZC+jaH8oF2glgYjrmhZWmSw==} - engines: {node: '>=14'} + resolution: + { integrity: sha512-QNXPTWteDclR2B4pDFpz0TNghgB33UMjUt14B+BZPmtH1MwUFAfLHBaP5If0Z5NZC+jaH8oF2glgYjrmhZWmSw== } + engines: { node: '>=14' } peerDependencies: '@opentelemetry/api': ^1.3.0 '@opentelemetry/instrumentation-fs@0.19.1': - resolution: {integrity: sha512-6g0FhB3B9UobAR60BGTcXg4IHZ6aaYJzp0Ki5FhnxyAPt8Ns+9SSvgcrnsN2eGmk3RWG5vYycUGOEApycQL24A==} - engines: {node: '>=14'} + resolution: + { integrity: sha512-6g0FhB3B9UobAR60BGTcXg4IHZ6aaYJzp0Ki5FhnxyAPt8Ns+9SSvgcrnsN2eGmk3RWG5vYycUGOEApycQL24A== } + engines: { node: '>=14' } peerDependencies: '@opentelemetry/api': ^1.3.0 '@opentelemetry/instrumentation-generic-pool@0.43.1': - resolution: {integrity: sha512-M6qGYsp1cURtvVLGDrPPZemMFEbuMmCXgQYTReC/IbimV5sGrLBjB+/hANUpRZjX67nGLdKSVLZuQQAiNz+sww==} - engines: {node: '>=14'} + resolution: + { integrity: sha512-M6qGYsp1cURtvVLGDrPPZemMFEbuMmCXgQYTReC/IbimV5sGrLBjB+/hANUpRZjX67nGLdKSVLZuQQAiNz+sww== } + engines: { node: '>=14' } peerDependencies: '@opentelemetry/api': ^1.3.0 '@opentelemetry/instrumentation-graphql@0.47.1': - resolution: {integrity: sha512-EGQRWMGqwiuVma8ZLAZnExQ7sBvbOx0N/AE/nlafISPs8S+QtXX+Viy6dcQwVWwYHQPAcuY3bFt3xgoAwb4ZNQ==} - engines: {node: '>=14'} + resolution: + { integrity: sha512-EGQRWMGqwiuVma8ZLAZnExQ7sBvbOx0N/AE/nlafISPs8S+QtXX+Viy6dcQwVWwYHQPAcuY3bFt3xgoAwb4ZNQ== } + engines: { node: '>=14' } peerDependencies: '@opentelemetry/api': ^1.3.0 '@opentelemetry/instrumentation-hapi@0.45.2': - resolution: {integrity: sha512-7Ehow/7Wp3aoyCrZwQpU7a2CnoMq0XhIcioFuKjBb0PLYfBfmTsFTUyatlHu0fRxhwcRsSQRTvEhmZu8CppBpQ==} - engines: {node: '>=14'} + resolution: + { integrity: sha512-7Ehow/7Wp3aoyCrZwQpU7a2CnoMq0XhIcioFuKjBb0PLYfBfmTsFTUyatlHu0fRxhwcRsSQRTvEhmZu8CppBpQ== } + engines: { node: '>=14' } peerDependencies: '@opentelemetry/api': ^1.3.0 '@opentelemetry/instrumentation-http@0.57.2': - resolution: {integrity: sha512-1Uz5iJ9ZAlFOiPuwYg29Bf7bJJc/GeoeJIFKJYQf67nTVKFe8RHbEtxgkOmK4UGZNHKXcpW4P8cWBYzBn1USpg==} - engines: {node: '>=14'} + resolution: + { integrity: sha512-1Uz5iJ9ZAlFOiPuwYg29Bf7bJJc/GeoeJIFKJYQf67nTVKFe8RHbEtxgkOmK4UGZNHKXcpW4P8cWBYzBn1USpg== } + engines: { node: '>=14' } peerDependencies: '@opentelemetry/api': ^1.3.0 '@opentelemetry/instrumentation-ioredis@0.47.1': - resolution: {integrity: sha512-OtFGSN+kgk/aoKgdkKQnBsQFDiG8WdCxu+UrHr0bXScdAmtSzLSraLo7wFIb25RVHfRWvzI5kZomqJYEg/l1iA==} - engines: {node: '>=14'} + resolution: + { integrity: sha512-OtFGSN+kgk/aoKgdkKQnBsQFDiG8WdCxu+UrHr0bXScdAmtSzLSraLo7wFIb25RVHfRWvzI5kZomqJYEg/l1iA== } + engines: { node: '>=14' } peerDependencies: '@opentelemetry/api': ^1.3.0 '@opentelemetry/instrumentation-kafkajs@0.7.1': - resolution: {integrity: sha512-OtjaKs8H7oysfErajdYr1yuWSjMAectT7Dwr+axIoZqT9lmEOkD/H/3rgAs8h/NIuEi2imSXD+vL4MZtOuJfqQ==} - engines: {node: '>=14'} + resolution: + { integrity: sha512-OtjaKs8H7oysfErajdYr1yuWSjMAectT7Dwr+axIoZqT9lmEOkD/H/3rgAs8h/NIuEi2imSXD+vL4MZtOuJfqQ== } + engines: { node: '>=14' } peerDependencies: '@opentelemetry/api': ^1.3.0 '@opentelemetry/instrumentation-knex@0.44.1': - resolution: {integrity: sha512-U4dQxkNhvPexffjEmGwCq68FuftFK15JgUF05y/HlK3M6W/G2iEaACIfXdSnwVNe9Qh0sPfw8LbOPxrWzGWGMQ==} - engines: {node: '>=14'} + resolution: + { integrity: sha512-U4dQxkNhvPexffjEmGwCq68FuftFK15JgUF05y/HlK3M6W/G2iEaACIfXdSnwVNe9Qh0sPfw8LbOPxrWzGWGMQ== } + engines: { node: '>=14' } peerDependencies: '@opentelemetry/api': ^1.3.0 '@opentelemetry/instrumentation-koa@0.47.1': - resolution: {integrity: sha512-l/c+Z9F86cOiPJUllUCt09v+kICKvT+Vg1vOAJHtHPsJIzurGayucfCMq2acd/A/yxeNWunl9d9eqZ0G+XiI6A==} - engines: {node: '>=14'} + resolution: + { integrity: sha512-l/c+Z9F86cOiPJUllUCt09v+kICKvT+Vg1vOAJHtHPsJIzurGayucfCMq2acd/A/yxeNWunl9d9eqZ0G+XiI6A== } + engines: { node: '>=14' } peerDependencies: '@opentelemetry/api': ^1.3.0 '@opentelemetry/instrumentation-lru-memoizer@0.44.1': - resolution: {integrity: sha512-5MPkYCvG2yw7WONEjYj5lr5JFehTobW7wX+ZUFy81oF2lr9IPfZk9qO+FTaM0bGEiymwfLwKe6jE15nHn1nmHg==} - engines: {node: '>=14'} + resolution: + { integrity: sha512-5MPkYCvG2yw7WONEjYj5lr5JFehTobW7wX+ZUFy81oF2lr9IPfZk9qO+FTaM0bGEiymwfLwKe6jE15nHn1nmHg== } + engines: { node: '>=14' } peerDependencies: '@opentelemetry/api': ^1.3.0 '@opentelemetry/instrumentation-mongodb@0.52.0': - resolution: {integrity: sha512-1xmAqOtRUQGR7QfJFfGV/M2kC7wmI2WgZdpru8hJl3S0r4hW0n3OQpEHlSGXJAaNFyvT+ilnwkT+g5L4ljHR6g==} - engines: {node: '>=14'} + resolution: + { integrity: sha512-1xmAqOtRUQGR7QfJFfGV/M2kC7wmI2WgZdpru8hJl3S0r4hW0n3OQpEHlSGXJAaNFyvT+ilnwkT+g5L4ljHR6g== } + engines: { node: '>=14' } peerDependencies: '@opentelemetry/api': ^1.3.0 '@opentelemetry/instrumentation-mongoose@0.46.1': - resolution: {integrity: sha512-3kINtW1LUTPkiXFRSSBmva1SXzS/72we/jL22N+BnF3DFcoewkdkHPYOIdAAk9gSicJ4d5Ojtt1/HeibEc5OQg==} - engines: {node: '>=14'} + resolution: + { integrity: sha512-3kINtW1LUTPkiXFRSSBmva1SXzS/72we/jL22N+BnF3DFcoewkdkHPYOIdAAk9gSicJ4d5Ojtt1/HeibEc5OQg== } + engines: { node: '>=14' } peerDependencies: '@opentelemetry/api': ^1.3.0 '@opentelemetry/instrumentation-mysql2@0.45.2': - resolution: {integrity: sha512-h6Ad60FjCYdJZ5DTz1Lk2VmQsShiViKe0G7sYikb0GHI0NVvApp2XQNRHNjEMz87roFttGPLHOYVPlfy+yVIhQ==} - engines: {node: '>=14'} + resolution: + { integrity: sha512-h6Ad60FjCYdJZ5DTz1Lk2VmQsShiViKe0G7sYikb0GHI0NVvApp2XQNRHNjEMz87roFttGPLHOYVPlfy+yVIhQ== } + engines: { node: '>=14' } peerDependencies: '@opentelemetry/api': ^1.3.0 '@opentelemetry/instrumentation-mysql@0.45.1': - resolution: {integrity: sha512-TKp4hQ8iKQsY7vnp/j0yJJ4ZsP109Ht6l4RHTj0lNEG1TfgTrIH5vJMbgmoYXWzNHAqBH2e7fncN12p3BP8LFg==} - engines: {node: '>=14'} + resolution: + { integrity: sha512-TKp4hQ8iKQsY7vnp/j0yJJ4ZsP109Ht6l4RHTj0lNEG1TfgTrIH5vJMbgmoYXWzNHAqBH2e7fncN12p3BP8LFg== } + engines: { node: '>=14' } peerDependencies: '@opentelemetry/api': ^1.3.0 '@opentelemetry/instrumentation-pg@0.51.1': - resolution: {integrity: sha512-QxgjSrxyWZc7Vk+qGSfsejPVFL1AgAJdSBMYZdDUbwg730D09ub3PXScB9d04vIqPriZ+0dqzjmQx0yWKiCi2Q==} - engines: {node: '>=14'} + resolution: + { integrity: sha512-QxgjSrxyWZc7Vk+qGSfsejPVFL1AgAJdSBMYZdDUbwg730D09ub3PXScB9d04vIqPriZ+0dqzjmQx0yWKiCi2Q== } + engines: { node: '>=14' } peerDependencies: '@opentelemetry/api': ^1.3.0 '@opentelemetry/instrumentation-redis-4@0.46.1': - resolution: {integrity: sha512-UMqleEoabYMsWoTkqyt9WAzXwZ4BlFZHO40wr3d5ZvtjKCHlD4YXLm+6OLCeIi/HkX7EXvQaz8gtAwkwwSEvcQ==} - engines: {node: '>=14'} + resolution: + { integrity: sha512-UMqleEoabYMsWoTkqyt9WAzXwZ4BlFZHO40wr3d5ZvtjKCHlD4YXLm+6OLCeIi/HkX7EXvQaz8gtAwkwwSEvcQ== } + engines: { node: '>=14' } peerDependencies: '@opentelemetry/api': ^1.3.0 '@opentelemetry/instrumentation-tedious@0.18.1': - resolution: {integrity: sha512-5Cuy/nj0HBaH+ZJ4leuD7RjgvA844aY2WW+B5uLcWtxGjRZl3MNLuxnNg5DYWZNPO+NafSSnra0q49KWAHsKBg==} - engines: {node: '>=14'} + resolution: + { integrity: sha512-5Cuy/nj0HBaH+ZJ4leuD7RjgvA844aY2WW+B5uLcWtxGjRZl3MNLuxnNg5DYWZNPO+NafSSnra0q49KWAHsKBg== } + engines: { node: '>=14' } peerDependencies: '@opentelemetry/api': ^1.3.0 '@opentelemetry/instrumentation-undici@0.10.1': - resolution: {integrity: sha512-rkOGikPEyRpMCmNu9AQuV5dtRlDmJp2dK5sw8roVshAGoB6hH/3QjDtRhdwd75SsJwgynWUNRUYe0wAkTo16tQ==} - engines: {node: '>=14'} + resolution: + { integrity: sha512-rkOGikPEyRpMCmNu9AQuV5dtRlDmJp2dK5sw8roVshAGoB6hH/3QjDtRhdwd75SsJwgynWUNRUYe0wAkTo16tQ== } + engines: { node: '>=14' } peerDependencies: '@opentelemetry/api': ^1.7.0 '@opentelemetry/instrumentation@0.57.2': - resolution: {integrity: sha512-BdBGhQBh8IjZ2oIIX6F2/Q3LKm/FDDKi6ccYKcBTeilh6SNdNKveDOLk73BkSJjQLJk6qe4Yh+hHw1UPhCDdrg==} - engines: {node: '>=14'} + resolution: + { integrity: sha512-BdBGhQBh8IjZ2oIIX6F2/Q3LKm/FDDKi6ccYKcBTeilh6SNdNKveDOLk73BkSJjQLJk6qe4Yh+hHw1UPhCDdrg== } + engines: { node: '>=14' } peerDependencies: '@opentelemetry/api': ^1.3.0 '@opentelemetry/redis-common@0.36.2': - resolution: {integrity: sha512-faYX1N0gpLhej/6nyp6bgRjzAKXn5GOEMYY7YhciSfCoITAktLUtQ36d24QEWNA1/WA1y6qQunCe0OhHRkVl9g==} - engines: {node: '>=14'} + resolution: + { integrity: sha512-faYX1N0gpLhej/6nyp6bgRjzAKXn5GOEMYY7YhciSfCoITAktLUtQ36d24QEWNA1/WA1y6qQunCe0OhHRkVl9g== } + engines: { node: '>=14' } '@opentelemetry/resources@1.30.1': - resolution: {integrity: sha512-5UxZqiAgLYGFjS4s9qm5mBVo433u+dSPUFWVWXmLAD4wB65oMCoXaJP1KJa9DIYYMeHu3z4BZcStG3LC593cWA==} - engines: {node: '>=14'} + resolution: + { integrity: sha512-5UxZqiAgLYGFjS4s9qm5mBVo433u+dSPUFWVWXmLAD4wB65oMCoXaJP1KJa9DIYYMeHu3z4BZcStG3LC593cWA== } + engines: { node: '>=14' } peerDependencies: '@opentelemetry/api': '>=1.0.0 <1.10.0' '@opentelemetry/sdk-trace-base@1.30.1': - resolution: {integrity: sha512-jVPgBbH1gCy2Lb7X0AVQ8XAfgg0pJ4nvl8/IiQA6nxOsPvS+0zMJaFSs2ltXe0J6C8dqjcnpyqINDJmU30+uOg==} - engines: {node: '>=14'} + resolution: + { integrity: sha512-jVPgBbH1gCy2Lb7X0AVQ8XAfgg0pJ4nvl8/IiQA6nxOsPvS+0zMJaFSs2ltXe0J6C8dqjcnpyqINDJmU30+uOg== } + engines: { node: '>=14' } peerDependencies: '@opentelemetry/api': '>=1.0.0 <1.10.0' '@opentelemetry/semantic-conventions@1.28.0': - resolution: {integrity: sha512-lp4qAiMTD4sNWW4DbKLBkfiMZ4jbAboJIGOQr5DvciMRI494OapieI9qiODpOt0XBr1LjIDy1xAGAnVs5supTA==} - engines: {node: '>=14'} + resolution: + { integrity: sha512-lp4qAiMTD4sNWW4DbKLBkfiMZ4jbAboJIGOQr5DvciMRI494OapieI9qiODpOt0XBr1LjIDy1xAGAnVs5supTA== } + engines: { node: '>=14' } '@opentelemetry/semantic-conventions@1.36.0': - resolution: {integrity: sha512-TtxJSRD8Ohxp6bKkhrm27JRHAxPczQA7idtcTOMYI+wQRRrfgqxHv1cFbCApcSnNjtXkmzFozn6jQtFrOmbjPQ==} - engines: {node: '>=14'} + resolution: + { integrity: sha512-TtxJSRD8Ohxp6bKkhrm27JRHAxPczQA7idtcTOMYI+wQRRrfgqxHv1cFbCApcSnNjtXkmzFozn6jQtFrOmbjPQ== } + engines: { node: '>=14' } '@opentelemetry/sql-common@0.40.1': - resolution: {integrity: sha512-nSDlnHSqzC3pXn/wZEZVLuAuJ1MYMXPBwtv2qAbCa3847SaHItdE7SzUq/Jtb0KZmh1zfAbNi3AAMjztTT4Ugg==} - engines: {node: '>=14'} + resolution: + { integrity: sha512-nSDlnHSqzC3pXn/wZEZVLuAuJ1MYMXPBwtv2qAbCa3847SaHItdE7SzUq/Jtb0KZmh1zfAbNi3AAMjztTT4Ugg== } + engines: { node: '>=14' } peerDependencies: '@opentelemetry/api': ^1.1.0 '@pkgr/core@0.2.7': - resolution: {integrity: sha512-YLT9Zo3oNPJoBjBc4q8G2mjU4tqIbf5CEOORbUUr48dCD9q3umJ3IPlVqOqDakPfd2HuwccBaqlGhN4Gmr5OWg==} - engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + resolution: + { integrity: sha512-YLT9Zo3oNPJoBjBc4q8G2mjU4tqIbf5CEOORbUUr48dCD9q3umJ3IPlVqOqDakPfd2HuwccBaqlGhN4Gmr5OWg== } + engines: { node: ^12.20.0 || ^14.18.0 || >=16.0.0 } '@popperjs/core@2.11.8': - resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==} + resolution: + { integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A== } '@prisma/instrumentation@6.11.1': - resolution: {integrity: sha512-mrZOev24EDhnefmnZX7WVVT7v+r9LttPRqf54ONvj6re4XMF7wFTpK2tLJi4XHB7fFp/6xhYbgRel8YV7gQiyA==} + resolution: + { integrity: sha512-mrZOev24EDhnefmnZX7WVVT7v+r9LttPRqf54ONvj6re4XMF7wFTpK2tLJi4XHB7fFp/6xhYbgRel8YV7gQiyA== } peerDependencies: '@opentelemetry/api': ^1.8 '@remix-run/router@1.23.0': - resolution: {integrity: sha512-O3rHJzAQKamUz1fvE0Qaw0xSFqsA/yafi2iqeE0pvdFtCO1viYx8QL6f3Ln/aCCTLxs68SLf0KPM9eSeM8yBnA==} - engines: {node: '>=14.0.0'} + resolution: + { integrity: sha512-O3rHJzAQKamUz1fvE0Qaw0xSFqsA/yafi2iqeE0pvdFtCO1viYx8QL6f3Ln/aCCTLxs68SLf0KPM9eSeM8yBnA== } + engines: { node: '>=14.0.0' } '@rolldown/pluginutils@1.0.0-beta.11': - resolution: {integrity: sha512-L/gAA/hyCSuzTF1ftlzUSI/IKr2POHsv1Dd78GfqkR83KMNuswWD61JxGV2L7nRwBBBSDr6R1gCkdTmoN7W4ag==} + resolution: + { integrity: sha512-L/gAA/hyCSuzTF1ftlzUSI/IKr2POHsv1Dd78GfqkR83KMNuswWD61JxGV2L7nRwBBBSDr6R1gCkdTmoN7W4ag== } '@rollup/rollup-android-arm-eabi@4.45.0': - resolution: {integrity: sha512-2o/FgACbji4tW1dzXOqAV15Eu7DdgbKsF2QKcxfG4xbh5iwU7yr5RRP5/U+0asQliSYv5M4o7BevlGIoSL0LXg==} + resolution: + { integrity: sha512-2o/FgACbji4tW1dzXOqAV15Eu7DdgbKsF2QKcxfG4xbh5iwU7yr5RRP5/U+0asQliSYv5M4o7BevlGIoSL0LXg== } cpu: [arm] os: [android] '@rollup/rollup-android-arm64@4.45.0': - resolution: {integrity: sha512-PSZ0SvMOjEAxwZeTx32eI/j5xSYtDCRxGu5k9zvzoY77xUNssZM+WV6HYBLROpY5CkXsbQjvz40fBb7WPwDqtQ==} + resolution: + { integrity: sha512-PSZ0SvMOjEAxwZeTx32eI/j5xSYtDCRxGu5k9zvzoY77xUNssZM+WV6HYBLROpY5CkXsbQjvz40fBb7WPwDqtQ== } cpu: [arm64] os: [android] '@rollup/rollup-darwin-arm64@4.45.0': - resolution: {integrity: sha512-BA4yPIPssPB2aRAWzmqzQ3y2/KotkLyZukVB7j3psK/U3nVJdceo6qr9pLM2xN6iRP/wKfxEbOb1yrlZH6sYZg==} + resolution: + { integrity: sha512-BA4yPIPssPB2aRAWzmqzQ3y2/KotkLyZukVB7j3psK/U3nVJdceo6qr9pLM2xN6iRP/wKfxEbOb1yrlZH6sYZg== } cpu: [arm64] os: [darwin] '@rollup/rollup-darwin-x64@4.45.0': - resolution: {integrity: sha512-Pr2o0lvTwsiG4HCr43Zy9xXrHspyMvsvEw4FwKYqhli4FuLE5FjcZzuQ4cfPe0iUFCvSQG6lACI0xj74FDZKRA==} + resolution: + { integrity: sha512-Pr2o0lvTwsiG4HCr43Zy9xXrHspyMvsvEw4FwKYqhli4FuLE5FjcZzuQ4cfPe0iUFCvSQG6lACI0xj74FDZKRA== } cpu: [x64] os: [darwin] '@rollup/rollup-freebsd-arm64@4.45.0': - resolution: {integrity: sha512-lYE8LkE5h4a/+6VnnLiL14zWMPnx6wNbDG23GcYFpRW1V9hYWHAw9lBZ6ZUIrOaoK7NliF1sdwYGiVmziUF4vA==} + resolution: + { integrity: sha512-lYE8LkE5h4a/+6VnnLiL14zWMPnx6wNbDG23GcYFpRW1V9hYWHAw9lBZ6ZUIrOaoK7NliF1sdwYGiVmziUF4vA== } cpu: [arm64] os: [freebsd] '@rollup/rollup-freebsd-x64@4.45.0': - resolution: {integrity: sha512-PVQWZK9sbzpvqC9Q0GlehNNSVHR+4m7+wET+7FgSnKG3ci5nAMgGmr9mGBXzAuE5SvguCKJ6mHL6vq1JaJ/gvw==} + resolution: + { integrity: sha512-PVQWZK9sbzpvqC9Q0GlehNNSVHR+4m7+wET+7FgSnKG3ci5nAMgGmr9mGBXzAuE5SvguCKJ6mHL6vq1JaJ/gvw== } cpu: [x64] os: [freebsd] '@rollup/rollup-linux-arm-gnueabihf@4.45.0': - resolution: {integrity: sha512-hLrmRl53prCcD+YXTfNvXd776HTxNh8wPAMllusQ+amcQmtgo3V5i/nkhPN6FakW+QVLoUUr2AsbtIRPFU3xIA==} + resolution: + { integrity: sha512-hLrmRl53prCcD+YXTfNvXd776HTxNh8wPAMllusQ+amcQmtgo3V5i/nkhPN6FakW+QVLoUUr2AsbtIRPFU3xIA== } cpu: [arm] os: [linux] '@rollup/rollup-linux-arm-musleabihf@4.45.0': - resolution: {integrity: sha512-XBKGSYcrkdiRRjl+8XvrUR3AosXU0NvF7VuqMsm7s5nRy+nt58ZMB19Jdp1RdqewLcaYnpk8zeVs/4MlLZEJxw==} + resolution: + { integrity: sha512-XBKGSYcrkdiRRjl+8XvrUR3AosXU0NvF7VuqMsm7s5nRy+nt58ZMB19Jdp1RdqewLcaYnpk8zeVs/4MlLZEJxw== } cpu: [arm] os: [linux] '@rollup/rollup-linux-arm64-gnu@4.45.0': - resolution: {integrity: sha512-fRvZZPUiBz7NztBE/2QnCS5AtqLVhXmUOPj9IHlfGEXkapgImf4W9+FSkL8cWqoAjozyUzqFmSc4zh2ooaeF6g==} + resolution: + { integrity: sha512-fRvZZPUiBz7NztBE/2QnCS5AtqLVhXmUOPj9IHlfGEXkapgImf4W9+FSkL8cWqoAjozyUzqFmSc4zh2ooaeF6g== } cpu: [arm64] os: [linux] '@rollup/rollup-linux-arm64-musl@4.45.0': - resolution: {integrity: sha512-Btv2WRZOcUGi8XU80XwIvzTg4U6+l6D0V6sZTrZx214nrwxw5nAi8hysaXj/mctyClWgesyuxbeLylCBNauimg==} + resolution: + { integrity: sha512-Btv2WRZOcUGi8XU80XwIvzTg4U6+l6D0V6sZTrZx214nrwxw5nAi8hysaXj/mctyClWgesyuxbeLylCBNauimg== } cpu: [arm64] os: [linux] '@rollup/rollup-linux-loongarch64-gnu@4.45.0': - resolution: {integrity: sha512-Li0emNnwtUZdLwHjQPBxn4VWztcrw/h7mgLyHiEI5Z0MhpeFGlzaiBHpSNVOMB/xucjXTTcO+dhv469Djr16KA==} + resolution: + { integrity: sha512-Li0emNnwtUZdLwHjQPBxn4VWztcrw/h7mgLyHiEI5Z0MhpeFGlzaiBHpSNVOMB/xucjXTTcO+dhv469Djr16KA== } cpu: [loong64] os: [linux] '@rollup/rollup-linux-powerpc64le-gnu@4.45.0': - resolution: {integrity: sha512-sB8+pfkYx2kvpDCfd63d5ScYT0Fz1LO6jIb2zLZvmK9ob2D8DeVqrmBDE0iDK8KlBVmsTNzrjr3G1xV4eUZhSw==} + resolution: + { integrity: sha512-sB8+pfkYx2kvpDCfd63d5ScYT0Fz1LO6jIb2zLZvmK9ob2D8DeVqrmBDE0iDK8KlBVmsTNzrjr3G1xV4eUZhSw== } cpu: [ppc64] os: [linux] '@rollup/rollup-linux-riscv64-gnu@4.45.0': - resolution: {integrity: sha512-5GQ6PFhh7E6jQm70p1aW05G2cap5zMOvO0se5JMecHeAdj5ZhWEHbJ4hiKpfi1nnnEdTauDXxPgXae/mqjow9w==} + resolution: + { integrity: sha512-5GQ6PFhh7E6jQm70p1aW05G2cap5zMOvO0se5JMecHeAdj5ZhWEHbJ4hiKpfi1nnnEdTauDXxPgXae/mqjow9w== } cpu: [riscv64] os: [linux] '@rollup/rollup-linux-riscv64-musl@4.45.0': - resolution: {integrity: sha512-N/euLsBd1rekWcuduakTo/dJw6U6sBP3eUq+RXM9RNfPuWTvG2w/WObDkIvJ2KChy6oxZmOSC08Ak2OJA0UiAA==} + resolution: + { integrity: sha512-N/euLsBd1rekWcuduakTo/dJw6U6sBP3eUq+RXM9RNfPuWTvG2w/WObDkIvJ2KChy6oxZmOSC08Ak2OJA0UiAA== } cpu: [riscv64] os: [linux] '@rollup/rollup-linux-s390x-gnu@4.45.0': - resolution: {integrity: sha512-2l9sA7d7QdikL0xQwNMO3xURBUNEWyHVHfAsHsUdq+E/pgLTUcCE+gih5PCdmyHmfTDeXUWVhqL0WZzg0nua3g==} + resolution: + { integrity: sha512-2l9sA7d7QdikL0xQwNMO3xURBUNEWyHVHfAsHsUdq+E/pgLTUcCE+gih5PCdmyHmfTDeXUWVhqL0WZzg0nua3g== } cpu: [s390x] os: [linux] '@rollup/rollup-linux-x64-gnu@4.45.0': - resolution: {integrity: sha512-XZdD3fEEQcwG2KrJDdEQu7NrHonPxxaV0/w2HpvINBdcqebz1aL+0vM2WFJq4DeiAVT6F5SUQas65HY5JDqoPw==} + resolution: + { integrity: sha512-XZdD3fEEQcwG2KrJDdEQu7NrHonPxxaV0/w2HpvINBdcqebz1aL+0vM2WFJq4DeiAVT6F5SUQas65HY5JDqoPw== } cpu: [x64] os: [linux] '@rollup/rollup-linux-x64-musl@4.45.0': - resolution: {integrity: sha512-7ayfgvtmmWgKWBkCGg5+xTQ0r5V1owVm67zTrsEY1008L5ro7mCyGYORomARt/OquB9KY7LpxVBZes+oSniAAQ==} + resolution: + { integrity: sha512-7ayfgvtmmWgKWBkCGg5+xTQ0r5V1owVm67zTrsEY1008L5ro7mCyGYORomARt/OquB9KY7LpxVBZes+oSniAAQ== } cpu: [x64] os: [linux] '@rollup/rollup-win32-arm64-msvc@4.45.0': - resolution: {integrity: sha512-B+IJgcBnE2bm93jEW5kHisqvPITs4ddLOROAcOc/diBgrEiQJJ6Qcjby75rFSmH5eMGrqJryUgJDhrfj942apQ==} + resolution: + { integrity: sha512-B+IJgcBnE2bm93jEW5kHisqvPITs4ddLOROAcOc/diBgrEiQJJ6Qcjby75rFSmH5eMGrqJryUgJDhrfj942apQ== } cpu: [arm64] os: [win32] '@rollup/rollup-win32-ia32-msvc@4.45.0': - resolution: {integrity: sha512-+CXwwG66g0/FpWOnP/v1HnrGVSOygK/osUbu3wPRy8ECXjoYKjRAyfxYpDQOfghC5qPJYLPH0oN4MCOjwgdMug==} + resolution: + { integrity: sha512-+CXwwG66g0/FpWOnP/v1HnrGVSOygK/osUbu3wPRy8ECXjoYKjRAyfxYpDQOfghC5qPJYLPH0oN4MCOjwgdMug== } cpu: [ia32] os: [win32] '@rollup/rollup-win32-x64-msvc@4.45.0': - resolution: {integrity: sha512-SRf1cytG7wqcHVLrBc9VtPK4pU5wxiB/lNIkNmW2ApKXIg+RpqwHfsaEK+e7eH4A1BpI6BX/aBWXxZCIrJg3uA==} + resolution: + { integrity: sha512-SRf1cytG7wqcHVLrBc9VtPK4pU5wxiB/lNIkNmW2ApKXIg+RpqwHfsaEK+e7eH4A1BpI6BX/aBWXxZCIrJg3uA== } cpu: [x64] os: [win32] '@sentry-internal/browser-utils@9.38.0': - resolution: {integrity: sha512-BkTaMPm4pjgoT1qNsLX5e3HjTCwBmsR/OGyKHFpMUnN+HINi9L1nGGbRroOEtfU49vMKi8MlM7HpuzzYV/3D1A==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-BkTaMPm4pjgoT1qNsLX5e3HjTCwBmsR/OGyKHFpMUnN+HINi9L1nGGbRroOEtfU49vMKi8MlM7HpuzzYV/3D1A== } + engines: { node: '>=18' } '@sentry-internal/feedback@9.38.0': - resolution: {integrity: sha512-vDVufE9WLqHCmUL2sa3nIKz5ARaBdaqCG+b9/hwkmkLnqaQUBiHE+ArxoYuc2toWqaELxSHcMDp2ajkeDBQeLA==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-vDVufE9WLqHCmUL2sa3nIKz5ARaBdaqCG+b9/hwkmkLnqaQUBiHE+ArxoYuc2toWqaELxSHcMDp2ajkeDBQeLA== } + engines: { node: '>=18' } '@sentry-internal/replay-canvas@9.38.0': - resolution: {integrity: sha512-87BZDTjszdaSB5p0CTiVav2QgxLMAab/6q1jcIUBzNsrXHZbqcoMaJmd446mCsQkR6wAccM/uAxJlgh9FIqA8w==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-87BZDTjszdaSB5p0CTiVav2QgxLMAab/6q1jcIUBzNsrXHZbqcoMaJmd446mCsQkR6wAccM/uAxJlgh9FIqA8w== } + engines: { node: '>=18' } '@sentry-internal/replay@9.38.0': - resolution: {integrity: sha512-LLZuQk5Khvco+EYKg2+woiSNMLyR4XZeoAdgvAa+HZriFoAQR6GFNAuu+TlynCDDt2H+w90HcIAV66NWFy8QoQ==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-LLZuQk5Khvco+EYKg2+woiSNMLyR4XZeoAdgvAa+HZriFoAQR6GFNAuu+TlynCDDt2H+w90HcIAV66NWFy8QoQ== } + engines: { node: '>=18' } '@sentry/browser@9.38.0': - resolution: {integrity: sha512-ZUIeU+3VUD3BntYgB2DkhBD6N9oybsuk1+U7yK1ezHIw/nvkPILcH6MZgPs0Km0RcWWozMUDSbdZNud9/isYmw==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-ZUIeU+3VUD3BntYgB2DkhBD6N9oybsuk1+U7yK1ezHIw/nvkPILcH6MZgPs0Km0RcWWozMUDSbdZNud9/isYmw== } + engines: { node: '>=18' } '@sentry/core@9.38.0': - resolution: {integrity: sha512-dUwSv1VXDfsrcY69a/cgZNDsFal6iYOf0C4T+/ylpmgYp5SVe3vQK+2FLXUMuvgnOf+kHO6IeW0RhnhSyUflmA==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-dUwSv1VXDfsrcY69a/cgZNDsFal6iYOf0C4T+/ylpmgYp5SVe3vQK+2FLXUMuvgnOf+kHO6IeW0RhnhSyUflmA== } + engines: { node: '>=18' } '@sentry/node-core@9.38.0': - resolution: {integrity: sha512-G0JmsntsvALoqS9iLTi4Jn1DcQB7gw9PY1Fmkdcdcf7i4EJEdRDX0tiD9ssDrcjgzzFPnm0PCrSAkIfTtd3Zyg==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-G0JmsntsvALoqS9iLTi4Jn1DcQB7gw9PY1Fmkdcdcf7i4EJEdRDX0tiD9ssDrcjgzzFPnm0PCrSAkIfTtd3Zyg== } + engines: { node: '>=18' } peerDependencies: '@opentelemetry/api': ^1.9.0 '@opentelemetry/context-async-hooks': ^1.30.1 || ^2.0.0 @@ -1197,12 +1371,14 @@ packages: '@opentelemetry/semantic-conventions': ^1.34.0 '@sentry/node@9.38.0': - resolution: {integrity: sha512-OhfRTge6hncSehrTBHpnz5R66OWRd8WMKn6ZoS0nwBmTfREjPkNRfOADIUqEElfyuaNj+gWsqTM1/E915pnZew==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-OhfRTge6hncSehrTBHpnz5R66OWRd8WMKn6ZoS0nwBmTfREjPkNRfOADIUqEElfyuaNj+gWsqTM1/E915pnZew== } + engines: { node: '>=18' } '@sentry/opentelemetry@9.38.0': - resolution: {integrity: sha512-Oa0kk4EiBMwCvHS5ZI50M/SMNfGM9ztsmedFEfpS+mZz8y9C5Artd0ukGK4OAYcSBggNVQkhmmhWbwpNnRNQiw==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-Oa0kk4EiBMwCvHS5ZI50M/SMNfGM9ztsmedFEfpS+mZz8y9C5Artd0ukGK4OAYcSBggNVQkhmmhWbwpNnRNQiw== } + engines: { node: '>=18' } peerDependencies: '@opentelemetry/api': ^1.9.0 '@opentelemetry/context-async-hooks': ^1.30.1 || ^2.0.0 @@ -1212,74 +1388,86 @@ packages: '@opentelemetry/semantic-conventions': ^1.34.0 '@sentry/react@9.38.0': - resolution: {integrity: sha512-MGnrzEJdwCEhGnQrFvljCGM+19agsC5ONAExRM+TuCVjeDJ/ifegZ4eEUyaGHt7YyjAUszddSbWbpEBUg2zBvQ==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-MGnrzEJdwCEhGnQrFvljCGM+19agsC5ONAExRM+TuCVjeDJ/ifegZ4eEUyaGHt7YyjAUszddSbWbpEBUg2zBvQ== } + engines: { node: '>=18' } peerDependencies: react: ^16.14.0 || 17.x || 18.x || 19.x '@swc/core-darwin-arm64@1.12.11': - resolution: {integrity: sha512-J19Jj9Y5x/N0loExH7W0OI9OwwoVyxutDdkyq1o/kgXyBqmmzV7Y/Q9QekI2Fm/qc5mNeAdP7aj4boY4AY/JPw==} - engines: {node: '>=10'} + resolution: + { integrity: sha512-J19Jj9Y5x/N0loExH7W0OI9OwwoVyxutDdkyq1o/kgXyBqmmzV7Y/Q9QekI2Fm/qc5mNeAdP7aj4boY4AY/JPw== } + engines: { node: '>=10' } cpu: [arm64] os: [darwin] '@swc/core-darwin-x64@1.12.11': - resolution: {integrity: sha512-PTuUQrfStQ6cjW+uprGO2lpQHy84/l0v+GqRqq8s/jdK55rFRjMfCeyf6FAR0l6saO5oNOQl+zWR1aNpj8pMQw==} - engines: {node: '>=10'} + resolution: + { integrity: sha512-PTuUQrfStQ6cjW+uprGO2lpQHy84/l0v+GqRqq8s/jdK55rFRjMfCeyf6FAR0l6saO5oNOQl+zWR1aNpj8pMQw== } + engines: { node: '>=10' } cpu: [x64] os: [darwin] '@swc/core-linux-arm-gnueabihf@1.12.11': - resolution: {integrity: sha512-poxBq152HsupOtnZilenvHmxZ9a8SRj4LtfxUnkMDNOGrZR9oxbQNwEzNKfi3RXEcXz+P8c0Rai1ubBazXv8oQ==} - engines: {node: '>=10'} + resolution: + { integrity: sha512-poxBq152HsupOtnZilenvHmxZ9a8SRj4LtfxUnkMDNOGrZR9oxbQNwEzNKfi3RXEcXz+P8c0Rai1ubBazXv8oQ== } + engines: { node: '>=10' } cpu: [arm] os: [linux] '@swc/core-linux-arm64-gnu@1.12.11': - resolution: {integrity: sha512-y1HNamR/D0Hc8xIE910ysyLe269UYiGaQPoLjQS0phzWFfWdMj9bHM++oydVXZ4RSWycO7KyJ3uvw4NilvyMKQ==} - engines: {node: '>=10'} + resolution: + { integrity: sha512-y1HNamR/D0Hc8xIE910ysyLe269UYiGaQPoLjQS0phzWFfWdMj9bHM++oydVXZ4RSWycO7KyJ3uvw4NilvyMKQ== } + engines: { node: '>=10' } cpu: [arm64] os: [linux] '@swc/core-linux-arm64-musl@1.12.11': - resolution: {integrity: sha512-LlBxPh/32pyQsu2emMEOFRm7poEFLsw12Y1mPY7FWZiZeptomKSOSHRzKDz9EolMiV4qhK1caP1lvW4vminYgQ==} - engines: {node: '>=10'} + resolution: + { integrity: sha512-LlBxPh/32pyQsu2emMEOFRm7poEFLsw12Y1mPY7FWZiZeptomKSOSHRzKDz9EolMiV4qhK1caP1lvW4vminYgQ== } + engines: { node: '>=10' } cpu: [arm64] os: [linux] '@swc/core-linux-x64-gnu@1.12.11': - resolution: {integrity: sha512-bOjiZB8O/1AzHkzjge1jqX62HGRIpOHqFUrGPfAln/NC6NR+Z2A78u3ixV7k5KesWZFhCV0YVGJL+qToL27myA==} - engines: {node: '>=10'} + resolution: + { integrity: sha512-bOjiZB8O/1AzHkzjge1jqX62HGRIpOHqFUrGPfAln/NC6NR+Z2A78u3ixV7k5KesWZFhCV0YVGJL+qToL27myA== } + engines: { node: '>=10' } cpu: [x64] os: [linux] '@swc/core-linux-x64-musl@1.12.11': - resolution: {integrity: sha512-4dzAtbT/m3/UjF045+33gLiHd8aSXJDoqof7gTtu4q0ZyAf7XJ3HHspz+/AvOJLVo4FHHdFcdXhmo/zi1nFn8A==} - engines: {node: '>=10'} + resolution: + { integrity: sha512-4dzAtbT/m3/UjF045+33gLiHd8aSXJDoqof7gTtu4q0ZyAf7XJ3HHspz+/AvOJLVo4FHHdFcdXhmo/zi1nFn8A== } + engines: { node: '>=10' } cpu: [x64] os: [linux] '@swc/core-win32-arm64-msvc@1.12.11': - resolution: {integrity: sha512-h8HiwBZErKvCAmjW92JvQp0iOqm6bncU4ac5jxBGkRApabpUenNJcj3h2g5O6GL5K6T9/WhnXE5gyq/s1fhPQg==} - engines: {node: '>=10'} + resolution: + { integrity: sha512-h8HiwBZErKvCAmjW92JvQp0iOqm6bncU4ac5jxBGkRApabpUenNJcj3h2g5O6GL5K6T9/WhnXE5gyq/s1fhPQg== } + engines: { node: '>=10' } cpu: [arm64] os: [win32] '@swc/core-win32-ia32-msvc@1.12.11': - resolution: {integrity: sha512-1pwr325mXRNUhxTtXmx1IokV5SiRL+6iDvnt3FRXj+X5UvXXKtg2zeyftk+03u8v8v8WUr5I32hIypVJPTNxNg==} - engines: {node: '>=10'} + resolution: + { integrity: sha512-1pwr325mXRNUhxTtXmx1IokV5SiRL+6iDvnt3FRXj+X5UvXXKtg2zeyftk+03u8v8v8WUr5I32hIypVJPTNxNg== } + engines: { node: '>=10' } cpu: [ia32] os: [win32] '@swc/core-win32-x64-msvc@1.12.11': - resolution: {integrity: sha512-5gggWo690Gvs7XiPxAmb5tHwzB9RTVXUV7AWoGb6bmyUd1OXYaebQF0HAOtade5jIoNhfQMQJ7QReRgt/d2jAA==} - engines: {node: '>=10'} + resolution: + { integrity: sha512-5gggWo690Gvs7XiPxAmb5tHwzB9RTVXUV7AWoGb6bmyUd1OXYaebQF0HAOtade5jIoNhfQMQJ7QReRgt/d2jAA== } + engines: { node: '>=10' } cpu: [x64] os: [win32] '@swc/core@1.12.11': - resolution: {integrity: sha512-P3GM+0lqjFctcp5HhR9mOcvLSX3SptI9L1aux0Fuvgt8oH4f92rCUrkodAa0U2ktmdjcyIiG37xg2mb/dSCYSA==} - engines: {node: '>=10'} + resolution: + { integrity: sha512-P3GM+0lqjFctcp5HhR9mOcvLSX3SptI9L1aux0Fuvgt8oH4f92rCUrkodAa0U2ktmdjcyIiG37xg2mb/dSCYSA== } + engines: { node: '>=10' } peerDependencies: '@swc/helpers': '>=0.5.17' peerDependenciesMeta: @@ -1287,71 +1475,84 @@ packages: optional: true '@swc/counter@0.1.3': - resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} + resolution: + { integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ== } '@swc/types@0.1.23': - resolution: {integrity: sha512-u1iIVZV9Q0jxY+yM2vw/hZGDNudsN85bBpTqzAQ9rzkxW9D+e3aEM4Han+ow518gSewkXgjmEK0BD79ZcNVgPw==} + resolution: + { integrity: sha512-u1iIVZV9Q0jxY+yM2vw/hZGDNudsN85bBpTqzAQ9rzkxW9D+e3aEM4Han+ow518gSewkXgjmEK0BD79ZcNVgPw== } '@tailwindcss/node@4.1.11': - resolution: {integrity: sha512-yzhzuGRmv5QyU9qLNg4GTlYI6STedBWRE7NjxP45CsFYYq9taI0zJXZBMqIC/c8fViNLhmrbpSFS57EoxUmD6Q==} + resolution: + { integrity: sha512-yzhzuGRmv5QyU9qLNg4GTlYI6STedBWRE7NjxP45CsFYYq9taI0zJXZBMqIC/c8fViNLhmrbpSFS57EoxUmD6Q== } '@tailwindcss/oxide-android-arm64@4.1.11': - resolution: {integrity: sha512-3IfFuATVRUMZZprEIx9OGDjG3Ou3jG4xQzNTvjDoKmU9JdmoCohQJ83MYd0GPnQIu89YoJqvMM0G3uqLRFtetg==} - engines: {node: '>= 10'} + resolution: + { integrity: sha512-3IfFuATVRUMZZprEIx9OGDjG3Ou3jG4xQzNTvjDoKmU9JdmoCohQJ83MYd0GPnQIu89YoJqvMM0G3uqLRFtetg== } + engines: { node: '>= 10' } cpu: [arm64] os: [android] '@tailwindcss/oxide-darwin-arm64@4.1.11': - resolution: {integrity: sha512-ESgStEOEsyg8J5YcMb1xl8WFOXfeBmrhAwGsFxxB2CxY9evy63+AtpbDLAyRkJnxLy2WsD1qF13E97uQyP1lfQ==} - engines: {node: '>= 10'} + resolution: + { integrity: sha512-ESgStEOEsyg8J5YcMb1xl8WFOXfeBmrhAwGsFxxB2CxY9evy63+AtpbDLAyRkJnxLy2WsD1qF13E97uQyP1lfQ== } + engines: { node: '>= 10' } cpu: [arm64] os: [darwin] '@tailwindcss/oxide-darwin-x64@4.1.11': - resolution: {integrity: sha512-EgnK8kRchgmgzG6jE10UQNaH9Mwi2n+yw1jWmof9Vyg2lpKNX2ioe7CJdf9M5f8V9uaQxInenZkOxnTVL3fhAw==} - engines: {node: '>= 10'} + resolution: + { integrity: sha512-EgnK8kRchgmgzG6jE10UQNaH9Mwi2n+yw1jWmof9Vyg2lpKNX2ioe7CJdf9M5f8V9uaQxInenZkOxnTVL3fhAw== } + engines: { node: '>= 10' } cpu: [x64] os: [darwin] '@tailwindcss/oxide-freebsd-x64@4.1.11': - resolution: {integrity: sha512-xdqKtbpHs7pQhIKmqVpxStnY1skuNh4CtbcyOHeX1YBE0hArj2romsFGb6yUmzkq/6M24nkxDqU8GYrKrz+UcA==} - engines: {node: '>= 10'} + resolution: + { integrity: sha512-xdqKtbpHs7pQhIKmqVpxStnY1skuNh4CtbcyOHeX1YBE0hArj2romsFGb6yUmzkq/6M24nkxDqU8GYrKrz+UcA== } + engines: { node: '>= 10' } cpu: [x64] os: [freebsd] '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.11': - resolution: {integrity: sha512-ryHQK2eyDYYMwB5wZL46uoxz2zzDZsFBwfjssgB7pzytAeCCa6glsiJGjhTEddq/4OsIjsLNMAiMlHNYnkEEeg==} - engines: {node: '>= 10'} + resolution: + { integrity: sha512-ryHQK2eyDYYMwB5wZL46uoxz2zzDZsFBwfjssgB7pzytAeCCa6glsiJGjhTEddq/4OsIjsLNMAiMlHNYnkEEeg== } + engines: { node: '>= 10' } cpu: [arm] os: [linux] '@tailwindcss/oxide-linux-arm64-gnu@4.1.11': - resolution: {integrity: sha512-mYwqheq4BXF83j/w75ewkPJmPZIqqP1nhoghS9D57CLjsh3Nfq0m4ftTotRYtGnZd3eCztgbSPJ9QhfC91gDZQ==} - engines: {node: '>= 10'} + resolution: + { integrity: sha512-mYwqheq4BXF83j/w75ewkPJmPZIqqP1nhoghS9D57CLjsh3Nfq0m4ftTotRYtGnZd3eCztgbSPJ9QhfC91gDZQ== } + engines: { node: '>= 10' } cpu: [arm64] os: [linux] '@tailwindcss/oxide-linux-arm64-musl@4.1.11': - resolution: {integrity: sha512-m/NVRFNGlEHJrNVk3O6I9ggVuNjXHIPoD6bqay/pubtYC9QIdAMpS+cswZQPBLvVvEF6GtSNONbDkZrjWZXYNQ==} - engines: {node: '>= 10'} + resolution: + { integrity: sha512-m/NVRFNGlEHJrNVk3O6I9ggVuNjXHIPoD6bqay/pubtYC9QIdAMpS+cswZQPBLvVvEF6GtSNONbDkZrjWZXYNQ== } + engines: { node: '>= 10' } cpu: [arm64] os: [linux] '@tailwindcss/oxide-linux-x64-gnu@4.1.11': - resolution: {integrity: sha512-YW6sblI7xukSD2TdbbaeQVDysIm/UPJtObHJHKxDEcW2exAtY47j52f8jZXkqE1krdnkhCMGqP3dbniu1Te2Fg==} - engines: {node: '>= 10'} + resolution: + { integrity: sha512-YW6sblI7xukSD2TdbbaeQVDysIm/UPJtObHJHKxDEcW2exAtY47j52f8jZXkqE1krdnkhCMGqP3dbniu1Te2Fg== } + engines: { node: '>= 10' } cpu: [x64] os: [linux] '@tailwindcss/oxide-linux-x64-musl@4.1.11': - resolution: {integrity: sha512-e3C/RRhGunWYNC3aSF7exsQkdXzQ/M+aYuZHKnw4U7KQwTJotnWsGOIVih0s2qQzmEzOFIJ3+xt7iq67K/p56Q==} - engines: {node: '>= 10'} + resolution: + { integrity: sha512-e3C/RRhGunWYNC3aSF7exsQkdXzQ/M+aYuZHKnw4U7KQwTJotnWsGOIVih0s2qQzmEzOFIJ3+xt7iq67K/p56Q== } + engines: { node: '>= 10' } cpu: [x64] os: [linux] '@tailwindcss/oxide-wasm32-wasi@4.1.11': - resolution: {integrity: sha512-Xo1+/GU0JEN/C/dvcammKHzeM6NqKovG+6921MR6oadee5XPBaKOumrJCXvopJ/Qb5TH7LX/UAywbqrP4lax0g==} - engines: {node: '>=14.0.0'} + resolution: + { integrity: sha512-Xo1+/GU0JEN/C/dvcammKHzeM6NqKovG+6921MR6oadee5XPBaKOumrJCXvopJ/Qb5TH7LX/UAywbqrP4lax0g== } + engines: { node: '>=14.0.0' } cpu: [wasm32] bundledDependencies: - '@napi-rs/wasm-runtime' @@ -1362,327 +1563,413 @@ packages: - tslib '@tailwindcss/oxide-win32-arm64-msvc@4.1.11': - resolution: {integrity: sha512-UgKYx5PwEKrac3GPNPf6HVMNhUIGuUh4wlDFR2jYYdkX6pL/rn73zTq/4pzUm8fOjAn5L8zDeHp9iXmUGOXZ+w==} - engines: {node: '>= 10'} + resolution: + { integrity: sha512-UgKYx5PwEKrac3GPNPf6HVMNhUIGuUh4wlDFR2jYYdkX6pL/rn73zTq/4pzUm8fOjAn5L8zDeHp9iXmUGOXZ+w== } + engines: { node: '>= 10' } cpu: [arm64] os: [win32] '@tailwindcss/oxide-win32-x64-msvc@4.1.11': - resolution: {integrity: sha512-YfHoggn1j0LK7wR82TOucWc5LDCguHnoS879idHekmmiR7g9HUtMw9MI0NHatS28u/Xlkfi9w5RJWgz2Dl+5Qg==} - engines: {node: '>= 10'} + resolution: + { integrity: sha512-YfHoggn1j0LK7wR82TOucWc5LDCguHnoS879idHekmmiR7g9HUtMw9MI0NHatS28u/Xlkfi9w5RJWgz2Dl+5Qg== } + engines: { node: '>= 10' } cpu: [x64] os: [win32] '@tailwindcss/oxide@4.1.11': - resolution: {integrity: sha512-Q69XzrtAhuyfHo+5/HMgr1lAiPP/G40OMFAnws7xcFEYqcypZmdW8eGXaOUIeOl1dzPJBPENXgbjsOyhg2nkrg==} - engines: {node: '>= 10'} + resolution: + { integrity: sha512-Q69XzrtAhuyfHo+5/HMgr1lAiPP/G40OMFAnws7xcFEYqcypZmdW8eGXaOUIeOl1dzPJBPENXgbjsOyhg2nkrg== } + engines: { node: '>= 10' } '@tailwindcss/postcss@4.1.11': - resolution: {integrity: sha512-q/EAIIpF6WpLhKEuQSEVMZNMIY8KhWoAemZ9eylNAih9jxMGAYPPWBn3I9QL/2jZ+e7OEz/tZkX5HwbBR4HohA==} + resolution: + { integrity: sha512-q/EAIIpF6WpLhKEuQSEVMZNMIY8KhWoAemZ9eylNAih9jxMGAYPPWBn3I9QL/2jZ+e7OEz/tZkX5HwbBR4HohA== } '@tanstack/eslint-plugin-query@5.83.1': - resolution: {integrity: sha512-tdkpPFfzkTksN9BIlT/qjixSAtKrsW6PUVRwdKWaOcag7DrD1vpki3UzzdfMQGDRGeg1Ue1Dg+rcl5FJGembNg==} + resolution: + { integrity: sha512-tdkpPFfzkTksN9BIlT/qjixSAtKrsW6PUVRwdKWaOcag7DrD1vpki3UzzdfMQGDRGeg1Ue1Dg+rcl5FJGembNg== } peerDependencies: eslint: ^8.57.0 || ^9.0.0 + '@tanstack/query-core@5.83.1': + resolution: + { integrity: sha512-OG69LQgT7jSp+5pPuCfzltq/+7l2xoweggjme9vlbCPa/d7D7zaqv5vN/S82SzSYZ4EDLTxNO1PWrv49RAS64Q== } + + '@tanstack/query-devtools@5.84.0': + resolution: + { integrity: sha512-fbF3n+z1rqhvd9EoGp5knHkv3p5B2Zml1yNRjh7sNXklngYI5RVIWUrUjZ1RIcEoscarUb0+bOvIs5x9dwzOXQ== } + + '@tanstack/react-query-devtools@5.84.1': + resolution: + { integrity: sha512-nle+OQ9B3Z3EG2R3ixvaNcJ6OeqGwmAc5iMDW6Vj+emLZkWRrN3BDsrzZQu414n34lpxplnC7z1jmKuU/scHCQ== } + peerDependencies: + '@tanstack/react-query': ^5.84.1 + react: ^18 || ^19 + + '@tanstack/react-query@5.84.1': + resolution: + { integrity: sha512-zo7EUygcWJMQfFNWDSG7CBhy8irje/XY0RDVKKV4IQJAysb+ZJkkJPcnQi+KboyGUgT+SQebRFoTqLuTtfoDLw== } + peerDependencies: + react: ^18 || ^19 + '@types/chai@5.2.2': - resolution: {integrity: sha512-8kB30R7Hwqf40JPiKhVzodJs2Qc1ZJ5zuT3uzw5Hq/dhNCl3G3l83jfpdI1e20BP348+fV7VIL/+FxaXkqBmWg==} + resolution: + { integrity: sha512-8kB30R7Hwqf40JPiKhVzodJs2Qc1ZJ5zuT3uzw5Hq/dhNCl3G3l83jfpdI1e20BP348+fV7VIL/+FxaXkqBmWg== } '@types/connect@3.4.38': - resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} + resolution: + { integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug== } '@types/deep-eql@4.0.2': - resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} + resolution: + { integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw== } '@types/estree@1.0.8': - resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + resolution: + { integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w== } '@types/file-saver@2.0.7': - resolution: {integrity: sha512-dNKVfHd/jk0SkR/exKGj2ggkB45MAkzvWCaqLUUgkyjITkGNzH8H+yUwr+BLJUBjZOe9w8X3wgmXhZDRg1ED6A==} + resolution: + { integrity: sha512-dNKVfHd/jk0SkR/exKGj2ggkB45MAkzvWCaqLUUgkyjITkGNzH8H+yUwr+BLJUBjZOe9w8X3wgmXhZDRg1ED6A== } '@types/history@4.7.11': - resolution: {integrity: sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==} + resolution: + { integrity: sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA== } '@types/is-base64@1.1.3': - resolution: {integrity: sha512-8h40c+MFeMKhEw8Ebckd11MEt9sngs4AAkvcZVfDYOFDd7FeTD80pTfm3uvepbWcld1zVkHW+WA6b7UaHAOU/w==} + resolution: + { integrity: sha512-8h40c+MFeMKhEw8Ebckd11MEt9sngs4AAkvcZVfDYOFDd7FeTD80pTfm3uvepbWcld1zVkHW+WA6b7UaHAOU/w== } '@types/json-schema@7.0.15': - resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + resolution: + { integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== } '@types/lodash-es@4.17.12': - resolution: {integrity: sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==} + resolution: + { integrity: sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ== } '@types/lodash@4.17.20': - resolution: {integrity: sha512-H3MHACvFUEiujabxhaI/ImO6gUrd8oOurg7LQtS7mbwIXA/cUqWrvBsaeJ23aZEPk1TAYkurjfMbSELfoCXlGA==} + resolution: + { integrity: sha512-H3MHACvFUEiujabxhaI/ImO6gUrd8oOurg7LQtS7mbwIXA/cUqWrvBsaeJ23aZEPk1TAYkurjfMbSELfoCXlGA== } '@types/mysql@2.15.26': - resolution: {integrity: sha512-DSLCOXhkvfS5WNNPbfn2KdICAmk8lLc+/PNvnPnF7gOdMZCxopXduqv0OQ13y/yA/zXTSikZZqVgybUxOEg6YQ==} + resolution: + { integrity: sha512-DSLCOXhkvfS5WNNPbfn2KdICAmk8lLc+/PNvnPnF7gOdMZCxopXduqv0OQ13y/yA/zXTSikZZqVgybUxOEg6YQ== } '@types/node@22.15.30': - resolution: {integrity: sha512-6Q7lr06bEHdlfplU6YRbgG1SFBdlsfNC4/lX+SkhiTs0cpJkOElmWls8PxDFv4yY/xKb8Y6SO0OmSX4wgqTZbA==} + resolution: + { integrity: sha512-6Q7lr06bEHdlfplU6YRbgG1SFBdlsfNC4/lX+SkhiTs0cpJkOElmWls8PxDFv4yY/xKb8Y6SO0OmSX4wgqTZbA== } '@types/parse-json@4.0.2': - resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==} + resolution: + { integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw== } '@types/pg-pool@2.0.6': - resolution: {integrity: sha512-TaAUE5rq2VQYxab5Ts7WZhKNmuN78Q6PiFonTDdpbx8a1H0M1vhy3rhiMjl+e2iHmogyMw7jZF4FrE6eJUy5HQ==} + resolution: + { integrity: sha512-TaAUE5rq2VQYxab5Ts7WZhKNmuN78Q6PiFonTDdpbx8a1H0M1vhy3rhiMjl+e2iHmogyMw7jZF4FrE6eJUy5HQ== } '@types/pg@8.6.1': - resolution: {integrity: sha512-1Kc4oAGzAl7uqUStZCDvaLFqZrW9qWSjXOmBfdgyBP5La7Us6Mg4GBvRlSoaZMhQF/zSj1C8CtKMBkoiT8eL8w==} + resolution: + { integrity: sha512-1Kc4oAGzAl7uqUStZCDvaLFqZrW9qWSjXOmBfdgyBP5La7Us6Mg4GBvRlSoaZMhQF/zSj1C8CtKMBkoiT8eL8w== } '@types/prop-types@15.7.15': - resolution: {integrity: sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==} + resolution: + { integrity: sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw== } '@types/react-dom@18.3.7': - resolution: {integrity: sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==} + resolution: + { integrity: sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ== } peerDependencies: '@types/react': ^18.0.0 '@types/react-router-dom@5.3.3': - resolution: {integrity: sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw==} + resolution: + { integrity: sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw== } '@types/react-router@5.1.20': - resolution: {integrity: sha512-jGjmu/ZqS7FjSH6owMcD5qpq19+1RS9DeVRqfl1FeBMxTDQAGwlMWOcs52NDoXaNKyG3d1cYQFMs9rCrb88o9Q==} + resolution: + { integrity: sha512-jGjmu/ZqS7FjSH6owMcD5qpq19+1RS9DeVRqfl1FeBMxTDQAGwlMWOcs52NDoXaNKyG3d1cYQFMs9rCrb88o9Q== } '@types/react-transition-group@4.4.12': - resolution: {integrity: sha512-8TV6R3h2j7a91c+1DXdJi3Syo69zzIZbz7Lg5tORM5LEJG7X/E6a1V3drRyBRZq7/utz7A+c4OgYLiLcYGHG6w==} + resolution: + { integrity: sha512-8TV6R3h2j7a91c+1DXdJi3Syo69zzIZbz7Lg5tORM5LEJG7X/E6a1V3drRyBRZq7/utz7A+c4OgYLiLcYGHG6w== } peerDependencies: '@types/react': '*' '@types/react-window@1.8.8': - resolution: {integrity: sha512-8Ls660bHR1AUA2kuRvVG9D/4XpRC6wjAaPT9dil7Ckc76eP9TKWZwwmgfq8Q1LANX3QNDnoU4Zp48A3w+zK69Q==} + resolution: + { integrity: sha512-8Ls660bHR1AUA2kuRvVG9D/4XpRC6wjAaPT9dil7Ckc76eP9TKWZwwmgfq8Q1LANX3QNDnoU4Zp48A3w+zK69Q== } '@types/react@18.3.20': - resolution: {integrity: sha512-IPaCZN7PShZK/3t6Q87pfTkRm6oLTd4vztyoj+cbHUF1g3FfVb2tFIL79uCRKEfv16AhqDMBywP2VW3KIZUvcg==} + resolution: + { integrity: sha512-IPaCZN7PShZK/3t6Q87pfTkRm6oLTd4vztyoj+cbHUF1g3FfVb2tFIL79uCRKEfv16AhqDMBywP2VW3KIZUvcg== } '@types/shimmer@1.2.0': - resolution: {integrity: sha512-UE7oxhQLLd9gub6JKIAhDq06T0F6FnztwMNRvYgjeQSBeMc1ZG/tA47EwfduvkuQS8apbkM/lpLpWsaCeYsXVg==} + resolution: + { integrity: sha512-UE7oxhQLLd9gub6JKIAhDq06T0F6FnztwMNRvYgjeQSBeMc1ZG/tA47EwfduvkuQS8apbkM/lpLpWsaCeYsXVg== } '@types/tedious@4.0.14': - resolution: {integrity: sha512-KHPsfX/FoVbUGbyYvk1q9MMQHLPeRZhRJZdO45Q4YjvFkv4hMNghCWTvy7rdKessBsmtz4euWCWAB6/tVpI1Iw==} + resolution: + { integrity: sha512-KHPsfX/FoVbUGbyYvk1q9MMQHLPeRZhRJZdO45Q4YjvFkv4hMNghCWTvy7rdKessBsmtz4euWCWAB6/tVpI1Iw== } '@types/use-sync-external-store@0.0.6': - resolution: {integrity: sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==} + resolution: + { integrity: sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg== } '@typescript-eslint/eslint-plugin@8.37.0': - resolution: {integrity: sha512-jsuVWeIkb6ggzB+wPCsR4e6loj+rM72ohW6IBn2C+5NCvfUVY8s33iFPySSVXqtm5Hu29Ne/9bnA0JmyLmgenA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + resolution: + { integrity: sha512-jsuVWeIkb6ggzB+wPCsR4e6loj+rM72ohW6IBn2C+5NCvfUVY8s33iFPySSVXqtm5Hu29Ne/9bnA0JmyLmgenA== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } peerDependencies: '@typescript-eslint/parser': ^8.37.0 eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.9.0' '@typescript-eslint/parser@8.37.0': - resolution: {integrity: sha512-kVIaQE9vrN9RLCQMQ3iyRlVJpTiDUY6woHGb30JDkfJErqrQEmtdWH3gV0PBAfGZgQXoqzXOO0T3K6ioApbbAA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + resolution: + { integrity: sha512-kVIaQE9vrN9RLCQMQ3iyRlVJpTiDUY6woHGb30JDkfJErqrQEmtdWH3gV0PBAfGZgQXoqzXOO0T3K6ioApbbAA== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.9.0' '@typescript-eslint/project-service@8.37.0': - resolution: {integrity: sha512-BIUXYsbkl5A1aJDdYJCBAo8rCEbAvdquQ8AnLb6z5Lp1u3x5PNgSSx9A/zqYc++Xnr/0DVpls8iQ2cJs/izTXA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + resolution: + { integrity: sha512-BIUXYsbkl5A1aJDdYJCBAo8rCEbAvdquQ8AnLb6z5Lp1u3x5PNgSSx9A/zqYc++Xnr/0DVpls8iQ2cJs/izTXA== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } peerDependencies: typescript: '>=4.8.4 <5.9.0' '@typescript-eslint/scope-manager@8.37.0': - resolution: {integrity: sha512-0vGq0yiU1gbjKob2q691ybTg9JX6ShiVXAAfm2jGf3q0hdP6/BruaFjL/ManAR/lj05AvYCH+5bbVo0VtzmjOA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + resolution: + { integrity: sha512-0vGq0yiU1gbjKob2q691ybTg9JX6ShiVXAAfm2jGf3q0hdP6/BruaFjL/ManAR/lj05AvYCH+5bbVo0VtzmjOA== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } '@typescript-eslint/tsconfig-utils@8.37.0': - resolution: {integrity: sha512-1/YHvAVTimMM9mmlPvTec9NP4bobA1RkDbMydxG8omqwJJLEW/Iy2C4adsAESIXU3WGLXFHSZUU+C9EoFWl4Zg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + resolution: + { integrity: sha512-1/YHvAVTimMM9mmlPvTec9NP4bobA1RkDbMydxG8omqwJJLEW/Iy2C4adsAESIXU3WGLXFHSZUU+C9EoFWl4Zg== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } peerDependencies: typescript: '>=4.8.4 <5.9.0' '@typescript-eslint/type-utils@8.37.0': - resolution: {integrity: sha512-SPkXWIkVZxhgwSwVq9rqj/4VFo7MnWwVaRNznfQDc/xPYHjXnPfLWn+4L6FF1cAz6e7dsqBeMawgl7QjUMj4Ow==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + resolution: + { integrity: sha512-SPkXWIkVZxhgwSwVq9rqj/4VFo7MnWwVaRNznfQDc/xPYHjXnPfLWn+4L6FF1cAz6e7dsqBeMawgl7QjUMj4Ow== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.9.0' '@typescript-eslint/types@8.37.0': - resolution: {integrity: sha512-ax0nv7PUF9NOVPs+lmQ7yIE7IQmAf8LGcXbMvHX5Gm+YJUYNAl340XkGnrimxZ0elXyoQJuN5sbg6C4evKA4SQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + resolution: + { integrity: sha512-ax0nv7PUF9NOVPs+lmQ7yIE7IQmAf8LGcXbMvHX5Gm+YJUYNAl340XkGnrimxZ0elXyoQJuN5sbg6C4evKA4SQ== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } '@typescript-eslint/typescript-estree@8.37.0': - resolution: {integrity: sha512-zuWDMDuzMRbQOM+bHyU4/slw27bAUEcKSKKs3hcv2aNnc/tvE/h7w60dwVw8vnal2Pub6RT1T7BI8tFZ1fE+yg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + resolution: + { integrity: sha512-zuWDMDuzMRbQOM+bHyU4/slw27bAUEcKSKKs3hcv2aNnc/tvE/h7w60dwVw8vnal2Pub6RT1T7BI8tFZ1fE+yg== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } peerDependencies: typescript: '>=4.8.4 <5.9.0' '@typescript-eslint/utils@8.37.0': - resolution: {integrity: sha512-TSFvkIW6gGjN2p6zbXo20FzCABbyUAuq6tBvNRGsKdsSQ6a7rnV6ADfZ7f4iI3lIiXc4F4WWvtUfDw9CJ9pO5A==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + resolution: + { integrity: sha512-TSFvkIW6gGjN2p6zbXo20FzCABbyUAuq6tBvNRGsKdsSQ6a7rnV6ADfZ7f4iI3lIiXc4F4WWvtUfDw9CJ9pO5A== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.9.0' '@typescript-eslint/visitor-keys@8.37.0': - resolution: {integrity: sha512-YzfhzcTnZVPiLfP/oeKtDp2evwvHLMe0LOy7oe+hb9KKIumLNohYS9Hgp1ifwpu42YWxhZE8yieggz6JpqO/1w==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + resolution: + { integrity: sha512-YzfhzcTnZVPiLfP/oeKtDp2evwvHLMe0LOy7oe+hb9KKIumLNohYS9Hgp1ifwpu42YWxhZE8yieggz6JpqO/1w== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } '@uiw/color-convert@2.7.1': - resolution: {integrity: sha512-wLA8Uit9/IxK8WXCLjZVwTIB66EytK2SKDzGP4NWTfWAXJlQFV7ne1FfTlhKG2OU4zRdMkj2h4N9BG6I80vNUw==} + resolution: + { integrity: sha512-wLA8Uit9/IxK8WXCLjZVwTIB66EytK2SKDzGP4NWTfWAXJlQFV7ne1FfTlhKG2OU4zRdMkj2h4N9BG6I80vNUw== } peerDependencies: '@babel/runtime': '>=7.19.0' '@uiw/react-color-alpha@2.7.1': - resolution: {integrity: sha512-3gGKGOLrYX3FhFGn6lD/luov1ur4+fM1psa4+azuSb5oQRUgBogbcEDK/0A+AoNXPFayAWqS8ZoqKEZKDX+geQ==} + resolution: + { integrity: sha512-3gGKGOLrYX3FhFGn6lD/luov1ur4+fM1psa4+azuSb5oQRUgBogbcEDK/0A+AoNXPFayAWqS8ZoqKEZKDX+geQ== } peerDependencies: '@babel/runtime': '>=7.19.0' react: '>=16.9.0' react-dom: '>=16.9.0' '@uiw/react-color-block@2.7.1': - resolution: {integrity: sha512-F7G6z3uxpoXvYK1llShU4cfbbpDx3UzNgwIgzmBAw9EVF1+I7bkclgNmfENjJvH1YYbQ6Nze6wZ9Yz921bU7Wg==} + resolution: + { integrity: sha512-F7G6z3uxpoXvYK1llShU4cfbbpDx3UzNgwIgzmBAw9EVF1+I7bkclgNmfENjJvH1YYbQ6Nze6wZ9Yz921bU7Wg== } peerDependencies: '@babel/runtime': '>=7.19.0' react: '>=16.9.0' react-dom: '>=16.9.0' '@uiw/react-color-chrome@2.7.1': - resolution: {integrity: sha512-DKqsyXvlf0Yp24uwngWIsDIr1ifK5tHwBewZ9zfAaqg8YM4bcjLv6uJhZp+sRPIPjhyANdaGKeUXL0ZclCNEkw==} + resolution: + { integrity: sha512-DKqsyXvlf0Yp24uwngWIsDIr1ifK5tHwBewZ9zfAaqg8YM4bcjLv6uJhZp+sRPIPjhyANdaGKeUXL0ZclCNEkw== } peerDependencies: '@babel/runtime': '>=7.19.0' react: '>=16.9.0' react-dom: '>=16.9.0' '@uiw/react-color-circle@2.7.1': - resolution: {integrity: sha512-B5Xl2mTE2HQUUTP26svBnfR7CX3+6TtFeqkNWarvRGXmUGUi3/ivllIG2sYqN6BdbaRf6T4rPjDeqEq1mZm7Vw==} + resolution: + { integrity: sha512-B5Xl2mTE2HQUUTP26svBnfR7CX3+6TtFeqkNWarvRGXmUGUi3/ivllIG2sYqN6BdbaRf6T4rPjDeqEq1mZm7Vw== } peerDependencies: '@babel/runtime': '>=7.19.0' react: '>=16.9.0' react-dom: '>=16.9.0' '@uiw/react-color-colorful@2.7.1': - resolution: {integrity: sha512-cnhdD/+wGVTTbD1SZmkQh/JRrbJsDYFbIEjt9oTNowCaiqAbSx3y+iP8N4/YleZpfKG1Vt/ex+ijaqFhTDkuIw==} + resolution: + { integrity: sha512-cnhdD/+wGVTTbD1SZmkQh/JRrbJsDYFbIEjt9oTNowCaiqAbSx3y+iP8N4/YleZpfKG1Vt/ex+ijaqFhTDkuIw== } peerDependencies: '@babel/runtime': '>=7.19.0' react: '>=16.9.0' react-dom: '>=16.9.0' '@uiw/react-color-compact@2.7.1': - resolution: {integrity: sha512-atr/JS8lkCCwYx2e7StYy3BlXjzfEoHgyWQT7KQYHZDrQt35UqImzegWJyexxTCNwYLysl0Fx/eGXVFjogh2CA==} + resolution: + { integrity: sha512-atr/JS8lkCCwYx2e7StYy3BlXjzfEoHgyWQT7KQYHZDrQt35UqImzegWJyexxTCNwYLysl0Fx/eGXVFjogh2CA== } peerDependencies: '@babel/runtime': '>=7.19.0' react: '>=16.9.0' react-dom: '>=16.9.0' '@uiw/react-color-editable-input-hsla@2.7.1': - resolution: {integrity: sha512-75YHFSsfuI8BygDHFVgKttos6uVWsVDPZYcrH+DzMt/QU2+FfNiHJjoQHJjJvvMF172uI0ir0Q9MNQIUHWjmMg==} + resolution: + { integrity: sha512-75YHFSsfuI8BygDHFVgKttos6uVWsVDPZYcrH+DzMt/QU2+FfNiHJjoQHJjJvvMF172uI0ir0Q9MNQIUHWjmMg== } peerDependencies: '@babel/runtime': '>=7.19.0' react: '>=16.9.0' react-dom: '>=16.9.0' '@uiw/react-color-editable-input-rgba@2.7.1': - resolution: {integrity: sha512-Qou4mVGrT+ndd4b5H1+sqoxTG3raiiGtI4MdmQKCQ/8RwO7XnOV6tWn9aJIuOfQ4woZZeoswiZWNSw6u0exUmA==} + resolution: + { integrity: sha512-Qou4mVGrT+ndd4b5H1+sqoxTG3raiiGtI4MdmQKCQ/8RwO7XnOV6tWn9aJIuOfQ4woZZeoswiZWNSw6u0exUmA== } peerDependencies: '@babel/runtime': '>=7.19.0' react: '>=16.9.0' react-dom: '>=16.9.0' '@uiw/react-color-editable-input@2.7.1': - resolution: {integrity: sha512-kaPf7dkCzyTadQ1ocF+5DSyh4PuSgrBRnAdnw/u+HFLZtVMfz23uHnNAgXkVZSmfaBahTCAJnUd7hq1ZzJOkgg==} + resolution: + { integrity: sha512-kaPf7dkCzyTadQ1ocF+5DSyh4PuSgrBRnAdnw/u+HFLZtVMfz23uHnNAgXkVZSmfaBahTCAJnUd7hq1ZzJOkgg== } peerDependencies: '@babel/runtime': '>=7.19.0' react: '>=16.9.0' react-dom: '>=16.9.0' '@uiw/react-color-github@2.7.1': - resolution: {integrity: sha512-RKhppBwvFA0K6w/sFUWbjJN2NoEEggSKepV8j129xngK33NIqjvoAyZswdKaXohB1nLIXueTv/7kn4HLED6I5A==} + resolution: + { integrity: sha512-RKhppBwvFA0K6w/sFUWbjJN2NoEEggSKepV8j129xngK33NIqjvoAyZswdKaXohB1nLIXueTv/7kn4HLED6I5A== } peerDependencies: '@babel/runtime': '>=7.19.0' react: '>=16.9.0' react-dom: '>=16.9.0' '@uiw/react-color-hue@2.7.1': - resolution: {integrity: sha512-3ZH2cOjatVm67RPklFXKqxcXDuoKd3j6H9o4cIhIxL4Dc5EET9wB9WcrNcz7QSO1V084Q8hIwFbay6zCAAhBhA==} + resolution: + { integrity: sha512-3ZH2cOjatVm67RPklFXKqxcXDuoKd3j6H9o4cIhIxL4Dc5EET9wB9WcrNcz7QSO1V084Q8hIwFbay6zCAAhBhA== } peerDependencies: '@babel/runtime': '>=7.19.0' react: '>=16.9.0' react-dom: '>=16.9.0' '@uiw/react-color-material@2.7.1': - resolution: {integrity: sha512-aEl54uBF4D8voMbNbc3uw9Wenwr4p/OllnXbzua1qu+g2mb6Em/QXx7ul4P2idBdSwTAfjNIeubUVhx2bjSLPw==} + resolution: + { integrity: sha512-aEl54uBF4D8voMbNbc3uw9Wenwr4p/OllnXbzua1qu+g2mb6Em/QXx7ul4P2idBdSwTAfjNIeubUVhx2bjSLPw== } peerDependencies: '@babel/runtime': '>=7.19.0' react: '>=16.9.0' react-dom: '>=16.9.0' '@uiw/react-color-name@2.7.1': - resolution: {integrity: sha512-0DCjUWWPnhC0kJ+0pUXzjjzv02v0mheERoSGhM284IbBvO7flLj9dm2NOzc5gO39GbcrsYqfwfNjeOxBxlHFRQ==} + resolution: + { integrity: sha512-0DCjUWWPnhC0kJ+0pUXzjjzv02v0mheERoSGhM284IbBvO7flLj9dm2NOzc5gO39GbcrsYqfwfNjeOxBxlHFRQ== } peerDependencies: '@babel/runtime': '>=7.19.0' '@uiw/react-color-saturation@2.7.1': - resolution: {integrity: sha512-CO3IYWpYQliEwkKEDviB26idVR5KZaW0nUSySRw5Y93N0ZHUILVR3dfYvYRP7GURoRAmXpf0Et5+WQbDTdXfMA==} + resolution: + { integrity: sha512-CO3IYWpYQliEwkKEDviB26idVR5KZaW0nUSySRw5Y93N0ZHUILVR3dfYvYRP7GURoRAmXpf0Et5+WQbDTdXfMA== } peerDependencies: '@babel/runtime': '>=7.19.0' react: '>=16.9.0' react-dom: '>=16.9.0' '@uiw/react-color-shade-slider@2.7.1': - resolution: {integrity: sha512-o5I0R6ZqoaOkcbjLZ+cqpNr2bQaqpEiMBdtHYYH3FUf6SmIqvmiiB7G9sncEqV+QeK7NFSDNYloxRRXjFZg57g==} + resolution: + { integrity: sha512-o5I0R6ZqoaOkcbjLZ+cqpNr2bQaqpEiMBdtHYYH3FUf6SmIqvmiiB7G9sncEqV+QeK7NFSDNYloxRRXjFZg57g== } peerDependencies: '@babel/runtime': '>=7.19.0' react: '>=16.9.0' react-dom: '>=16.9.0' '@uiw/react-color-sketch@2.7.1': - resolution: {integrity: sha512-Ajwth4wlGXh8gQVpi3GuhsvbABHGVcoXv7srMEL1NUmC5XaOw2uqni0hZewmiUmdgCu/LY853wCrtIg6agRSnQ==} + resolution: + { integrity: sha512-Ajwth4wlGXh8gQVpi3GuhsvbABHGVcoXv7srMEL1NUmC5XaOw2uqni0hZewmiUmdgCu/LY853wCrtIg6agRSnQ== } peerDependencies: '@babel/runtime': '>=7.19.0' react: '>=16.9.0' react-dom: '>=16.9.0' '@uiw/react-color-slider@2.7.1': - resolution: {integrity: sha512-DfBczIJokE7wYWN8olmpAtdLQyUkSeT1Ykq3iSaRfsy+lAOKG48MJhL/v8qponr/vcGpw+6SoOYRDRLXTyH8kA==} + resolution: + { integrity: sha512-DfBczIJokE7wYWN8olmpAtdLQyUkSeT1Ykq3iSaRfsy+lAOKG48MJhL/v8qponr/vcGpw+6SoOYRDRLXTyH8kA== } peerDependencies: '@babel/runtime': '>=7.19.0' react: '>=16.9.0' react-dom: '>=16.9.0' '@uiw/react-color-swatch@2.7.1': - resolution: {integrity: sha512-1uS+S+JQw1+5RlM3yRfvuuHHldGqxTt88/IZEd3hwcMI60Q6WVS4noWZTXrma83yQoJnL5RkbLPzAcrpZ9ddIg==} + resolution: + { integrity: sha512-1uS+S+JQw1+5RlM3yRfvuuHHldGqxTt88/IZEd3hwcMI60Q6WVS4noWZTXrma83yQoJnL5RkbLPzAcrpZ9ddIg== } peerDependencies: '@babel/runtime': '>=7.19.0' react: '>=16.9.0' react-dom: '>=16.9.0' '@uiw/react-color-wheel@2.7.1': - resolution: {integrity: sha512-WKgEaOYYAxGPOwe4H+XaTfbJ9xIhRY9wXHo+gmOjIJmr8M1aXhzRwcRcSpFfY2S1/d9XhKz6nFbqURDeWjtEqQ==} + resolution: + { integrity: sha512-WKgEaOYYAxGPOwe4H+XaTfbJ9xIhRY9wXHo+gmOjIJmr8M1aXhzRwcRcSpFfY2S1/d9XhKz6nFbqURDeWjtEqQ== } peerDependencies: '@babel/runtime': '>=7.19.0' react: '>=16.9.0' react-dom: '>=16.9.0' '@uiw/react-color@2.7.1': - resolution: {integrity: sha512-c7XL5ppD8BVxg2ZA2PvpqZsoVc8Fzst6amLYfFgaN9DlfN2jIBm3SoLAs5rPRRhkixnu++stQfanPruXEkfP4A==} + resolution: + { integrity: sha512-c7XL5ppD8BVxg2ZA2PvpqZsoVc8Fzst6amLYfFgaN9DlfN2jIBm3SoLAs5rPRRhkixnu++stQfanPruXEkfP4A== } peerDependencies: '@babel/runtime': '>=7.19.0' react: '>=16.9.0' react-dom: '>=16.9.0' '@uiw/react-drag-event-interactive@2.7.1': - resolution: {integrity: sha512-7qT0e6aNc4enYofwseC7uYzWKemijf+DWxfCjZUOEzP2FDv/j5c7wQwnsLvfrOq5VDpR6FW4wIopPpxaz8a/Kw==} + resolution: + { integrity: sha512-7qT0e6aNc4enYofwseC7uYzWKemijf+DWxfCjZUOEzP2FDv/j5c7wQwnsLvfrOq5VDpR6FW4wIopPpxaz8a/Kw== } peerDependencies: '@babel/runtime': '>=7.19.0' react: '>=16.9.0' react-dom: '>=16.9.0' '@vitejs/plugin-react-swc@3.10.2': - resolution: {integrity: sha512-xD3Rdvrt5LgANug7WekBn1KhcvLn1H3jNBfJRL3reeOIua/WnZOEV5qi5qIBq5T8R0jUDmRtxuvk4bPhzGHDWw==} + resolution: + { integrity: sha512-xD3Rdvrt5LgANug7WekBn1KhcvLn1H3jNBfJRL3reeOIua/WnZOEV5qi5qIBq5T8R0jUDmRtxuvk4bPhzGHDWw== } peerDependencies: vite: ^4 || ^5 || ^6 || ^7.0.0-beta.0 '@vitest/expect@3.2.4': - resolution: {integrity: sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==} + resolution: + { integrity: sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig== } '@vitest/mocker@3.2.4': - resolution: {integrity: sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ==} + resolution: + { integrity: sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ== } peerDependencies: msw: ^2.4.9 vite: ^5.0.0 || ^6.0.0 || ^7.0.0-0 @@ -1693,256 +1980,335 @@ packages: optional: true '@vitest/pretty-format@3.2.4': - resolution: {integrity: sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==} + resolution: + { integrity: sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA== } '@vitest/runner@3.2.4': - resolution: {integrity: sha512-oukfKT9Mk41LreEW09vt45f8wx7DordoWUZMYdY/cyAk7w5TWkTRCNZYF7sX7n2wB7jyGAl74OxgwhPgKaqDMQ==} + resolution: + { integrity: sha512-oukfKT9Mk41LreEW09vt45f8wx7DordoWUZMYdY/cyAk7w5TWkTRCNZYF7sX7n2wB7jyGAl74OxgwhPgKaqDMQ== } '@vitest/snapshot@3.2.4': - resolution: {integrity: sha512-dEYtS7qQP2CjU27QBC5oUOxLE/v5eLkGqPE0ZKEIDGMs4vKWe7IjgLOeauHsR0D5YuuycGRO5oSRXnwnmA78fQ==} + resolution: + { integrity: sha512-dEYtS7qQP2CjU27QBC5oUOxLE/v5eLkGqPE0ZKEIDGMs4vKWe7IjgLOeauHsR0D5YuuycGRO5oSRXnwnmA78fQ== } '@vitest/spy@3.2.4': - resolution: {integrity: sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==} + resolution: + { integrity: sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw== } '@vitest/utils@3.2.4': - resolution: {integrity: sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==} + resolution: + { integrity: sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA== } '@wry/caches@1.0.1': - resolution: {integrity: sha512-bXuaUNLVVkD20wcGBWRyo7j9N3TxePEWFZj2Y+r9OoUzfqmavM84+mFykRicNsBqatba5JLay1t48wxaXaWnlA==} - engines: {node: '>=8'} + resolution: + { integrity: sha512-bXuaUNLVVkD20wcGBWRyo7j9N3TxePEWFZj2Y+r9OoUzfqmavM84+mFykRicNsBqatba5JLay1t48wxaXaWnlA== } + engines: { node: '>=8' } '@wry/context@0.7.4': - resolution: {integrity: sha512-jmT7Sb4ZQWI5iyu3lobQxICu2nC/vbUhP0vIdd6tHC9PTfenmRmuIFqktc6GH9cgi+ZHnsLWPvfSvc4DrYmKiQ==} - engines: {node: '>=8'} + resolution: + { integrity: sha512-jmT7Sb4ZQWI5iyu3lobQxICu2nC/vbUhP0vIdd6tHC9PTfenmRmuIFqktc6GH9cgi+ZHnsLWPvfSvc4DrYmKiQ== } + engines: { node: '>=8' } '@wry/equality@0.5.7': - resolution: {integrity: sha512-BRFORjsTuQv5gxcXsuDXx6oGRhuVsEGwZy6LOzRRfgu+eSfxbhUQ9L9YtSEIuIjY/o7g3iWFjrc5eSY1GXP2Dw==} - engines: {node: '>=8'} + resolution: + { integrity: sha512-BRFORjsTuQv5gxcXsuDXx6oGRhuVsEGwZy6LOzRRfgu+eSfxbhUQ9L9YtSEIuIjY/o7g3iWFjrc5eSY1GXP2Dw== } + engines: { node: '>=8' } '@wry/trie@0.5.0': - resolution: {integrity: sha512-FNoYzHawTMk/6KMQoEG5O4PuioX19UbwdQKF44yw0nLfOypfQdjtfZzo/UIJWAJ23sNIFbD1Ug9lbaDGMwbqQA==} - engines: {node: '>=8'} + resolution: + { integrity: sha512-FNoYzHawTMk/6KMQoEG5O4PuioX19UbwdQKF44yw0nLfOypfQdjtfZzo/UIJWAJ23sNIFbD1Ug9lbaDGMwbqQA== } + engines: { node: '>=8' } acorn-import-attributes@1.9.5: - resolution: {integrity: sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==} + resolution: + { integrity: sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ== } peerDependencies: acorn: ^8 acorn-jsx@5.3.2: - resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + resolution: + { integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== } peerDependencies: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 acorn@8.15.0: - resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} - engines: {node: '>=0.4.0'} + resolution: + { integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg== } + engines: { node: '>=0.4.0' } hasBin: true agent-base@7.1.4: - resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} - engines: {node: '>= 14'} + resolution: + { integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ== } + engines: { node: '>= 14' } ajv@6.12.6: - resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + resolution: + { integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== } ansi-regex@5.0.1: - resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} - engines: {node: '>=8'} + resolution: + { integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== } + engines: { node: '>=8' } ansi-styles@4.3.0: - resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} - engines: {node: '>=8'} + resolution: + { integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== } + engines: { node: '>=8' } argparse@2.0.1: - resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + resolution: + { integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== } array-buffer-byte-length@1.0.2: - resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw== } + engines: { node: '>= 0.4' } array-includes@3.1.9: - resolution: {integrity: sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ== } + engines: { node: '>= 0.4' } array.prototype.findlast@1.2.5: - resolution: {integrity: sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ== } + engines: { node: '>= 0.4' } array.prototype.flat@1.3.3: - resolution: {integrity: sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg== } + engines: { node: '>= 0.4' } array.prototype.flatmap@1.3.3: - resolution: {integrity: sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg== } + engines: { node: '>= 0.4' } array.prototype.tosorted@1.1.4: - resolution: {integrity: sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA== } + engines: { node: '>= 0.4' } arraybuffer.prototype.slice@1.0.4: - resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ== } + engines: { node: '>= 0.4' } assertion-error@2.0.1: - resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} - engines: {node: '>=12'} + resolution: + { integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA== } + engines: { node: '>=12' } async-function@1.0.0: - resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA== } + engines: { node: '>= 0.4' } + + asynckit@0.4.0: + resolution: + { integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== } autoprefixer@10.4.21: - resolution: {integrity: sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ==} - engines: {node: ^10 || ^12 || >=14} + resolution: + { integrity: sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ== } + engines: { node: ^10 || ^12 || >=14 } hasBin: true peerDependencies: postcss: ^8.1.0 available-typed-arrays@1.0.7: - resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ== } + engines: { node: '>= 0.4' } + + axios@1.11.0: + resolution: + { integrity: sha512-1Lx3WLFQWm3ooKDYZD1eXmoGO9fxYQjrycfHFC8P0sCfQVXyROp0p9PFWBehewBOdCwHc+f/b8I0fMto5eSfwA== } babel-plugin-macros@3.1.0: - resolution: {integrity: sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==} - engines: {node: '>=10', npm: '>=6'} + resolution: + { integrity: sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg== } + engines: { node: '>=10', npm: '>=6' } balanced-match@1.0.2: - resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + resolution: + { integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== } brace-expansion@1.1.12: - resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} + resolution: + { integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg== } brace-expansion@2.0.2: - resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==} + resolution: + { integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ== } braces@3.0.3: - resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} - engines: {node: '>=8'} + resolution: + { integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA== } + engines: { node: '>=8' } browserslist@4.25.1: - resolution: {integrity: sha512-KGj0KoOMXLpSNkkEI6Z6mShmQy0bc1I+T7K9N81k4WWMrfz+6fQ6es80B/YLAeRoKvjYE1YSHHOW1qe9xIVzHw==} - engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + resolution: + { integrity: sha512-KGj0KoOMXLpSNkkEI6Z6mShmQy0bc1I+T7K9N81k4WWMrfz+6fQ6es80B/YLAeRoKvjYE1YSHHOW1qe9xIVzHw== } + engines: { node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7 } hasBin: true cac@6.7.14: - resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} - engines: {node: '>=8'} + resolution: + { integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ== } + engines: { node: '>=8' } call-bind-apply-helpers@1.0.2: - resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ== } + engines: { node: '>= 0.4' } call-bind@1.0.8: - resolution: {integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww== } + engines: { node: '>= 0.4' } call-bound@1.0.4: - resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg== } + engines: { node: '>= 0.4' } callsites@3.1.0: - resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} - engines: {node: '>=6'} + resolution: + { integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== } + engines: { node: '>=6' } caniuse-lite@1.0.30001727: - resolution: {integrity: sha512-pB68nIHmbN6L/4C6MH1DokyR3bYqFwjaSs/sWDHGj4CTcFtQUQMuJftVwWkXq7mNWOybD3KhUv3oWHoGxgP14Q==} + resolution: + { integrity: sha512-pB68nIHmbN6L/4C6MH1DokyR3bYqFwjaSs/sWDHGj4CTcFtQUQMuJftVwWkXq7mNWOybD3KhUv3oWHoGxgP14Q== } chai@5.2.1: - resolution: {integrity: sha512-5nFxhUrX0PqtyogoYOA8IPswy5sZFTOsBFl/9bNsmDLgsxYTzSZQJDPppDnZPTQbzSEm0hqGjWPzRemQCYbD6A==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-5nFxhUrX0PqtyogoYOA8IPswy5sZFTOsBFl/9bNsmDLgsxYTzSZQJDPppDnZPTQbzSEm0hqGjWPzRemQCYbD6A== } + engines: { node: '>=18' } chalk@4.1.2: - resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} - engines: {node: '>=10'} + resolution: + { integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== } + engines: { node: '>=10' } check-error@2.1.1: - resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} - engines: {node: '>= 16'} + resolution: + { integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw== } + engines: { node: '>= 16' } chownr@3.0.0: - resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g== } + engines: { node: '>=18' } cjs-module-lexer@1.4.3: - resolution: {integrity: sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==} + resolution: + { integrity: sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q== } cliui@8.0.1: - resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} - engines: {node: '>=12'} + resolution: + { integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ== } + engines: { node: '>=12' } clsx@2.1.1: - resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} - engines: {node: '>=6'} + resolution: + { integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA== } + engines: { node: '>=6' } color-convert@2.0.1: - resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} - engines: {node: '>=7.0.0'} + resolution: + { integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== } + engines: { node: '>=7.0.0' } color-name@1.1.4: - resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + resolution: + { integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== } colorizr@3.0.8: - resolution: {integrity: sha512-5B5bNiGU/iEbdL3JsiIYRf57T0CuJjHSgVfe3SP3W3ePe2waJuEYl+llzwm1ZhxIcVyA+gThRlBu3yXBV3tAQQ==} + resolution: + { integrity: sha512-5B5bNiGU/iEbdL3JsiIYRf57T0CuJjHSgVfe3SP3W3ePe2waJuEYl+llzwm1ZhxIcVyA+gThRlBu3yXBV3tAQQ== } colors-named-hex@1.0.2: - resolution: {integrity: sha512-k6kq1e1pUCQvSVwIaGFq2l0LrkAPQZWyeuZn1Z8nOiYSEZiKoFj4qx690h2Kd34DFl9Me0gKS6MUwAMBJj8nuA==} - engines: {node: '>=14.16'} + resolution: + { integrity: sha512-k6kq1e1pUCQvSVwIaGFq2l0LrkAPQZWyeuZn1Z8nOiYSEZiKoFj4qx690h2Kd34DFl9Me0gKS6MUwAMBJj8nuA== } + engines: { node: '>=14.16' } colors-named@1.0.2: - resolution: {integrity: sha512-2ANq2r393PV9njYUD66UdfBcxR1slMqRA3QRTWgCx49JoCJ+kOhyfbQYxKJbPZQIhZUcNjVOs5AlyY1WwXec3w==} - engines: {node: '>=14.16'} + resolution: + { integrity: sha512-2ANq2r393PV9njYUD66UdfBcxR1slMqRA3QRTWgCx49JoCJ+kOhyfbQYxKJbPZQIhZUcNjVOs5AlyY1WwXec3w== } + engines: { node: '>=14.16' } + + combined-stream@1.0.8: + resolution: + { integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== } + engines: { node: '>= 0.8' } concat-map@0.0.1: - resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + resolution: + { integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== } convert-source-map@1.9.0: - resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} + resolution: + { integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A== } cosmiconfig@7.1.0: - resolution: {integrity: sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==} - engines: {node: '>=10'} + resolution: + { integrity: sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA== } + engines: { node: '>=10' } cross-spawn@7.0.6: - resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} - engines: {node: '>= 8'} + resolution: + { integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA== } + engines: { node: '>= 8' } css-box-model@1.2.1: - resolution: {integrity: sha512-a7Vr4Q/kd/aw96bnJG332W9V9LkJO69JRcaCYDUqjp6/z0w6VcZjgAcTbgFxEPfBgdnAwlh3iwu+hLopa+flJw==} + resolution: + { integrity: sha512-a7Vr4Q/kd/aw96bnJG332W9V9LkJO69JRcaCYDUqjp6/z0w6VcZjgAcTbgFxEPfBgdnAwlh3iwu+hLopa+flJw== } cssstyle@4.6.0: - resolution: {integrity: sha512-2z+rWdzbbSZv6/rhtvzvqeZQHrBaqgogqt85sqFNbabZOuFbCVFb8kPeEtZjiKkbrm395irpNKiYeFeLiQnFPg==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-2z+rWdzbbSZv6/rhtvzvqeZQHrBaqgogqt85sqFNbabZOuFbCVFb8kPeEtZjiKkbrm395irpNKiYeFeLiQnFPg== } + engines: { node: '>=18' } csstype@3.1.3: - resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + resolution: + { integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw== } data-urls@5.0.0: - resolution: {integrity: sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg== } + engines: { node: '>=18' } data-view-buffer@1.0.2: - resolution: {integrity: sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ== } + engines: { node: '>= 0.4' } data-view-byte-length@1.0.2: - resolution: {integrity: sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ== } + engines: { node: '>= 0.4' } data-view-byte-offset@1.0.1: - resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ== } + engines: { node: '>= 0.4' } date-fns@2.30.0: - resolution: {integrity: sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==} - engines: {node: '>=0.11'} + resolution: + { integrity: sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw== } + engines: { node: '>=0.11' } dayjs@1.11.13: - resolution: {integrity: sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==} + resolution: + { integrity: sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg== } debug@4.4.1: - resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==} - engines: {node: '>=6.0'} + resolution: + { integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ== } + engines: { node: '>=6.0' } peerDependencies: supports-color: '*' peerDependenciesMeta: @@ -1950,116 +2316,150 @@ packages: optional: true decimal.js@10.6.0: - resolution: {integrity: sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==} + resolution: + { integrity: sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg== } deep-eql@5.0.2: - resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} - engines: {node: '>=6'} + resolution: + { integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q== } + engines: { node: '>=6' } deep-is@0.1.4: - resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + resolution: + { integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== } define-data-property@1.1.4: - resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A== } + engines: { node: '>= 0.4' } define-lazy-prop@2.0.0: - resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==} - engines: {node: '>=8'} + resolution: + { integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== } + engines: { node: '>=8' } define-properties@1.2.1: - resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg== } + engines: { node: '>= 0.4' } + + delayed-stream@1.0.0: + resolution: + { integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== } + engines: { node: '>=0.4.0' } detect-libc@2.0.4: - resolution: {integrity: sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==} - engines: {node: '>=8'} + resolution: + { integrity: sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA== } + engines: { node: '>=8' } doctrine@2.1.0: - resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} - engines: {node: '>=0.10.0'} + resolution: + { integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw== } + engines: { node: '>=0.10.0' } dom-helpers@5.2.1: - resolution: {integrity: sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==} + resolution: + { integrity: sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA== } dunder-proto@1.0.1: - resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A== } + engines: { node: '>= 0.4' } electron-to-chromium@1.5.182: - resolution: {integrity: sha512-Lv65Btwv9W4J9pyODI6EWpdnhfvrve/us5h1WspW8B2Fb0366REPtY3hX7ounk1CkV/TBjWCEvCBBbYbmV0qCA==} + resolution: + { integrity: sha512-Lv65Btwv9W4J9pyODI6EWpdnhfvrve/us5h1WspW8B2Fb0366REPtY3hX7ounk1CkV/TBjWCEvCBBbYbmV0qCA== } emoji-regex@8.0.0: - resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + resolution: + { integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== } enhanced-resolve@5.18.2: - resolution: {integrity: sha512-6Jw4sE1maoRJo3q8MsSIn2onJFbLTOjY9hlx4DZXmOKvLRd1Ok2kXmAGXaafL2+ijsJZ1ClYbl/pmqr9+k4iUQ==} - engines: {node: '>=10.13.0'} + resolution: + { integrity: sha512-6Jw4sE1maoRJo3q8MsSIn2onJFbLTOjY9hlx4DZXmOKvLRd1Ok2kXmAGXaafL2+ijsJZ1ClYbl/pmqr9+k4iUQ== } + engines: { node: '>=10.13.0' } entities@6.0.1: - resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==} - engines: {node: '>=0.12'} + resolution: + { integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g== } + engines: { node: '>=0.12' } error-ex@1.3.2: - resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + resolution: + { integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== } es-abstract@1.24.0: - resolution: {integrity: sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg== } + engines: { node: '>= 0.4' } es-define-property@1.0.1: - resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g== } + engines: { node: '>= 0.4' } es-errors@1.3.0: - resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== } + engines: { node: '>= 0.4' } es-iterator-helpers@1.2.1: - resolution: {integrity: sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w== } + engines: { node: '>= 0.4' } es-module-lexer@1.7.0: - resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} + resolution: + { integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA== } es-object-atoms@1.1.1: - resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA== } + engines: { node: '>= 0.4' } es-set-tostringtag@2.1.0: - resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA== } + engines: { node: '>= 0.4' } es-shim-unscopables@1.1.0: - resolution: {integrity: sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw== } + engines: { node: '>= 0.4' } es-to-primitive@1.3.0: - resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g== } + engines: { node: '>= 0.4' } esbuild@0.25.6: - resolution: {integrity: sha512-GVuzuUwtdsghE3ocJ9Bs8PNoF13HNQ5TXbEi2AhvVb8xU1Iwt9Fos9FEamfoee+u/TOsn7GUWc04lz46n2bbTg==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-GVuzuUwtdsghE3ocJ9Bs8PNoF13HNQ5TXbEi2AhvVb8xU1Iwt9Fos9FEamfoee+u/TOsn7GUWc04lz46n2bbTg== } + engines: { node: '>=18' } hasBin: true escalade@3.2.0: - resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} - engines: {node: '>=6'} + resolution: + { integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA== } + engines: { node: '>=6' } escape-string-regexp@4.0.0: - resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} - engines: {node: '>=10'} + resolution: + { integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== } + engines: { node: '>=10' } eslint-config-prettier@10.1.5: - resolution: {integrity: sha512-zc1UmCpNltmVY34vuLRV61r1K27sWuX39E+uyUnY8xS2Bex88VV9cugG+UZbRSRGtGyFboj+D8JODyme1plMpw==} + resolution: + { integrity: sha512-zc1UmCpNltmVY34vuLRV61r1K27sWuX39E+uyUnY8xS2Bex88VV9cugG+UZbRSRGtGyFboj+D8JODyme1plMpw== } hasBin: true peerDependencies: eslint: '>=7.0.0' eslint-plugin-prettier@5.5.1: - resolution: {integrity: sha512-dobTkHT6XaEVOo8IO90Q4DOSxnm3Y151QxPJlM/vKC0bVy+d6cVWQZLlFiuZPP0wS6vZwSKeJgKkcS+KfMBlRw==} - engines: {node: ^14.18.0 || >=16.0.0} + resolution: + { integrity: sha512-dobTkHT6XaEVOo8IO90Q4DOSxnm3Y151QxPJlM/vKC0bVy+d6cVWQZLlFiuZPP0wS6vZwSKeJgKkcS+KfMBlRw== } + engines: { node: ^14.18.0 || >=16.0.0 } peerDependencies: '@types/eslint': '>=8.0.0' eslint: '>=8.0.0' @@ -2072,24 +2472,28 @@ packages: optional: true eslint-plugin-react-hooks@5.2.0: - resolution: {integrity: sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg==} - engines: {node: '>=10'} + resolution: + { integrity: sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg== } + engines: { node: '>=10' } peerDependencies: eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 eslint-plugin-react@7.37.5: - resolution: {integrity: sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==} - engines: {node: '>=4'} + resolution: + { integrity: sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA== } + engines: { node: '>=4' } peerDependencies: eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7 eslint-plugin-simple-import-sort@12.1.1: - resolution: {integrity: sha512-6nuzu4xwQtE3332Uz0to+TxDQYRLTKRESSc2hefVT48Zc8JthmN23Gx9lnYhu0FtkRSL1oxny3kJ2aveVhmOVA==} + resolution: + { integrity: sha512-6nuzu4xwQtE3332Uz0to+TxDQYRLTKRESSc2hefVT48Zc8JthmN23Gx9lnYhu0FtkRSL1oxny3kJ2aveVhmOVA== } peerDependencies: eslint: '>=5.0.0' eslint-plugin-unused-imports@4.1.4: - resolution: {integrity: sha512-YptD6IzQjDardkl0POxnnRBhU1OEePMV0nd6siHaRBbd+lyh6NAhFEobiznKU7kTsSsDeSD62Pe7kAM1b7dAZQ==} + resolution: + { integrity: sha512-YptD6IzQjDardkl0POxnnRBhU1OEePMV0nd6siHaRBbd+lyh6NAhFEobiznKU7kTsSsDeSD62Pe7kAM1b7dAZQ== } peerDependencies: '@typescript-eslint/eslint-plugin': ^8.0.0-0 || ^7.0.0 || ^6.0.0 || ^5.0.0 eslint: ^9.0.0 || ^8.0.0 @@ -2098,20 +2502,24 @@ packages: optional: true eslint-scope@8.4.0: - resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + resolution: + { integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } eslint-visitor-keys@3.4.3: - resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + resolution: + { integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== } + engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 } eslint-visitor-keys@4.2.1: - resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + resolution: + { integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } eslint@9.31.0: - resolution: {integrity: sha512-QldCVh/ztyKJJZLr4jXNUByx3gR+TDYZCRXEktiZoUR3PGy4qCmSbkxcIle8GEwGpb5JBZazlaJ/CxLidXdEbQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + resolution: + { integrity: sha512-QldCVh/ztyKJJZLr4jXNUByx3gR+TDYZCRXEktiZoUR3PGy4qCmSbkxcIle8GEwGpb5JBZazlaJ/CxLidXdEbQ== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } hasBin: true peerDependencies: jiti: '*' @@ -2120,53 +2528,67 @@ packages: optional: true espree@10.4.0: - resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + resolution: + { integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } esquery@1.6.0: - resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} - engines: {node: '>=0.10'} + resolution: + { integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg== } + engines: { node: '>=0.10' } esrecurse@4.3.0: - resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} - engines: {node: '>=4.0'} + resolution: + { integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== } + engines: { node: '>=4.0' } estraverse@5.3.0: - resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} - engines: {node: '>=4.0'} + resolution: + { integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== } + engines: { node: '>=4.0' } estree-walker@3.0.3: - resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + resolution: + { integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g== } esutils@2.0.3: - resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} - engines: {node: '>=0.10.0'} + resolution: + { integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== } + engines: { node: '>=0.10.0' } expect-type@1.2.2: - resolution: {integrity: sha512-JhFGDVJ7tmDJItKhYgJCGLOWjuK9vPxiXoUFLwLDc99NlmklilbiQJwoctZtt13+xMw91MCk/REan6MWHqDjyA==} - engines: {node: '>=12.0.0'} + resolution: + { integrity: sha512-JhFGDVJ7tmDJItKhYgJCGLOWjuK9vPxiXoUFLwLDc99NlmklilbiQJwoctZtt13+xMw91MCk/REan6MWHqDjyA== } + engines: { node: '>=12.0.0' } fast-deep-equal@3.1.3: - resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + resolution: + { integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== } fast-diff@1.3.0: - resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==} + resolution: + { integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw== } fast-glob@3.3.3: - resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} - engines: {node: '>=8.6.0'} + resolution: + { integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg== } + engines: { node: '>=8.6.0' } fast-json-stable-stringify@2.1.0: - resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + resolution: + { integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== } fast-levenshtein@2.0.6: - resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + resolution: + { integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== } fastq@1.19.1: - resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} + resolution: + { integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ== } fdir@6.4.6: - resolution: {integrity: sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==} + resolution: + { integrity: sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w== } peerDependencies: picomatch: ^3 || ^4 peerDependenciesMeta: @@ -2174,42 +2596,68 @@ packages: optional: true file-entry-cache@8.0.0: - resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} - engines: {node: '>=16.0.0'} + resolution: + { integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ== } + engines: { node: '>=16.0.0' } file-saver@2.0.5: - resolution: {integrity: sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA==} + resolution: + { integrity: sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA== } fill-range@7.1.1: - resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} - engines: {node: '>=8'} + resolution: + { integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg== } + engines: { node: '>=8' } find-root@1.1.0: - resolution: {integrity: sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==} + resolution: + { integrity: sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng== } find-up@5.0.0: - resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} - engines: {node: '>=10'} + resolution: + { integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== } + engines: { node: '>=10' } flat-cache@4.0.1: - resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} - engines: {node: '>=16'} + resolution: + { integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw== } + engines: { node: '>=16' } flatted@3.3.3: - resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} + resolution: + { integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg== } + + follow-redirects@1.15.11: + resolution: + { integrity: sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ== } + engines: { node: '>=4.0' } + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true for-each@0.3.5: - resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg== } + engines: { node: '>= 0.4' } + + form-data@4.0.4: + resolution: + { integrity: sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow== } + engines: { node: '>= 6' } forwarded-parse@2.1.2: - resolution: {integrity: sha512-alTFZZQDKMporBH77856pXgzhEzaUVmLCDk+egLgIgHst3Tpndzz8MnKe+GzRJRfvVdn69HhpW7cmXzvtLvJAw==} + resolution: + { integrity: sha512-alTFZZQDKMporBH77856pXgzhEzaUVmLCDk+egLgIgHst3Tpndzz8MnKe+GzRJRfvVdn69HhpW7cmXzvtLvJAw== } fraction.js@4.3.7: - resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==} + resolution: + { integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew== } framer-motion@12.23.3: - resolution: {integrity: sha512-llmLkf44zuIZOPSrE4bl4J0UTg6bav+rlKEfMRKgvDMXqBrUtMg6cspoQeRVK3nqRLxTmAJhfGXk39UDdZD7Kw==} + resolution: + { integrity: sha512-llmLkf44zuIZOPSrE4bl4J0UTg6bav+rlKEfMRKgvDMXqBrUtMg6cspoQeRVK3nqRLxTmAJhfGXk39UDdZD7Kw== } peerDependencies: '@emotion/is-prop-valid': '*' react: ^18.0.0 || ^19.0.0 @@ -2223,315 +2671,396 @@ packages: optional: true fsevents@2.3.3: - resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + resolution: + { integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== } + engines: { node: ^8.16.0 || ^10.6.0 || >=11.0.0 } os: [darwin] function-bind@1.1.2: - resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + resolution: + { integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== } function.prototype.name@1.1.8: - resolution: {integrity: sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q== } + engines: { node: '>= 0.4' } functions-have-names@1.2.3: - resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + resolution: + { integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== } fuse.js@7.1.0: - resolution: {integrity: sha512-trLf4SzuuUxfusZADLINj+dE8clK1frKdmqiJNb1Es75fmI5oY6X2mxLVUciLLjxqw/xr72Dhy+lER6dGd02FQ==} - engines: {node: '>=10'} + resolution: + { integrity: sha512-trLf4SzuuUxfusZADLINj+dE8clK1frKdmqiJNb1Es75fmI5oY6X2mxLVUciLLjxqw/xr72Dhy+lER6dGd02FQ== } + engines: { node: '>=10' } get-caller-file@2.0.5: - resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} - engines: {node: 6.* || 8.* || >= 10.*} + resolution: + { integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== } + engines: { node: 6.* || 8.* || >= 10.* } get-intrinsic@1.3.0: - resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ== } + engines: { node: '>= 0.4' } get-proto@1.0.1: - resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g== } + engines: { node: '>= 0.4' } get-symbol-description@1.1.0: - resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg== } + engines: { node: '>= 0.4' } glob-parent@5.1.2: - resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} - engines: {node: '>= 6'} + resolution: + { integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== } + engines: { node: '>= 6' } glob-parent@6.0.2: - resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} - engines: {node: '>=10.13.0'} + resolution: + { integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== } + engines: { node: '>=10.13.0' } globals@14.0.0: - resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ== } + engines: { node: '>=18' } globals@16.3.0: - resolution: {integrity: sha512-bqWEnJ1Nt3neqx2q5SFfGS8r/ahumIakg3HcwtNlrVlwXIeNumWn/c7Pn/wKzGhf6SaW6H6uWXLqC30STCMchQ==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-bqWEnJ1Nt3neqx2q5SFfGS8r/ahumIakg3HcwtNlrVlwXIeNumWn/c7Pn/wKzGhf6SaW6H6uWXLqC30STCMchQ== } + engines: { node: '>=18' } globalthis@1.0.4: - resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ== } + engines: { node: '>= 0.4' } globrex@0.1.2: - resolution: {integrity: sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==} + resolution: + { integrity: sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg== } gopd@1.2.0: - resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg== } + engines: { node: '>= 0.4' } graceful-fs@4.2.11: - resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + resolution: + { integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== } graphemer@1.4.0: - resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + resolution: + { integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== } graphql-tag@2.12.6: - resolution: {integrity: sha512-FdSNcu2QQcWnM2VNvSCCDCVS5PpPqpzgFT8+GXzqJuoDd0CBncxCY278u4mhRO7tMgo2JjgJA5aZ+nWSQ/Z+xg==} - engines: {node: '>=10'} + resolution: + { integrity: sha512-FdSNcu2QQcWnM2VNvSCCDCVS5PpPqpzgFT8+GXzqJuoDd0CBncxCY278u4mhRO7tMgo2JjgJA5aZ+nWSQ/Z+xg== } + 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 graphql@16.9.0: - resolution: {integrity: sha512-GGTKBX4SD7Wdb8mqeDLni2oaRGYQWjWHGKPQ24ZMnUtKfcsVoiv4uX8+LJr1K6U5VW2Lu1BwJnj7uiori0YtRw==} - engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0} + resolution: + { integrity: sha512-GGTKBX4SD7Wdb8mqeDLni2oaRGYQWjWHGKPQ24ZMnUtKfcsVoiv4uX8+LJr1K6U5VW2Lu1BwJnj7uiori0YtRw== } + engines: { node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0 } has-bigints@1.1.0: - resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg== } + engines: { node: '>= 0.4' } has-flag@4.0.0: - resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} - engines: {node: '>=8'} + resolution: + { integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== } + engines: { node: '>=8' } has-property-descriptors@1.0.2: - resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + resolution: + { integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg== } has-proto@1.2.0: - resolution: {integrity: sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ== } + engines: { node: '>= 0.4' } has-symbols@1.1.0: - resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ== } + engines: { node: '>= 0.4' } has-tostringtag@1.0.2: - resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw== } + engines: { node: '>= 0.4' } hasown@2.0.2: - resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ== } + engines: { node: '>= 0.4' } hoist-non-react-statics@3.3.2: - resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==} + resolution: + { integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== } html-encoding-sniffer@4.0.0: - resolution: {integrity: sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ== } + engines: { node: '>=18' } http-proxy-agent@7.0.2: - resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} - engines: {node: '>= 14'} + resolution: + { integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig== } + engines: { node: '>= 14' } https-proxy-agent@7.0.6: - resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} - engines: {node: '>= 14'} + resolution: + { integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw== } + engines: { node: '>= 14' } iconv-lite@0.6.3: - resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} - engines: {node: '>=0.10.0'} + resolution: + { integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== } + engines: { node: '>=0.10.0' } ics@3.8.1: - resolution: {integrity: sha512-UqQlfkajfhrS4pUGQfGIJMYz/Jsl/ob3LqcfEhUmLbwumg+ZNkU0/6S734Vsjq3/FYNpEcZVKodLBoe+zBM69g==} + resolution: + { integrity: sha512-UqQlfkajfhrS4pUGQfGIJMYz/Jsl/ob3LqcfEhUmLbwumg+ZNkU0/6S734Vsjq3/FYNpEcZVKodLBoe+zBM69g== } idb@7.1.1: - resolution: {integrity: sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==} + resolution: + { integrity: sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ== } ignore@5.3.2: - resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} - engines: {node: '>= 4'} + resolution: + { integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g== } + engines: { node: '>= 4' } ignore@7.0.5: - resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} - engines: {node: '>= 4'} + resolution: + { integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg== } + engines: { node: '>= 4' } import-fresh@3.3.1: - resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} - engines: {node: '>=6'} + resolution: + { integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ== } + engines: { node: '>=6' } import-from-esm@1.3.4: - resolution: {integrity: sha512-7EyUlPFC0HOlBDpUFGfYstsU7XHxZJKAAMzCT8wZ0hMW7b+hG51LIKTDcsgtz8Pu6YC0HqRVbX+rVUtsGMUKvg==} - engines: {node: '>=16.20'} + resolution: + { integrity: sha512-7EyUlPFC0HOlBDpUFGfYstsU7XHxZJKAAMzCT8wZ0hMW7b+hG51LIKTDcsgtz8Pu6YC0HqRVbX+rVUtsGMUKvg== } + engines: { node: '>=16.20' } import-in-the-middle@1.14.2: - resolution: {integrity: sha512-5tCuY9BV8ujfOpwtAGgsTx9CGUapcFMEEyByLv1B+v2+6DhAcw+Zr0nhQT7uwaZ7DiourxFEscghOR8e1aPLQw==} + resolution: + { integrity: sha512-5tCuY9BV8ujfOpwtAGgsTx9CGUapcFMEEyByLv1B+v2+6DhAcw+Zr0nhQT7uwaZ7DiourxFEscghOR8e1aPLQw== } import-meta-resolve@4.1.0: - resolution: {integrity: sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==} + resolution: + { integrity: sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw== } imurmurhash@0.1.4: - resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} - engines: {node: '>=0.8.19'} + resolution: + { integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== } + engines: { node: '>=0.8.19' } internal-slot@1.1.0: - resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw== } + engines: { node: '>= 0.4' } is-array-buffer@3.0.5: - resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A== } + engines: { node: '>= 0.4' } is-arrayish@0.2.1: - resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + resolution: + { integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== } is-async-function@2.1.1: - resolution: {integrity: sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ== } + engines: { node: '>= 0.4' } is-base64@1.1.0: - resolution: {integrity: sha512-Nlhg7Z2dVC4/PTvIFkgVVNvPHSO2eR/Yd0XzhGiXCXEvWnptXlXa/clQ8aePPiMuxEGcWfzWbGw2Fe3d+Y3v1g==} + resolution: + { integrity: sha512-Nlhg7Z2dVC4/PTvIFkgVVNvPHSO2eR/Yd0XzhGiXCXEvWnptXlXa/clQ8aePPiMuxEGcWfzWbGw2Fe3d+Y3v1g== } hasBin: true is-bigint@1.1.0: - resolution: {integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ== } + engines: { node: '>= 0.4' } is-boolean-object@1.2.2: - resolution: {integrity: sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A== } + engines: { node: '>= 0.4' } is-callable@1.2.7: - resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== } + engines: { node: '>= 0.4' } is-core-module@2.16.1: - resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w== } + engines: { node: '>= 0.4' } is-data-view@1.0.2: - resolution: {integrity: sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw== } + engines: { node: '>= 0.4' } is-date-object@1.1.0: - resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg== } + engines: { node: '>= 0.4' } is-docker@2.2.1: - resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} - engines: {node: '>=8'} + resolution: + { integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== } + engines: { node: '>=8' } hasBin: true is-extglob@2.1.1: - resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} - engines: {node: '>=0.10.0'} + resolution: + { integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== } + engines: { node: '>=0.10.0' } is-finalizationregistry@1.1.1: - resolution: {integrity: sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg== } + engines: { node: '>= 0.4' } is-fullwidth-code-point@3.0.0: - resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} - engines: {node: '>=8'} + resolution: + { integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== } + engines: { node: '>=8' } is-generator-function@1.1.0: - resolution: {integrity: sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ== } + engines: { node: '>= 0.4' } is-glob@4.0.3: - resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} - engines: {node: '>=0.10.0'} + resolution: + { integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== } + engines: { node: '>=0.10.0' } is-map@2.0.3: - resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw== } + engines: { node: '>= 0.4' } is-negative-zero@2.0.3: - resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw== } + engines: { node: '>= 0.4' } is-number-object@1.1.1: - resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw== } + engines: { node: '>= 0.4' } is-number@7.0.0: - resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} - engines: {node: '>=0.12.0'} + resolution: + { integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== } + engines: { node: '>=0.12.0' } is-potential-custom-element-name@1.0.1: - resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} + resolution: + { integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ== } is-regex@1.2.1: - resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g== } + engines: { node: '>= 0.4' } is-set@2.0.3: - resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg== } + engines: { node: '>= 0.4' } is-shared-array-buffer@1.0.4: - resolution: {integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A== } + engines: { node: '>= 0.4' } is-string@1.1.1: - resolution: {integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA== } + engines: { node: '>= 0.4' } is-symbol@1.1.1: - resolution: {integrity: sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w== } + engines: { node: '>= 0.4' } is-typed-array@1.1.15: - resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ== } + engines: { node: '>= 0.4' } is-weakmap@2.0.2: - resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w== } + engines: { node: '>= 0.4' } is-weakref@1.1.1: - resolution: {integrity: sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew== } + engines: { node: '>= 0.4' } is-weakset@2.0.4: - resolution: {integrity: sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ== } + engines: { node: '>= 0.4' } is-wsl@2.2.0: - resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} - engines: {node: '>=8'} + resolution: + { integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== } + engines: { node: '>=8' } isarray@2.0.5: - resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + resolution: + { integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== } isexe@2.0.0: - resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + resolution: + { integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== } iterator.prototype@1.1.5: - resolution: {integrity: sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g== } + engines: { node: '>= 0.4' } jiti@2.4.2: - resolution: {integrity: sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==} + resolution: + { integrity: sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A== } hasBin: true js-tokens@4.0.0: - resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + resolution: + { integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== } js-tokens@9.0.1: - resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==} + resolution: + { integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ== } js-yaml@4.1.0: - resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + resolution: + { integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== } hasBin: true jsdom@26.1.0: - resolution: {integrity: sha512-Cvc9WUhxSMEo4McES3P7oK3QaXldCfNWp7pl2NNeiIFlCoLr3kfq9kb1fxftiwk1FLV7CvpvDfonxtzUDeSOPg==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-Cvc9WUhxSMEo4McES3P7oK3QaXldCfNWp7pl2NNeiIFlCoLr3kfq9kb1fxftiwk1FLV7CvpvDfonxtzUDeSOPg== } + engines: { node: '>=18' } peerDependencies: canvas: ^3.0.0 peerDependenciesMeta: @@ -2539,363 +3068,469 @@ packages: optional: true jsesc@3.1.0: - resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} - engines: {node: '>=6'} + resolution: + { integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA== } + engines: { node: '>=6' } hasBin: true json-buffer@3.0.1: - resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + resolution: + { integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== } json-parse-even-better-errors@2.3.1: - resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + resolution: + { integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== } json-schema-traverse@0.4.1: - resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + resolution: + { integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== } json-stable-stringify-without-jsonify@1.0.1: - resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + resolution: + { integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== } jsx-ast-utils@3.3.5: - resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} - engines: {node: '>=4.0'} + resolution: + { integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ== } + engines: { node: '>=4.0' } keyv@4.5.4: - resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + resolution: + { integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw== } levn@0.4.1: - resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} - engines: {node: '>= 0.8.0'} + resolution: + { integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== } + engines: { node: '>= 0.8.0' } lightningcss-darwin-arm64@1.30.1: - resolution: {integrity: sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ==} - engines: {node: '>= 12.0.0'} + resolution: + { integrity: sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ== } + engines: { node: '>= 12.0.0' } cpu: [arm64] os: [darwin] lightningcss-darwin-x64@1.30.1: - resolution: {integrity: sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA==} - engines: {node: '>= 12.0.0'} + resolution: + { integrity: sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA== } + engines: { node: '>= 12.0.0' } cpu: [x64] os: [darwin] lightningcss-freebsd-x64@1.30.1: - resolution: {integrity: sha512-kmW6UGCGg2PcyUE59K5r0kWfKPAVy4SltVeut+umLCFoJ53RdCUWxcRDzO1eTaxf/7Q2H7LTquFHPL5R+Gjyig==} - engines: {node: '>= 12.0.0'} + resolution: + { integrity: sha512-kmW6UGCGg2PcyUE59K5r0kWfKPAVy4SltVeut+umLCFoJ53RdCUWxcRDzO1eTaxf/7Q2H7LTquFHPL5R+Gjyig== } + engines: { node: '>= 12.0.0' } cpu: [x64] os: [freebsd] lightningcss-linux-arm-gnueabihf@1.30.1: - resolution: {integrity: sha512-MjxUShl1v8pit+6D/zSPq9S9dQ2NPFSQwGvxBCYaBYLPlCWuPh9/t1MRS8iUaR8i+a6w7aps+B4N0S1TYP/R+Q==} - engines: {node: '>= 12.0.0'} + resolution: + { integrity: sha512-MjxUShl1v8pit+6D/zSPq9S9dQ2NPFSQwGvxBCYaBYLPlCWuPh9/t1MRS8iUaR8i+a6w7aps+B4N0S1TYP/R+Q== } + engines: { node: '>= 12.0.0' } cpu: [arm] os: [linux] lightningcss-linux-arm64-gnu@1.30.1: - resolution: {integrity: sha512-gB72maP8rmrKsnKYy8XUuXi/4OctJiuQjcuqWNlJQ6jZiWqtPvqFziskH3hnajfvKB27ynbVCucKSm2rkQp4Bw==} - engines: {node: '>= 12.0.0'} + resolution: + { integrity: sha512-gB72maP8rmrKsnKYy8XUuXi/4OctJiuQjcuqWNlJQ6jZiWqtPvqFziskH3hnajfvKB27ynbVCucKSm2rkQp4Bw== } + engines: { node: '>= 12.0.0' } cpu: [arm64] os: [linux] lightningcss-linux-arm64-musl@1.30.1: - resolution: {integrity: sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ==} - engines: {node: '>= 12.0.0'} + resolution: + { integrity: sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ== } + engines: { node: '>= 12.0.0' } cpu: [arm64] os: [linux] lightningcss-linux-x64-gnu@1.30.1: - resolution: {integrity: sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw==} - engines: {node: '>= 12.0.0'} + resolution: + { integrity: sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw== } + engines: { node: '>= 12.0.0' } cpu: [x64] os: [linux] lightningcss-linux-x64-musl@1.30.1: - resolution: {integrity: sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ==} - engines: {node: '>= 12.0.0'} + resolution: + { integrity: sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ== } + engines: { node: '>= 12.0.0' } cpu: [x64] os: [linux] lightningcss-win32-arm64-msvc@1.30.1: - resolution: {integrity: sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA==} - engines: {node: '>= 12.0.0'} + resolution: + { integrity: sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA== } + engines: { node: '>= 12.0.0' } cpu: [arm64] os: [win32] lightningcss-win32-x64-msvc@1.30.1: - resolution: {integrity: sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg==} - engines: {node: '>= 12.0.0'} + resolution: + { integrity: sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg== } + engines: { node: '>= 12.0.0' } cpu: [x64] os: [win32] lightningcss@1.30.1: - resolution: {integrity: sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg==} - engines: {node: '>= 12.0.0'} + resolution: + { integrity: sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg== } + engines: { node: '>= 12.0.0' } lines-and-columns@1.2.4: - resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + resolution: + { integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== } locate-path@6.0.0: - resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} - engines: {node: '>=10'} + resolution: + { integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== } + engines: { node: '>=10' } lodash-es@4.17.21: - resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==} + resolution: + { integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw== } lodash.merge@4.6.2: - resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + resolution: + { integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== } loose-envify@1.4.0: - resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + resolution: + { integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== } hasBin: true loupe@3.1.4: - resolution: {integrity: sha512-wJzkKwJrheKtknCOKNEtDK4iqg/MxmZheEMtSTYvnzRdEYaZzmgH976nenp8WdJRdx5Vc1X/9MO0Oszl6ezeXg==} + resolution: + { integrity: sha512-wJzkKwJrheKtknCOKNEtDK4iqg/MxmZheEMtSTYvnzRdEYaZzmgH976nenp8WdJRdx5Vc1X/9MO0Oszl6ezeXg== } lru-cache@10.4.3: - resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + resolution: + { integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ== } magic-string@0.30.17: - resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} + resolution: + { integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA== } math-intrinsics@1.1.0: - resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g== } + engines: { node: '>= 0.4' } memoize-one@5.2.1: - resolution: {integrity: sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==} + resolution: + { integrity: sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q== } merge2@1.4.1: - resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} - engines: {node: '>= 8'} + resolution: + { integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== } + engines: { node: '>= 8' } micromatch@4.0.8: - resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} - engines: {node: '>=8.6'} + resolution: + { integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA== } + engines: { node: '>=8.6' } + + mime-db@1.52.0: + resolution: + { integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== } + engines: { node: '>= 0.6' } + + mime-types@2.1.35: + resolution: + { integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== } + engines: { node: '>= 0.6' } minimatch@3.1.2: - resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + resolution: + { integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== } minimatch@9.0.5: - resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} - engines: {node: '>=16 || 14 >=14.17'} + resolution: + { integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow== } + engines: { node: '>=16 || 14 >=14.17' } minipass@7.1.2: - resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} - engines: {node: '>=16 || 14 >=14.17'} + resolution: + { integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw== } + engines: { node: '>=16 || 14 >=14.17' } minizlib@3.0.2: - resolution: {integrity: sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA==} - engines: {node: '>= 18'} + resolution: + { integrity: sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA== } + engines: { node: '>= 18' } mkdirp@3.0.1: - resolution: {integrity: sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==} - engines: {node: '>=10'} + resolution: + { integrity: sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg== } + engines: { node: '>=10' } hasBin: true module-details-from-path@1.0.4: - resolution: {integrity: sha512-EGWKgxALGMgzvxYF1UyGTy0HXX/2vHLkw6+NvDKW2jypWbHpjQuj4UMcqQWXHERJhVGKikolT06G3bcKe4fi7w==} + resolution: + { integrity: sha512-EGWKgxALGMgzvxYF1UyGTy0HXX/2vHLkw6+NvDKW2jypWbHpjQuj4UMcqQWXHERJhVGKikolT06G3bcKe4fi7w== } motion-dom@12.23.2: - resolution: {integrity: sha512-73j6xDHX/NvVh5L5oS1ouAVnshsvmApOq4F3VZo5MkYSD/YVsVLal4Qp9wvVgJM9uU2bLZyc0Sn8B9c/MMKk4g==} + resolution: + { integrity: sha512-73j6xDHX/NvVh5L5oS1ouAVnshsvmApOq4F3VZo5MkYSD/YVsVLal4Qp9wvVgJM9uU2bLZyc0Sn8B9c/MMKk4g== } motion-utils@12.23.2: - resolution: {integrity: sha512-cIEXlBlXAOUyiAtR0S+QPQUM9L3Diz23Bo+zM420NvSd/oPQJwg6U+rT+WRTpp0rizMsBGQOsAwhWIfglUcZfA==} + resolution: + { integrity: sha512-cIEXlBlXAOUyiAtR0S+QPQUM9L3Diz23Bo+zM420NvSd/oPQJwg6U+rT+WRTpp0rizMsBGQOsAwhWIfglUcZfA== } ms@2.1.3: - resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + resolution: + { integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== } nanoid@3.3.11: - resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} - engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + resolution: + { integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w== } + engines: { node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1 } hasBin: true natural-compare@1.4.0: - resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + resolution: + { integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== } node-releases@2.0.19: - resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==} + resolution: + { integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw== } normalize-range@0.1.2: - resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==} - engines: {node: '>=0.10.0'} + resolution: + { integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA== } + engines: { node: '>=0.10.0' } nwsapi@2.2.20: - resolution: {integrity: sha512-/ieB+mDe4MrrKMT8z+mQL8klXydZWGR5Dowt4RAGKbJ3kIGEx3X4ljUo+6V73IXtUPWgfOlU5B9MlGxFO5T+cA==} + resolution: + { integrity: sha512-/ieB+mDe4MrrKMT8z+mQL8klXydZWGR5Dowt4RAGKbJ3kIGEx3X4ljUo+6V73IXtUPWgfOlU5B9MlGxFO5T+cA== } object-assign@4.1.1: - resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} - engines: {node: '>=0.10.0'} + resolution: + { integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== } + engines: { node: '>=0.10.0' } object-inspect@1.13.4: - resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew== } + engines: { node: '>= 0.4' } object-keys@1.1.1: - resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== } + engines: { node: '>= 0.4' } object.assign@4.1.7: - resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw== } + engines: { node: '>= 0.4' } object.entries@1.1.9: - resolution: {integrity: sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw== } + engines: { node: '>= 0.4' } object.fromentries@2.0.8: - resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ== } + engines: { node: '>= 0.4' } object.values@1.2.1: - resolution: {integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA== } + engines: { node: '>= 0.4' } open@8.4.2: - resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==} - engines: {node: '>=12'} + resolution: + { integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ== } + engines: { node: '>=12' } optimism@0.18.1: - resolution: {integrity: sha512-mLXNwWPa9dgFyDqkNi54sjDyNJ9/fTI6WGBLgnXku1vdKY/jovHfZT5r+aiVeFFLOz+foPNOm5YJ4mqgld2GBQ==} + resolution: + { integrity: sha512-mLXNwWPa9dgFyDqkNi54sjDyNJ9/fTI6WGBLgnXku1vdKY/jovHfZT5r+aiVeFFLOz+foPNOm5YJ4mqgld2GBQ== } optionator@0.9.4: - resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} - engines: {node: '>= 0.8.0'} + resolution: + { integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g== } + engines: { node: '>= 0.8.0' } own-keys@1.0.1: - resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg== } + engines: { node: '>= 0.4' } p-limit@3.1.0: - resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} - engines: {node: '>=10'} + resolution: + { integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== } + engines: { node: '>=10' } p-locate@5.0.0: - resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} - engines: {node: '>=10'} + resolution: + { integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== } + engines: { node: '>=10' } parent-module@1.0.1: - resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} - engines: {node: '>=6'} + resolution: + { integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== } + engines: { node: '>=6' } parse-json@5.2.0: - resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} - engines: {node: '>=8'} + resolution: + { integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== } + engines: { node: '>=8' } parse5@7.3.0: - resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==} + resolution: + { integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw== } path-exists@4.0.0: - resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} - engines: {node: '>=8'} + resolution: + { integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== } + engines: { node: '>=8' } path-key@3.1.1: - resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} - engines: {node: '>=8'} + resolution: + { integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== } + engines: { node: '>=8' } path-parse@1.0.7: - resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + resolution: + { integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== } path-type@4.0.0: - resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} - engines: {node: '>=8'} + resolution: + { integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== } + engines: { node: '>=8' } pathe@2.0.3: - resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + resolution: + { integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w== } pathval@2.0.1: - resolution: {integrity: sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==} - engines: {node: '>= 14.16'} + resolution: + { integrity: sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ== } + engines: { node: '>= 14.16' } pg-int8@1.0.1: - resolution: {integrity: sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==} - engines: {node: '>=4.0.0'} + resolution: + { integrity: sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw== } + engines: { node: '>=4.0.0' } pg-protocol@1.10.3: - resolution: {integrity: sha512-6DIBgBQaTKDJyxnXaLiLR8wBpQQcGWuAESkRBX/t6OwA8YsqP+iVSiond2EDy6Y/dsGk8rh/jtax3js5NeV7JQ==} + resolution: + { integrity: sha512-6DIBgBQaTKDJyxnXaLiLR8wBpQQcGWuAESkRBX/t6OwA8YsqP+iVSiond2EDy6Y/dsGk8rh/jtax3js5NeV7JQ== } pg-types@2.2.0: - resolution: {integrity: sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==} - engines: {node: '>=4'} + resolution: + { integrity: sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA== } + engines: { node: '>=4' } picocolors@1.1.1: - resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + resolution: + { integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA== } picomatch@2.3.1: - resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} - engines: {node: '>=8.6'} + resolution: + { integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== } + engines: { node: '>=8.6' } picomatch@4.0.2: - resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} - engines: {node: '>=12'} + resolution: + { integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg== } + engines: { node: '>=12' } possible-typed-array-names@1.1.0: - resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg== } + engines: { node: '>= 0.4' } postcss-value-parser@4.2.0: - resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} + resolution: + { integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== } postcss@8.5.6: - resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} - engines: {node: ^10 || ^12 || >=14} + resolution: + { integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg== } + engines: { node: ^10 || ^12 || >=14 } postgres-array@2.0.0: - resolution: {integrity: sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==} - engines: {node: '>=4'} + resolution: + { integrity: sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA== } + engines: { node: '>=4' } postgres-bytea@1.0.0: - resolution: {integrity: sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==} - engines: {node: '>=0.10.0'} + resolution: + { integrity: sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w== } + engines: { node: '>=0.10.0' } postgres-date@1.0.7: - resolution: {integrity: sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==} - engines: {node: '>=0.10.0'} + resolution: + { integrity: sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q== } + engines: { node: '>=0.10.0' } postgres-interval@1.2.0: - resolution: {integrity: sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==} - engines: {node: '>=0.10.0'} + resolution: + { integrity: sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ== } + engines: { node: '>=0.10.0' } prelude-ls@1.2.1: - resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} - engines: {node: '>= 0.8.0'} + resolution: + { integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== } + engines: { node: '>= 0.8.0' } prettier-linter-helpers@1.0.0: - resolution: {integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==} - engines: {node: '>=6.0.0'} + resolution: + { integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w== } + engines: { node: '>=6.0.0' } prettier@3.6.2: - resolution: {integrity: sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==} - engines: {node: '>=14'} + resolution: + { integrity: sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ== } + engines: { node: '>=14' } hasBin: true prop-types@15.8.1: - resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} + resolution: + { integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== } property-expr@2.0.6: - resolution: {integrity: sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA==} + resolution: + { integrity: sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA== } + + proxy-from-env@1.1.0: + resolution: + { integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== } punycode@2.3.1: - resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} - engines: {node: '>=6'} + resolution: + { integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== } + engines: { node: '>=6' } queue-microtask@1.2.3: - resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + resolution: + { integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== } raf-schd@4.0.3: - resolution: {integrity: sha512-tQkJl2GRWh83ui2DiPTJz9wEiMN20syf+5oKfB03yYP7ioZcJwsIK8FjrtLwH1m7C7e+Tt2yYBlrOpdT+dyeIQ==} + resolution: + { integrity: sha512-tQkJl2GRWh83ui2DiPTJz9wEiMN20syf+5oKfB03yYP7ioZcJwsIK8FjrtLwH1m7C7e+Tt2yYBlrOpdT+dyeIQ== } react-dom@18.3.1: - resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==} + resolution: + { integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw== } peerDependencies: react: ^18.3.1 react-is@16.13.1: - resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + resolution: + { integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== } react-is@19.1.0: - resolution: {integrity: sha512-Oe56aUPnkHyyDxxkvqtd7KkdQP5uIUfHxd5XTb3wE9d/kRnZLmKbDB0GWk919tdQ+mxxPtG6EAs6RMT6i1qtHg==} + resolution: + { integrity: sha512-Oe56aUPnkHyyDxxkvqtd7KkdQP5uIUfHxd5XTb3wE9d/kRnZLmKbDB0GWk919tdQ+mxxPtG6EAs6RMT6i1qtHg== } react-redux@9.2.0: - resolution: {integrity: sha512-ROY9fvHhwOD9ySfrF0wmvu//bKCQ6AeZZq1nJNtbDC+kk5DuSuNX/n6YWYF/SYy7bSba4D4FSz8DJeKY/S/r+g==} + resolution: + { integrity: sha512-ROY9fvHhwOD9ySfrF0wmvu//bKCQ6AeZZq1nJNtbDC+kk5DuSuNX/n6YWYF/SYy7bSba4D4FSz8DJeKY/S/r+g== } peerDependencies: '@types/react': ^18.2.25 || ^19 react: ^18.0 || ^19 @@ -2907,48 +3542,57 @@ packages: optional: true react-router-dom@6.30.0: - resolution: {integrity: sha512-x30B78HV5tFk8ex0ITwzC9TTZMua4jGyA9IUlH1JLQYQTFyxr/ZxwOJq7evg1JX1qGVUcvhsmQSKdPncQrjTgA==} - engines: {node: '>=14.0.0'} + resolution: + { integrity: sha512-x30B78HV5tFk8ex0ITwzC9TTZMua4jGyA9IUlH1JLQYQTFyxr/ZxwOJq7evg1JX1qGVUcvhsmQSKdPncQrjTgA== } + engines: { node: '>=14.0.0' } peerDependencies: react: '>=16.8' react-dom: '>=16.8' react-router@6.30.0: - resolution: {integrity: sha512-D3X8FyH9nBcTSHGdEKurK7r8OYE1kKFn3d/CF+CoxbSHkxU7o37+Uh7eAHRXr6k2tSExXYO++07PeXJtA/dEhQ==} - engines: {node: '>=14.0.0'} + resolution: + { integrity: sha512-D3X8FyH9nBcTSHGdEKurK7r8OYE1kKFn3d/CF+CoxbSHkxU7o37+Uh7eAHRXr6k2tSExXYO++07PeXJtA/dEhQ== } + engines: { node: '>=14.0.0' } peerDependencies: react: '>=16.8' react-transition-group@4.4.5: - resolution: {integrity: sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==} + resolution: + { integrity: sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g== } peerDependencies: react: '>=16.6.0' react-dom: '>=16.6.0' react-window@1.8.11: - resolution: {integrity: sha512-+SRbUVT2scadgFSWx+R1P754xHPEqvcfSfVX10QYg6POOz+WNgkN48pS+BtZNIMGiL1HYrSEiCkwsMS15QogEQ==} - engines: {node: '>8.0.0'} + resolution: + { integrity: sha512-+SRbUVT2scadgFSWx+R1P754xHPEqvcfSfVX10QYg6POOz+WNgkN48pS+BtZNIMGiL1HYrSEiCkwsMS15QogEQ== } + engines: { node: '>8.0.0' } peerDependencies: react: ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react@18.3.1: - resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} - engines: {node: '>=0.10.0'} + resolution: + { integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ== } + engines: { node: '>=0.10.0' } redux@5.0.1: - resolution: {integrity: sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==} + resolution: + { integrity: sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w== } reflect.getprototypeof@1.0.10: - resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw== } + engines: { node: '>= 0.4' } regexp.prototype.flags@1.5.4: - resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA== } + engines: { node: '>= 0.4' } rehackt@0.1.0: - resolution: {integrity: sha512-7kRDOuLHB87D/JESKxQoRwv4DzbIdwkAGQ7p6QKGdVlY1IZheUnVhlk/4UZlNUVxdAXpyxikE3URsG067ybVzw==} + resolution: + { integrity: sha512-7kRDOuLHB87D/JESKxQoRwv4DzbIdwkAGQ7p6QKGdVlY1IZheUnVhlk/4UZlNUVxdAXpyxikE3URsG067ybVzw== } peerDependencies: '@types/react': '*' react: '*' @@ -2959,33 +3603,40 @@ packages: optional: true require-directory@2.1.1: - resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} - engines: {node: '>=0.10.0'} + resolution: + { integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== } + engines: { node: '>=0.10.0' } require-in-the-middle@7.5.2: - resolution: {integrity: sha512-gAZ+kLqBdHarXB64XpAe2VCjB7rIRv+mU8tfRWziHRJ5umKsIHN2tLLv6EtMw7WCdP19S0ERVMldNvxYCHnhSQ==} - engines: {node: '>=8.6.0'} + resolution: + { integrity: sha512-gAZ+kLqBdHarXB64XpAe2VCjB7rIRv+mU8tfRWziHRJ5umKsIHN2tLLv6EtMw7WCdP19S0ERVMldNvxYCHnhSQ== } + engines: { node: '>=8.6.0' } resolve-from@4.0.0: - resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} - engines: {node: '>=4'} + resolution: + { integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== } + engines: { node: '>=4' } resolve@1.22.10: - resolution: {integrity: sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w== } + engines: { node: '>= 0.4' } hasBin: true resolve@2.0.0-next.5: - resolution: {integrity: sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==} + resolution: + { integrity: sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA== } hasBin: true reusify@1.1.0: - resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} - engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + resolution: + { integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw== } + engines: { iojs: '>=1.0.0', node: '>=0.10.0' } rollup-plugin-visualizer@5.14.0: - resolution: {integrity: sha512-VlDXneTDaKsHIw8yzJAFWtrzguoJ/LnQ+lMpoVfYJ3jJF4Ihe5oYLAqLklIK/35lgUY+1yEzCkHyZ1j4A5w5fA==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-VlDXneTDaKsHIw8yzJAFWtrzguoJ/LnQ+lMpoVfYJ3jJF4Ihe5oYLAqLklIK/35lgUY+1yEzCkHyZ1j4A5w5fA== } + engines: { node: '>=18' } hasBin: true peerDependencies: rolldown: 1.x @@ -2997,251 +3648,317 @@ packages: optional: true rollup@4.45.0: - resolution: {integrity: sha512-WLjEcJRIo7i3WDDgOIJqVI2d+lAC3EwvOGy+Xfq6hs+GQuAA4Di/H72xmXkOhrIWFg2PFYSKZYfH0f4vfKXN4A==} - engines: {node: '>=18.0.0', npm: '>=8.0.0'} + resolution: + { integrity: sha512-WLjEcJRIo7i3WDDgOIJqVI2d+lAC3EwvOGy+Xfq6hs+GQuAA4Di/H72xmXkOhrIWFg2PFYSKZYfH0f4vfKXN4A== } + engines: { node: '>=18.0.0', npm: '>=8.0.0' } hasBin: true rrweb-cssom@0.8.0: - resolution: {integrity: sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==} + resolution: + { integrity: sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw== } run-parallel@1.2.0: - resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + resolution: + { integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== } runes2@1.1.4: - resolution: {integrity: sha512-LNPnEDPOOU4ehF71m5JoQyzT2yxwD6ZreFJ7MxZUAoMKNMY1XrAo60H1CUoX5ncSm0rIuKlqn9JZNRrRkNou2g==} + resolution: + { integrity: sha512-LNPnEDPOOU4ehF71m5JoQyzT2yxwD6ZreFJ7MxZUAoMKNMY1XrAo60H1CUoX5ncSm0rIuKlqn9JZNRrRkNou2g== } safe-array-concat@1.1.3: - resolution: {integrity: sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==} - engines: {node: '>=0.4'} + resolution: + { integrity: sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q== } + engines: { node: '>=0.4' } safe-push-apply@1.0.0: - resolution: {integrity: sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA== } + engines: { node: '>= 0.4' } safe-regex-test@1.1.0: - resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw== } + engines: { node: '>= 0.4' } safer-buffer@2.1.2: - resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + resolution: + { integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== } saxes@6.0.0: - resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==} - engines: {node: '>=v12.22.7'} + resolution: + { integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA== } + engines: { node: '>=v12.22.7' } scheduler@0.23.2: - resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==} + resolution: + { integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ== } semver@6.3.1: - resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + resolution: + { integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== } hasBin: true semver@7.7.2: - resolution: {integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==} - engines: {node: '>=10'} + resolution: + { integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA== } + engines: { node: '>=10' } hasBin: true set-function-length@1.2.2: - resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg== } + engines: { node: '>= 0.4' } set-function-name@2.0.2: - resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ== } + engines: { node: '>= 0.4' } set-proto@1.0.0: - resolution: {integrity: sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw== } + engines: { node: '>= 0.4' } shebang-command@2.0.0: - resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} - engines: {node: '>=8'} + resolution: + { integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== } + engines: { node: '>=8' } shebang-regex@3.0.0: - resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} - engines: {node: '>=8'} + resolution: + { integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== } + engines: { node: '>=8' } shimmer@1.2.1: - resolution: {integrity: sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==} + resolution: + { integrity: sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw== } side-channel-list@1.0.0: - resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA== } + engines: { node: '>= 0.4' } side-channel-map@1.0.1: - resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA== } + engines: { node: '>= 0.4' } side-channel-weakmap@1.0.2: - resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A== } + engines: { node: '>= 0.4' } side-channel@1.1.0: - resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw== } + engines: { node: '>= 0.4' } siginfo@2.0.0: - resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + resolution: + { integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g== } source-map-js@1.2.1: - resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} - engines: {node: '>=0.10.0'} + resolution: + { integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA== } + engines: { node: '>=0.10.0' } source-map@0.5.7: - resolution: {integrity: sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==} - engines: {node: '>=0.10.0'} + resolution: + { integrity: sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ== } + engines: { node: '>=0.10.0' } source-map@0.7.4: - resolution: {integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==} - engines: {node: '>= 8'} + resolution: + { integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA== } + engines: { node: '>= 8' } stackback@0.0.2: - resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + resolution: + { integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw== } std-env@3.9.0: - resolution: {integrity: sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==} + resolution: + { integrity: sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw== } stop-iteration-iterator@1.1.0: - resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ== } + engines: { node: '>= 0.4' } string-width@4.2.3: - resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} - engines: {node: '>=8'} + resolution: + { integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== } + engines: { node: '>=8' } string.prototype.matchall@4.0.12: - resolution: {integrity: sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA== } + engines: { node: '>= 0.4' } string.prototype.repeat@1.0.0: - resolution: {integrity: sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==} + resolution: + { integrity: sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w== } string.prototype.trim@1.2.10: - resolution: {integrity: sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA== } + engines: { node: '>= 0.4' } string.prototype.trimend@1.0.9: - resolution: {integrity: sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ== } + engines: { node: '>= 0.4' } string.prototype.trimstart@1.0.8: - resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg== } + engines: { node: '>= 0.4' } strip-ansi@6.0.1: - resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} - engines: {node: '>=8'} + resolution: + { integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== } + engines: { node: '>=8' } strip-json-comments@3.1.1: - resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} - engines: {node: '>=8'} + resolution: + { integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== } + engines: { node: '>=8' } strip-literal@3.0.0: - resolution: {integrity: sha512-TcccoMhJOM3OebGhSBEmp3UZ2SfDMZUEBdRA/9ynfLi8yYajyWX3JiXArcJt4Umh4vISpspkQIY8ZZoCqjbviA==} + resolution: + { integrity: sha512-TcccoMhJOM3OebGhSBEmp3UZ2SfDMZUEBdRA/9ynfLi8yYajyWX3JiXArcJt4Umh4vISpspkQIY8ZZoCqjbviA== } stylis@4.2.0: - resolution: {integrity: sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==} + resolution: + { integrity: sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw== } supports-color@7.2.0: - resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} - engines: {node: '>=8'} + resolution: + { integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== } + engines: { node: '>=8' } supports-preserve-symlinks-flag@1.0.0: - resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== } + engines: { node: '>= 0.4' } symbol-observable@4.0.0: - resolution: {integrity: sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ==} - engines: {node: '>=0.10'} + resolution: + { integrity: sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ== } + engines: { node: '>=0.10' } symbol-tree@3.2.4: - resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} + resolution: + { integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== } synckit@0.11.8: - resolution: {integrity: sha512-+XZ+r1XGIJGeQk3VvXhT6xx/VpbHsRzsTkGgF6E5RX9TTXD0118l87puaEBZ566FhqblC6U0d4XnubznJDm30A==} - engines: {node: ^14.18.0 || >=16.0.0} + resolution: + { integrity: sha512-+XZ+r1XGIJGeQk3VvXhT6xx/VpbHsRzsTkGgF6E5RX9TTXD0118l87puaEBZ566FhqblC6U0d4XnubznJDm30A== } + engines: { node: ^14.18.0 || >=16.0.0 } tailwind-merge@3.3.1: - resolution: {integrity: sha512-gBXpgUm/3rp1lMZZrM/w7D8GKqshif0zAymAhbCyIt8KMe+0v9DQ7cdYLR4FHH/cKpdTXb+A/tKKU3eolfsI+g==} + resolution: + { integrity: sha512-gBXpgUm/3rp1lMZZrM/w7D8GKqshif0zAymAhbCyIt8KMe+0v9DQ7cdYLR4FHH/cKpdTXb+A/tKKU3eolfsI+g== } tailwindcss@4.1.11: - resolution: {integrity: sha512-2E9TBm6MDD/xKYe+dvJZAmg3yxIEDNRc0jwlNyDg/4Fil2QcSLjFKGVff0lAf1jjeaArlG/M75Ey/EYr/OJtBA==} + resolution: + { integrity: sha512-2E9TBm6MDD/xKYe+dvJZAmg3yxIEDNRc0jwlNyDg/4Fil2QcSLjFKGVff0lAf1jjeaArlG/M75Ey/EYr/OJtBA== } tapable@2.2.2: - resolution: {integrity: sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==} - engines: {node: '>=6'} + resolution: + { integrity: sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg== } + engines: { node: '>=6' } tar@7.4.3: - resolution: {integrity: sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw== } + engines: { node: '>=18' } tiny-case@1.0.3: - resolution: {integrity: sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q==} + resolution: + { integrity: sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q== } tiny-invariant@1.3.3: - resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} + resolution: + { integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg== } tinybench@2.9.0: - resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} + resolution: + { integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg== } tinyexec@0.3.2: - resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} + resolution: + { integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA== } tinyglobby@0.2.14: - resolution: {integrity: sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==} - engines: {node: '>=12.0.0'} + resolution: + { integrity: sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ== } + engines: { node: '>=12.0.0' } tinypool@1.1.1: - resolution: {integrity: sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==} - engines: {node: ^18.0.0 || >=20.0.0} + resolution: + { integrity: sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg== } + engines: { node: ^18.0.0 || >=20.0.0 } tinyrainbow@2.0.0: - resolution: {integrity: sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==} - engines: {node: '>=14.0.0'} + resolution: + { integrity: sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw== } + engines: { node: '>=14.0.0' } tinyspy@4.0.3: - resolution: {integrity: sha512-t2T/WLB2WRgZ9EpE4jgPJ9w+i66UZfDc8wHh0xrwiRNN+UwH98GIJkTeZqX9rg0i0ptwzqW+uYeIF0T4F8LR7A==} - engines: {node: '>=14.0.0'} + resolution: + { integrity: sha512-t2T/WLB2WRgZ9EpE4jgPJ9w+i66UZfDc8wHh0xrwiRNN+UwH98GIJkTeZqX9rg0i0ptwzqW+uYeIF0T4F8LR7A== } + engines: { node: '>=14.0.0' } tldts-core@6.1.86: - resolution: {integrity: sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA==} + resolution: + { integrity: sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA== } tldts@6.1.86: - resolution: {integrity: sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==} + resolution: + { integrity: sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ== } hasBin: true tmp@0.2.3: - resolution: {integrity: sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==} - engines: {node: '>=14.14'} + resolution: + { integrity: sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w== } + engines: { node: '>=14.14' } to-regex-range@5.0.1: - resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} - engines: {node: '>=8.0'} + resolution: + { integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== } + engines: { node: '>=8.0' } toposort@2.0.2: - resolution: {integrity: sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg==} + resolution: + { integrity: sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg== } tough-cookie@5.1.2: - resolution: {integrity: sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==} - engines: {node: '>=16'} + resolution: + { integrity: sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A== } + engines: { node: '>=16' } tr46@5.1.1: - resolution: {integrity: sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw== } + engines: { node: '>=18' } ts-api-utils@2.1.0: - resolution: {integrity: sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==} - engines: {node: '>=18.12'} + resolution: + { integrity: sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ== } + engines: { node: '>=18.12' } peerDependencies: typescript: '>=4.8.4' ts-invariant@0.10.3: - resolution: {integrity: sha512-uivwYcQaxAucv1CzRp2n/QdYPo4ILf9VXgH19zEIjFx2EJufV16P0JtJVpYHy89DItG6Kwj2oIUjrcK5au+4tQ==} - engines: {node: '>=8'} + resolution: + { integrity: sha512-uivwYcQaxAucv1CzRp2n/QdYPo4ILf9VXgH19zEIjFx2EJufV16P0JtJVpYHy89DItG6Kwj2oIUjrcK5au+4tQ== } + engines: { node: '>=8' } tsconfck@3.1.6: - resolution: {integrity: sha512-ks6Vjr/jEw0P1gmOVwutM3B7fWxoWBL2KRDb1JfqGVawBmO5UsvmWOQFGHBPl5yxYz4eERr19E6L7NMv+Fej4w==} - engines: {node: ^18 || >=20} + resolution: + { integrity: sha512-ks6Vjr/jEw0P1gmOVwutM3B7fWxoWBL2KRDb1JfqGVawBmO5UsvmWOQFGHBPl5yxYz4eERr19E6L7NMv+Fej4w== } + engines: { node: ^18 || >=20 } hasBin: true peerDependencies: typescript: ^5.0.0 @@ -3250,81 +3967,99 @@ packages: optional: true tslib@2.8.1: - resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + resolution: + { integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== } type-check@0.4.0: - resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} - engines: {node: '>= 0.8.0'} + resolution: + { integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== } + engines: { node: '>= 0.8.0' } type-fest@2.19.0: - resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==} - engines: {node: '>=12.20'} + resolution: + { integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA== } + engines: { node: '>=12.20' } typed-array-buffer@1.0.3: - resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw== } + engines: { node: '>= 0.4' } typed-array-byte-length@1.0.3: - resolution: {integrity: sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg== } + engines: { node: '>= 0.4' } typed-array-byte-offset@1.0.4: - resolution: {integrity: sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ== } + engines: { node: '>= 0.4' } typed-array-length@1.0.7: - resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg== } + engines: { node: '>= 0.4' } typescript-eslint@8.37.0: - resolution: {integrity: sha512-TnbEjzkE9EmcO0Q2zM+GE8NQLItNAJpMmED1BdgoBMYNdqMhzlbqfdSwiRlAzEK2pA9UzVW0gzaaIzXWg2BjfA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + resolution: + { integrity: sha512-TnbEjzkE9EmcO0Q2zM+GE8NQLItNAJpMmED1BdgoBMYNdqMhzlbqfdSwiRlAzEK2pA9UzVW0gzaaIzXWg2BjfA== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.9.0' typescript@5.8.3: - resolution: {integrity: sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==} - engines: {node: '>=14.17'} + resolution: + { integrity: sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ== } + engines: { node: '>=14.17' } hasBin: true unbox-primitive@1.1.0: - resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw== } + engines: { node: '>= 0.4' } undici-types@6.21.0: - resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + resolution: + { integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ== } update-browserslist-db@1.1.3: - resolution: {integrity: sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==} + resolution: + { integrity: sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw== } hasBin: true peerDependencies: browserslist: '>= 4.21.0' uri-js@4.4.1: - resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + resolution: + { integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== } use-sync-external-store@1.5.0: - resolution: {integrity: sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A==} + resolution: + { integrity: sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A== } peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 uuid@11.1.0: - resolution: {integrity: sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==} + resolution: + { integrity: sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A== } hasBin: true vite-bundle-visualizer@1.2.1: - resolution: {integrity: sha512-cwz/Pg6+95YbgIDp+RPwEToc4TKxfsFWSG/tsl2DSZd9YZicUag1tQXjJ5xcL7ydvEoaC2FOZeaXOU60t9BRXw==} - engines: {node: ^18.19.0 || >=20.6.0} + resolution: + { integrity: sha512-cwz/Pg6+95YbgIDp+RPwEToc4TKxfsFWSG/tsl2DSZd9YZicUag1tQXjJ5xcL7ydvEoaC2FOZeaXOU60t9BRXw== } + engines: { node: ^18.19.0 || >=20.6.0 } hasBin: true vite-node@3.2.4: - resolution: {integrity: sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==} - engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + resolution: + { integrity: sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg== } + engines: { node: ^18.0.0 || ^20.0.0 || >=22.0.0 } hasBin: true vite-tsconfig-paths@5.1.4: - resolution: {integrity: sha512-cYj0LRuLV2c2sMqhqhGpaO3LretdtMn/BVX4cPLanIZuwwrkVl+lK84E/miEXkCHWXuq65rhNN4rXsBcOB3S4w==} + resolution: + { integrity: sha512-cYj0LRuLV2c2sMqhqhGpaO3LretdtMn/BVX4cPLanIZuwwrkVl+lK84E/miEXkCHWXuq65rhNN4rXsBcOB3S4w== } peerDependencies: vite: '*' peerDependenciesMeta: @@ -3332,8 +4067,9 @@ packages: optional: true vite@7.0.4: - resolution: {integrity: sha512-SkaSguuS7nnmV7mfJ8l81JGBFV7Gvzp8IzgE8A8t23+AxuNX61Q5H1Tpz5efduSN7NHC8nQXD3sKQKZAu5mNEA==} - engines: {node: ^20.19.0 || >=22.12.0} + resolution: + { integrity: sha512-SkaSguuS7nnmV7mfJ8l81JGBFV7Gvzp8IzgE8A8t23+AxuNX61Q5H1Tpz5efduSN7NHC8nQXD3sKQKZAu5mNEA== } + engines: { node: ^20.19.0 || >=22.12.0 } hasBin: true peerDependencies: '@types/node': ^20.19.0 || >=22.12.0 @@ -3372,8 +4108,9 @@ packages: optional: true vitest@3.2.4: - resolution: {integrity: sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==} - engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + resolution: + { integrity: sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A== } + engines: { node: ^18.0.0 || ^20.0.0 || >=22.0.0 } hasBin: true peerDependencies: '@edge-runtime/vm': '*' @@ -3400,101 +4137,128 @@ packages: optional: true w3c-xmlserializer@5.0.0: - resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA== } + engines: { node: '>=18' } web-vitals@4.2.4: - resolution: {integrity: sha512-r4DIlprAGwJ7YM11VZp4R884m0Vmgr6EAKe3P+kO0PPj3Unqyvv59rczf6UiGcb9Z8QxZVcqKNwv/g0WNdWwsw==} + resolution: + { integrity: sha512-r4DIlprAGwJ7YM11VZp4R884m0Vmgr6EAKe3P+kO0PPj3Unqyvv59rczf6UiGcb9Z8QxZVcqKNwv/g0WNdWwsw== } webidl-conversions@7.0.0: - resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==} - engines: {node: '>=12'} + resolution: + { integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g== } + engines: { node: '>=12' } whatwg-encoding@3.1.1: - resolution: {integrity: sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ== } + engines: { node: '>=18' } whatwg-mimetype@4.0.0: - resolution: {integrity: sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg== } + engines: { node: '>=18' } whatwg-url@14.2.0: - resolution: {integrity: sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw== } + engines: { node: '>=18' } which-boxed-primitive@1.1.1: - resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA== } + engines: { node: '>= 0.4' } which-builtin-type@1.2.1: - resolution: {integrity: sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q== } + engines: { node: '>= 0.4' } which-collection@1.0.2: - resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw== } + engines: { node: '>= 0.4' } which-typed-array@1.1.19: - resolution: {integrity: sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw== } + engines: { node: '>= 0.4' } which@2.0.2: - resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} - engines: {node: '>= 8'} + resolution: + { integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== } + engines: { node: '>= 8' } hasBin: true why-is-node-running@2.3.0: - resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} - engines: {node: '>=8'} + resolution: + { integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w== } + engines: { node: '>=8' } hasBin: true word-wrap@1.2.5: - resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} - engines: {node: '>=0.10.0'} + resolution: + { integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA== } + engines: { node: '>=0.10.0' } workbox-background-sync@7.3.0: - resolution: {integrity: sha512-PCSk3eK7Mxeuyatb22pcSx9dlgWNv3+M8PqPaYDokks8Y5/FX4soaOqj3yhAZr5k6Q5JWTOMYgaJBpbw11G9Eg==} + resolution: + { integrity: sha512-PCSk3eK7Mxeuyatb22pcSx9dlgWNv3+M8PqPaYDokks8Y5/FX4soaOqj3yhAZr5k6Q5JWTOMYgaJBpbw11G9Eg== } workbox-broadcast-update@7.3.0: - resolution: {integrity: sha512-T9/F5VEdJVhwmrIAE+E/kq5at2OY6+OXXgOWQevnubal6sO92Gjo24v6dCVwQiclAF5NS3hlmsifRrpQzZCdUA==} + resolution: + { integrity: sha512-T9/F5VEdJVhwmrIAE+E/kq5at2OY6+OXXgOWQevnubal6sO92Gjo24v6dCVwQiclAF5NS3hlmsifRrpQzZCdUA== } workbox-cacheable-response@7.3.0: - resolution: {integrity: sha512-eAFERIg6J2LuyELhLlmeRcJFa5e16Mj8kL2yCDbhWE+HUun9skRQrGIFVUagqWj4DMaaPSMWfAolM7XZZxNmxA==} + resolution: + { integrity: sha512-eAFERIg6J2LuyELhLlmeRcJFa5e16Mj8kL2yCDbhWE+HUun9skRQrGIFVUagqWj4DMaaPSMWfAolM7XZZxNmxA== } workbox-core@7.3.0: - resolution: {integrity: sha512-Z+mYrErfh4t3zi7NVTvOuACB0A/jA3bgxUN3PwtAVHvfEsZxV9Iju580VEETug3zYJRc0Dmii/aixI/Uxj8fmw==} + resolution: + { integrity: sha512-Z+mYrErfh4t3zi7NVTvOuACB0A/jA3bgxUN3PwtAVHvfEsZxV9Iju580VEETug3zYJRc0Dmii/aixI/Uxj8fmw== } workbox-expiration@7.3.0: - resolution: {integrity: sha512-lpnSSLp2BM+K6bgFCWc5bS1LR5pAwDWbcKt1iL87/eTSJRdLdAwGQznZE+1czLgn/X05YChsrEegTNxjM067vQ==} + resolution: + { integrity: sha512-lpnSSLp2BM+K6bgFCWc5bS1LR5pAwDWbcKt1iL87/eTSJRdLdAwGQznZE+1czLgn/X05YChsrEegTNxjM067vQ== } workbox-google-analytics@7.3.0: - resolution: {integrity: sha512-ii/tSfFdhjLHZ2BrYgFNTrb/yk04pw2hasgbM70jpZfLk0vdJAXgaiMAWsoE+wfJDNWoZmBYY0hMVI0v5wWDbg==} + resolution: + { integrity: sha512-ii/tSfFdhjLHZ2BrYgFNTrb/yk04pw2hasgbM70jpZfLk0vdJAXgaiMAWsoE+wfJDNWoZmBYY0hMVI0v5wWDbg== } workbox-navigation-preload@7.3.0: - resolution: {integrity: sha512-fTJzogmFaTv4bShZ6aA7Bfj4Cewaq5rp30qcxl2iYM45YD79rKIhvzNHiFj1P+u5ZZldroqhASXwwoyusnr2cg==} + resolution: + { integrity: sha512-fTJzogmFaTv4bShZ6aA7Bfj4Cewaq5rp30qcxl2iYM45YD79rKIhvzNHiFj1P+u5ZZldroqhASXwwoyusnr2cg== } workbox-precaching@7.3.0: - resolution: {integrity: sha512-ckp/3t0msgXclVAYaNndAGeAoWQUv7Rwc4fdhWL69CCAb2UHo3Cef0KIUctqfQj1p8h6aGyz3w8Cy3Ihq9OmIw==} + resolution: + { integrity: sha512-ckp/3t0msgXclVAYaNndAGeAoWQUv7Rwc4fdhWL69CCAb2UHo3Cef0KIUctqfQj1p8h6aGyz3w8Cy3Ihq9OmIw== } workbox-range-requests@7.3.0: - resolution: {integrity: sha512-EyFmM1KpDzzAouNF3+EWa15yDEenwxoeXu9bgxOEYnFfCxns7eAxA9WSSaVd8kujFFt3eIbShNqa4hLQNFvmVQ==} + resolution: + { integrity: sha512-EyFmM1KpDzzAouNF3+EWa15yDEenwxoeXu9bgxOEYnFfCxns7eAxA9WSSaVd8kujFFt3eIbShNqa4hLQNFvmVQ== } workbox-routing@7.3.0: - resolution: {integrity: sha512-ZUlysUVn5ZUzMOmQN3bqu+gK98vNfgX/gSTZ127izJg/pMMy4LryAthnYtjuqcjkN4HEAx1mdgxNiKJMZQM76A==} + resolution: + { integrity: sha512-ZUlysUVn5ZUzMOmQN3bqu+gK98vNfgX/gSTZ127izJg/pMMy4LryAthnYtjuqcjkN4HEAx1mdgxNiKJMZQM76A== } workbox-strategies@7.3.0: - resolution: {integrity: sha512-tmZydug+qzDFATwX7QiEL5Hdf7FrkhjaF9db1CbB39sDmEZJg3l9ayDvPxy8Y18C3Y66Nrr9kkN1f/RlkDgllg==} + resolution: + { integrity: sha512-tmZydug+qzDFATwX7QiEL5Hdf7FrkhjaF9db1CbB39sDmEZJg3l9ayDvPxy8Y18C3Y66Nrr9kkN1f/RlkDgllg== } workbox-streams@7.3.0: - resolution: {integrity: sha512-SZnXucyg8x2Y61VGtDjKPO5EgPUG5NDn/v86WYHX+9ZqvAsGOytP0Jxp1bl663YUuMoXSAtsGLL+byHzEuMRpw==} + resolution: + { integrity: sha512-SZnXucyg8x2Y61VGtDjKPO5EgPUG5NDn/v86WYHX+9ZqvAsGOytP0Jxp1bl663YUuMoXSAtsGLL+byHzEuMRpw== } wrap-ansi@7.0.0: - resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} - engines: {node: '>=10'} + resolution: + { integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== } + engines: { node: '>=10' } ws@8.18.3: - resolution: {integrity: sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==} - engines: {node: '>=10.0.0'} + resolution: + { integrity: sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg== } + engines: { node: '>=10.0.0' } peerDependencies: bufferutil: ^4.0.1 utf-8-validate: '>=5.0.2' @@ -3505,56 +4269,68 @@ packages: optional: true xml-name-validator@5.0.0: - resolution: {integrity: sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg== } + engines: { node: '>=18' } xmlchars@2.2.0: - resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==} + resolution: + { integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== } xtend@4.0.2: - resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} - engines: {node: '>=0.4'} + resolution: + { integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== } + engines: { node: '>=0.4' } y18n@5.0.8: - resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} - engines: {node: '>=10'} + resolution: + { integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== } + engines: { node: '>=10' } yallist@5.0.0: - resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw== } + engines: { node: '>=18' } yaml@1.10.2: - resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} - engines: {node: '>= 6'} + resolution: + { integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== } + engines: { node: '>= 6' } yaml@2.7.1: - resolution: {integrity: sha512-10ULxpnOCQXxJvBgxsn9ptjq6uviG/htZKk9veJGhlqn3w/DxQ631zFF+nlQXLwmImeS5amR2dl2U8sg6U9jsQ==} - engines: {node: '>= 14'} + resolution: + { integrity: sha512-10ULxpnOCQXxJvBgxsn9ptjq6uviG/htZKk9veJGhlqn3w/DxQ631zFF+nlQXLwmImeS5amR2dl2U8sg6U9jsQ== } + engines: { node: '>= 14' } hasBin: true yargs-parser@21.1.1: - resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} - engines: {node: '>=12'} + resolution: + { integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== } + engines: { node: '>=12' } yargs@17.7.2: - resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} - engines: {node: '>=12'} + resolution: + { integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w== } + engines: { node: '>=12' } yocto-queue@0.1.0: - resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} - engines: {node: '>=10'} + resolution: + { integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== } + engines: { node: '>=10' } yup@1.6.1: - resolution: {integrity: sha512-JED8pB50qbA4FOkDol0bYF/p60qSEDQqBD0/qeIrUCG1KbPBIQ776fCUNb9ldbPcSTxA69g/47XTo4TqWiuXOA==} + resolution: + { integrity: sha512-JED8pB50qbA4FOkDol0bYF/p60qSEDQqBD0/qeIrUCG1KbPBIQ776fCUNb9ldbPcSTxA69g/47XTo4TqWiuXOA== } zen-observable-ts@1.2.5: - resolution: {integrity: sha512-QZWQekv6iB72Naeake9hS1KxHlotfRpe+WGNbNx5/ta+R3DNjVO2bswf63gXlWDcs+EMd7XY8HfVQyP1X6T4Zg==} + resolution: + { integrity: sha512-QZWQekv6iB72Naeake9hS1KxHlotfRpe+WGNbNx5/ta+R3DNjVO2bswf63gXlWDcs+EMd7XY8HfVQyP1X6T4Zg== } zen-observable@0.8.15: - resolution: {integrity: sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ==} + resolution: + { integrity: sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ== } snapshots: - '@alloc/quick-lru@5.2.0': {} '@ampproject/remapping@2.3.0': @@ -4664,6 +5440,21 @@ snapshots: - supports-color - typescript + '@tanstack/query-core@5.83.1': {} + + '@tanstack/query-devtools@5.84.0': {} + + '@tanstack/react-query-devtools@5.84.1(@tanstack/react-query@5.84.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@tanstack/query-devtools': 5.84.0 + '@tanstack/react-query': 5.84.1(react@18.3.1) + react: 18.3.1 + + '@tanstack/react-query@5.84.1(react@18.3.1)': + dependencies: + '@tanstack/query-core': 5.83.1 + react: 18.3.1 + '@types/chai@5.2.2': dependencies: '@types/deep-eql': 4.0.2 @@ -5195,6 +5986,8 @@ snapshots: async-function@1.0.0: {} + asynckit@0.4.0: {} + autoprefixer@10.4.21(postcss@8.5.6): dependencies: browserslist: 4.25.1 @@ -5209,6 +6002,14 @@ snapshots: dependencies: possible-typed-array-names: 1.1.0 + axios@1.11.0: + dependencies: + follow-redirects: 1.15.11 + form-data: 4.0.4 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + babel-plugin-macros@3.1.0: dependencies: '@babel/runtime': 7.27.6 @@ -5299,6 +6100,10 @@ snapshots: colors-named@1.0.2: {} + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + concat-map@0.0.1: {} convert-source-map@1.9.0: {} @@ -5381,6 +6186,8 @@ snapshots: has-property-descriptors: 1.0.2 object-keys: 1.1.1 + delayed-stream@1.0.0: {} + detect-libc@2.0.4: {} doctrine@2.1.0: @@ -5721,10 +6528,20 @@ snapshots: flatted@3.3.3: {} + follow-redirects@1.15.11: {} + for-each@0.3.5: dependencies: is-callable: 1.2.7 + form-data@4.0.4: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + es-set-tostringtag: 2.1.0 + hasown: 2.0.2 + mime-types: 2.1.35 + forwarded-parse@2.1.2: {} fraction.js@4.3.7: {} @@ -6179,6 +6996,12 @@ snapshots: braces: 3.0.3 picomatch: 2.3.1 + mime-db@1.52.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + minimatch@3.1.2: dependencies: brace-expansion: 1.1.12 @@ -6368,6 +7191,8 @@ snapshots: property-expr@2.0.6: {} + proxy-from-env@1.1.0: {} + punycode@2.3.1: {} queue-microtask@1.2.3: {} diff --git a/client/src/App.tsx b/client/src/App.tsx index 252070418..355c56f2c 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -3,11 +3,12 @@ import { styled } from '@mui/system'; import { LocalizationProvider } from '@mui/x-date-pickers'; import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns'; import * as Sentry from '@sentry/react'; -import React, { useContext, useEffect } from 'react'; +import React, { useContext, useEffect, useMemo } from 'react'; import { Outlet } from 'react-router-dom'; import getCourseInfo from './api/getCourseInfo'; import getCoursesList from './api/getCoursesList'; +import { useGetUserSettingsQuery } from './api/user/queries'; import T3SelectGif from './assets/T3-select.gif'; import Alerts from './components/Alerts'; import Controls from './components/controls/Controls'; @@ -18,7 +19,7 @@ import Sidebar from './components/sidebar/Sidebar'; import Sponsors from './components/Sponsors'; import Timetable from './components/timetable/Timetable'; import { TimetableTabs } from './components/timetableTabs/TimetableTabs'; -import { contentPadding, rightContentPadding, themes } from './constants/theme'; +import { contentPadding, darkTheme, lightTheme, rightContentPadding } from './constants/theme'; import { daysLong, getAvailableTermDetails, @@ -98,17 +99,6 @@ const ICSButton = styled(Button)` const App: React.FC = () => { const { - themeObject, - currentTheme, - setCurrentTheme, - is12HourMode, - isDarkMode, - isSquareEdges, - isShowOnlyOpenClasses, - isDefaultUnscheduled, - isHideClassInfo, - isHideExamClasses, - isConvertToLocalTimezone, setAlertMsg, setErrorVisibility, days, @@ -144,7 +134,9 @@ const App: React.FC = () => { setAssignedColors, } = useContext(CourseContext); - const decodedAssignedColors = useColorsDecoder(assignedColors, currentTheme); + const { preferredTheme, isDarkMode, unscheduleClassesByDefault, convertToLocalTimezone } = useGetUserSettingsQuery(); + + const decodedAssignedColors = useColorsDecoder(assignedColors, preferredTheme); setDropzoneRange(days.length, earliestStartTime, latestEndTime); @@ -276,7 +268,7 @@ const App: React.FC = () => { // null means a class is unscheduled Object.keys(course.activities).forEach((activity) => { - prev[course.code][activity] = isDefaultUnscheduled + prev[course.code][activity] = unscheduleClassesByDefault ? null : (course.activities[activity].find((x) => x.enrolments !== x.capacity && x.periods.length) ?? course.activities[activity].find((x) => x.periods.length) ?? @@ -302,7 +294,7 @@ const App: React.FC = () => { const codes: string[] = Array.isArray(data) ? data : [data]; Promise.all( codes.map((code) => - getCourseInfo(term.substring(0, 2), code, term.substring(2), isConvertToLocalTimezone).catch((err) => { + getCourseInfo(term.substring(0, 2), code, term.substring(2), convertToLocalTimezone).catch((err) => { return err; }), ), @@ -440,7 +432,7 @@ const App: React.FC = () => { useEffect(() => { updateTimetableEvents(); - }, [year, isConvertToLocalTimezone]); + }, [year, convertToLocalTimezone]); // The following three useUpdateEffects update local storage whenever a change is made to the timetable useUpdateEffect(() => { @@ -505,8 +497,8 @@ const App: React.FC = () => { * Upon switching timetable, reset default bounds */ useEffect(() => { - setEarliestStartTime(getDefaultStartTime(isConvertToLocalTimezone)); - setLatestEndTime(getDefaultEndTime(isConvertToLocalTimezone)); + setEarliestStartTime(getDefaultStartTime(convertToLocalTimezone)); + setLatestEndTime(getDefaultEndTime(convertToLocalTimezone)); }, [selectedTimetable]); /** @@ -517,7 +509,7 @@ const App: React.FC = () => { Math.min( ...selectedCourses.map((course) => course.earliestStartTime), ...Object.entries(createdEvents).map(([_, eventPeriod]) => Math.floor(eventPeriod.time.start)), - getDefaultStartTime(isConvertToLocalTimezone), + getDefaultStartTime(convertToLocalTimezone), prev, ), ); @@ -526,7 +518,7 @@ const App: React.FC = () => { Math.max( ...selectedCourses.map((course) => course.latestFinishTime), ...Object.entries(createdEvents).map(([_, eventPeriod]) => Math.ceil(eventPeriod.time.end)), - getDefaultEndTime(isConvertToLocalTimezone), + getDefaultEndTime(convertToLocalTimezone), prev, ), ); @@ -546,50 +538,12 @@ const App: React.FC = () => { useUpdateEffect(() => { updateTimetableDaysAndTimes(); - }, [createdEvents, selectedCourses, isConvertToLocalTimezone]); - - useEffect(() => { - storage.set('currentTheme', currentTheme); - }, [currentTheme]); - - useEffect(() => { - storage.set('is12HourMode', is12HourMode); - }, [is12HourMode]); - - useEffect(() => { - storage.set('isDarkMode', isDarkMode); - }, [isDarkMode]); - - useEffect(() => { - storage.set('isSquareEdges', isSquareEdges); - }, [isSquareEdges]); - - useEffect(() => { - storage.set('isShowOnlyOpenClasses', isShowOnlyOpenClasses); - }, [isShowOnlyOpenClasses]); + }, [createdEvents, selectedCourses, convertToLocalTimezone]); - useEffect(() => { - storage.set('isDefaultUnscheduled', isDefaultUnscheduled); - }, [isDefaultUnscheduled]); - - useEffect(() => { - storage.set('isHideClassInfo', isHideClassInfo); - }, [isHideClassInfo]); - - useEffect(() => { - storage.set('isHideExamClasses', isHideExamClasses); - }, [isHideExamClasses]); - - useEffect(() => { - storage.set('isConvertToLocalTimezone', isConvertToLocalTimezone); - }, [isConvertToLocalTimezone]); - - // Validate the currentTheme - useEffect(() => { - if (!Object.keys(themes).includes(currentTheme)) { - setCurrentTheme(Object.keys(themes)[0]); - } - }, [currentTheme]); + const themeObject = useMemo( + () => (isDarkMode ? darkTheme(preferredTheme) : lightTheme(preferredTheme)), + [isDarkMode, preferredTheme], + ); const globalStyle = { body: { diff --git a/client/src/api/timetable/mutations.ts b/client/src/api/timetable/mutations.ts new file mode 100644 index 000000000..e69de29bb diff --git a/client/src/api/timetable/queries.ts b/client/src/api/timetable/queries.ts new file mode 100644 index 000000000..e69de29bb diff --git a/client/src/api/timetable/routes.ts b/client/src/api/timetable/routes.ts new file mode 100644 index 000000000..e69de29bb diff --git a/client/src/api/user/mutations.ts b/client/src/api/user/mutations.ts new file mode 100644 index 000000000..1edab041d --- /dev/null +++ b/client/src/api/user/mutations.ts @@ -0,0 +1,12 @@ +import { useMutation } from '@tanstack/react-query'; + +import type { UserSettings } from '../../interfaces/User'; +import { setUserSettings } from './routes'; + +export const useSetUserSettings = () => + useMutation({ + mutationFn: (settings: Partial) => setUserSettings(settings), + meta: { + invalidatesQuery: ['settings'], + }, + }).mutate; diff --git a/client/src/api/user/queries.ts b/client/src/api/user/queries.ts new file mode 100644 index 000000000..0b3f1ab09 --- /dev/null +++ b/client/src/api/user/queries.ts @@ -0,0 +1,9 @@ +import { useSuspenseQuery } from '@tanstack/react-query'; + +import { getUserSettings } from './routes'; + +export const useGetUserSettingsQuery = () => + useSuspenseQuery({ + queryKey: ['settings'], + queryFn: getUserSettings, + }).data; diff --git a/client/src/api/user/routes.ts b/client/src/api/user/routes.ts new file mode 100644 index 000000000..b516a9bcb --- /dev/null +++ b/client/src/api/user/routes.ts @@ -0,0 +1,24 @@ +import axios from 'axios'; + +import { UserInfo, UserSettings } from '../../interfaces/User'; +import { API_URL } from '../config'; + +const apiClient = axios.create({ + baseURL: API_URL.server, + withCredentials: true, + headers: { + 'Content-Type': 'application/json', + }, +}); + +export const getUserProfile = async (): Promise => { + return (await apiClient.get('/user/profile')).data; +}; + +export const getUserSettings = async (): Promise => { + return (await apiClient.get('/user/settings')).data; +}; + +export const setUserSettings = async (settings: Partial): Promise => { + await apiClient.post('/user/settings', settings); +}; diff --git a/client/src/components/ErrorBoundary.tsx b/client/src/components/ErrorBoundary.tsx new file mode 100644 index 000000000..54e7fe884 --- /dev/null +++ b/client/src/components/ErrorBoundary.tsx @@ -0,0 +1,34 @@ +import React from 'react'; + +import PageError from './ErrorPage/ErrorPage'; + +interface ErrorBoundaryProps { + children: React.ReactNode; +} + +interface ErrorBoundaryState { + hasError: boolean; + error: Error; +} + +class ErrorBoundary extends React.Component { + state: ErrorBoundaryState = { hasError: false, error: new Error('Uknown error') }; + + static getDerivedStateFromError(error: Error) { + return { hasError: true, error: error }; + } + + componentDidCatch(error: Error, errorInfo: React.ErrorInfo) { + console.error('Error caught by ErrorBoundary:', error, errorInfo); + } + + render() { + if (this.state.hasError) { + return ; + } + + return this.props.children; + } +} + +export default ErrorBoundary; diff --git a/client/src/components/ErrorPage/ErrorPage.tsx b/client/src/components/ErrorPage/ErrorPage.tsx new file mode 100644 index 000000000..7fc43928d --- /dev/null +++ b/client/src/components/ErrorPage/ErrorPage.tsx @@ -0,0 +1,111 @@ +import { styled } from '@mui/material/styles'; + +import logo from '../../assets/notanglesWithBg.png'; +import { notanglesBlue, notanglesHoverBlue } from '../../constants/theme'; + +const PageWrapper = styled('div')` + height: 100vh; + display: flex; + align-items: center; + justify-content: center; + flex-direction: column; + text-align: center; + gap: 2rem; + padding-top: 10%; +`; + +const LoadingLogo = styled('img')` + width: 200px; + border-radius: 50%; + animation: spin 3s linear infinite; +`; + +const Button = styled('button')` + padding: 1rem 2rem; + background-color: ${notanglesBlue}; + color: white; + border: none; + border-radius: 1rem; + cursor: pointer; + font-size: 1.2rem; + &:hover { + background-color: ${notanglesHoverBlue}; + } +`; + +const ErrorMessage = styled('p')` + color: red; + font-size: 1.2rem; +`; + +const HintMessage = styled('p')` + color: #555; + font-size: 1rem; +`; + +const Link = styled('a')` + color: ${notanglesBlue}; + text-decoration: underline; + cursor: pointer; + &:hover { + color: ${notanglesHoverBlue}; + } +`; + +const MessageWrapper = styled('div')` + display: flex; + flex-direction: column; + align-items: center; + gap: 1rem; +`; + +const ErrorWrapper = styled('div')` + background-color: #f8d7da; + padding: 1rem; + border-radius: 0.5rem; + border: 1px solid #f5c6cb; + color: #721c24; + margin-top: 1rem; + text-align: left; + width: 80%; +`; + +const ErrorStack = styled('pre')` + color: #f00; + font-size: 0.9rem; + white-space: pre-wrap; + max-height: 200px; + overflow-y: auto; +`; + +interface PageErrorProps { + errorStack: Error; +} + +const PageError: React.FC = ({ errorStack }) => { + return ( + + + + {"Oops! It seems we've hit a snag in the Notangles."} + {"Don't worry, even the best angles sometimes get tangled. You can:"} + + + {'Still stuck?'} + Report the issue + {"on Discord, and we'll untangle it for you!"} + + + + Error Details: + + {errorStack.message} + {errorStack.stack ? `\n${errorStack.stack}` : ''} + + + + + ); +}; + +export default PageError; diff --git a/client/src/components/Sponsors.tsx b/client/src/components/Sponsors.tsx index c29b0086d..d0f449c4f 100644 --- a/client/src/components/Sponsors.tsx +++ b/client/src/components/Sponsors.tsx @@ -1,7 +1,7 @@ import { Box, Link, Stack } from '@mui/material'; import styled from '@mui/system/styled'; -import { useContext } from 'react'; +import { useGetUserSettingsQuery } from '../api/user/queries'; import aristaBlack from '../assets/sponsors/arista_black.png'; import aristaWhite from '../assets/sponsors/arista_white.png'; import janeStreetBlack from '../assets/sponsors/jane_street_black.svg'; @@ -10,7 +10,6 @@ import safetyCultureBlack from '../assets/sponsors/safetyculture_black.png'; import safetyCultureWhite from '../assets/sponsors/safetyculture_white.png'; import theTradeDeskBlack from '../assets/sponsors/thetradedesk_black.png'; import theTradeDeskWhite from '../assets/sponsors/thetradedesk_white.png'; -import { AppContext } from '../context/AppContext'; const SponsorBox = styled(Box)` padding-top: 10px; @@ -41,7 +40,7 @@ const StyledGoldSponsorLogo = styled(StyledPlatinumSponsorLogo)` `; const Sponsors = () => { - const { isDarkMode } = useContext(AppContext); + const { isDarkMode } = useGetUserSettingsQuery(); const platinumSponsorData = [ { diff --git a/client/src/components/controls/ColorOptions.tsx b/client/src/components/controls/ColorOptions.tsx index 5e7b213bb..7ac3de053 100644 --- a/client/src/components/controls/ColorOptions.tsx +++ b/client/src/components/controls/ColorOptions.tsx @@ -2,10 +2,11 @@ import styled from '@emotion/styled'; import AddIcon from '@mui/icons-material/Add'; import CloseIcon from '@mui/icons-material/Close'; import { IconButton, List, ListItem } from '@mui/material'; -import { FC, useContext } from 'react'; +import { FC, useMemo } from 'react'; -import { AppContext } from '../../context/AppContext'; -import { useColorDecoder } from '../../hooks/useColorDecoder'; +import { useGetUserSettingsQuery } from '../../api/user/queries'; +import { darkTheme, lightTheme } from '../../constants/theme'; +import { useColorsDecoder } from '../../hooks/useColorDecoder'; interface ColorOptionsProps { colors: string[]; maxDefaultColors?: number; @@ -33,20 +34,23 @@ const ColorOptions: FC = ({ onSelectColor, onCustomColorSelect, }) => { - // Get the current theme as from AppContext - const { themeObject, currentTheme } = useContext(AppContext); + const { isDarkMode, preferredTheme } = useGetUserSettingsQuery(); + const themeObject = useMemo( + () => (isDarkMode ? lightTheme(preferredTheme) : darkTheme(preferredTheme)), + [isDarkMode, preferredTheme], + ); - const decodedColors = colors.map((color) => { - const decodedColor = useColorDecoder(color, currentTheme); - return decodedColor; - }); + const decodedColors = useColorsDecoder( + colors.reduce((obj, color, index) => ({ ...obj, [index]: color }), {}), + preferredTheme, + ); return ( {/* Default Theme Colors (1-4) */} - + {colors.slice(0, maxDefaultColors).map((color, index) => ( - + = ({ /> ))} - + {/* Default Theme Colors (5-7) */} - - {colors.slice(maxDefaultColors, colors.length - 1).map((color, index) => ( - + + {colors.slice(maxDefaultColors, maxDefaultColors + 3).map((color, index) => ( + = ({ {showCustomColorPicker ? : } - + ); }; diff --git a/client/src/components/controls/ColorPicker.tsx b/client/src/components/controls/ColorPicker.tsx index 199af7d18..f48169cac 100644 --- a/client/src/components/controls/ColorPicker.tsx +++ b/client/src/components/controls/ColorPicker.tsx @@ -1,7 +1,8 @@ -import { Box, Button, ButtonGroup, ListItem, Popover, TextField } from '@mui/material'; +import { Box, Button, ButtonGroup, List, ListItem, Popover, TextField } from '@mui/material'; import { Colorful } from '@uiw/react-color'; import { useContext, useEffect, useState } from 'react'; +import { useGetUserSettingsQuery } from '../../api/user/queries'; import { colors } from '../../constants/timetable'; import { AppContext } from '../../context/AppContext'; import { useColorDecoder } from '../../hooks/useColorDecoder'; @@ -24,8 +25,8 @@ const ColorPicker: React.FC = ({ const [showCustomColorPicker, setShowCustomColorPicker] = useState(false); - const { currentTheme } = useContext(AppContext); - const decodedColor = useColorDecoder(color, currentTheme); + const { preferredTheme } = useGetUserSettingsQuery(); + const decodedColor = useColorDecoder(color, preferredTheme); const [textFieldValue, setTextFieldValue] = useState(oklchToHex(decodedColor)); useEffect(() => { @@ -34,7 +35,7 @@ const ColorPicker: React.FC = ({ return ( - + diff --git a/server/package.json b/server/package.json index 345066b6c..475b0dad5 100644 --- a/server/package.json +++ b/server/package.json @@ -35,6 +35,7 @@ "graphql-tag": "2.12.6", "openid-client": "6.6.2", "passport": "0.7.0", + "passport-custom": "1.1.1", "reflect-metadata": "0.2.2", "rxjs": "7.8.2" }, diff --git a/server/pnpm-lock.yaml b/server/pnpm-lock.yaml index b14f18e4a..2151b2909 100644 --- a/server/pnpm-lock.yaml +++ b/server/pnpm-lock.yaml @@ -44,6 +44,9 @@ importers: passport: specifier: 0.7.0 version: 0.7.0 + passport-custom: + specifier: 1.1.1 + version: 1.1.1 reflect-metadata: specifier: 0.2.2 version: 0.2.2 @@ -3927,6 +3930,10 @@ packages: pascal-case@3.1.2: resolution: {integrity: sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==} + passport-custom@1.1.1: + resolution: {integrity: sha512-/2m7jUGxmCYvoqenLB9UrmkCgPt64h8ZtV+UtuQklZ/Tn1NpKBeOorCYkB/8lMRoiZ5hUrCoMmDtxCS/d38mlg==} + engines: {node: '>= 0.10.0'} + passport-strategy@1.0.0: resolution: {integrity: sha512-CB97UUvDKJde2V0KDWWB3lyf6PC3FaZP7YxZ2G8OAtn9p4HI9j9JLP9qjOGZFvyl8uwNT8qM+hGnz/n16NI7oA==} engines: {node: '>= 0.4.0'} @@ -9350,6 +9357,10 @@ snapshots: no-case: 3.0.4 tslib: 2.8.1 + passport-custom@1.1.1: + dependencies: + passport-strategy: 1.0.0 + passport-strategy@1.0.0: {} passport@0.7.0: diff --git a/server/prisma/migrations/20250904021810_support_different_auth/migration.sql b/server/prisma/migrations/20250904021810_support_different_auth/migration.sql new file mode 100644 index 000000000..b4f9f8d76 --- /dev/null +++ b/server/prisma/migrations/20250904021810_support_different_auth/migration.sql @@ -0,0 +1,20 @@ +/* + Warnings: + + - You are about to drop the column `oidcId` on the `user` table. All the data in the column will be lost. + - A unique constraint covering the columns `[authProvider,authSubject]` on the table `user` will be added. If there are existing duplicate values, this will fail. + +*/ +-- CreateEnum +CREATE TYPE "AuthProvider" AS ENUM ('GOOGLE', 'ZID'); + +-- DropIndex +DROP INDEX "user_oidcId_key"; + +-- AlterTable +ALTER TABLE "user" DROP COLUMN "oidcId", +ADD COLUMN "authProvider" "AuthProvider", +ADD COLUMN "authSubject" VARCHAR(100); + +-- CreateIndex +CREATE UNIQUE INDEX "user_authProvider_authSubject_key" ON "user"("authProvider", "authSubject"); diff --git a/server/prisma/migrations/20250904030756_add_github_auth_provider/migration.sql b/server/prisma/migrations/20250904030756_add_github_auth_provider/migration.sql new file mode 100644 index 000000000..83d30cbbd --- /dev/null +++ b/server/prisma/migrations/20250904030756_add_github_auth_provider/migration.sql @@ -0,0 +1,2 @@ +-- AlterEnum +ALTER TYPE "AuthProvider" ADD VALUE 'GITHUB'; diff --git a/server/prisma/schema.prisma b/server/prisma/schema.prisma index 9e64b6082..65ae11736 100644 --- a/server/prisma/schema.prisma +++ b/server/prisma/schema.prisma @@ -8,12 +8,19 @@ datasource db { url = env("DATABASE_URL") } +enum AuthProvider { + ZID + GOOGLE + GITHUB +} + model User { // Unique per-user ID - id String @id @default(cuid(2)) @db.VarChar(30) - // ID given by auth - probably zID - oidcId String? @unique - isGuest Boolean @default(true) + id String @id @default(cuid(2)) @db.VarChar(30) + + authProvider AuthProvider? + authSubject String? @db.VarChar(100) + isGuest Boolean @default(true) firstName String lastName String @@ -24,6 +31,7 @@ model User { createdAt DateTime @default(now()) lastLogin DateTime @default(now()) + @@unique([authProvider, authSubject]) @@map("user") } @@ -50,9 +58,9 @@ model Settings { userId String @unique preferredTheme String @default("Classic") - is12HourMode Boolean @default(true) - isDarkMode Boolean @default(false) - isSquareEdges Boolean @default(false) + is12HourMode Boolean @default(true) + isDarkMode Boolean @default(false) + isSquareEdges Boolean @default(false) hideFullClasses Boolean @default(false) hideClassInfo Boolean @default(false) unscheduleClassesByDefault Boolean @default(true) diff --git a/server/src/auth/auth.controller.ts b/server/src/auth/auth.controller.ts index f99167095..e777259c7 100644 --- a/server/src/auth/auth.controller.ts +++ b/server/src/auth/auth.controller.ts @@ -1,6 +1,16 @@ import { Controller, Get, Res, UseGuards } from '@nestjs/common'; import { AuthGuard } from '@nestjs/passport'; import { Response } from 'express'; +import { AuthProvider } from 'src/generated/prisma/enums'; + +export interface AuthenticatedRequest extends Request { + user: { + id: string; + authProvider?: AuthProvider; + authSub?: string; + isGuest: boolean; + }; +} @Controller('auth') export class AuthController { @@ -16,4 +26,15 @@ export class AuthController { `${process.env.CLIENT_HOST_NAME}:${process.env.CLIENT_HOST_PORT}/home`, ); } + + @Get('login/guest') + @UseGuards(AuthGuard('guest')) + guest(@Res() res: Response) { + res.redirect( + (process.env.NODE_ENV === 'dev' ? `http://` : `https://`) + + `${process.env.CLIENT_HOST_NAME}:${process.env.CLIENT_HOST_PORT}/home`, + ); + } + + // TODO: Add logout (and deleting guest users) } diff --git a/server/src/auth/auth.module.ts b/server/src/auth/auth.module.ts index f9bcd6a26..dd46a2d8c 100644 --- a/server/src/auth/auth.module.ts +++ b/server/src/auth/auth.module.ts @@ -1,6 +1,7 @@ import { Module } from '@nestjs/common'; import { AuthService } from './auth.service'; import { getConfig, OidcStrategy } from './oidc.strategy'; +import { GuestStrategy } from './guest.strategy'; import { PassportModule } from '@nestjs/passport'; import { AuthController } from './auth.controller'; import { SessionSerializer } from './session.serializer'; @@ -24,6 +25,7 @@ const OidcStrategyFactory = { AuthService, PrismaService, OidcStrategyFactory, + GuestStrategy, SessionSerializer, ], }) diff --git a/server/src/auth/guest.strategy.ts b/server/src/auth/guest.strategy.ts new file mode 100644 index 000000000..9d09887de --- /dev/null +++ b/server/src/auth/guest.strategy.ts @@ -0,0 +1,37 @@ +import { Injectable } from '@nestjs/common'; +import { PassportStrategy } from '@nestjs/passport'; +import { Request } from 'express'; +import { Strategy } from 'passport-custom'; +import { PrismaService } from 'src/prisma/prisma.service'; +import { promisify } from 'util'; + +// TODO: Track usage of guest accounts, delete inactive ones +@Injectable() +export class GuestStrategy extends PassportStrategy(Strategy, 'guest') { + constructor(private readonly prisma: PrismaService) { + // TODO: How to fix this lint? + // eslint-disable-next-line @typescript-eslint/no-unsafe-call + super(); + } + + async validate(req: Request) { + const user = await this.prisma.user.create({ + // TODO: Generate unique names for guest users (to help with debugging) + data: { + firstName: 'Guest', + lastName: 'User', + isGuest: true, + }, + }); + + await this.prisma.settings.create({ + data: { + userId: user.id, + }, + }); + + const login = promisify(req.login.bind(req)); + await login(user); + return user; + } +} diff --git a/server/src/auth/oidc.strategy.ts b/server/src/auth/oidc.strategy.ts index e05b9f526..b9a8ca423 100644 --- a/server/src/auth/oidc.strategy.ts +++ b/server/src/auth/oidc.strategy.ts @@ -81,13 +81,17 @@ export class OidcStrategy extends PassportStrategy(Strategy, 'oidc') { const user = await this.prisma.user.upsert({ where: { - oidcId: userInfo.sub, + authProvider_authSubject: { + authProvider: 'ZID', + authSubject: userInfo.sub, + }, }, update: { lastLogin: new Date(), }, create: { - oidcId: userInfo.sub, + authProvider: 'ZID', + authSubject: userInfo.sub, firstName: userData.firstName, lastName: userData.lastName, isGuest: false, diff --git a/server/src/auth/session.serializer.ts b/server/src/auth/session.serializer.ts index 22490450b..a4b85e898 100644 --- a/server/src/auth/session.serializer.ts +++ b/server/src/auth/session.serializer.ts @@ -1,9 +1,11 @@ import { Injectable } from '@nestjs/common'; import { PassportSerializer } from '@nestjs/passport'; +import { AuthProvider } from 'src/generated/prisma/enums'; type SessionUser = { id: string; - oidcId: string; + authSubject?: string; + authProvider?: AuthProvider; isGuest: boolean; }; @@ -16,7 +18,8 @@ export class SessionSerializer extends PassportSerializer { // Only cache the minimal required fields in session done(null, { id: user.id, - oidcId: user.oidcId, + authSubject: user.authSubject, + authProvider: user.authProvider, isGuest: user.isGuest, }); } diff --git a/server/src/timetable/timetable.controller.ts b/server/src/timetable/timetable.controller.ts index 7ac33afac..a63632e63 100644 --- a/server/src/timetable/timetable.controller.ts +++ b/server/src/timetable/timetable.controller.ts @@ -13,14 +13,7 @@ import { import { TimetableService } from './timetable.service'; import { AuthenticatedGuard } from 'src/auth/authenticated.guard'; import { Request } from 'express'; - -interface AuthenticatedRequest extends Request { - user: { - id: string; - oidcId?: string; - isGuest: boolean; - }; -} +import { AuthenticatedRequest } from 'src/auth/auth.controller'; @Controller('user/timetables') export class TimetableController { diff --git a/server/src/user/user.controller.ts b/server/src/user/user.controller.ts index 7fa6f2bed..25584d71b 100644 --- a/server/src/user/user.controller.ts +++ b/server/src/user/user.controller.ts @@ -1,16 +1,8 @@ import { Body, Controller, Get, Post, Req, UseGuards } from '@nestjs/common'; import { UserService } from './user.service'; import { AuthenticatedGuard } from 'src/auth/authenticated.guard'; -import { Request } from 'express'; import { UserSettings } from './types'; - -interface AuthenticatedRequest extends Request { - user: { - id: string; - oidcId?: string; - isGuest: boolean; - }; -} +import { AuthenticatedRequest } from 'src/auth/auth.controller'; @Controller('user') export class UserController { From 91ad125967de9afb37105366ea3c536bf797e71a Mon Sep 17 00:00:00 2001 From: jason4193 <100593637+jason4193@users.noreply.github.com> Date: Thu, 4 Sep 2025 12:58:21 +0800 Subject: [PATCH 20/33] Upgrade to Apollo 4 (#1053) * upgrade apollo client to 4.0.4 with codemod migration * Fixed the FE build error by proper typing for the graphQL queries * Remove redundant comments --- client/package.json | 4 +- client/pnpm-lock.yaml | 101 +++++++------------- client/src/api/config.ts | 7 +- client/src/api/getCourseInfo.ts | 16 ++-- client/src/api/getCoursesList.ts | 5 +- client/src/constants/timetable.ts | 1 + client/src/index.tsx | 2 +- client/src/interfaces/GraphQLCourseInfo.ts | 10 +- client/src/utils/graphQLCourseToDbCourse.ts | 10 +- 9 files changed, 64 insertions(+), 92 deletions(-) diff --git a/client/package.json b/client/package.json index ce33a7892..6e3344e8c 100644 --- a/client/package.json +++ b/client/package.json @@ -16,7 +16,7 @@ "format": "prettier --write 'src/**/*.{js,mjs,cjs,jsx,mjsx,ts,tsx,mtsx}'" }, "dependencies": { - "@apollo/client": "3.14.0", + "@apollo/client": "4.0.4", "@emotion/react": "11.14.0", "@emotion/styled": "11.14.1", "@fontsource-variable/roboto-flex": "5.2.6", @@ -40,6 +40,7 @@ "file-saver": "2.0.5", "framer-motion": "12.23.12", "fuse.js": "7.1.0", + "graphql": "16.11.0", "ics": "3.8.1", "is-base64": "1.1.0", "lodash-es": "4.17.21", @@ -49,6 +50,7 @@ "react-router-dom": "6.30.0", "react-transition-group": "4.4.5", "react-window": "1.8.11", + "rxjs": "7.8.2", "tailwind-merge": "3.3.1", "uuid": "11.1.0", "web-vitals": "5.1.0", diff --git a/client/pnpm-lock.yaml b/client/pnpm-lock.yaml index 1f07661ef..1a97067df 100644 --- a/client/pnpm-lock.yaml +++ b/client/pnpm-lock.yaml @@ -9,8 +9,8 @@ importers: .: dependencies: '@apollo/client': - specifier: 3.14.0 - version: 3.14.0(@types/react@18.3.20)(graphql@16.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: 4.0.4 + version: 4.0.4(graphql@16.11.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rxjs@7.8.2) '@emotion/react': specifier: 11.14.0 version: 11.14.0(@types/react@18.3.20)(react@18.3.1) @@ -80,6 +80,9 @@ importers: fuse.js: specifier: 7.1.0 version: 7.1.0 + graphql: + specifier: 16.11.0 + version: 16.11.0 ics: specifier: 3.8.1 version: 3.8.1 @@ -107,6 +110,9 @@ importers: react-window: specifier: 1.8.11 version: 1.8.11(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rxjs: + specifier: 7.8.2 + version: 7.8.2 tailwind-merge: specifier: 3.3.1 version: 3.3.1 @@ -259,13 +265,14 @@ packages: resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} engines: {node: '>=10'} - '@apollo/client@3.14.0': - resolution: {integrity: sha512-0YQKKRIxiMlIou+SekQqdCo0ZTHxOcES+K8vKB53cIDpwABNR0P0yRzPgsbgcj3zRJniD93S/ontsnZsCLZrxQ==} + '@apollo/client@4.0.4': + resolution: {integrity: sha512-3+fTQUA3AdC08urPF7si0ptLiAaVOH5R/3drwXzic8yqzTL4W3ME6klLj/EpgMND0FbWD7sM8TCkEDoe4OckMw==} peerDependencies: - graphql: ^15.0.0 || ^16.0.0 + graphql: ^16.0.0 graphql-ws: ^5.5.5 || ^6.0.3 - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || >=19.0.0-rc - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || >=19.0.0-rc + react: ^17.0.0 || ^18.0.0 || >=19.0.0-rc + react-dom: ^17.0.0 || ^18.0.0 || >=19.0.0-rc + rxjs: ^7.3.0 subscriptions-transport-ws: ^0.9.0 || ^0.11.0 peerDependenciesMeta: graphql-ws: @@ -2325,8 +2332,8 @@ packages: 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 - graphql@16.9.0: - resolution: {integrity: sha512-GGTKBX4SD7Wdb8mqeDLni2oaRGYQWjWHGKPQ24ZMnUtKfcsVoiv4uX8+LJr1K6U5VW2Lu1BwJnj7uiori0YtRw==} + graphql@16.11.0: + resolution: {integrity: sha512-mS1lbMsxgQj6hge1XZ6p7GPhbrtFwUFYi3wRzXAC/FmYnyXMTvvI3td3rjmQ2u8ewXueaSvRPWaEcgVVOT9Jnw==} engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0} has-bigints@1.1.0: @@ -2990,17 +2997,6 @@ packages: resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} engines: {node: '>= 0.4'} - rehackt@0.1.0: - resolution: {integrity: sha512-7kRDOuLHB87D/JESKxQoRwv4DzbIdwkAGQ7p6QKGdVlY1IZheUnVhlk/4UZlNUVxdAXpyxikE3URsG067ybVzw==} - peerDependencies: - '@types/react': '*' - react: '*' - peerDependenciesMeta: - '@types/react': - optional: true - react: - optional: true - require-directory@2.1.1: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} engines: {node: '>=0.10.0'} @@ -3056,6 +3052,9 @@ packages: runes2@1.1.4: resolution: {integrity: sha512-LNPnEDPOOU4ehF71m5JoQyzT2yxwD6ZreFJ7MxZUAoMKNMY1XrAo60H1CUoX5ncSm0rIuKlqn9JZNRrRkNou2g==} + rxjs@7.8.2: + resolution: {integrity: sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==} + safe-array-concat@1.1.3: resolution: {integrity: sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==} engines: {node: '>=0.4'} @@ -3196,10 +3195,6 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} - symbol-observable@4.0.0: - resolution: {integrity: sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ==} - engines: {node: '>=0.10'} - symbol-tree@3.2.4: resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} @@ -3281,10 +3276,6 @@ packages: peerDependencies: typescript: '>=4.8.4' - ts-invariant@0.10.3: - resolution: {integrity: sha512-uivwYcQaxAucv1CzRp2n/QdYPo4ILf9VXgH19zEIjFx2EJufV16P0JtJVpYHy89DItG6Kwj2oIUjrcK5au+4tQ==} - engines: {node: '>=8'} - tsconfck@3.1.6: resolution: {integrity: sha512-ks6Vjr/jEw0P1gmOVwutM3B7fWxoWBL2KRDb1JfqGVawBmO5UsvmWOQFGHBPl5yxYz4eERr19E6L7NMv+Fej4w==} engines: {node: ^18 || >=20} @@ -3593,37 +3584,24 @@ packages: yup@1.7.0: resolution: {integrity: sha512-VJce62dBd+JQvoc+fCVq+KZfPHr+hXaxCcVgotfwWvlR0Ja3ffYKaJBT8rptPOSKOGJDCUnW2C2JWpud7aRP6Q==} - zen-observable-ts@1.2.5: - resolution: {integrity: sha512-QZWQekv6iB72Naeake9hS1KxHlotfRpe+WGNbNx5/ta+R3DNjVO2bswf63gXlWDcs+EMd7XY8HfVQyP1X6T4Zg==} - - zen-observable@0.8.15: - resolution: {integrity: sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ==} - snapshots: '@alloc/quick-lru@5.2.0': {} - '@apollo/client@3.14.0(@types/react@18.3.20)(graphql@16.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@apollo/client@4.0.4(graphql@16.11.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rxjs@7.8.2)': dependencies: - '@graphql-typed-document-node/core': 3.2.0(graphql@16.9.0) + '@graphql-typed-document-node/core': 3.2.0(graphql@16.11.0) '@wry/caches': 1.0.1 '@wry/equality': 0.5.7 '@wry/trie': 0.5.0 - graphql: 16.9.0 - graphql-tag: 2.12.6(graphql@16.9.0) - hoist-non-react-statics: 3.3.2 + graphql: 16.11.0 + graphql-tag: 2.12.6(graphql@16.11.0) optimism: 0.18.1 - prop-types: 15.8.1 - rehackt: 0.1.0(@types/react@18.3.20)(react@18.3.1) - symbol-observable: 4.0.0 - ts-invariant: 0.10.3 + rxjs: 7.8.2 tslib: 2.8.1 - zen-observable-ts: 1.2.5 optionalDependencies: react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - transitivePeerDependencies: - - '@types/react' '@asamuzakjp/css-color@3.2.0': dependencies: @@ -3916,9 +3894,9 @@ snapshots: '@fontsource-variable/roboto-flex@5.2.6': {} - '@graphql-typed-document-node/core@3.2.0(graphql@16.9.0)': + '@graphql-typed-document-node/core@3.2.0(graphql@16.11.0)': dependencies: - graphql: 16.9.0 + graphql: 16.11.0 '@hello-pangea/dnd@18.0.1(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: @@ -5860,12 +5838,12 @@ snapshots: graphemer@1.4.0: {} - graphql-tag@2.12.6(graphql@16.9.0): + graphql-tag@2.12.6(graphql@16.11.0): dependencies: - graphql: 16.9.0 + graphql: 16.11.0 tslib: 2.8.1 - graphql@16.9.0: {} + graphql@16.11.0: {} has-bigints@1.1.0: {} @@ -6509,11 +6487,6 @@ snapshots: gopd: 1.2.0 set-function-name: 2.0.2 - rehackt@0.1.0(@types/react@18.3.20)(react@18.3.1): - optionalDependencies: - '@types/react': 18.3.20 - react: 18.3.1 - require-directory@2.1.1: {} require-in-the-middle@7.5.2: @@ -6586,6 +6559,10 @@ snapshots: runes2@1.1.4: {} + rxjs@7.8.2: + dependencies: + tslib: 2.8.1 + safe-array-concat@1.1.3: dependencies: call-bind: 1.0.8 @@ -6762,8 +6739,6 @@ snapshots: supports-preserve-symlinks-flag@1.0.0: {} - symbol-observable@4.0.0: {} - symbol-tree@3.2.4: {} synckit@0.11.11: @@ -6830,10 +6805,6 @@ snapshots: dependencies: typescript: 5.8.3 - ts-invariant@0.10.3: - dependencies: - tslib: 2.8.1 - tsconfck@3.1.6(typescript@5.8.3): optionalDependencies: typescript: 5.8.3 @@ -7185,9 +7156,3 @@ snapshots: tiny-case: 1.0.3 toposort: 2.0.2 type-fest: 2.19.0 - - zen-observable-ts@1.2.5: - dependencies: - zen-observable: 0.8.15 - - zen-observable@0.8.15: {} diff --git a/client/src/api/config.ts b/client/src/api/config.ts index d50767896..519963310 100644 --- a/client/src/api/config.ts +++ b/client/src/api/config.ts @@ -1,4 +1,4 @@ -import { ApolloClient, InMemoryCache } from '@apollo/client'; +import { ApolloClient, HttpLink, InMemoryCache } from '@apollo/client'; export enum Env { DEV = 'development', @@ -16,8 +16,11 @@ const HASURAGRES_GRAPHQL_API = 'https://graphql.csesoc.app/v1/graphql'; const LOCAL = 'http://localhost:3001'; export const client = new ApolloClient({ - uri: HASURAGRES_GRAPHQL_API, cache: new InMemoryCache(), + + link: new HttpLink({ + uri: HASURAGRES_GRAPHQL_API, + }), }); const API_CONFIG: Record = Object.freeze({ diff --git a/client/src/api/getCourseInfo.ts b/client/src/api/getCourseInfo.ts index e5f9c7986..07e2a994d 100644 --- a/client/src/api/getCourseInfo.ts +++ b/client/src/api/getCourseInfo.ts @@ -1,14 +1,14 @@ -import { gql } from '@apollo/client'; +import { gql, TypedDocumentNode } from '@apollo/client'; import { client } from '../api/config'; import { DbCourse, DbTimes } from '../interfaces/Database'; -import { GraphQLCourse } from '../interfaces/GraphQLCourseInfo'; +import { CoursesData, GetCourseInfoVars } from '../interfaces/GraphQLCourseInfo'; import NetworkError from '../interfaces/NetworkError'; import { CourseCode, CourseData } from '../interfaces/Periods'; import { dbCourseToCourseData } from '../utils/DbCourse'; import { graphQLCourseToDbCourse } from '../utils/graphQLCourseToDbCourse'; -const GET_COURSE_INFO = gql` +const GET_COURSE_INFO: TypedDocumentNode = gql` query GetCourseInfo($courseCode: String!, $term: String!, $year: String!) { courses(where: { course_code: { _eq: $courseCode } }) { course_code @@ -109,10 +109,11 @@ const getCourseInfo = async ( isConvertToLocalTimezone: boolean, ): Promise => { try { - const data: GraphQLCourse = await client.query({ + const { data } = await client.query({ query: GET_COURSE_INFO, variables: { courseCode, term, year }, }); + if (data === undefined) throw new NetworkError('Internal server error'); const json: DbCourse = graphQLCourseToDbCourse(data); json.classes.forEach((dbClass) => { @@ -140,10 +141,10 @@ const getCourseInfo = async ( // Convert the numerical representation of the weeks the classes are running back to a string for (let k = 0; k < dbClassTimesList.length; k++) { if (k == 0 || k == dbClassTimesList.length - 1) { - newWeeks += dbClassTimesList[k]; + newWeeks += String(dbClassTimesList[k]); } else if (isEndOfRange) { // Add the start of the range - newWeeks += dbClassTimesList[k]; + newWeeks += String(dbClassTimesList[k]); isEndOfRange = false; } @@ -154,7 +155,7 @@ const getCourseInfo = async ( if (!isEndOfRange) { // Add the end of the range (last consecutive number) - newWeeks += '-' + dbClassTimesList[k]; + newWeeks += '-' + String(dbClassTimesList[k]); // If this isn't the last week, we will need to add more weeks if (k !== dbClassTimesList.length - 1) { @@ -173,7 +174,6 @@ const getCourseInfo = async ( } }); - if (!json) throw new NetworkError('Internal server error'); return dbCourseToCourseData(json, isConvertToLocalTimezone); } catch (error) { console.log(error); diff --git a/client/src/api/getCoursesList.ts b/client/src/api/getCoursesList.ts index 7d12fec74..428da293d 100644 --- a/client/src/api/getCoursesList.ts +++ b/client/src/api/getCoursesList.ts @@ -1,4 +1,4 @@ -import { gql } from '@apollo/client'; +import { gql, TypedDocumentNode } from '@apollo/client'; import { client } from '../api/config'; import { CoursesList, CoursesListWithDate, FetchedCourse } from '../interfaces/Courses'; @@ -14,7 +14,7 @@ const toCoursesList = (data: FetchedCourse[]): CoursesList => faculty: course.faculty, })); -const GET_COURSE_LIST = gql` +const GET_COURSE_LIST: TypedDocumentNode<{ courses: FetchedCourse[] }, { term: string }> = gql` query GetCoursesByTerm($term: String!) { courses(where: { terms: { _ilike: $term } }) { campus @@ -46,6 +46,7 @@ const getCoursesList = async (term: string): Promise => { try { const termWithWildcard = `%${term}%`; const { data } = await client.query({ query: GET_COURSE_LIST, variables: { term: termWithWildcard } }); + if (data === undefined) throw new NetworkError('Internal server error'); return { courses: toCoursesList(data.courses), diff --git a/client/src/constants/timetable.ts b/client/src/constants/timetable.ts index f939a9e5e..675d47976 100644 --- a/client/src/constants/timetable.ts +++ b/client/src/constants/timetable.ts @@ -52,6 +52,7 @@ const parseTermOfferingPeriods = (termInfo: TermInfoFetch): TermDateDetails => { const constructTermDetailsMap = async (): Promise> => { const termInfoMap = new Map(); const availableTermData = await client.query<{ classes: TermInfoFetch[] }>({ query: GET_CLASSES }); + if (availableTermData.data === undefined) throw new NetworkError('Internal server error'); availableTermData.data.classes.map((cls: TermInfoFetch) => { const termOfferingPeriods = parseTermOfferingPeriods(cls); const termKey: Term = cls.term + termOfferingPeriods.startDate.getFullYear(); diff --git a/client/src/index.tsx b/client/src/index.tsx index 2273b74b2..539191642 100644 --- a/client/src/index.tsx +++ b/client/src/index.tsx @@ -1,7 +1,7 @@ import '@fontsource-variable/roboto-flex'; import './index.css'; -import { ApolloProvider } from '@apollo/client'; +import { ApolloProvider } from '@apollo/client/react'; import { browserTracingIntegration } from '@sentry/browser'; import * as Sentry from '@sentry/react'; import { MutationCache, QueryClient, QueryClientProvider, QueryKey } from '@tanstack/react-query'; diff --git a/client/src/interfaces/GraphQLCourseInfo.ts b/client/src/interfaces/GraphQLCourseInfo.ts index d0143f77a..4288a48b7 100644 --- a/client/src/interfaces/GraphQLCourseInfo.ts +++ b/client/src/interfaces/GraphQLCourseInfo.ts @@ -24,12 +24,12 @@ interface Course { classes: Class[]; } -interface CoursesData { +export interface CoursesData { courses: Course[]; } -export interface GraphQLCourse { - data: CoursesData; - loading: boolean; - networkStatus: number; +export interface GetCourseInfoVars { + courseCode: string; + term: string; + year: string; } diff --git a/client/src/utils/graphQLCourseToDbCourse.ts b/client/src/utils/graphQLCourseToDbCourse.ts index 0bb9855c1..a8665f51a 100644 --- a/client/src/utils/graphQLCourseToDbCourse.ts +++ b/client/src/utils/graphQLCourseToDbCourse.ts @@ -1,5 +1,5 @@ import { DbCourse } from '../interfaces/Database'; -import { GraphQLCourse } from '../interfaces/GraphQLCourseInfo'; +import { CoursesData } from '../interfaces/GraphQLCourseInfo'; import { Status } from '../interfaces/Periods'; const statusMapping: Record = { @@ -11,15 +11,15 @@ const statusMapping: Record = { /** * An adapter that formats a GraphQLCourse object to a DBCourse object * - * @param graphQLCourse A GraphQLCourse object + * @param CoursesData A GraphQLCourse object * @return A DBCourse object * * @example * const data = await client.query({query: GET_COURSE_INFO, variables: { courseCode, term }}); * const json: DbCourse = graphQLCourseToDbCourse(data); */ -export const graphQLCourseToDbCourse = (graphQLCourse: GraphQLCourse): DbCourse => { - const course = graphQLCourse.data.courses[0]; +export const graphQLCourseToDbCourse = (graphQLCourse: CoursesData): DbCourse => { + const course = graphQLCourse.courses[0]; return { courseCode: course.course_code, @@ -27,7 +27,7 @@ export const graphQLCourseToDbCourse = (graphQLCourse: GraphQLCourse): DbCourse classes: course.classes.map((classItem) => ({ section: classItem.section, activity: classItem.activity, - status: statusMapping[classItem.status.toLowerCase()] || 'Open', + status: statusMapping[classItem.status.toLowerCase()] ?? 'Open', courseEnrolment: { enrolments: parseInt(classItem.course_enrolment.split('/')[0].trim()), capacity: parseInt(classItem.course_enrolment.split('/')[1].trim()), From 96717c56e857ed6daf0aaacf61aa07cacc076bce Mon Sep 17 00:00:00 2001 From: Lucas Date: Fri, 5 Sep 2025 14:56:46 +1000 Subject: [PATCH 21/33] Migrate to React 19 (#1055) * Migrate to React 19 * Fix null issue with drag and drop * Clean up rippleRef usages * Fix ripple effect on the first click * Bump minor and bug frontend dependencies * Upgrade to React Router 7 * Bump minor and bug frontend dependencies --- client/package.json | 46 +- client/pnpm-lock.yaml | 1370 ++++++++--------- client/src/App.test.tsx | 7 +- client/src/App.tsx | 2 +- client/src/components/EventShareModal.tsx | 2 +- .../src/components/controls/CourseSelect.tsx | 2 +- .../landingPage/HeroSection/HeroSection.tsx | 2 +- client/src/components/login/AuthGuard.tsx | 3 +- .../src/components/timetable/DroppedCards.tsx | 2 +- .../src/components/timetable/DroppedClass.tsx | 77 +- .../src/components/timetable/DroppedEvent.tsx | 61 +- client/src/index.tsx | 9 +- client/src/styles/DroppedCardStyles.tsx | 27 +- 13 files changed, 798 insertions(+), 812 deletions(-) diff --git a/client/package.json b/client/package.json index 6e3344e8c..5e56d9cb4 100644 --- a/client/package.json +++ b/client/package.json @@ -22,15 +22,15 @@ "@fontsource-variable/roboto-flex": "5.2.6", "@hello-pangea/dnd": "18.0.1", "@heroicons/react": "2.2.0", - "@mui/icons-material": "7.3.1", - "@mui/lab": "7.0.0-beta.16", - "@mui/material": "7.3.1", - "@mui/system": "7.3.1", - "@mui/x-date-pickers": "8.11.0", - "@sentry/browser": "10.8.0", - "@sentry/node": "10.8.0", - "@sentry/react": "10.8.0", - "@tanstack/react-query": "5.85.6", + "@mui/icons-material": "7.3.2", + "@mui/lab": "7.0.0-beta.17", + "@mui/material": "7.3.2", + "@mui/system": "7.3.2", + "@mui/x-date-pickers": "8.11.1", + "@sentry/browser": "10.10.0", + "@sentry/node": "10.10.0", + "@sentry/react": "10.10.0", + "@tanstack/react-query": "5.86.0", "@uiw/react-color": "2.8.0", "axios": "1.11.0", "clsx": "2.1.1", @@ -44,10 +44,9 @@ "ics": "3.8.1", "is-base64": "1.1.0", "lodash-es": "4.17.21", - "react": "18.3.1", - "react-dom": "18.3.1", - "react-is": "18.3.1", - "react-router-dom": "6.30.0", + "react": "19.1.1", + "react-dom": "19.1.1", + "react-router": "7.8.2", "react-transition-group": "4.4.5", "react-window": "1.8.11", "rxjs": "7.8.2", @@ -81,16 +80,15 @@ }, "devDependencies": { "@eslint/js": "9.34.0", - "@tailwindcss/postcss": "4.1.12", - "@tanstack/eslint-plugin-query": "5.83.1", - "@tanstack/react-query-devtools": "5.85.6", + "@tailwindcss/postcss": "4.1.13", + "@tanstack/eslint-plugin-query": "5.86.0", + "@tanstack/react-query-devtools": "5.86.0", "@types/file-saver": "2.0.7", "@types/is-base64": "1.1.3", "@types/lodash-es": "4.17.12", "@types/node": "22.15.30", - "@types/react": "18.3.20", - "@types/react-dom": "18.3.7", - "@types/react-router-dom": "5.3.3", + "@types/react": "19.1.12", + "@types/react-dom": "19.1.9", "@types/react-transition-group": "4.4.12", "@types/react-window": "1.8.8", "@vitejs/plugin-react-swc": "4.0.1", @@ -106,13 +104,13 @@ "jsdom": "26.1.0", "postcss": "8.5.6", "prettier": "3.6.2", - "tailwindcss": "4.1.12", - "typescript": "5.8.3", - "typescript-eslint": "8.41.0", - "vite": "7.1.3", + "tailwindcss": "4.1.13", + "typescript": "5.9.2", + "typescript-eslint": "8.42.0", + "vite": "7.1.4", "vite-bundle-visualizer": "1.2.1", "vite-tsconfig-paths": "5.1.4", "vitest": "3.2.4" }, - "packageManager": "pnpm@10.15.0+sha512.486ebc259d3e999a4e8691ce03b5cac4a71cbeca39372a9b762cb500cfdf0873e2cb16abe3d951b1ee2cf012503f027b98b6584e4df22524e0c7450d9ec7aa7b" + "packageManager": "pnpm@10.15.1+sha512.34e538c329b5553014ca8e8f4535997f96180a1d0f614339357449935350d924e22f8614682191264ec33d1462ac21561aff97f6bb18065351c162c7e8f6de67" } diff --git a/client/pnpm-lock.yaml b/client/pnpm-lock.yaml index 1a97067df..db9efca5f 100644 --- a/client/pnpm-lock.yaml +++ b/client/pnpm-lock.yaml @@ -10,52 +10,52 @@ importers: dependencies: '@apollo/client': specifier: 4.0.4 - version: 4.0.4(graphql@16.11.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rxjs@7.8.2) + version: 4.0.4(graphql@16.11.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(rxjs@7.8.2) '@emotion/react': specifier: 11.14.0 - version: 11.14.0(@types/react@18.3.20)(react@18.3.1) + version: 11.14.0(@types/react@19.1.12)(react@19.1.1) '@emotion/styled': specifier: 11.14.1 - version: 11.14.1(@emotion/react@11.14.0(@types/react@18.3.20)(react@18.3.1))(@types/react@18.3.20)(react@18.3.1) + version: 11.14.1(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@types/react@19.1.12)(react@19.1.1) '@fontsource-variable/roboto-flex': specifier: 5.2.6 version: 5.2.6 '@hello-pangea/dnd': specifier: 18.0.1 - version: 18.0.1(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 18.0.1(@types/react@19.1.12)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) '@heroicons/react': specifier: 2.2.0 - version: 2.2.0(react@18.3.1) + version: 2.2.0(react@19.1.1) '@mui/icons-material': - specifier: 7.3.1 - version: 7.3.1(@mui/material@7.3.1(@emotion/react@11.14.0(@types/react@18.3.20)(react@18.3.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@18.3.20)(react@18.3.1))(@types/react@18.3.20)(react@18.3.1))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.20)(react@18.3.1) + specifier: 7.3.2 + version: 7.3.2(@mui/material@7.3.2(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@types/react@19.1.12)(react@19.1.1))(@types/react@19.1.12)(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(@types/react@19.1.12)(react@19.1.1) '@mui/lab': - specifier: 7.0.0-beta.16 - version: 7.0.0-beta.16(@emotion/react@11.14.0(@types/react@18.3.20)(react@18.3.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@18.3.20)(react@18.3.1))(@types/react@18.3.20)(react@18.3.1))(@mui/material@7.3.1(@emotion/react@11.14.0(@types/react@18.3.20)(react@18.3.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@18.3.20)(react@18.3.1))(@types/react@18.3.20)(react@18.3.1))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: 7.0.0-beta.17 + version: 7.0.0-beta.17(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@types/react@19.1.12)(react@19.1.1))(@mui/material@7.3.2(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@types/react@19.1.12)(react@19.1.1))(@types/react@19.1.12)(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(@types/react@19.1.12)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) '@mui/material': - specifier: 7.3.1 - version: 7.3.1(@emotion/react@11.14.0(@types/react@18.3.20)(react@18.3.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@18.3.20)(react@18.3.1))(@types/react@18.3.20)(react@18.3.1))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: 7.3.2 + version: 7.3.2(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@types/react@19.1.12)(react@19.1.1))(@types/react@19.1.12)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) '@mui/system': - specifier: 7.3.1 - version: 7.3.1(@emotion/react@11.14.0(@types/react@18.3.20)(react@18.3.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@18.3.20)(react@18.3.1))(@types/react@18.3.20)(react@18.3.1))(@types/react@18.3.20)(react@18.3.1) + specifier: 7.3.2 + version: 7.3.2(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@types/react@19.1.12)(react@19.1.1))(@types/react@19.1.12)(react@19.1.1) '@mui/x-date-pickers': - specifier: 8.11.0 - version: 8.11.0(@emotion/react@11.14.0(@types/react@18.3.20)(react@18.3.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@18.3.20)(react@18.3.1))(@types/react@18.3.20)(react@18.3.1))(@mui/material@7.3.1(@emotion/react@11.14.0(@types/react@18.3.20)(react@18.3.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@18.3.20)(react@18.3.1))(@types/react@18.3.20)(react@18.3.1))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mui/system@7.3.1(@emotion/react@11.14.0(@types/react@18.3.20)(react@18.3.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@18.3.20)(react@18.3.1))(@types/react@18.3.20)(react@18.3.1))(@types/react@18.3.20)(react@18.3.1))(@types/react@18.3.20)(date-fns@4.1.0)(dayjs@1.11.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: 8.11.1 + version: 8.11.1(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@types/react@19.1.12)(react@19.1.1))(@mui/material@7.3.2(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@types/react@19.1.12)(react@19.1.1))(@types/react@19.1.12)(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(@mui/system@7.3.2(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@types/react@19.1.12)(react@19.1.1))(@types/react@19.1.12)(react@19.1.1))(@types/react@19.1.12)(date-fns@4.1.0)(dayjs@1.11.18)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) '@sentry/browser': - specifier: 10.8.0 - version: 10.8.0 + specifier: 10.10.0 + version: 10.10.0 '@sentry/node': - specifier: 10.8.0 - version: 10.8.0 + specifier: 10.10.0 + version: 10.10.0 '@sentry/react': - specifier: 10.8.0 - version: 10.8.0(react@18.3.1) + specifier: 10.10.0 + version: 10.10.0(react@19.1.1) '@tanstack/react-query': - specifier: 5.85.6 - version: 5.85.6(react@18.3.1) + specifier: 5.86.0 + version: 5.86.0(react@19.1.1) '@uiw/react-color': specifier: 2.8.0 - version: 2.8.0(@babel/runtime@7.28.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 2.8.0(@babel/runtime@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) axios: specifier: 1.11.0 version: 1.11.0 @@ -76,7 +76,7 @@ importers: version: 2.0.5 framer-motion: specifier: 12.23.12 - version: 12.23.12(@emotion/is-prop-valid@1.3.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 12.23.12(@emotion/is-prop-valid@1.4.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) fuse.js: specifier: 7.1.0 version: 7.1.0 @@ -93,23 +93,20 @@ importers: specifier: 4.17.21 version: 4.17.21 react: - specifier: 18.3.1 - version: 18.3.1 + specifier: 19.1.1 + version: 19.1.1 react-dom: - specifier: 18.3.1 - version: 18.3.1(react@18.3.1) - react-is: - specifier: 18.3.1 - version: 18.3.1 - react-router-dom: - specifier: 6.30.0 - version: 6.30.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: 19.1.1 + version: 19.1.1(react@19.1.1) + react-router: + specifier: 7.8.2 + version: 7.8.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1) react-transition-group: specifier: 4.4.5 - version: 4.4.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 4.4.5(react-dom@19.1.1(react@19.1.1))(react@19.1.1) react-window: specifier: 1.8.11 - version: 1.8.11(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 1.8.11(react-dom@19.1.1(react@19.1.1))(react@19.1.1) rxjs: specifier: 7.8.2 version: 7.8.2 @@ -163,14 +160,14 @@ importers: specifier: 9.34.0 version: 9.34.0 '@tailwindcss/postcss': - specifier: 4.1.12 - version: 4.1.12 + specifier: 4.1.13 + version: 4.1.13 '@tanstack/eslint-plugin-query': - specifier: 5.83.1 - version: 5.83.1(eslint@9.34.0(jiti@2.5.1))(typescript@5.8.3) + specifier: 5.86.0 + version: 5.86.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) '@tanstack/react-query-devtools': - specifier: 5.85.6 - version: 5.85.6(@tanstack/react-query@5.85.6(react@18.3.1))(react@18.3.1) + specifier: 5.86.0 + version: 5.86.0(@tanstack/react-query@5.86.0(react@19.1.1))(react@19.1.1) '@types/file-saver': specifier: 2.0.7 version: 2.0.7 @@ -184,23 +181,20 @@ importers: specifier: 22.15.30 version: 22.15.30 '@types/react': - specifier: 18.3.20 - version: 18.3.20 + specifier: 19.1.12 + version: 19.1.12 '@types/react-dom': - specifier: 18.3.7 - version: 18.3.7(@types/react@18.3.20) - '@types/react-router-dom': - specifier: 5.3.3 - version: 5.3.3 + specifier: 19.1.9 + version: 19.1.9(@types/react@19.1.12) '@types/react-transition-group': specifier: 4.4.12 - version: 4.4.12(@types/react@18.3.20) + version: 4.4.12(@types/react@19.1.12) '@types/react-window': specifier: 1.8.8 version: 1.8.8 '@vitejs/plugin-react-swc': specifier: 4.0.1 - version: 4.0.1(vite@7.1.3(@types/node@22.15.30)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.7.1)) + version: 4.0.1(vite@7.1.4(@types/node@22.15.30)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.7.1)) autoprefixer: specifier: 10.4.21 version: 10.4.21(postcss@8.5.6) @@ -224,7 +218,7 @@ importers: version: 12.1.1(eslint@9.34.0(jiti@2.5.1)) eslint-plugin-unused-imports: specifier: 4.2.0 - version: 4.2.0(@typescript-eslint/eslint-plugin@8.41.0(@typescript-eslint/parser@8.41.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.8.3))(eslint@9.34.0(jiti@2.5.1))(typescript@5.8.3))(eslint@9.34.0(jiti@2.5.1)) + version: 4.2.0(@typescript-eslint/eslint-plugin@8.42.0(@typescript-eslint/parser@8.42.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.34.0(jiti@2.5.1)) globals: specifier: 16.3.0 version: 16.3.0 @@ -238,23 +232,23 @@ importers: specifier: 3.6.2 version: 3.6.2 tailwindcss: - specifier: 4.1.12 - version: 4.1.12 + specifier: 4.1.13 + version: 4.1.13 typescript: - specifier: 5.8.3 - version: 5.8.3 + specifier: 5.9.2 + version: 5.9.2 typescript-eslint: - specifier: 8.41.0 - version: 8.41.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.8.3) + specifier: 8.42.0 + version: 8.42.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) vite: - specifier: 7.1.3 - version: 7.1.3(@types/node@22.15.30)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.7.1) + specifier: 7.1.4 + version: 7.1.4(@types/node@22.15.30)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.7.1) vite-bundle-visualizer: specifier: 1.2.1 version: 1.2.1(rollup@4.50.0) vite-tsconfig-paths: specifier: 5.1.4 - version: 5.1.4(typescript@5.8.3)(vite@7.1.3(@types/node@22.15.30)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.7.1)) + version: 5.1.4(typescript@5.9.2)(vite@7.1.4(@types/node@22.15.30)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.7.1)) vitest: specifier: 3.2.4 version: 3.2.4(@types/node@22.15.30)(jiti@2.5.1)(jsdom@26.1.0)(lightningcss@1.30.1)(yaml@2.7.1) @@ -369,8 +363,8 @@ packages: '@emotion/hash@0.9.2': resolution: {integrity: sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==} - '@emotion/is-prop-valid@1.3.1': - resolution: {integrity: sha512-/ACwoqx7XQi9knQs/G0qKvv5teDMhD7bXYns9N/wM8ah8iNb8jZ2uNO0YOgiq2o2poIvVtJS2YALasQuMSQ7Kw==} + '@emotion/is-prop-valid@1.4.0': + resolution: {integrity: sha512-QgD4fyscGcbbKwJmqNvUMSE02OsHUa+lAWKdEUIJKgqe5IwRSKd7+KhibEWdaKwgjLj0DRSHA9biAIqGBk05lw==} '@emotion/memoize@0.9.0': resolution: {integrity: sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==} @@ -570,8 +564,8 @@ packages: cpu: [x64] os: [win32] - '@eslint-community/eslint-utils@4.7.0': - resolution: {integrity: sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==} + '@eslint-community/eslint-utils@4.8.0': + resolution: {integrity: sha512-MJQFqrZgcW0UNYLGOuQpey/oTN59vyWwplvCGZztn1cKz9agZPPYpJB7h2OMmuu7VLqkvEjN8feFZJmxNF9D+Q==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 @@ -631,18 +625,14 @@ packages: resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} engines: {node: '>=18.18.0'} - '@humanfs/node@0.16.6': - resolution: {integrity: sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==} + '@humanfs/node@0.16.7': + resolution: {integrity: sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==} engines: {node: '>=18.18.0'} '@humanwhocodes/module-importer@1.0.1': resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} engines: {node: '>=12.22'} - '@humanwhocodes/retry@0.3.1': - resolution: {integrity: sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==} - engines: {node: '>=18.18'} - '@humanwhocodes/retry@0.4.3': resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} engines: {node: '>=18.18'} @@ -667,28 +657,28 @@ packages: '@jridgewell/trace-mapping@0.3.30': resolution: {integrity: sha512-GQ7Nw5G2lTu/BtHTKfXhKHok2WGetd4XYcVKGx00SjAk8GMwgJM3zr6zORiPGuOE+/vkc90KtTosSSvaCjKb2Q==} - '@mui/core-downloads-tracker@7.3.1': - resolution: {integrity: sha512-+mIK1Z0BhOaQ0vCgOkT1mSrIpEHLo338h4/duuL4TBLXPvUMit732mnwJY3W40Avy30HdeSfwUAAGRkKmwRaEQ==} + '@mui/core-downloads-tracker@7.3.2': + resolution: {integrity: sha512-AOyfHjyDKVPGJJFtxOlept3EYEdLoar/RvssBTWVAvDJGIE676dLi2oT/Kx+FoVXFoA/JdV7DEMq/BVWV3KHRw==} - '@mui/icons-material@7.3.1': - resolution: {integrity: sha512-upzCtG6awpL6noEZlJ5Z01khZ9VnLNLaj7tb6iPbN6G97eYfUTs8e9OyPKy3rEms3VQWmVBfri7jzeaRxdFIzA==} + '@mui/icons-material@7.3.2': + resolution: {integrity: sha512-TZWazBjWXBjR6iGcNkbKklnwodcwj0SrChCNHc9BhD9rBgET22J1eFhHsEmvSvru9+opDy3umqAimQjokhfJlQ==} engines: {node: '>=14.0.0'} peerDependencies: - '@mui/material': ^7.3.1 + '@mui/material': ^7.3.2 '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 react: ^17.0.0 || ^18.0.0 || ^19.0.0 peerDependenciesMeta: '@types/react': optional: true - '@mui/lab@7.0.0-beta.16': - resolution: {integrity: sha512-YiyDU84F6ujjaa5xuItuXa40KN1aPC+8PBkP2OAOJGO2MMvdEicuvkEfVSnikH6uLHtKOwGzOeqEqrfaYxcOxw==} + '@mui/lab@7.0.0-beta.17': + resolution: {integrity: sha512-H8tSINm6Xgbi7o49MplAwks4tAEE6SpFNd9l7n4NURl0GSpOv0CZvgXKSJt4+6TmquDhE7pomHpHWJiVh/2aCg==} engines: {node: '>=14.0.0'} peerDependencies: '@emotion/react': ^11.5.0 '@emotion/styled': ^11.3.0 - '@mui/material': ^7.3.1 - '@mui/material-pigment-css': ^7.3.1 + '@mui/material': ^7.3.2 + '@mui/material-pigment-css': ^7.3.2 '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 react: ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^17.0.0 || ^18.0.0 || ^19.0.0 @@ -702,13 +692,13 @@ packages: '@types/react': optional: true - '@mui/material@7.3.1': - resolution: {integrity: sha512-Xf6Shbo03YmcBedZMwSpEFOwpYDtU7tC+rhAHTrA9FHk0FpsDqiQ9jUa1j/9s3HLs7KWb5mDcGnlwdh9Q9KAag==} + '@mui/material@7.3.2': + resolution: {integrity: sha512-qXvbnawQhqUVfH1LMgMaiytP+ZpGoYhnGl7yYq2x57GYzcFL/iPzSZ3L30tlbwEjSVKNYcbiKO8tANR1tadjUg==} engines: {node: '>=14.0.0'} peerDependencies: '@emotion/react': ^11.5.0 '@emotion/styled': ^11.3.0 - '@mui/material-pigment-css': ^7.3.1 + '@mui/material-pigment-css': ^7.3.2 '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 react: ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^17.0.0 || ^18.0.0 || ^19.0.0 @@ -722,8 +712,8 @@ packages: '@types/react': optional: true - '@mui/private-theming@7.3.1': - resolution: {integrity: sha512-WU3YLkKXii/x8ZEKnrLKsPwplCVE11yZxUvlaaZSIzCcI3x2OdFC8eMlNy74hVeUsYQvzzX1Es/k4ARPlFvpPQ==} + '@mui/private-theming@7.3.2': + resolution: {integrity: sha512-ha7mFoOyZGJr75xeiO9lugS3joRROjc8tG1u4P50dH0KR7bwhHznVMcYg7MouochUy0OxooJm/OOSpJ7gKcMvg==} engines: {node: '>=14.0.0'} peerDependencies: '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 @@ -732,8 +722,8 @@ packages: '@types/react': optional: true - '@mui/styled-engine@7.3.1': - resolution: {integrity: sha512-Nqo6OHjvJpXJ1+9TekTE//+8RybgPQUKwns2Lh0sq+8rJOUSUKS3KALv4InSOdHhIM9Mdi8/L7LTF1/Ky6D6TQ==} + '@mui/styled-engine@7.3.2': + resolution: {integrity: sha512-PkJzW+mTaek4e0nPYZ6qLnW5RGa0KN+eRTf5FA2nc7cFZTeM+qebmGibaTLrgQBy3UpcpemaqfzToBNkzuxqew==} engines: {node: '>=14.0.0'} peerDependencies: '@emotion/react': ^11.4.1 @@ -745,8 +735,8 @@ packages: '@emotion/styled': optional: true - '@mui/system@7.3.1': - resolution: {integrity: sha512-mIidecvcNVpNJMdPDmCeoSL5zshKBbYPcphjuh6ZMjhybhqhZ4mX6k9zmIWh6XOXcqRQMg5KrcjnO0QstrNj3w==} + '@mui/system@7.3.2': + resolution: {integrity: sha512-9d8JEvZW+H6cVkaZ+FK56R53vkJe3HsTpcjMUtH8v1xK6Y1TjzHdZ7Jck02mGXJsE6MQGWVs3ogRHTQmS9Q/rA==} engines: {node: '>=14.0.0'} peerDependencies: '@emotion/react': ^11.5.0 @@ -761,16 +751,16 @@ packages: '@types/react': optional: true - '@mui/types@7.4.5': - resolution: {integrity: sha512-ZPwlAOE3e8C0piCKbaabwrqZbW4QvWz0uapVPWya7fYj6PeDkl5sSJmomT7wjOcZGPB48G/a6Ubidqreptxz4g==} + '@mui/types@7.4.6': + resolution: {integrity: sha512-NVBbIw+4CDMMppNamVxyTccNv0WxtDb7motWDlMeSC8Oy95saj1TIZMGynPpFLePt3yOD8TskzumeqORCgRGWw==} peerDependencies: '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 peerDependenciesMeta: '@types/react': optional: true - '@mui/utils@7.3.1': - resolution: {integrity: sha512-/31y4wZqVWa0jzMnzo6JPjxwP6xXy4P3+iLbosFg/mJQowL1KIou0LC+lquWW60FKVbKz5ZUWBg2H3jausa0pw==} + '@mui/utils@7.3.2': + resolution: {integrity: sha512-4DMWQGenOdLnM3y/SdFQFwKsCLM+mqxzvoWp9+x2XdEzXapkznauHLiXtSohHs/mc0+5/9UACt1GdugCX2te5g==} engines: {node: '>=14.0.0'} peerDependencies: '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 @@ -779,8 +769,8 @@ packages: '@types/react': optional: true - '@mui/x-date-pickers@8.11.0': - resolution: {integrity: sha512-UHGVG8+zb9GkpUpHHCBCRA4ugrz1XOsGIPTs1cHDtZ/DNkCi+hrhKW1EH5Scoxn9GjE3PXxiN5eH+ZVpeq0jcw==} + '@mui/x-date-pickers@8.11.1': + resolution: {integrity: sha512-q3n7gHQXnupkddzSJSFhbkYANheeJX0rPfXr9BSgoUlcZF8i5fav8hurBZqpQNmXTffGf6yfJ7KblB0RnPqqkA==} engines: {node: '>=14.0.0'} peerDependencies: '@emotion/react': ^11.9.0 @@ -816,8 +806,8 @@ packages: moment-jalaali: optional: true - '@mui/x-internals@8.11.0': - resolution: {integrity: sha512-SFPMLMkNWSEOxIgKMQ9RqEL01klb1lwIdd4f4d18fJNrJOlTxeIDWd6eVllS5sRLdKVsE5FC1802V+yLe6W+pQ==} + '@mui/x-internals@8.11.1': + resolution: {integrity: sha512-/l0VpgdgYhC7DzqdWaQcuv3wX7cr+o3DBnoKa/t/Vze3y/Wh2VeNSJY/TsW2dIVkFAA9dsjUEMjclT7ScZTDqA==} engines: {node: '>=14.0.0'} peerDependencies: react: ^17.0.0 || ^18.0.0 || ^19.0.0 @@ -846,8 +836,8 @@ packages: resolution: {integrity: sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==} engines: {node: '>=8.0.0'} - '@opentelemetry/context-async-hooks@2.0.1': - resolution: {integrity: sha512-XuY23lSI3d4PEqKA+7SLtAgwqIfc6E/E9eAQWLN1vlpC53ybO3o6jW4BsXo1xvz9lYyyWItfQDDLzezER01mCw==} + '@opentelemetry/context-async-hooks@2.1.0': + resolution: {integrity: sha512-zOyetmZppnwTyPrt4S7jMfXiSX9yyfF0hxlA8B5oo2TtKl+/RGCy7fi4DrBfIf3lCPrkKsRBWZZD7RFojK7FDg==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': '>=1.0.0 <1.10.0' @@ -858,6 +848,12 @@ packages: peerDependencies: '@opentelemetry/api': '>=1.0.0 <1.10.0' + '@opentelemetry/core@2.1.0': + resolution: {integrity: sha512-RMEtHsxJs/GiHHxYT58IY57UXAQTuUnZVco6ymDEqTNlJKTimM4qPUPVe8InNFyBjhHBEAx4k3Q8LtNayBsbUQ==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': '>=1.0.0 <1.10.0' + '@opentelemetry/instrumentation-amqplib@0.50.0': resolution: {integrity: sha512-kwNs/itehHG/qaQBcVrLNcvXVPW0I4FCOVtw3LHMLdYIqD7GJ6Yv2nX+a4YHjzbzIeRYj8iyMp0Bl7tlkidq5w==} engines: {node: ^18.19.0 || >=20.6.0} @@ -1006,20 +1002,20 @@ packages: resolution: {integrity: sha512-4Wc0AWURII2cfXVVoZ6vDqK+s5n4K5IssdrlVrvGsx6OEOKdghKtJZqXAHWFiZv4nTDLH2/2fldjIHY8clMOjQ==} engines: {node: ^18.19.0 || >=20.6.0} - '@opentelemetry/resources@2.0.1': - resolution: {integrity: sha512-dZOB3R6zvBwDKnHDTB4X1xtMArB/d324VsbiPkX/Yu0Q8T2xceRthoIVFhJdvgVM2QhGVUyX9tzwiNxGtoBJUw==} + '@opentelemetry/resources@2.1.0': + resolution: {integrity: sha512-1CJjf3LCvoefUOgegxi8h6r4B/wLSzInyhGP2UmIBYNlo4Qk5CZ73e1eEyWmfXvFtm1ybkmfb2DqWvspsYLrWw==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': '>=1.3.0 <1.10.0' - '@opentelemetry/sdk-trace-base@2.0.1': - resolution: {integrity: sha512-xYLlvk/xdScGx1aEqvxLwf6sXQLXCjk3/1SQT9X9AoN5rXRhkdvIFShuNNmtTEPRBqcsMbS4p/gJLNI2wXaDuQ==} + '@opentelemetry/sdk-trace-base@2.1.0': + resolution: {integrity: sha512-uTX9FBlVQm4S2gVQO1sb5qyBLq/FPjbp+tmGoxu4tIgtYGmBYB44+KX/725RFDe30yBSaA9Ml9fqphe1hbUyLQ==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': '>=1.3.0 <1.10.0' - '@opentelemetry/semantic-conventions@1.36.0': - resolution: {integrity: sha512-TtxJSRD8Ohxp6bKkhrm27JRHAxPczQA7idtcTOMYI+wQRRrfgqxHv1cFbCApcSnNjtXkmzFozn6jQtFrOmbjPQ==} + '@opentelemetry/semantic-conventions@1.37.0': + resolution: {integrity: sha512-JD6DerIKdJGmRp4jQyX5FlrQjA4tjOw1cvfsPAZXfOOEErMUHjPcPSICS+6WnM0nB0efSFARh0KAZss+bvExOA==} engines: {node: '>=14'} '@opentelemetry/sql-common@0.41.0': @@ -1040,10 +1036,6 @@ packages: peerDependencies: '@opentelemetry/api': ^1.8 - '@remix-run/router@1.23.0': - resolution: {integrity: sha512-O3rHJzAQKamUz1fvE0Qaw0xSFqsA/yafi2iqeE0pvdFtCO1viYx8QL6f3Ln/aCCTLxs68SLf0KPM9eSeM8yBnA==} - engines: {node: '>=14.0.0'} - '@rolldown/pluginutils@1.0.0-beta.32': resolution: {integrity: sha512-QReCdvxiUZAPkvp1xpAg62IeNzykOFA6syH2CnClif4YmALN1XKpB39XneL80008UbtMShthSVDKmrx05N1q/g==} @@ -1152,32 +1144,32 @@ packages: cpu: [x64] os: [win32] - '@sentry-internal/browser-utils@10.8.0': - resolution: {integrity: sha512-FaQX9eefc8sh3h3ZQy16U73KiH0xgDldXnrFiWK6OeWg8X4bJpnYbLqEi96LgHiQhjnnz+UQP1GDzH5oFuu5fA==} + '@sentry-internal/browser-utils@10.10.0': + resolution: {integrity: sha512-209QN9vsQBwJcS+9DU7B4yl9mb4OqCt2kdL3LYDvqsuOdpICpwfowdK3RMn825Ruf4KLJa0KHM1scQbXZCc4lw==} engines: {node: '>=18'} - '@sentry-internal/feedback@10.8.0': - resolution: {integrity: sha512-n7SqgFQItq4QSPG7bCjcZcIwK6AatKnnmSDJ/i6e8jXNIyLwkEuY2NyvTXACxVdO/kafGD5VmrwnTo3Ekc1AMg==} + '@sentry-internal/feedback@10.10.0': + resolution: {integrity: sha512-oSU4F/ebOsJA9Eof0me9hLpSDTSelpnEY6gmhU9sHyIG+U7hJRuCfeGICxQOzBtteepWRhAaZEv4s9ZBh3iD2w==} engines: {node: '>=18'} - '@sentry-internal/replay-canvas@10.8.0': - resolution: {integrity: sha512-jC4OOwiNgrlIPeXIPMLkaW53BSS1do+toYHoWzzO5AXGpN6jRhanoSj36FpVuH2N3kFnxKVfVxrwh8L+/3vFWg==} + '@sentry-internal/replay-canvas@10.10.0': + resolution: {integrity: sha512-mJBNB0EBbE3vzL7lgd8lDoWWhRaRwxXdI4Kkx3r39u2+1qTdJP/xHbJDihyemCaw7gRL1FR/GC44JLipzEfkKQ==} engines: {node: '>=18'} - '@sentry-internal/replay@10.8.0': - resolution: {integrity: sha512-9+qDEoEjv4VopLuOzK1zM4LcvcUsvB5N0iJ+FRCM3XzzOCbebJOniXTQbt5HflJc3XLnQNKFdKfTfgj8M/0RKQ==} + '@sentry-internal/replay@10.10.0': + resolution: {integrity: sha512-sKFYWBaft0ET6gd5B0pThR6gYTjaUECXCzVAnSYxy64a2/PK6lV93BtnA1C2Q34Yhv/0scdyIbZtfTnSsEgwUg==} engines: {node: '>=18'} - '@sentry/browser@10.8.0': - resolution: {integrity: sha512-2J7HST8/ixCaboq17yFn/j/OEokXSXoCBMXRrFx4FKJggKWZ90e2Iau5mP/IPPhrW+W9zCptCgNMY0167wS4qA==} + '@sentry/browser@10.10.0': + resolution: {integrity: sha512-STBs29meUk0CvluIOXXnnRGRtjKsJN9fAHS3dUu3GMjmow4rxKBiBbAwoPYftAVdfvGypT7zQCQ+K30dbRxp0g==} engines: {node: '>=18'} - '@sentry/core@10.8.0': - resolution: {integrity: sha512-scYzM/UOItu4PjEq6CpHLdArpXjIS0laHYxE4YjkIbYIH6VMcXGQbD/FSBClsnCr1wXRnlXfXBzj0hrQAFyw+Q==} + '@sentry/core@10.10.0': + resolution: {integrity: sha512-4O1O6my/vYE98ZgfEuLEwOOuHzqqzfBT6IdRo1yiQM7/AXcmSl0H/k4HJtXCiCTiHm+veEuTDBHp0GQZmpIbtA==} engines: {node: '>=18'} - '@sentry/node-core@10.8.0': - resolution: {integrity: sha512-KCFy5Otq6KTXge8hBKMgU13EDRFkO4gNwSyZGXub8a7KHYFtoUgpRkborR59SWxeJmC6aEYTyh0PyOoWZJbHUQ==} + '@sentry/node-core@10.10.0': + resolution: {integrity: sha512-7jHM1Is0Si737SVA0sHPg7lj7OmKoNM+f7+E3ySvtHIUeSINZBLM6jg1q57R1kIg8eavpHXudYljRMpuv/8bYA==} engines: {node: '>=18'} peerDependencies: '@opentelemetry/api': ^1.9.0 @@ -1188,12 +1180,12 @@ packages: '@opentelemetry/sdk-trace-base': ^1.30.1 || ^2.0.0 '@opentelemetry/semantic-conventions': ^1.34.0 - '@sentry/node@10.8.0': - resolution: {integrity: sha512-1TtCjxzn4SxoGw+ulLK+jF/v9NaZfP0yCclQIqfvWNDjMf2F+SbZL1UnXx4L184FGlNpRQnJBDrBe88gxnMX0A==} + '@sentry/node@10.10.0': + resolution: {integrity: sha512-GdI/ELIipKhdL8gdvnRLtz1ItPzAXRCZrvTwGMd5C+kDRALakQIR7pONC9nf5TKCG2UaslHEX+2XDImorhM7OA==} engines: {node: '>=18'} - '@sentry/opentelemetry@10.8.0': - resolution: {integrity: sha512-62R/RPwTYVaiZ5lVcxcjHCAGwgCyfn8Q3kaQld8/LPm8FRizZeUJmmtrI80KaYCvPJhSB/Pvfma4X3w+aN5Q3A==} + '@sentry/opentelemetry@10.10.0': + resolution: {integrity: sha512-EQ5/1Ps4n1JosmaDiFCyb5iByjjKja2pnmeMiLzTDZ5Zikjs/3GKzmh+SgTRFLOm6yKgQps0GdiCH2gxdrbONg==} engines: {node: '>=18'} peerDependencies: '@opentelemetry/api': ^1.9.0 @@ -1202,8 +1194,8 @@ packages: '@opentelemetry/sdk-trace-base': ^1.30.1 || ^2.0.0 '@opentelemetry/semantic-conventions': ^1.34.0 - '@sentry/react@10.8.0': - resolution: {integrity: sha512-w/dGLMCLJG2lp8gKVKX1jjeg2inXewKfPb73+PS1CDi9/ihvqZU2DAXxnaNsBA7YYtGwlWVJe1bLAqguwTEpqw==} + '@sentry/react@10.10.0': + resolution: {integrity: sha512-wfYq9W36uKBwaxwy3II/LXjs5XCAQ9MZz7OmkDvKhL9ly3YupnOua5DaFcNdlLmePuYVqOfEk2lBCJBj9FliOg==} engines: {node: '>=18'} peerDependencies: react: ^16.14.0 || 17.x || 18.x || 19.x @@ -1283,65 +1275,65 @@ packages: '@swc/types@0.1.24': resolution: {integrity: sha512-tjTMh3V4vAORHtdTprLlfoMptu1WfTZG9Rsca6yOKyNYsRr+MUXutKmliB17orgSZk5DpnDxs8GUdd/qwYxOng==} - '@tailwindcss/node@4.1.12': - resolution: {integrity: sha512-3hm9brwvQkZFe++SBt+oLjo4OLDtkvlE8q2WalaD/7QWaeM7KEJbAiY/LJZUaCs7Xa8aUu4xy3uoyX4q54UVdQ==} + '@tailwindcss/node@4.1.13': + resolution: {integrity: sha512-eq3ouolC1oEFOAvOMOBAmfCIqZBJuvWvvYWh5h5iOYfe1HFC6+GZ6EIL0JdM3/niGRJmnrOc+8gl9/HGUaaptw==} - '@tailwindcss/oxide-android-arm64@4.1.12': - resolution: {integrity: sha512-oNY5pq+1gc4T6QVTsZKwZaGpBb2N1H1fsc1GD4o7yinFySqIuRZ2E4NvGasWc6PhYJwGK2+5YT1f9Tp80zUQZQ==} + '@tailwindcss/oxide-android-arm64@4.1.13': + resolution: {integrity: sha512-BrpTrVYyejbgGo57yc8ieE+D6VT9GOgnNdmh5Sac6+t0m+v+sKQevpFVpwX3pBrM2qKrQwJ0c5eDbtjouY/+ew==} engines: {node: '>= 10'} cpu: [arm64] os: [android] - '@tailwindcss/oxide-darwin-arm64@4.1.12': - resolution: {integrity: sha512-cq1qmq2HEtDV9HvZlTtrj671mCdGB93bVY6J29mwCyaMYCP/JaUBXxrQQQm7Qn33AXXASPUb2HFZlWiiHWFytw==} + '@tailwindcss/oxide-darwin-arm64@4.1.13': + resolution: {integrity: sha512-YP+Jksc4U0KHcu76UhRDHq9bx4qtBftp9ShK/7UGfq0wpaP96YVnnjFnj3ZFrUAjc5iECzODl/Ts0AN7ZPOANQ==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] - '@tailwindcss/oxide-darwin-x64@4.1.12': - resolution: {integrity: sha512-6UCsIeFUcBfpangqlXay9Ffty9XhFH1QuUFn0WV83W8lGdX8cD5/+2ONLluALJD5+yJ7k8mVtwy3zMZmzEfbLg==} + '@tailwindcss/oxide-darwin-x64@4.1.13': + resolution: {integrity: sha512-aAJ3bbwrn/PQHDxCto9sxwQfT30PzyYJFG0u/BWZGeVXi5Hx6uuUOQEI2Fa43qvmUjTRQNZnGqe9t0Zntexeuw==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] - '@tailwindcss/oxide-freebsd-x64@4.1.12': - resolution: {integrity: sha512-JOH/f7j6+nYXIrHobRYCtoArJdMJh5zy5lr0FV0Qu47MID/vqJAY3r/OElPzx1C/wdT1uS7cPq+xdYYelny1ww==} + '@tailwindcss/oxide-freebsd-x64@4.1.13': + resolution: {integrity: sha512-Wt8KvASHwSXhKE/dJLCCWcTSVmBj3xhVhp/aF3RpAhGeZ3sVo7+NTfgiN8Vey/Fi8prRClDs6/f0KXPDTZE6nQ==} engines: {node: '>= 10'} cpu: [x64] os: [freebsd] - '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.12': - resolution: {integrity: sha512-v4Ghvi9AU1SYgGr3/j38PD8PEe6bRfTnNSUE3YCMIRrrNigCFtHZ2TCm8142X8fcSqHBZBceDx+JlFJEfNg5zQ==} + '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.13': + resolution: {integrity: sha512-mbVbcAsW3Gkm2MGwA93eLtWrwajz91aXZCNSkGTx/R5eb6KpKD5q8Ueckkh9YNboU8RH7jiv+ol/I7ZyQ9H7Bw==} engines: {node: '>= 10'} cpu: [arm] os: [linux] - '@tailwindcss/oxide-linux-arm64-gnu@4.1.12': - resolution: {integrity: sha512-YP5s1LmetL9UsvVAKusHSyPlzSRqYyRB0f+Kl/xcYQSPLEw/BvGfxzbH+ihUciePDjiXwHh+p+qbSP3SlJw+6g==} + '@tailwindcss/oxide-linux-arm64-gnu@4.1.13': + resolution: {integrity: sha512-wdtfkmpXiwej/yoAkrCP2DNzRXCALq9NVLgLELgLim1QpSfhQM5+ZxQQF8fkOiEpuNoKLp4nKZ6RC4kmeFH0HQ==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@tailwindcss/oxide-linux-arm64-musl@4.1.12': - resolution: {integrity: sha512-V8pAM3s8gsrXcCv6kCHSuwyb/gPsd863iT+v1PGXC4fSL/OJqsKhfK//v8P+w9ThKIoqNbEnsZqNy+WDnwQqCA==} + '@tailwindcss/oxide-linux-arm64-musl@4.1.13': + resolution: {integrity: sha512-hZQrmtLdhyqzXHB7mkXfq0IYbxegaqTmfa1p9MBj72WPoDD3oNOh1Lnxf6xZLY9C3OV6qiCYkO1i/LrzEdW2mg==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@tailwindcss/oxide-linux-x64-gnu@4.1.12': - resolution: {integrity: sha512-xYfqYLjvm2UQ3TZggTGrwxjYaLB62b1Wiysw/YE3Yqbh86sOMoTn0feF98PonP7LtjsWOWcXEbGqDL7zv0uW8Q==} + '@tailwindcss/oxide-linux-x64-gnu@4.1.13': + resolution: {integrity: sha512-uaZTYWxSXyMWDJZNY1Ul7XkJTCBRFZ5Fo6wtjrgBKzZLoJNrG+WderJwAjPzuNZOnmdrVg260DKwXCFtJ/hWRQ==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@tailwindcss/oxide-linux-x64-musl@4.1.12': - resolution: {integrity: sha512-ha0pHPamN+fWZY7GCzz5rKunlv9L5R8kdh+YNvP5awe3LtuXb5nRi/H27GeL2U+TdhDOptU7T6Is7mdwh5Ar3A==} + '@tailwindcss/oxide-linux-x64-musl@4.1.13': + resolution: {integrity: sha512-oXiPj5mi4Hdn50v5RdnuuIms0PVPI/EG4fxAfFiIKQh5TgQgX7oSuDWntHW7WNIi/yVLAiS+CRGW4RkoGSSgVQ==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@tailwindcss/oxide-wasm32-wasi@4.1.12': - resolution: {integrity: sha512-4tSyu3dW+ktzdEpuk6g49KdEangu3eCYoqPhWNsZgUhyegEda3M9rG0/j1GV/JjVVsj+lG7jWAyrTlLzd/WEBg==} + '@tailwindcss/oxide-wasm32-wasi@4.1.13': + resolution: {integrity: sha512-+LC2nNtPovtrDwBc/nqnIKYh/W2+R69FA0hgoeOn64BdCX522u19ryLh3Vf3F8W49XBcMIxSe665kwy21FkhvA==} engines: {node: '>=14.0.0'} cpu: [wasm32] bundledDependencies: @@ -1352,44 +1344,44 @@ packages: - '@emnapi/wasi-threads' - tslib - '@tailwindcss/oxide-win32-arm64-msvc@4.1.12': - resolution: {integrity: sha512-iGLyD/cVP724+FGtMWslhcFyg4xyYyM+5F4hGvKA7eifPkXHRAUDFaimu53fpNg9X8dfP75pXx/zFt/jlNF+lg==} + '@tailwindcss/oxide-win32-arm64-msvc@4.1.13': + resolution: {integrity: sha512-dziTNeQXtoQ2KBXmrjCxsuPk3F3CQ/yb7ZNZNA+UkNTeiTGgfeh+gH5Pi7mRncVgcPD2xgHvkFCh/MhZWSgyQg==} engines: {node: '>= 10'} cpu: [arm64] os: [win32] - '@tailwindcss/oxide-win32-x64-msvc@4.1.12': - resolution: {integrity: sha512-NKIh5rzw6CpEodv/++r0hGLlfgT/gFN+5WNdZtvh6wpU2BpGNgdjvj6H2oFc8nCM839QM1YOhjpgbAONUb4IxA==} + '@tailwindcss/oxide-win32-x64-msvc@4.1.13': + resolution: {integrity: sha512-3+LKesjXydTkHk5zXX01b5KMzLV1xl2mcktBJkje7rhFUpUlYJy7IMOLqjIRQncLTa1WZZiFY/foAeB5nmaiTw==} engines: {node: '>= 10'} cpu: [x64] os: [win32] - '@tailwindcss/oxide@4.1.12': - resolution: {integrity: sha512-gM5EoKHW/ukmlEtphNwaGx45fGoEmP10v51t9unv55voWh6WrOL19hfuIdo2FjxIaZzw776/BUQg7Pck++cIVw==} + '@tailwindcss/oxide@4.1.13': + resolution: {integrity: sha512-CPgsM1IpGRa880sMbYmG1s4xhAy3xEt1QULgTJGQmZUeNgXFR7s1YxYygmJyBGtou4SyEosGAGEeYqY7R53bIA==} engines: {node: '>= 10'} - '@tailwindcss/postcss@4.1.12': - resolution: {integrity: sha512-5PpLYhCAwf9SJEeIsSmCDLgyVfdBhdBpzX1OJ87anT9IVR0Z9pjM0FNixCAUAHGnMBGB8K99SwAheXrT0Kh6QQ==} + '@tailwindcss/postcss@4.1.13': + resolution: {integrity: sha512-HLgx6YSFKJT7rJqh9oJs/TkBFhxuMOfUKSBEPYwV+t78POOBsdQ7crhZLzwcH3T0UyUuOzU/GK5pk5eKr3wCiQ==} - '@tanstack/eslint-plugin-query@5.83.1': - resolution: {integrity: sha512-tdkpPFfzkTksN9BIlT/qjixSAtKrsW6PUVRwdKWaOcag7DrD1vpki3UzzdfMQGDRGeg1Ue1Dg+rcl5FJGembNg==} + '@tanstack/eslint-plugin-query@5.86.0': + resolution: {integrity: sha512-tmXdnx/fF3yY5G5jpzrJQbASY3PNzsKF0gq9IsZVqz3LJ4sExgdUFGQ305nao0wTMBOclyrSC13v/VQ3yOXu/Q==} peerDependencies: eslint: ^8.57.0 || ^9.0.0 - '@tanstack/query-core@5.85.6': - resolution: {integrity: sha512-hCj0TktzdCv2bCepIdfwqVwUVWb+GSHm1Jnn8w+40lfhQ3m7lCO7ADRUJy+2unxQ/nzjh2ipC6ye69NDW3l73g==} + '@tanstack/query-core@5.86.0': + resolution: {integrity: sha512-Y6ibQm6BXbw6w1p3a5LrPn8Ae64M0dx7hGmnhrm9P+XAkCCKXOwZN0J5Z1wK/0RdNHtR9o+sWHDXd4veNI60tQ==} - '@tanstack/query-devtools@5.84.0': - resolution: {integrity: sha512-fbF3n+z1rqhvd9EoGp5knHkv3p5B2Zml1yNRjh7sNXklngYI5RVIWUrUjZ1RIcEoscarUb0+bOvIs5x9dwzOXQ==} + '@tanstack/query-devtools@5.86.0': + resolution: {integrity: sha512-/JDw9BP80eambEK/EsDMGAcsL2VFT+8F5KCOwierjPU7QP8Wt1GT32yJpn3qOinBM8/zS3Jy36+F0GiyJp411A==} - '@tanstack/react-query-devtools@5.85.6': - resolution: {integrity: sha512-A6rE39FypFV7eonefk4fxC/vuV/7YJMAcQT94CFAvCpiw65QZX8MOuUpdLBeG1cXajy4Pj8T8sEWHigccntJqg==} + '@tanstack/react-query-devtools@5.86.0': + resolution: {integrity: sha512-+50IcXI+54qHx3IDccbTala4tkToKxa0WKqP4XWlTnP1mQNfHO3dJj8wwnzpG50os69kpSbnU8C98Q/i8b6lyA==} peerDependencies: - '@tanstack/react-query': ^5.85.6 + '@tanstack/react-query': ^5.86.0 react: ^18 || ^19 - '@tanstack/react-query@5.85.6': - resolution: {integrity: sha512-VUAag4ERjh+qlmg0wNivQIVCZUrYndqYu3/wPCVZd4r0E+1IqotbeyGTc+ICroL/PqbpSaGZg02zSWYfcvxbdA==} + '@tanstack/react-query@5.86.0': + resolution: {integrity: sha512-jgS/v0oSJkGHucv9zxOS8rL7mjATh1XO3K4eqAV4WMpAly8okcBrGi1YxRZN5S4B59F54x9JFjWrK5vMAvJYqA==} peerDependencies: react: ^18 || ^19 @@ -1408,9 +1400,6 @@ packages: '@types/file-saver@2.0.7': resolution: {integrity: sha512-dNKVfHd/jk0SkR/exKGj2ggkB45MAkzvWCaqLUUgkyjITkGNzH8H+yUwr+BLJUBjZOe9w8X3wgmXhZDRg1ED6A==} - '@types/history@4.7.11': - resolution: {integrity: sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==} - '@types/is-base64@1.1.3': resolution: {integrity: sha512-8h40c+MFeMKhEw8Ebckd11MEt9sngs4AAkvcZVfDYOFDd7FeTD80pTfm3uvepbWcld1zVkHW+WA6b7UaHAOU/w==} @@ -1441,16 +1430,10 @@ packages: '@types/prop-types@15.7.15': resolution: {integrity: sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==} - '@types/react-dom@18.3.7': - resolution: {integrity: sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==} + '@types/react-dom@19.1.9': + resolution: {integrity: sha512-qXRuZaOsAdXKFyOhRBg6Lqqc0yay13vN7KrIg4L7N4aaHN68ma9OK3NE1BoDFgFOTfM7zg+3/8+2n8rLUH3OKQ==} peerDependencies: - '@types/react': ^18.0.0 - - '@types/react-router-dom@5.3.3': - resolution: {integrity: sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw==} - - '@types/react-router@5.1.20': - resolution: {integrity: sha512-jGjmu/ZqS7FjSH6owMcD5qpq19+1RS9DeVRqfl1FeBMxTDQAGwlMWOcs52NDoXaNKyG3d1cYQFMs9rCrb88o9Q==} + '@types/react': ^19.0.0 '@types/react-transition-group@4.4.12': resolution: {integrity: sha512-8TV6R3h2j7a91c+1DXdJi3Syo69zzIZbz7Lg5tORM5LEJG7X/E6a1V3drRyBRZq7/utz7A+c4OgYLiLcYGHG6w==} @@ -1460,8 +1443,8 @@ packages: '@types/react-window@1.8.8': resolution: {integrity: sha512-8Ls660bHR1AUA2kuRvVG9D/4XpRC6wjAaPT9dil7Ckc76eP9TKWZwwmgfq8Q1LANX3QNDnoU4Zp48A3w+zK69Q==} - '@types/react@18.3.20': - resolution: {integrity: sha512-IPaCZN7PShZK/3t6Q87pfTkRm6oLTd4vztyoj+cbHUF1g3FfVb2tFIL79uCRKEfv16AhqDMBywP2VW3KIZUvcg==} + '@types/react@19.1.12': + resolution: {integrity: sha512-cMoR+FoAf/Jyq6+Df2/Z41jISvGZZ2eTlnsaJRptmZ76Caldwy1odD4xTr/gNV9VLj0AWgg/nmkevIyUfIIq5w==} '@types/shimmer@1.2.0': resolution: {integrity: sha512-UE7oxhQLLd9gub6JKIAhDq06T0F6FnztwMNRvYgjeQSBeMc1ZG/tA47EwfduvkuQS8apbkM/lpLpWsaCeYsXVg==} @@ -1472,63 +1455,63 @@ packages: '@types/use-sync-external-store@0.0.6': resolution: {integrity: sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==} - '@typescript-eslint/eslint-plugin@8.41.0': - resolution: {integrity: sha512-8fz6oa6wEKZrhXWro/S3n2eRJqlRcIa6SlDh59FXJ5Wp5XRZ8B9ixpJDcjadHq47hMx0u+HW6SNa6LjJQ6NLtw==} + '@typescript-eslint/eslint-plugin@8.42.0': + resolution: {integrity: sha512-Aq2dPqsQkxHOLfb2OPv43RnIvfj05nw8v/6n3B2NABIPpHnjQnaLo9QGMTvml+tv4korl/Cjfrb/BYhoL8UUTQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.41.0 + '@typescript-eslint/parser': ^8.42.0 eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/parser@8.41.0': - resolution: {integrity: sha512-gTtSdWX9xiMPA/7MV9STjJOOYtWwIJIYxkQxnSV1U3xcE+mnJSH3f6zI0RYP+ew66WSlZ5ed+h0VCxsvdC1jJg==} + '@typescript-eslint/parser@8.42.0': + resolution: {integrity: sha512-r1XG74QgShUgXph1BYseJ+KZd17bKQib/yF3SR+demvytiRXrwd12Blnz5eYGm8tXaeRdd4x88MlfwldHoudGg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/project-service@8.41.0': - resolution: {integrity: sha512-b8V9SdGBQzQdjJ/IO3eDifGpDBJfvrNTp2QD9P2BeqWTGrRibgfgIlBSw6z3b6R7dPzg752tOs4u/7yCLxksSQ==} + '@typescript-eslint/project-service@8.42.0': + resolution: {integrity: sha512-vfVpLHAhbPjilrabtOSNcUDmBboQNrJUiNAGoImkZKnMjs2TIcWG33s4Ds0wY3/50aZmTMqJa6PiwkwezaAklg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/scope-manager@8.41.0': - resolution: {integrity: sha512-n6m05bXn/Cd6DZDGyrpXrELCPVaTnLdPToyhBoFkLIMznRUQUEQdSp96s/pcWSQdqOhrgR1mzJ+yItK7T+WPMQ==} + '@typescript-eslint/scope-manager@8.42.0': + resolution: {integrity: sha512-51+x9o78NBAVgQzOPd17DkNTnIzJ8T/O2dmMBLoK9qbY0Gm52XJcdJcCl18ExBMiHo6jPMErUQWUv5RLE51zJw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/tsconfig-utils@8.41.0': - resolution: {integrity: sha512-TDhxYFPUYRFxFhuU5hTIJk+auzM/wKvWgoNYOPcOf6i4ReYlOoYN8q1dV5kOTjNQNJgzWN3TUUQMtlLOcUgdUw==} + '@typescript-eslint/tsconfig-utils@8.42.0': + resolution: {integrity: sha512-kHeFUOdwAJfUmYKjR3CLgZSglGHjbNTi1H8sTYRYV2xX6eNz4RyJ2LIgsDLKf8Yi0/GL1WZAC/DgZBeBft8QAQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/type-utils@8.41.0': - resolution: {integrity: sha512-63qt1h91vg3KsjVVonFJWjgSK7pZHSQFKH6uwqxAH9bBrsyRhO6ONoKyXxyVBzG1lJnFAJcKAcxLS54N1ee1OQ==} + '@typescript-eslint/type-utils@8.42.0': + resolution: {integrity: sha512-9KChw92sbPTYVFw3JLRH1ockhyR3zqqn9lQXol3/YbI6jVxzWoGcT3AsAW0mu1MY0gYtsXnUGV/AKpkAj5tVlQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/types@8.41.0': - resolution: {integrity: sha512-9EwxsWdVqh42afLbHP90n2VdHaWU/oWgbH2P0CfcNfdKL7CuKpwMQGjwev56vWu9cSKU7FWSu6r9zck6CVfnag==} + '@typescript-eslint/types@8.42.0': + resolution: {integrity: sha512-LdtAWMiFmbRLNP7JNeY0SqEtJvGMYSzfiWBSmx+VSZ1CH+1zyl8Mmw1TT39OrtsRvIYShjJWzTDMPWZJCpwBlw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@8.41.0': - resolution: {integrity: sha512-D43UwUYJmGhuwHfY7MtNKRZMmfd8+p/eNSfFe6tH5mbVDto+VQCayeAt35rOx3Cs6wxD16DQtIKw/YXxt5E0UQ==} + '@typescript-eslint/typescript-estree@8.42.0': + resolution: {integrity: sha512-ku/uYtT4QXY8sl9EDJETD27o3Ewdi72hcXg1ah/kkUgBvAYHLwj2ofswFFNXS+FL5G+AGkxBtvGt8pFBHKlHsQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/utils@8.41.0': - resolution: {integrity: sha512-udbCVstxZ5jiPIXrdH+BZWnPatjlYwJuJkDA4Tbo3WyYLh8NvB+h/bKeSZHDOFKfphsZYJQqaFtLeXEqurQn1A==} + '@typescript-eslint/utils@8.42.0': + resolution: {integrity: sha512-JnIzu7H3RH5BrKC4NoZqRfmjqCIS1u3hGZltDYJgkVdqAezl4L9d1ZLw+36huCujtSBSAirGINF/S4UxOcR+/g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/visitor-keys@8.41.0': - resolution: {integrity: sha512-+GeGMebMCy0elMNg67LRNoVnUFPIm37iu5CmHESVx56/9Jsfdpsvbv605DQ81Pi/x11IdKUsS5nzgTYbCQU9fg==} + '@typescript-eslint/visitor-keys@8.42.0': + resolution: {integrity: sha512-3WbiuzoEowaEn8RSnhJBrxSwX8ULYE9CXaPepS2C2W3NSA5NNIvBaslpBSBElPq0UGr0xVJlXFWOAKIkyylydQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@uiw/color-convert@2.8.0': @@ -1860,8 +1843,8 @@ packages: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} - caniuse-lite@1.0.30001739: - resolution: {integrity: sha512-y+j60d6ulelrNSwpPyrHdl+9mJnQzHBr08xm48Qno0nSk4h3Qojh+ziv2qE6rXf4k3tadF4o1J/1tAbVm1NtnA==} + caniuse-lite@1.0.30001740: + resolution: {integrity: sha512-X6I2FZW2KjXKkAgsGgTwRmQXOcN0c7HtPR80KgJVj9LJi29be++fbf7JRPBnNXuzyJEW2ToGIpZ6JZeqqIwO0Q==} chai@5.3.3: resolution: {integrity: sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==} @@ -1918,6 +1901,10 @@ packages: convert-source-map@1.9.0: resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} + cookie@1.0.2: + resolution: {integrity: sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==} + engines: {node: '>=18'} + cosmiconfig@7.1.0: resolution: {integrity: sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==} engines: {node: '>=10'} @@ -2008,8 +1995,8 @@ packages: resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} engines: {node: '>= 0.4'} - electron-to-chromium@1.5.211: - resolution: {integrity: sha512-IGBvimJkotaLzFnwIVgW9/UD/AOJ2tByUmeOrtqBfACSbAw5b1G0XpvdaieKyc7ULmbwXVx+4e4Be8pOPBrYkw==} + electron-to-chromium@1.5.214: + resolution: {integrity: sha512-TpvUNdha+X3ybfU78NoQatKvQEm1oq3lf2QbnmCEdw+Bd9RuIAY+hJTvq1avzHM0f7EJfnH3vbCnbzKzisc/9Q==} emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -2930,17 +2917,14 @@ packages: raf-schd@4.0.3: resolution: {integrity: sha512-tQkJl2GRWh83ui2DiPTJz9wEiMN20syf+5oKfB03yYP7ioZcJwsIK8FjrtLwH1m7C7e+Tt2yYBlrOpdT+dyeIQ==} - react-dom@18.3.1: - resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==} + react-dom@19.1.1: + resolution: {integrity: sha512-Dlq/5LAZgF0Gaz6yiqZCf6VCcZs1ghAJyrsu84Q/GT0gV+mCxbfmKNoGRKBYMJ8IEdGPqu49YWXD02GCknEDkw==} peerDependencies: - react: ^18.3.1 + react: ^19.1.1 react-is@16.13.1: resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} - react-is@18.3.1: - resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} - react-is@19.1.1: resolution: {integrity: sha512-tr41fA15Vn8p4X9ntI+yCyeGSf1TlYaY5vlTZfQmeLBrFo3psOPX6HhTDnFNL9uj3EhP0KAQ80cugCl4b4BERA==} @@ -2956,18 +2940,15 @@ packages: redux: optional: true - react-router-dom@6.30.0: - resolution: {integrity: sha512-x30B78HV5tFk8ex0ITwzC9TTZMua4jGyA9IUlH1JLQYQTFyxr/ZxwOJq7evg1JX1qGVUcvhsmQSKdPncQrjTgA==} - engines: {node: '>=14.0.0'} + react-router@7.8.2: + resolution: {integrity: sha512-7M2fR1JbIZ/jFWqelpvSZx+7vd7UlBTfdZqf6OSdF9g6+sfdqJDAWcak6ervbHph200ePlu+7G8LdoiC3ReyAQ==} + engines: {node: '>=20.0.0'} peerDependencies: - react: '>=16.8' - react-dom: '>=16.8' - - react-router@6.30.0: - resolution: {integrity: sha512-D3X8FyH9nBcTSHGdEKurK7r8OYE1kKFn3d/CF+CoxbSHkxU7o37+Uh7eAHRXr6k2tSExXYO++07PeXJtA/dEhQ==} - engines: {node: '>=14.0.0'} - peerDependencies: - react: '>=16.8' + react: '>=18' + react-dom: '>=18' + peerDependenciesMeta: + react-dom: + optional: true react-transition-group@4.4.5: resolution: {integrity: sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==} @@ -2982,8 +2963,8 @@ packages: react: ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - react@18.3.1: - resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} + react@19.1.1: + resolution: {integrity: sha512-w8nqGImo45dmMIfljjMwOGtbmC/mk4CMYhWIicdSflH91J9TyCyczcPFXJzrZ/ZXcgGRFeP6BU0BEJTw6tZdfQ==} engines: {node: '>=0.10.0'} redux@5.0.1: @@ -3074,8 +3055,8 @@ packages: resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==} engines: {node: '>=v12.22.7'} - scheduler@0.23.2: - resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==} + scheduler@0.26.0: + resolution: {integrity: sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==} semver@6.3.1: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} @@ -3086,6 +3067,9 @@ packages: engines: {node: '>=10'} hasBin: true + set-cookie-parser@2.7.1: + resolution: {integrity: sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==} + set-function-length@1.2.2: resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} engines: {node: '>= 0.4'} @@ -3205,8 +3189,8 @@ packages: tailwind-merge@3.3.1: resolution: {integrity: sha512-gBXpgUm/3rp1lMZZrM/w7D8GKqshif0zAymAhbCyIt8KMe+0v9DQ7cdYLR4FHH/cKpdTXb+A/tKKU3eolfsI+g==} - tailwindcss@4.1.12: - resolution: {integrity: sha512-DzFtxOi+7NsFf7DBtI3BJsynR+0Yp6etH+nRPTbpWnS2pZBaSksv/JGctNwSWzbFjp0vxSqknaUylseZqMDGrA==} + tailwindcss@4.1.13: + resolution: {integrity: sha512-i+zidfmTqtwquj4hMEwdjshYYgMbOrPzb9a0M3ZgNa0JMoZeFC6bxZvO8yr8ozS6ix2SDz0+mvryPeBs2TFE+w==} tapable@2.2.3: resolution: {integrity: sha512-ZL6DDuAlRlLGghwcfmSn9sK3Hr6ArtyudlSAiCqQ6IfE+b+HHbydbYDIG15IfS5do+7XQQBdBiubF/cV2dnDzg==} @@ -3313,15 +3297,15 @@ packages: resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==} engines: {node: '>= 0.4'} - typescript-eslint@8.41.0: - resolution: {integrity: sha512-n66rzs5OBXW3SFSnZHr2T685q1i4ODm2nulFJhMZBotaTavsS8TrI3d7bDlRSs9yWo7HmyWrN9qDu14Qv7Y0Dw==} + typescript-eslint@8.42.0: + resolution: {integrity: sha512-ozR/rQn+aQXQxh1YgbCzQWDFrsi9mcg+1PM3l/z5o1+20P7suOIaNg515bpr/OYt6FObz/NHcBstydDLHWeEKg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - typescript@5.8.3: - resolution: {integrity: sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==} + typescript@5.9.2: + resolution: {integrity: sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==} engines: {node: '>=14.17'} hasBin: true @@ -3368,8 +3352,8 @@ packages: vite: optional: true - vite@7.1.3: - resolution: {integrity: sha512-OOUi5zjkDxYrKhTV3V7iKsoS37VUM7v40+HuwEmcrsf11Cdx9y3DIr2Px6liIcZFwt3XSRpQvFpL3WVy7ApkGw==} + vite@7.1.4: + resolution: {integrity: sha512-X5QFK4SGynAeeIt+A7ZWnApdUyHYm+pzv/8/A57LqSGcI88U6R6ipOs3uCesdc6yl7nl+zNO0t8LmqAdXcQihw==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: @@ -3588,7 +3572,7 @@ snapshots: '@alloc/quick-lru@5.2.0': {} - '@apollo/client@4.0.4(graphql@16.11.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rxjs@7.8.2)': + '@apollo/client@4.0.4(graphql@16.11.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(rxjs@7.8.2)': dependencies: '@graphql-typed-document-node/core': 3.2.0(graphql@16.11.0) '@wry/caches': 1.0.1 @@ -3600,8 +3584,8 @@ snapshots: rxjs: 7.8.2 tslib: 2.8.1 optionalDependencies: - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) '@asamuzakjp/css-color@3.2.0': dependencies: @@ -3713,25 +3697,25 @@ snapshots: '@emotion/hash@0.9.2': {} - '@emotion/is-prop-valid@1.3.1': + '@emotion/is-prop-valid@1.4.0': dependencies: '@emotion/memoize': 0.9.0 '@emotion/memoize@0.9.0': {} - '@emotion/react@11.14.0(@types/react@18.3.20)(react@18.3.1)': + '@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1)': dependencies: '@babel/runtime': 7.28.3 '@emotion/babel-plugin': 11.13.5 '@emotion/cache': 11.14.0 '@emotion/serialize': 1.3.3 - '@emotion/use-insertion-effect-with-fallbacks': 1.2.0(react@18.3.1) + '@emotion/use-insertion-effect-with-fallbacks': 1.2.0(react@19.1.1) '@emotion/utils': 1.4.2 '@emotion/weak-memoize': 0.4.0 hoist-non-react-statics: 3.3.2 - react: 18.3.1 + react: 19.1.1 optionalDependencies: - '@types/react': 18.3.20 + '@types/react': 19.1.12 transitivePeerDependencies: - supports-color @@ -3745,26 +3729,26 @@ snapshots: '@emotion/sheet@1.4.0': {} - '@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@18.3.20)(react@18.3.1))(@types/react@18.3.20)(react@18.3.1)': + '@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@types/react@19.1.12)(react@19.1.1)': dependencies: '@babel/runtime': 7.28.3 '@emotion/babel-plugin': 11.13.5 - '@emotion/is-prop-valid': 1.3.1 - '@emotion/react': 11.14.0(@types/react@18.3.20)(react@18.3.1) + '@emotion/is-prop-valid': 1.4.0 + '@emotion/react': 11.14.0(@types/react@19.1.12)(react@19.1.1) '@emotion/serialize': 1.3.3 - '@emotion/use-insertion-effect-with-fallbacks': 1.2.0(react@18.3.1) + '@emotion/use-insertion-effect-with-fallbacks': 1.2.0(react@19.1.1) '@emotion/utils': 1.4.2 - react: 18.3.1 + react: 19.1.1 optionalDependencies: - '@types/react': 18.3.20 + '@types/react': 19.1.12 transitivePeerDependencies: - supports-color '@emotion/unitless@0.10.0': {} - '@emotion/use-insertion-effect-with-fallbacks@1.2.0(react@18.3.1)': + '@emotion/use-insertion-effect-with-fallbacks@1.2.0(react@19.1.1)': dependencies: - react: 18.3.1 + react: 19.1.1 '@emotion/utils@1.4.2': {} @@ -3848,7 +3832,7 @@ snapshots: '@esbuild/win32-x64@0.25.9': optional: true - '@eslint-community/eslint-utils@4.7.0(eslint@9.34.0(jiti@2.5.1))': + '@eslint-community/eslint-utils@4.8.0(eslint@9.34.0(jiti@2.5.1))': dependencies: eslint: 9.34.0(jiti@2.5.1) eslint-visitor-keys: 3.4.3 @@ -3898,33 +3882,31 @@ snapshots: dependencies: graphql: 16.11.0 - '@hello-pangea/dnd@18.0.1(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@hello-pangea/dnd@18.0.1(@types/react@19.1.12)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': dependencies: '@babel/runtime': 7.28.3 css-box-model: 1.2.1 raf-schd: 4.0.3 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - react-redux: 9.2.0(@types/react@18.3.20)(react@18.3.1)(redux@5.0.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + react-redux: 9.2.0(@types/react@19.1.12)(react@19.1.1)(redux@5.0.1) redux: 5.0.1 transitivePeerDependencies: - '@types/react' - '@heroicons/react@2.2.0(react@18.3.1)': + '@heroicons/react@2.2.0(react@19.1.1)': dependencies: - react: 18.3.1 + react: 19.1.1 '@humanfs/core@0.19.1': {} - '@humanfs/node@0.16.6': + '@humanfs/node@0.16.7': dependencies: '@humanfs/core': 0.19.1 - '@humanwhocodes/retry': 0.3.1 + '@humanwhocodes/retry': 0.4.3 '@humanwhocodes/module-importer@1.0.1': {} - '@humanwhocodes/retry@0.3.1': {} - '@humanwhocodes/retry@0.4.3': {} '@isaacs/fs-minipass@4.0.1': @@ -3950,63 +3932,63 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.5 - '@mui/core-downloads-tracker@7.3.1': {} + '@mui/core-downloads-tracker@7.3.2': {} - '@mui/icons-material@7.3.1(@mui/material@7.3.1(@emotion/react@11.14.0(@types/react@18.3.20)(react@18.3.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@18.3.20)(react@18.3.1))(@types/react@18.3.20)(react@18.3.1))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.20)(react@18.3.1)': + '@mui/icons-material@7.3.2(@mui/material@7.3.2(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@types/react@19.1.12)(react@19.1.1))(@types/react@19.1.12)(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(@types/react@19.1.12)(react@19.1.1)': dependencies: '@babel/runtime': 7.28.3 - '@mui/material': 7.3.1(@emotion/react@11.14.0(@types/react@18.3.20)(react@18.3.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@18.3.20)(react@18.3.1))(@types/react@18.3.20)(react@18.3.1))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 + '@mui/material': 7.3.2(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@types/react@19.1.12)(react@19.1.1))(@types/react@19.1.12)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + react: 19.1.1 optionalDependencies: - '@types/react': 18.3.20 + '@types/react': 19.1.12 - '@mui/lab@7.0.0-beta.16(@emotion/react@11.14.0(@types/react@18.3.20)(react@18.3.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@18.3.20)(react@18.3.1))(@types/react@18.3.20)(react@18.3.1))(@mui/material@7.3.1(@emotion/react@11.14.0(@types/react@18.3.20)(react@18.3.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@18.3.20)(react@18.3.1))(@types/react@18.3.20)(react@18.3.1))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@mui/lab@7.0.0-beta.17(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@types/react@19.1.12)(react@19.1.1))(@mui/material@7.3.2(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@types/react@19.1.12)(react@19.1.1))(@types/react@19.1.12)(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(@types/react@19.1.12)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': dependencies: '@babel/runtime': 7.28.3 - '@mui/material': 7.3.1(@emotion/react@11.14.0(@types/react@18.3.20)(react@18.3.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@18.3.20)(react@18.3.1))(@types/react@18.3.20)(react@18.3.1))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@mui/system': 7.3.1(@emotion/react@11.14.0(@types/react@18.3.20)(react@18.3.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@18.3.20)(react@18.3.1))(@types/react@18.3.20)(react@18.3.1))(@types/react@18.3.20)(react@18.3.1) - '@mui/types': 7.4.5(@types/react@18.3.20) - '@mui/utils': 7.3.1(@types/react@18.3.20)(react@18.3.1) + '@mui/material': 7.3.2(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@types/react@19.1.12)(react@19.1.1))(@types/react@19.1.12)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@mui/system': 7.3.2(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@types/react@19.1.12)(react@19.1.1))(@types/react@19.1.12)(react@19.1.1) + '@mui/types': 7.4.6(@types/react@19.1.12) + '@mui/utils': 7.3.2(@types/react@19.1.12)(react@19.1.1) clsx: 2.1.1 prop-types: 15.8.1 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) optionalDependencies: - '@emotion/react': 11.14.0(@types/react@18.3.20)(react@18.3.1) - '@emotion/styled': 11.14.1(@emotion/react@11.14.0(@types/react@18.3.20)(react@18.3.1))(@types/react@18.3.20)(react@18.3.1) - '@types/react': 18.3.20 + '@emotion/react': 11.14.0(@types/react@19.1.12)(react@19.1.1) + '@emotion/styled': 11.14.1(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@types/react@19.1.12)(react@19.1.1) + '@types/react': 19.1.12 - '@mui/material@7.3.1(@emotion/react@11.14.0(@types/react@18.3.20)(react@18.3.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@18.3.20)(react@18.3.1))(@types/react@18.3.20)(react@18.3.1))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@mui/material@7.3.2(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@types/react@19.1.12)(react@19.1.1))(@types/react@19.1.12)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': dependencies: '@babel/runtime': 7.28.3 - '@mui/core-downloads-tracker': 7.3.1 - '@mui/system': 7.3.1(@emotion/react@11.14.0(@types/react@18.3.20)(react@18.3.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@18.3.20)(react@18.3.1))(@types/react@18.3.20)(react@18.3.1))(@types/react@18.3.20)(react@18.3.1) - '@mui/types': 7.4.5(@types/react@18.3.20) - '@mui/utils': 7.3.1(@types/react@18.3.20)(react@18.3.1) + '@mui/core-downloads-tracker': 7.3.2 + '@mui/system': 7.3.2(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@types/react@19.1.12)(react@19.1.1))(@types/react@19.1.12)(react@19.1.1) + '@mui/types': 7.4.6(@types/react@19.1.12) + '@mui/utils': 7.3.2(@types/react@19.1.12)(react@19.1.1) '@popperjs/core': 2.11.8 - '@types/react-transition-group': 4.4.12(@types/react@18.3.20) + '@types/react-transition-group': 4.4.12(@types/react@19.1.12) clsx: 2.1.1 csstype: 3.1.3 prop-types: 15.8.1 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) react-is: 19.1.1 - react-transition-group: 4.4.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react-transition-group: 4.4.5(react-dom@19.1.1(react@19.1.1))(react@19.1.1) optionalDependencies: - '@emotion/react': 11.14.0(@types/react@18.3.20)(react@18.3.1) - '@emotion/styled': 11.14.1(@emotion/react@11.14.0(@types/react@18.3.20)(react@18.3.1))(@types/react@18.3.20)(react@18.3.1) - '@types/react': 18.3.20 + '@emotion/react': 11.14.0(@types/react@19.1.12)(react@19.1.1) + '@emotion/styled': 11.14.1(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@types/react@19.1.12)(react@19.1.1) + '@types/react': 19.1.12 - '@mui/private-theming@7.3.1(@types/react@18.3.20)(react@18.3.1)': + '@mui/private-theming@7.3.2(@types/react@19.1.12)(react@19.1.1)': dependencies: '@babel/runtime': 7.28.3 - '@mui/utils': 7.3.1(@types/react@18.3.20)(react@18.3.1) + '@mui/utils': 7.3.2(@types/react@19.1.12)(react@19.1.1) prop-types: 15.8.1 - react: 18.3.1 + react: 19.1.1 optionalDependencies: - '@types/react': 18.3.20 + '@types/react': 19.1.12 - '@mui/styled-engine@7.3.1(@emotion/react@11.14.0(@types/react@18.3.20)(react@18.3.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@18.3.20)(react@18.3.1))(@types/react@18.3.20)(react@18.3.1))(react@18.3.1)': + '@mui/styled-engine@7.3.2(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@types/react@19.1.12)(react@19.1.1))(react@19.1.1)': dependencies: '@babel/runtime': 7.28.3 '@emotion/cache': 11.14.0 @@ -4014,73 +3996,73 @@ snapshots: '@emotion/sheet': 1.4.0 csstype: 3.1.3 prop-types: 15.8.1 - react: 18.3.1 + react: 19.1.1 optionalDependencies: - '@emotion/react': 11.14.0(@types/react@18.3.20)(react@18.3.1) - '@emotion/styled': 11.14.1(@emotion/react@11.14.0(@types/react@18.3.20)(react@18.3.1))(@types/react@18.3.20)(react@18.3.1) + '@emotion/react': 11.14.0(@types/react@19.1.12)(react@19.1.1) + '@emotion/styled': 11.14.1(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@types/react@19.1.12)(react@19.1.1) - '@mui/system@7.3.1(@emotion/react@11.14.0(@types/react@18.3.20)(react@18.3.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@18.3.20)(react@18.3.1))(@types/react@18.3.20)(react@18.3.1))(@types/react@18.3.20)(react@18.3.1)': + '@mui/system@7.3.2(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@types/react@19.1.12)(react@19.1.1))(@types/react@19.1.12)(react@19.1.1)': dependencies: '@babel/runtime': 7.28.3 - '@mui/private-theming': 7.3.1(@types/react@18.3.20)(react@18.3.1) - '@mui/styled-engine': 7.3.1(@emotion/react@11.14.0(@types/react@18.3.20)(react@18.3.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@18.3.20)(react@18.3.1))(@types/react@18.3.20)(react@18.3.1))(react@18.3.1) - '@mui/types': 7.4.5(@types/react@18.3.20) - '@mui/utils': 7.3.1(@types/react@18.3.20)(react@18.3.1) + '@mui/private-theming': 7.3.2(@types/react@19.1.12)(react@19.1.1) + '@mui/styled-engine': 7.3.2(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@types/react@19.1.12)(react@19.1.1))(react@19.1.1) + '@mui/types': 7.4.6(@types/react@19.1.12) + '@mui/utils': 7.3.2(@types/react@19.1.12)(react@19.1.1) clsx: 2.1.1 csstype: 3.1.3 prop-types: 15.8.1 - react: 18.3.1 + react: 19.1.1 optionalDependencies: - '@emotion/react': 11.14.0(@types/react@18.3.20)(react@18.3.1) - '@emotion/styled': 11.14.1(@emotion/react@11.14.0(@types/react@18.3.20)(react@18.3.1))(@types/react@18.3.20)(react@18.3.1) - '@types/react': 18.3.20 + '@emotion/react': 11.14.0(@types/react@19.1.12)(react@19.1.1) + '@emotion/styled': 11.14.1(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@types/react@19.1.12)(react@19.1.1) + '@types/react': 19.1.12 - '@mui/types@7.4.5(@types/react@18.3.20)': + '@mui/types@7.4.6(@types/react@19.1.12)': dependencies: '@babel/runtime': 7.28.3 optionalDependencies: - '@types/react': 18.3.20 + '@types/react': 19.1.12 - '@mui/utils@7.3.1(@types/react@18.3.20)(react@18.3.1)': + '@mui/utils@7.3.2(@types/react@19.1.12)(react@19.1.1)': dependencies: '@babel/runtime': 7.28.3 - '@mui/types': 7.4.5(@types/react@18.3.20) + '@mui/types': 7.4.6(@types/react@19.1.12) '@types/prop-types': 15.7.15 clsx: 2.1.1 prop-types: 15.8.1 - react: 18.3.1 + react: 19.1.1 react-is: 19.1.1 optionalDependencies: - '@types/react': 18.3.20 + '@types/react': 19.1.12 - '@mui/x-date-pickers@8.11.0(@emotion/react@11.14.0(@types/react@18.3.20)(react@18.3.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@18.3.20)(react@18.3.1))(@types/react@18.3.20)(react@18.3.1))(@mui/material@7.3.1(@emotion/react@11.14.0(@types/react@18.3.20)(react@18.3.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@18.3.20)(react@18.3.1))(@types/react@18.3.20)(react@18.3.1))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mui/system@7.3.1(@emotion/react@11.14.0(@types/react@18.3.20)(react@18.3.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@18.3.20)(react@18.3.1))(@types/react@18.3.20)(react@18.3.1))(@types/react@18.3.20)(react@18.3.1))(@types/react@18.3.20)(date-fns@4.1.0)(dayjs@1.11.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@mui/x-date-pickers@8.11.1(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@types/react@19.1.12)(react@19.1.1))(@mui/material@7.3.2(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@types/react@19.1.12)(react@19.1.1))(@types/react@19.1.12)(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(@mui/system@7.3.2(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@types/react@19.1.12)(react@19.1.1))(@types/react@19.1.12)(react@19.1.1))(@types/react@19.1.12)(date-fns@4.1.0)(dayjs@1.11.18)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': dependencies: '@babel/runtime': 7.28.3 - '@mui/material': 7.3.1(@emotion/react@11.14.0(@types/react@18.3.20)(react@18.3.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@18.3.20)(react@18.3.1))(@types/react@18.3.20)(react@18.3.1))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@mui/system': 7.3.1(@emotion/react@11.14.0(@types/react@18.3.20)(react@18.3.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@18.3.20)(react@18.3.1))(@types/react@18.3.20)(react@18.3.1))(@types/react@18.3.20)(react@18.3.1) - '@mui/utils': 7.3.1(@types/react@18.3.20)(react@18.3.1) - '@mui/x-internals': 8.11.0(@types/react@18.3.20)(react@18.3.1) - '@types/react-transition-group': 4.4.12(@types/react@18.3.20) + '@mui/material': 7.3.2(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@types/react@19.1.12)(react@19.1.1))(@types/react@19.1.12)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@mui/system': 7.3.2(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@types/react@19.1.12)(react@19.1.1))(@types/react@19.1.12)(react@19.1.1) + '@mui/utils': 7.3.2(@types/react@19.1.12)(react@19.1.1) + '@mui/x-internals': 8.11.1(@types/react@19.1.12)(react@19.1.1) + '@types/react-transition-group': 4.4.12(@types/react@19.1.12) clsx: 2.1.1 prop-types: 15.8.1 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - react-transition-group: 4.4.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + react-transition-group: 4.4.5(react-dom@19.1.1(react@19.1.1))(react@19.1.1) optionalDependencies: - '@emotion/react': 11.14.0(@types/react@18.3.20)(react@18.3.1) - '@emotion/styled': 11.14.1(@emotion/react@11.14.0(@types/react@18.3.20)(react@18.3.1))(@types/react@18.3.20)(react@18.3.1) + '@emotion/react': 11.14.0(@types/react@19.1.12)(react@19.1.1) + '@emotion/styled': 11.14.1(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@types/react@19.1.12)(react@19.1.1) date-fns: 4.1.0 dayjs: 1.11.18 transitivePeerDependencies: - '@types/react' - '@mui/x-internals@8.11.0(@types/react@18.3.20)(react@18.3.1)': + '@mui/x-internals@8.11.1(@types/react@19.1.12)(react@19.1.1)': dependencies: '@babel/runtime': 7.28.3 - '@mui/utils': 7.3.1(@types/react@18.3.20)(react@18.3.1) - react: 18.3.1 + '@mui/utils': 7.3.2(@types/react@19.1.12)(react@19.1.1) + react: 19.1.1 reselect: 5.1.1 - use-sync-external-store: 1.5.0(react@18.3.1) + use-sync-external-store: 1.5.0(react@19.1.1) transitivePeerDependencies: - '@types/react' @@ -4106,30 +4088,35 @@ snapshots: '@opentelemetry/api@1.9.0': {} - '@opentelemetry/context-async-hooks@2.0.1(@opentelemetry/api@1.9.0)': + '@opentelemetry/context-async-hooks@2.1.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 '@opentelemetry/core@2.0.1(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/semantic-conventions': 1.36.0 + '@opentelemetry/semantic-conventions': 1.37.0 + + '@opentelemetry/core@2.1.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/semantic-conventions': 1.37.0 '@opentelemetry/instrumentation-amqplib@0.50.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 2.1.0(@opentelemetry/api@1.9.0) '@opentelemetry/instrumentation': 0.203.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.36.0 + '@opentelemetry/semantic-conventions': 1.37.0 transitivePeerDependencies: - supports-color '@opentelemetry/instrumentation-connect@0.47.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 2.1.0(@opentelemetry/api@1.9.0) '@opentelemetry/instrumentation': 0.203.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.36.0 + '@opentelemetry/semantic-conventions': 1.37.0 '@types/connect': 3.4.38 transitivePeerDependencies: - supports-color @@ -4144,16 +4131,16 @@ snapshots: '@opentelemetry/instrumentation-express@0.52.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 2.1.0(@opentelemetry/api@1.9.0) '@opentelemetry/instrumentation': 0.203.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.36.0 + '@opentelemetry/semantic-conventions': 1.37.0 transitivePeerDependencies: - supports-color '@opentelemetry/instrumentation-fs@0.23.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 2.1.0(@opentelemetry/api@1.9.0) '@opentelemetry/instrumentation': 0.203.0(@opentelemetry/api@1.9.0) transitivePeerDependencies: - supports-color @@ -4175,9 +4162,9 @@ snapshots: '@opentelemetry/instrumentation-hapi@0.50.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 2.1.0(@opentelemetry/api@1.9.0) '@opentelemetry/instrumentation': 0.203.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.36.0 + '@opentelemetry/semantic-conventions': 1.37.0 transitivePeerDependencies: - supports-color @@ -4186,7 +4173,7 @@ snapshots: '@opentelemetry/api': 1.9.0 '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) '@opentelemetry/instrumentation': 0.203.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.36.0 + '@opentelemetry/semantic-conventions': 1.37.0 forwarded-parse: 2.1.2 transitivePeerDependencies: - supports-color @@ -4196,7 +4183,7 @@ snapshots: '@opentelemetry/api': 1.9.0 '@opentelemetry/instrumentation': 0.203.0(@opentelemetry/api@1.9.0) '@opentelemetry/redis-common': 0.38.0 - '@opentelemetry/semantic-conventions': 1.36.0 + '@opentelemetry/semantic-conventions': 1.37.0 transitivePeerDependencies: - supports-color @@ -4204,7 +4191,7 @@ snapshots: dependencies: '@opentelemetry/api': 1.9.0 '@opentelemetry/instrumentation': 0.203.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.36.0 + '@opentelemetry/semantic-conventions': 1.37.0 transitivePeerDependencies: - supports-color @@ -4212,16 +4199,16 @@ snapshots: dependencies: '@opentelemetry/api': 1.9.0 '@opentelemetry/instrumentation': 0.203.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.36.0 + '@opentelemetry/semantic-conventions': 1.37.0 transitivePeerDependencies: - supports-color '@opentelemetry/instrumentation-koa@0.51.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 2.1.0(@opentelemetry/api@1.9.0) '@opentelemetry/instrumentation': 0.203.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.36.0 + '@opentelemetry/semantic-conventions': 1.37.0 transitivePeerDependencies: - supports-color @@ -4236,16 +4223,16 @@ snapshots: dependencies: '@opentelemetry/api': 1.9.0 '@opentelemetry/instrumentation': 0.203.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.36.0 + '@opentelemetry/semantic-conventions': 1.37.0 transitivePeerDependencies: - supports-color '@opentelemetry/instrumentation-mongoose@0.50.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 2.1.0(@opentelemetry/api@1.9.0) '@opentelemetry/instrumentation': 0.203.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.36.0 + '@opentelemetry/semantic-conventions': 1.37.0 transitivePeerDependencies: - supports-color @@ -4253,7 +4240,7 @@ snapshots: dependencies: '@opentelemetry/api': 1.9.0 '@opentelemetry/instrumentation': 0.203.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.36.0 + '@opentelemetry/semantic-conventions': 1.37.0 '@opentelemetry/sql-common': 0.41.0(@opentelemetry/api@1.9.0) transitivePeerDependencies: - supports-color @@ -4262,7 +4249,7 @@ snapshots: dependencies: '@opentelemetry/api': 1.9.0 '@opentelemetry/instrumentation': 0.203.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.36.0 + '@opentelemetry/semantic-conventions': 1.37.0 '@types/mysql': 2.15.27 transitivePeerDependencies: - supports-color @@ -4270,9 +4257,9 @@ snapshots: '@opentelemetry/instrumentation-pg@0.55.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 2.1.0(@opentelemetry/api@1.9.0) '@opentelemetry/instrumentation': 0.203.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.36.0 + '@opentelemetry/semantic-conventions': 1.37.0 '@opentelemetry/sql-common': 0.41.0(@opentelemetry/api@1.9.0) '@types/pg': 8.15.4 '@types/pg-pool': 2.0.6 @@ -4284,7 +4271,7 @@ snapshots: '@opentelemetry/api': 1.9.0 '@opentelemetry/instrumentation': 0.203.0(@opentelemetry/api@1.9.0) '@opentelemetry/redis-common': 0.38.0 - '@opentelemetry/semantic-conventions': 1.36.0 + '@opentelemetry/semantic-conventions': 1.37.0 transitivePeerDependencies: - supports-color @@ -4292,7 +4279,7 @@ snapshots: dependencies: '@opentelemetry/api': 1.9.0 '@opentelemetry/instrumentation': 0.203.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.36.0 + '@opentelemetry/semantic-conventions': 1.37.0 '@types/tedious': 4.0.14 transitivePeerDependencies: - supports-color @@ -4300,7 +4287,7 @@ snapshots: '@opentelemetry/instrumentation-undici@0.14.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 2.1.0(@opentelemetry/api@1.9.0) '@opentelemetry/instrumentation': 0.203.0(@opentelemetry/api@1.9.0) transitivePeerDependencies: - supports-color @@ -4328,25 +4315,25 @@ snapshots: '@opentelemetry/redis-common@0.38.0': {} - '@opentelemetry/resources@2.0.1(@opentelemetry/api@1.9.0)': + '@opentelemetry/resources@2.1.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.36.0 + '@opentelemetry/core': 2.1.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.37.0 - '@opentelemetry/sdk-trace-base@2.0.1(@opentelemetry/api@1.9.0)': + '@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.36.0 + '@opentelemetry/core': 2.1.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.1.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.37.0 - '@opentelemetry/semantic-conventions@1.36.0': {} + '@opentelemetry/semantic-conventions@1.37.0': {} '@opentelemetry/sql-common@0.41.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 2.1.0(@opentelemetry/api@1.9.0) '@pkgr/core@0.2.9': {} @@ -4359,8 +4346,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@remix-run/router@1.23.0': {} - '@rolldown/pluginutils@1.0.0-beta.32': {} '@rollup/rollup-android-arm-eabi@4.50.0': @@ -4426,52 +4411,52 @@ snapshots: '@rollup/rollup-win32-x64-msvc@4.50.0': optional: true - '@sentry-internal/browser-utils@10.8.0': + '@sentry-internal/browser-utils@10.10.0': dependencies: - '@sentry/core': 10.8.0 + '@sentry/core': 10.10.0 - '@sentry-internal/feedback@10.8.0': + '@sentry-internal/feedback@10.10.0': dependencies: - '@sentry/core': 10.8.0 + '@sentry/core': 10.10.0 - '@sentry-internal/replay-canvas@10.8.0': + '@sentry-internal/replay-canvas@10.10.0': dependencies: - '@sentry-internal/replay': 10.8.0 - '@sentry/core': 10.8.0 + '@sentry-internal/replay': 10.10.0 + '@sentry/core': 10.10.0 - '@sentry-internal/replay@10.8.0': + '@sentry-internal/replay@10.10.0': dependencies: - '@sentry-internal/browser-utils': 10.8.0 - '@sentry/core': 10.8.0 + '@sentry-internal/browser-utils': 10.10.0 + '@sentry/core': 10.10.0 - '@sentry/browser@10.8.0': + '@sentry/browser@10.10.0': dependencies: - '@sentry-internal/browser-utils': 10.8.0 - '@sentry-internal/feedback': 10.8.0 - '@sentry-internal/replay': 10.8.0 - '@sentry-internal/replay-canvas': 10.8.0 - '@sentry/core': 10.8.0 + '@sentry-internal/browser-utils': 10.10.0 + '@sentry-internal/feedback': 10.10.0 + '@sentry-internal/replay': 10.10.0 + '@sentry-internal/replay-canvas': 10.10.0 + '@sentry/core': 10.10.0 - '@sentry/core@10.8.0': {} + '@sentry/core@10.10.0': {} - '@sentry/node-core@10.8.0(@opentelemetry/api@1.9.0)(@opentelemetry/context-async-hooks@2.0.1(@opentelemetry/api@1.9.0))(@opentelemetry/core@2.0.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/resources@2.0.1(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.0.1(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.36.0)': + '@sentry/node-core@10.10.0(@opentelemetry/api@1.9.0)(@opentelemetry/context-async-hooks@2.1.0(@opentelemetry/api@1.9.0))(@opentelemetry/core@2.1.0(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/resources@2.1.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.37.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/context-async-hooks': 2.0.1(@opentelemetry/api@1.9.0) - '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/context-async-hooks': 2.1.0(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 2.1.0(@opentelemetry/api@1.9.0) '@opentelemetry/instrumentation': 0.203.0(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-trace-base': 2.0.1(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.36.0 - '@sentry/core': 10.8.0 - '@sentry/opentelemetry': 10.8.0(@opentelemetry/api@1.9.0)(@opentelemetry/context-async-hooks@2.0.1(@opentelemetry/api@1.9.0))(@opentelemetry/core@2.0.1(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.0.1(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.36.0) + '@opentelemetry/resources': 2.1.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-base': 2.1.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.37.0 + '@sentry/core': 10.10.0 + '@sentry/opentelemetry': 10.10.0(@opentelemetry/api@1.9.0)(@opentelemetry/context-async-hooks@2.1.0(@opentelemetry/api@1.9.0))(@opentelemetry/core@2.1.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.37.0) import-in-the-middle: 1.14.2 - '@sentry/node@10.8.0': + '@sentry/node@10.10.0': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/context-async-hooks': 2.0.1(@opentelemetry/api@1.9.0) - '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/context-async-hooks': 2.1.0(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 2.1.0(@opentelemetry/api@1.9.0) '@opentelemetry/instrumentation': 0.203.0(@opentelemetry/api@1.9.0) '@opentelemetry/instrumentation-amqplib': 0.50.0(@opentelemetry/api@1.9.0) '@opentelemetry/instrumentation-connect': 0.47.0(@opentelemetry/api@1.9.0) @@ -4495,33 +4480,33 @@ snapshots: '@opentelemetry/instrumentation-redis': 0.51.0(@opentelemetry/api@1.9.0) '@opentelemetry/instrumentation-tedious': 0.22.0(@opentelemetry/api@1.9.0) '@opentelemetry/instrumentation-undici': 0.14.0(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-trace-base': 2.0.1(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.36.0 + '@opentelemetry/resources': 2.1.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-base': 2.1.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.37.0 '@prisma/instrumentation': 6.14.0(@opentelemetry/api@1.9.0) - '@sentry/core': 10.8.0 - '@sentry/node-core': 10.8.0(@opentelemetry/api@1.9.0)(@opentelemetry/context-async-hooks@2.0.1(@opentelemetry/api@1.9.0))(@opentelemetry/core@2.0.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/resources@2.0.1(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.0.1(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.36.0) - '@sentry/opentelemetry': 10.8.0(@opentelemetry/api@1.9.0)(@opentelemetry/context-async-hooks@2.0.1(@opentelemetry/api@1.9.0))(@opentelemetry/core@2.0.1(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.0.1(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.36.0) + '@sentry/core': 10.10.0 + '@sentry/node-core': 10.10.0(@opentelemetry/api@1.9.0)(@opentelemetry/context-async-hooks@2.1.0(@opentelemetry/api@1.9.0))(@opentelemetry/core@2.1.0(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/resources@2.1.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.37.0) + '@sentry/opentelemetry': 10.10.0(@opentelemetry/api@1.9.0)(@opentelemetry/context-async-hooks@2.1.0(@opentelemetry/api@1.9.0))(@opentelemetry/core@2.1.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.37.0) import-in-the-middle: 1.14.2 minimatch: 9.0.5 transitivePeerDependencies: - supports-color - '@sentry/opentelemetry@10.8.0(@opentelemetry/api@1.9.0)(@opentelemetry/context-async-hooks@2.0.1(@opentelemetry/api@1.9.0))(@opentelemetry/core@2.0.1(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.0.1(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.36.0)': + '@sentry/opentelemetry@10.10.0(@opentelemetry/api@1.9.0)(@opentelemetry/context-async-hooks@2.1.0(@opentelemetry/api@1.9.0))(@opentelemetry/core@2.1.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.37.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/context-async-hooks': 2.0.1(@opentelemetry/api@1.9.0) - '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-trace-base': 2.0.1(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.36.0 - '@sentry/core': 10.8.0 + '@opentelemetry/context-async-hooks': 2.1.0(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 2.1.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-base': 2.1.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.37.0 + '@sentry/core': 10.10.0 - '@sentry/react@10.8.0(react@18.3.1)': + '@sentry/react@10.10.0(react@19.1.1)': dependencies: - '@sentry/browser': 10.8.0 - '@sentry/core': 10.8.0 + '@sentry/browser': 10.10.0 + '@sentry/core': 10.10.0 hoist-non-react-statics: 3.3.2 - react: 18.3.1 + react: 19.1.1 '@swc/core-darwin-arm64@1.13.5': optional: true @@ -4575,7 +4560,7 @@ snapshots: dependencies: '@swc/counter': 0.1.3 - '@tailwindcss/node@4.1.12': + '@tailwindcss/node@4.1.13': dependencies: '@jridgewell/remapping': 2.3.5 enhanced-resolve: 5.18.3 @@ -4583,92 +4568,92 @@ snapshots: lightningcss: 1.30.1 magic-string: 0.30.18 source-map-js: 1.2.1 - tailwindcss: 4.1.12 + tailwindcss: 4.1.13 - '@tailwindcss/oxide-android-arm64@4.1.12': + '@tailwindcss/oxide-android-arm64@4.1.13': optional: true - '@tailwindcss/oxide-darwin-arm64@4.1.12': + '@tailwindcss/oxide-darwin-arm64@4.1.13': optional: true - '@tailwindcss/oxide-darwin-x64@4.1.12': + '@tailwindcss/oxide-darwin-x64@4.1.13': optional: true - '@tailwindcss/oxide-freebsd-x64@4.1.12': + '@tailwindcss/oxide-freebsd-x64@4.1.13': optional: true - '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.12': + '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.13': optional: true - '@tailwindcss/oxide-linux-arm64-gnu@4.1.12': + '@tailwindcss/oxide-linux-arm64-gnu@4.1.13': optional: true - '@tailwindcss/oxide-linux-arm64-musl@4.1.12': + '@tailwindcss/oxide-linux-arm64-musl@4.1.13': optional: true - '@tailwindcss/oxide-linux-x64-gnu@4.1.12': + '@tailwindcss/oxide-linux-x64-gnu@4.1.13': optional: true - '@tailwindcss/oxide-linux-x64-musl@4.1.12': + '@tailwindcss/oxide-linux-x64-musl@4.1.13': optional: true - '@tailwindcss/oxide-wasm32-wasi@4.1.12': + '@tailwindcss/oxide-wasm32-wasi@4.1.13': optional: true - '@tailwindcss/oxide-win32-arm64-msvc@4.1.12': + '@tailwindcss/oxide-win32-arm64-msvc@4.1.13': optional: true - '@tailwindcss/oxide-win32-x64-msvc@4.1.12': + '@tailwindcss/oxide-win32-x64-msvc@4.1.13': optional: true - '@tailwindcss/oxide@4.1.12': + '@tailwindcss/oxide@4.1.13': dependencies: detect-libc: 2.0.4 tar: 7.4.3 optionalDependencies: - '@tailwindcss/oxide-android-arm64': 4.1.12 - '@tailwindcss/oxide-darwin-arm64': 4.1.12 - '@tailwindcss/oxide-darwin-x64': 4.1.12 - '@tailwindcss/oxide-freebsd-x64': 4.1.12 - '@tailwindcss/oxide-linux-arm-gnueabihf': 4.1.12 - '@tailwindcss/oxide-linux-arm64-gnu': 4.1.12 - '@tailwindcss/oxide-linux-arm64-musl': 4.1.12 - '@tailwindcss/oxide-linux-x64-gnu': 4.1.12 - '@tailwindcss/oxide-linux-x64-musl': 4.1.12 - '@tailwindcss/oxide-wasm32-wasi': 4.1.12 - '@tailwindcss/oxide-win32-arm64-msvc': 4.1.12 - '@tailwindcss/oxide-win32-x64-msvc': 4.1.12 - - '@tailwindcss/postcss@4.1.12': + '@tailwindcss/oxide-android-arm64': 4.1.13 + '@tailwindcss/oxide-darwin-arm64': 4.1.13 + '@tailwindcss/oxide-darwin-x64': 4.1.13 + '@tailwindcss/oxide-freebsd-x64': 4.1.13 + '@tailwindcss/oxide-linux-arm-gnueabihf': 4.1.13 + '@tailwindcss/oxide-linux-arm64-gnu': 4.1.13 + '@tailwindcss/oxide-linux-arm64-musl': 4.1.13 + '@tailwindcss/oxide-linux-x64-gnu': 4.1.13 + '@tailwindcss/oxide-linux-x64-musl': 4.1.13 + '@tailwindcss/oxide-wasm32-wasi': 4.1.13 + '@tailwindcss/oxide-win32-arm64-msvc': 4.1.13 + '@tailwindcss/oxide-win32-x64-msvc': 4.1.13 + + '@tailwindcss/postcss@4.1.13': dependencies: '@alloc/quick-lru': 5.2.0 - '@tailwindcss/node': 4.1.12 - '@tailwindcss/oxide': 4.1.12 + '@tailwindcss/node': 4.1.13 + '@tailwindcss/oxide': 4.1.13 postcss: 8.5.6 - tailwindcss: 4.1.12 + tailwindcss: 4.1.13 - '@tanstack/eslint-plugin-query@5.83.1(eslint@9.34.0(jiti@2.5.1))(typescript@5.8.3)': + '@tanstack/eslint-plugin-query@5.86.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2)': dependencies: - '@typescript-eslint/utils': 8.41.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.8.3) + '@typescript-eslint/utils': 8.42.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) eslint: 9.34.0(jiti@2.5.1) transitivePeerDependencies: - supports-color - typescript - '@tanstack/query-core@5.85.6': {} + '@tanstack/query-core@5.86.0': {} - '@tanstack/query-devtools@5.84.0': {} + '@tanstack/query-devtools@5.86.0': {} - '@tanstack/react-query-devtools@5.85.6(@tanstack/react-query@5.85.6(react@18.3.1))(react@18.3.1)': + '@tanstack/react-query-devtools@5.86.0(@tanstack/react-query@5.86.0(react@19.1.1))(react@19.1.1)': dependencies: - '@tanstack/query-devtools': 5.84.0 - '@tanstack/react-query': 5.85.6(react@18.3.1) - react: 18.3.1 + '@tanstack/query-devtools': 5.86.0 + '@tanstack/react-query': 5.86.0(react@19.1.1) + react: 19.1.1 - '@tanstack/react-query@5.85.6(react@18.3.1)': + '@tanstack/react-query@5.86.0(react@19.1.1)': dependencies: - '@tanstack/query-core': 5.85.6 - react: 18.3.1 + '@tanstack/query-core': 5.86.0 + react: 19.1.1 '@types/chai@5.2.2': dependencies: @@ -4684,8 +4669,6 @@ snapshots: '@types/file-saver@2.0.7': {} - '@types/history@4.7.11': {} - '@types/is-base64@1.1.3': {} '@types/json-schema@7.0.15': {} @@ -4718,32 +4701,20 @@ snapshots: '@types/prop-types@15.7.15': {} - '@types/react-dom@18.3.7(@types/react@18.3.20)': - dependencies: - '@types/react': 18.3.20 - - '@types/react-router-dom@5.3.3': - dependencies: - '@types/history': 4.7.11 - '@types/react': 18.3.20 - '@types/react-router': 5.1.20 - - '@types/react-router@5.1.20': + '@types/react-dom@19.1.9(@types/react@19.1.12)': dependencies: - '@types/history': 4.7.11 - '@types/react': 18.3.20 + '@types/react': 19.1.12 - '@types/react-transition-group@4.4.12(@types/react@18.3.20)': + '@types/react-transition-group@4.4.12(@types/react@19.1.12)': dependencies: - '@types/react': 18.3.20 + '@types/react': 19.1.12 '@types/react-window@1.8.8': dependencies: - '@types/react': 18.3.20 + '@types/react': 19.1.12 - '@types/react@18.3.20': + '@types/react@19.1.12': dependencies: - '@types/prop-types': 15.7.15 csstype: 3.1.3 '@types/shimmer@1.2.0': {} @@ -4754,208 +4725,208 @@ snapshots: '@types/use-sync-external-store@0.0.6': {} - '@typescript-eslint/eslint-plugin@8.41.0(@typescript-eslint/parser@8.41.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.8.3))(eslint@9.34.0(jiti@2.5.1))(typescript@5.8.3)': + '@typescript-eslint/eslint-plugin@8.42.0(@typescript-eslint/parser@8.42.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2)': dependencies: '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 8.41.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.8.3) - '@typescript-eslint/scope-manager': 8.41.0 - '@typescript-eslint/type-utils': 8.41.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.8.3) - '@typescript-eslint/utils': 8.41.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.8.3) - '@typescript-eslint/visitor-keys': 8.41.0 + '@typescript-eslint/parser': 8.42.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) + '@typescript-eslint/scope-manager': 8.42.0 + '@typescript-eslint/type-utils': 8.42.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) + '@typescript-eslint/utils': 8.42.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) + '@typescript-eslint/visitor-keys': 8.42.0 eslint: 9.34.0(jiti@2.5.1) graphemer: 1.4.0 ignore: 7.0.5 natural-compare: 1.4.0 - ts-api-utils: 2.1.0(typescript@5.8.3) - typescript: 5.8.3 + ts-api-utils: 2.1.0(typescript@5.9.2) + typescript: 5.9.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.41.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.8.3)': + '@typescript-eslint/parser@8.42.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2)': dependencies: - '@typescript-eslint/scope-manager': 8.41.0 - '@typescript-eslint/types': 8.41.0 - '@typescript-eslint/typescript-estree': 8.41.0(typescript@5.8.3) - '@typescript-eslint/visitor-keys': 8.41.0 + '@typescript-eslint/scope-manager': 8.42.0 + '@typescript-eslint/types': 8.42.0 + '@typescript-eslint/typescript-estree': 8.42.0(typescript@5.9.2) + '@typescript-eslint/visitor-keys': 8.42.0 debug: 4.4.1 eslint: 9.34.0(jiti@2.5.1) - typescript: 5.8.3 + typescript: 5.9.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.41.0(typescript@5.8.3)': + '@typescript-eslint/project-service@8.42.0(typescript@5.9.2)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.41.0(typescript@5.8.3) - '@typescript-eslint/types': 8.41.0 + '@typescript-eslint/tsconfig-utils': 8.42.0(typescript@5.9.2) + '@typescript-eslint/types': 8.42.0 debug: 4.4.1 - typescript: 5.8.3 + typescript: 5.9.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@8.41.0': + '@typescript-eslint/scope-manager@8.42.0': dependencies: - '@typescript-eslint/types': 8.41.0 - '@typescript-eslint/visitor-keys': 8.41.0 + '@typescript-eslint/types': 8.42.0 + '@typescript-eslint/visitor-keys': 8.42.0 - '@typescript-eslint/tsconfig-utils@8.41.0(typescript@5.8.3)': + '@typescript-eslint/tsconfig-utils@8.42.0(typescript@5.9.2)': dependencies: - typescript: 5.8.3 + typescript: 5.9.2 - '@typescript-eslint/type-utils@8.41.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.8.3)': + '@typescript-eslint/type-utils@8.42.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2)': dependencies: - '@typescript-eslint/types': 8.41.0 - '@typescript-eslint/typescript-estree': 8.41.0(typescript@5.8.3) - '@typescript-eslint/utils': 8.41.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.8.3) + '@typescript-eslint/types': 8.42.0 + '@typescript-eslint/typescript-estree': 8.42.0(typescript@5.9.2) + '@typescript-eslint/utils': 8.42.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) debug: 4.4.1 eslint: 9.34.0(jiti@2.5.1) - ts-api-utils: 2.1.0(typescript@5.8.3) - typescript: 5.8.3 + ts-api-utils: 2.1.0(typescript@5.9.2) + typescript: 5.9.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/types@8.41.0': {} + '@typescript-eslint/types@8.42.0': {} - '@typescript-eslint/typescript-estree@8.41.0(typescript@5.8.3)': + '@typescript-eslint/typescript-estree@8.42.0(typescript@5.9.2)': dependencies: - '@typescript-eslint/project-service': 8.41.0(typescript@5.8.3) - '@typescript-eslint/tsconfig-utils': 8.41.0(typescript@5.8.3) - '@typescript-eslint/types': 8.41.0 - '@typescript-eslint/visitor-keys': 8.41.0 + '@typescript-eslint/project-service': 8.42.0(typescript@5.9.2) + '@typescript-eslint/tsconfig-utils': 8.42.0(typescript@5.9.2) + '@typescript-eslint/types': 8.42.0 + '@typescript-eslint/visitor-keys': 8.42.0 debug: 4.4.1 fast-glob: 3.3.3 is-glob: 4.0.3 minimatch: 9.0.5 semver: 7.7.2 - ts-api-utils: 2.1.0(typescript@5.8.3) - typescript: 5.8.3 + ts-api-utils: 2.1.0(typescript@5.9.2) + typescript: 5.9.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.41.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.8.3)': + '@typescript-eslint/utils@8.42.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2)': dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.34.0(jiti@2.5.1)) - '@typescript-eslint/scope-manager': 8.41.0 - '@typescript-eslint/types': 8.41.0 - '@typescript-eslint/typescript-estree': 8.41.0(typescript@5.8.3) + '@eslint-community/eslint-utils': 4.8.0(eslint@9.34.0(jiti@2.5.1)) + '@typescript-eslint/scope-manager': 8.42.0 + '@typescript-eslint/types': 8.42.0 + '@typescript-eslint/typescript-estree': 8.42.0(typescript@5.9.2) eslint: 9.34.0(jiti@2.5.1) - typescript: 5.8.3 + typescript: 5.9.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/visitor-keys@8.41.0': + '@typescript-eslint/visitor-keys@8.42.0': dependencies: - '@typescript-eslint/types': 8.41.0 + '@typescript-eslint/types': 8.42.0 eslint-visitor-keys: 4.2.1 '@uiw/color-convert@2.8.0(@babel/runtime@7.28.3)': dependencies: '@babel/runtime': 7.28.3 - '@uiw/react-color-alpha@2.8.0(@babel/runtime@7.28.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@uiw/react-color-alpha@2.8.0(@babel/runtime@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': dependencies: '@babel/runtime': 7.28.3 '@uiw/color-convert': 2.8.0(@babel/runtime@7.28.3) - '@uiw/react-drag-event-interactive': 2.8.0(@babel/runtime@7.28.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + '@uiw/react-drag-event-interactive': 2.8.0(@babel/runtime@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) - '@uiw/react-color-block@2.8.0(@babel/runtime@7.28.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@uiw/react-color-block@2.8.0(@babel/runtime@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': dependencies: '@babel/runtime': 7.28.3 '@uiw/color-convert': 2.8.0(@babel/runtime@7.28.3) - '@uiw/react-color-editable-input': 2.8.0(@babel/runtime@7.28.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@uiw/react-color-swatch': 2.8.0(@babel/runtime@7.28.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + '@uiw/react-color-editable-input': 2.8.0(@babel/runtime@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@uiw/react-color-swatch': 2.8.0(@babel/runtime@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) - '@uiw/react-color-chrome@2.8.0(@babel/runtime@7.28.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@uiw/react-color-chrome@2.8.0(@babel/runtime@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': dependencies: '@babel/runtime': 7.28.3 '@uiw/color-convert': 2.8.0(@babel/runtime@7.28.3) - '@uiw/react-color-alpha': 2.8.0(@babel/runtime@7.28.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@uiw/react-color-editable-input': 2.8.0(@babel/runtime@7.28.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@uiw/react-color-editable-input-hsla': 2.8.0(@babel/runtime@7.28.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@uiw/react-color-editable-input-rgba': 2.8.0(@babel/runtime@7.28.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@uiw/react-color-github': 2.8.0(@babel/runtime@7.28.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@uiw/react-color-hue': 2.8.0(@babel/runtime@7.28.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@uiw/react-color-saturation': 2.8.0(@babel/runtime@7.28.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - - '@uiw/react-color-circle@2.8.0(@babel/runtime@7.28.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@uiw/react-color-alpha': 2.8.0(@babel/runtime@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@uiw/react-color-editable-input': 2.8.0(@babel/runtime@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@uiw/react-color-editable-input-hsla': 2.8.0(@babel/runtime@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@uiw/react-color-editable-input-rgba': 2.8.0(@babel/runtime@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@uiw/react-color-github': 2.8.0(@babel/runtime@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@uiw/react-color-hue': 2.8.0(@babel/runtime@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@uiw/react-color-saturation': 2.8.0(@babel/runtime@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + + '@uiw/react-color-circle@2.8.0(@babel/runtime@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': dependencies: '@babel/runtime': 7.28.3 '@uiw/color-convert': 2.8.0(@babel/runtime@7.28.3) - '@uiw/react-color-swatch': 2.8.0(@babel/runtime@7.28.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + '@uiw/react-color-swatch': 2.8.0(@babel/runtime@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) - '@uiw/react-color-colorful@2.8.0(@babel/runtime@7.28.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@uiw/react-color-colorful@2.8.0(@babel/runtime@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': dependencies: '@babel/runtime': 7.28.3 '@uiw/color-convert': 2.8.0(@babel/runtime@7.28.3) - '@uiw/react-color-alpha': 2.8.0(@babel/runtime@7.28.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@uiw/react-color-hue': 2.8.0(@babel/runtime@7.28.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@uiw/react-color-saturation': 2.8.0(@babel/runtime@7.28.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + '@uiw/react-color-alpha': 2.8.0(@babel/runtime@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@uiw/react-color-hue': 2.8.0(@babel/runtime@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@uiw/react-color-saturation': 2.8.0(@babel/runtime@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) - '@uiw/react-color-compact@2.8.0(@babel/runtime@7.28.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@uiw/react-color-compact@2.8.0(@babel/runtime@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': dependencies: '@babel/runtime': 7.28.3 '@uiw/color-convert': 2.8.0(@babel/runtime@7.28.3) - '@uiw/react-color-editable-input': 2.8.0(@babel/runtime@7.28.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@uiw/react-color-editable-input-rgba': 2.8.0(@babel/runtime@7.28.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@uiw/react-color-swatch': 2.8.0(@babel/runtime@7.28.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + '@uiw/react-color-editable-input': 2.8.0(@babel/runtime@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@uiw/react-color-editable-input-rgba': 2.8.0(@babel/runtime@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@uiw/react-color-swatch': 2.8.0(@babel/runtime@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) - '@uiw/react-color-editable-input-hsla@2.8.0(@babel/runtime@7.28.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@uiw/react-color-editable-input-hsla@2.8.0(@babel/runtime@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': dependencies: '@babel/runtime': 7.28.3 '@uiw/color-convert': 2.8.0(@babel/runtime@7.28.3) - '@uiw/react-color-editable-input-rgba': 2.8.0(@babel/runtime@7.28.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + '@uiw/react-color-editable-input-rgba': 2.8.0(@babel/runtime@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) - '@uiw/react-color-editable-input-rgba@2.8.0(@babel/runtime@7.28.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@uiw/react-color-editable-input-rgba@2.8.0(@babel/runtime@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': dependencies: '@babel/runtime': 7.28.3 '@uiw/color-convert': 2.8.0(@babel/runtime@7.28.3) - '@uiw/react-color-editable-input': 2.8.0(@babel/runtime@7.28.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + '@uiw/react-color-editable-input': 2.8.0(@babel/runtime@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) - '@uiw/react-color-editable-input@2.8.0(@babel/runtime@7.28.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@uiw/react-color-editable-input@2.8.0(@babel/runtime@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': dependencies: '@babel/runtime': 7.28.3 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) - '@uiw/react-color-github@2.8.0(@babel/runtime@7.28.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@uiw/react-color-github@2.8.0(@babel/runtime@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': dependencies: '@babel/runtime': 7.28.3 '@uiw/color-convert': 2.8.0(@babel/runtime@7.28.3) - '@uiw/react-color-swatch': 2.8.0(@babel/runtime@7.28.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + '@uiw/react-color-swatch': 2.8.0(@babel/runtime@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) - '@uiw/react-color-hue@2.8.0(@babel/runtime@7.28.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@uiw/react-color-hue@2.8.0(@babel/runtime@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': dependencies: '@babel/runtime': 7.28.3 '@uiw/color-convert': 2.8.0(@babel/runtime@7.28.3) - '@uiw/react-color-alpha': 2.8.0(@babel/runtime@7.28.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + '@uiw/react-color-alpha': 2.8.0(@babel/runtime@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) - '@uiw/react-color-material@2.8.0(@babel/runtime@7.28.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@uiw/react-color-material@2.8.0(@babel/runtime@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': dependencies: '@babel/runtime': 7.28.3 '@uiw/color-convert': 2.8.0(@babel/runtime@7.28.3) - '@uiw/react-color-editable-input': 2.8.0(@babel/runtime@7.28.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@uiw/react-color-editable-input-rgba': 2.8.0(@babel/runtime@7.28.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + '@uiw/react-color-editable-input': 2.8.0(@babel/runtime@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@uiw/react-color-editable-input-rgba': 2.8.0(@babel/runtime@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) '@uiw/react-color-name@2.8.0(@babel/runtime@7.28.3)': dependencies: @@ -4963,95 +4934,95 @@ snapshots: colors-named: 1.0.2 colors-named-hex: 1.0.2 - '@uiw/react-color-saturation@2.8.0(@babel/runtime@7.28.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@uiw/react-color-saturation@2.8.0(@babel/runtime@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': dependencies: '@babel/runtime': 7.28.3 '@uiw/color-convert': 2.8.0(@babel/runtime@7.28.3) - '@uiw/react-drag-event-interactive': 2.8.0(@babel/runtime@7.28.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + '@uiw/react-drag-event-interactive': 2.8.0(@babel/runtime@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) - '@uiw/react-color-shade-slider@2.8.0(@babel/runtime@7.28.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@uiw/react-color-shade-slider@2.8.0(@babel/runtime@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': dependencies: '@babel/runtime': 7.28.3 '@uiw/color-convert': 2.8.0(@babel/runtime@7.28.3) - '@uiw/react-color-alpha': 2.8.0(@babel/runtime@7.28.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + '@uiw/react-color-alpha': 2.8.0(@babel/runtime@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) - '@uiw/react-color-sketch@2.8.0(@babel/runtime@7.28.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@uiw/react-color-sketch@2.8.0(@babel/runtime@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': dependencies: '@babel/runtime': 7.28.3 '@uiw/color-convert': 2.8.0(@babel/runtime@7.28.3) - '@uiw/react-color-alpha': 2.8.0(@babel/runtime@7.28.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@uiw/react-color-editable-input': 2.8.0(@babel/runtime@7.28.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@uiw/react-color-editable-input-rgba': 2.8.0(@babel/runtime@7.28.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@uiw/react-color-hue': 2.8.0(@babel/runtime@7.28.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@uiw/react-color-saturation': 2.8.0(@babel/runtime@7.28.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@uiw/react-color-swatch': 2.8.0(@babel/runtime@7.28.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + '@uiw/react-color-alpha': 2.8.0(@babel/runtime@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@uiw/react-color-editable-input': 2.8.0(@babel/runtime@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@uiw/react-color-editable-input-rgba': 2.8.0(@babel/runtime@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@uiw/react-color-hue': 2.8.0(@babel/runtime@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@uiw/react-color-saturation': 2.8.0(@babel/runtime@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@uiw/react-color-swatch': 2.8.0(@babel/runtime@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) - '@uiw/react-color-slider@2.8.0(@babel/runtime@7.28.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@uiw/react-color-slider@2.8.0(@babel/runtime@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': dependencies: '@babel/runtime': 7.28.3 '@uiw/color-convert': 2.8.0(@babel/runtime@7.28.3) - '@uiw/react-color-alpha': 2.8.0(@babel/runtime@7.28.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + '@uiw/react-color-alpha': 2.8.0(@babel/runtime@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) - '@uiw/react-color-swatch@2.8.0(@babel/runtime@7.28.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@uiw/react-color-swatch@2.8.0(@babel/runtime@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': dependencies: '@babel/runtime': 7.28.3 '@uiw/color-convert': 2.8.0(@babel/runtime@7.28.3) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) - '@uiw/react-color-wheel@2.8.0(@babel/runtime@7.28.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@uiw/react-color-wheel@2.8.0(@babel/runtime@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': dependencies: '@babel/runtime': 7.28.3 '@uiw/color-convert': 2.8.0(@babel/runtime@7.28.3) - '@uiw/react-drag-event-interactive': 2.8.0(@babel/runtime@7.28.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + '@uiw/react-drag-event-interactive': 2.8.0(@babel/runtime@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) - '@uiw/react-color@2.8.0(@babel/runtime@7.28.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@uiw/react-color@2.8.0(@babel/runtime@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': dependencies: '@babel/runtime': 7.28.3 '@uiw/color-convert': 2.8.0(@babel/runtime@7.28.3) - '@uiw/react-color-alpha': 2.8.0(@babel/runtime@7.28.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@uiw/react-color-block': 2.8.0(@babel/runtime@7.28.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@uiw/react-color-chrome': 2.8.0(@babel/runtime@7.28.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@uiw/react-color-circle': 2.8.0(@babel/runtime@7.28.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@uiw/react-color-colorful': 2.8.0(@babel/runtime@7.28.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@uiw/react-color-compact': 2.8.0(@babel/runtime@7.28.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@uiw/react-color-editable-input': 2.8.0(@babel/runtime@7.28.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@uiw/react-color-editable-input-hsla': 2.8.0(@babel/runtime@7.28.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@uiw/react-color-editable-input-rgba': 2.8.0(@babel/runtime@7.28.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@uiw/react-color-github': 2.8.0(@babel/runtime@7.28.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@uiw/react-color-hue': 2.8.0(@babel/runtime@7.28.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@uiw/react-color-material': 2.8.0(@babel/runtime@7.28.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@uiw/react-color-alpha': 2.8.0(@babel/runtime@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@uiw/react-color-block': 2.8.0(@babel/runtime@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@uiw/react-color-chrome': 2.8.0(@babel/runtime@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@uiw/react-color-circle': 2.8.0(@babel/runtime@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@uiw/react-color-colorful': 2.8.0(@babel/runtime@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@uiw/react-color-compact': 2.8.0(@babel/runtime@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@uiw/react-color-editable-input': 2.8.0(@babel/runtime@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@uiw/react-color-editable-input-hsla': 2.8.0(@babel/runtime@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@uiw/react-color-editable-input-rgba': 2.8.0(@babel/runtime@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@uiw/react-color-github': 2.8.0(@babel/runtime@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@uiw/react-color-hue': 2.8.0(@babel/runtime@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@uiw/react-color-material': 2.8.0(@babel/runtime@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) '@uiw/react-color-name': 2.8.0(@babel/runtime@7.28.3) - '@uiw/react-color-saturation': 2.8.0(@babel/runtime@7.28.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@uiw/react-color-shade-slider': 2.8.0(@babel/runtime@7.28.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@uiw/react-color-sketch': 2.8.0(@babel/runtime@7.28.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@uiw/react-color-slider': 2.8.0(@babel/runtime@7.28.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@uiw/react-color-swatch': 2.8.0(@babel/runtime@7.28.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@uiw/react-color-wheel': 2.8.0(@babel/runtime@7.28.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + '@uiw/react-color-saturation': 2.8.0(@babel/runtime@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@uiw/react-color-shade-slider': 2.8.0(@babel/runtime@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@uiw/react-color-sketch': 2.8.0(@babel/runtime@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@uiw/react-color-slider': 2.8.0(@babel/runtime@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@uiw/react-color-swatch': 2.8.0(@babel/runtime@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@uiw/react-color-wheel': 2.8.0(@babel/runtime@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) - '@uiw/react-drag-event-interactive@2.8.0(@babel/runtime@7.28.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@uiw/react-drag-event-interactive@2.8.0(@babel/runtime@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': dependencies: '@babel/runtime': 7.28.3 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) - '@vitejs/plugin-react-swc@4.0.1(vite@7.1.3(@types/node@22.15.30)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.7.1))': + '@vitejs/plugin-react-swc@4.0.1(vite@7.1.4(@types/node@22.15.30)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.7.1))': dependencies: '@rolldown/pluginutils': 1.0.0-beta.32 '@swc/core': 1.13.5 - vite: 7.1.3(@types/node@22.15.30)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.7.1) + vite: 7.1.4(@types/node@22.15.30)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.7.1) transitivePeerDependencies: - '@swc/helpers' @@ -5063,13 +5034,13 @@ snapshots: chai: 5.3.3 tinyrainbow: 2.0.0 - '@vitest/mocker@3.2.4(vite@7.1.3(@types/node@22.15.30)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.7.1))': + '@vitest/mocker@3.2.4(vite@7.1.4(@types/node@22.15.30)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.7.1))': dependencies: '@vitest/spy': 3.2.4 estree-walker: 3.0.3 magic-string: 0.30.18 optionalDependencies: - vite: 7.1.3(@types/node@22.15.30)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.7.1) + vite: 7.1.4(@types/node@22.15.30)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.7.1) '@vitest/pretty-format@3.2.4': dependencies: @@ -5206,7 +5177,7 @@ snapshots: autoprefixer@10.4.21(postcss@8.5.6): dependencies: browserslist: 4.25.4 - caniuse-lite: 1.0.30001739 + caniuse-lite: 1.0.30001740 fraction.js: 4.3.7 normalize-range: 0.1.2 picocolors: 1.1.1 @@ -5248,8 +5219,8 @@ snapshots: browserslist@4.25.4: dependencies: - caniuse-lite: 1.0.30001739 - electron-to-chromium: 1.5.211 + caniuse-lite: 1.0.30001740 + electron-to-chromium: 1.5.214 node-releases: 2.0.19 update-browserslist-db: 1.1.3(browserslist@4.25.4) @@ -5274,7 +5245,7 @@ snapshots: callsites@3.1.0: {} - caniuse-lite@1.0.30001739: {} + caniuse-lite@1.0.30001740: {} chai@5.3.3: dependencies: @@ -5323,6 +5294,8 @@ snapshots: convert-source-map@1.9.0: {} + cookie@1.0.2: {} + cosmiconfig@7.1.0: dependencies: '@types/parse-json': 4.0.2 @@ -5418,7 +5391,7 @@ snapshots: es-errors: 1.3.0 gopd: 1.2.0 - electron-to-chromium@1.5.211: {} + electron-to-chromium@1.5.214: {} emoji-regex@8.0.0: {} @@ -5612,11 +5585,11 @@ snapshots: dependencies: eslint: 9.34.0(jiti@2.5.1) - eslint-plugin-unused-imports@4.2.0(@typescript-eslint/eslint-plugin@8.41.0(@typescript-eslint/parser@8.41.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.8.3))(eslint@9.34.0(jiti@2.5.1))(typescript@5.8.3))(eslint@9.34.0(jiti@2.5.1)): + eslint-plugin-unused-imports@4.2.0(@typescript-eslint/eslint-plugin@8.42.0(@typescript-eslint/parser@8.42.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.34.0(jiti@2.5.1)): dependencies: eslint: 9.34.0(jiti@2.5.1) optionalDependencies: - '@typescript-eslint/eslint-plugin': 8.41.0(@typescript-eslint/parser@8.41.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.8.3))(eslint@9.34.0(jiti@2.5.1))(typescript@5.8.3) + '@typescript-eslint/eslint-plugin': 8.42.0(@typescript-eslint/parser@8.42.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) eslint-scope@8.4.0: dependencies: @@ -5629,7 +5602,7 @@ snapshots: eslint@9.34.0(jiti@2.5.1): dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.34.0(jiti@2.5.1)) + '@eslint-community/eslint-utils': 4.8.0(eslint@9.34.0(jiti@2.5.1)) '@eslint-community/regexpp': 4.12.1 '@eslint/config-array': 0.21.0 '@eslint/config-helpers': 0.3.1 @@ -5637,7 +5610,7 @@ snapshots: '@eslint/eslintrc': 3.3.1 '@eslint/js': 9.34.0 '@eslint/plugin-kit': 0.3.5 - '@humanfs/node': 0.16.6 + '@humanfs/node': 0.16.7 '@humanwhocodes/module-importer': 1.0.1 '@humanwhocodes/retry': 0.4.3 '@types/estree': 1.0.8 @@ -5759,15 +5732,15 @@ snapshots: fraction.js@4.3.7: {} - framer-motion@12.23.12(@emotion/is-prop-valid@1.3.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + framer-motion@12.23.12(@emotion/is-prop-valid@1.4.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1): dependencies: motion-dom: 12.23.12 motion-utils: 12.23.6 tslib: 2.8.1 optionalDependencies: - '@emotion/is-prop-valid': 1.3.1 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + '@emotion/is-prop-valid': 1.4.0 + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) fsevents@2.3.3: optional: true @@ -6412,58 +6385,49 @@ snapshots: raf-schd@4.0.3: {} - react-dom@18.3.1(react@18.3.1): + react-dom@19.1.1(react@19.1.1): dependencies: - loose-envify: 1.4.0 - react: 18.3.1 - scheduler: 0.23.2 + react: 19.1.1 + scheduler: 0.26.0 react-is@16.13.1: {} - react-is@18.3.1: {} - react-is@19.1.1: {} - react-redux@9.2.0(@types/react@18.3.20)(react@18.3.1)(redux@5.0.1): + react-redux@9.2.0(@types/react@19.1.12)(react@19.1.1)(redux@5.0.1): dependencies: '@types/use-sync-external-store': 0.0.6 - react: 18.3.1 - use-sync-external-store: 1.5.0(react@18.3.1) + react: 19.1.1 + use-sync-external-store: 1.5.0(react@19.1.1) optionalDependencies: - '@types/react': 18.3.20 + '@types/react': 19.1.12 redux: 5.0.1 - react-router-dom@6.30.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + react-router@7.8.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1): dependencies: - '@remix-run/router': 1.23.0 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - react-router: 6.30.0(react@18.3.1) - - react-router@6.30.0(react@18.3.1): - dependencies: - '@remix-run/router': 1.23.0 - react: 18.3.1 + cookie: 1.0.2 + react: 19.1.1 + set-cookie-parser: 2.7.1 + optionalDependencies: + react-dom: 19.1.1(react@19.1.1) - react-transition-group@4.4.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + react-transition-group@4.4.5(react-dom@19.1.1(react@19.1.1))(react@19.1.1): dependencies: '@babel/runtime': 7.28.3 dom-helpers: 5.2.1 loose-envify: 1.4.0 prop-types: 15.8.1 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) - react-window@1.8.11(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + react-window@1.8.11(react-dom@19.1.1(react@19.1.1))(react@19.1.1): dependencies: '@babel/runtime': 7.28.3 memoize-one: 5.2.1 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) - react@18.3.1: - dependencies: - loose-envify: 1.4.0 + react@19.1.1: {} redux@5.0.1: {} @@ -6588,14 +6552,14 @@ snapshots: dependencies: xmlchars: 2.2.0 - scheduler@0.23.2: - dependencies: - loose-envify: 1.4.0 + scheduler@0.26.0: {} semver@6.3.1: {} semver@7.7.2: {} + set-cookie-parser@2.7.1: {} + set-function-length@1.2.2: dependencies: define-data-property: 1.1.4 @@ -6747,7 +6711,7 @@ snapshots: tailwind-merge@3.3.1: {} - tailwindcss@4.1.12: {} + tailwindcss@4.1.13: {} tapable@2.2.3: {} @@ -6801,13 +6765,13 @@ snapshots: dependencies: punycode: 2.3.1 - ts-api-utils@2.1.0(typescript@5.8.3): + ts-api-utils@2.1.0(typescript@5.9.2): dependencies: - typescript: 5.8.3 + typescript: 5.9.2 - tsconfck@3.1.6(typescript@5.8.3): + tsconfck@3.1.6(typescript@5.9.2): optionalDependencies: - typescript: 5.8.3 + typescript: 5.9.2 tslib@2.8.1: {} @@ -6850,18 +6814,18 @@ snapshots: possible-typed-array-names: 1.1.0 reflect.getprototypeof: 1.0.10 - typescript-eslint@8.41.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.8.3): + typescript-eslint@8.42.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2): dependencies: - '@typescript-eslint/eslint-plugin': 8.41.0(@typescript-eslint/parser@8.41.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.8.3))(eslint@9.34.0(jiti@2.5.1))(typescript@5.8.3) - '@typescript-eslint/parser': 8.41.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.8.3) - '@typescript-eslint/typescript-estree': 8.41.0(typescript@5.8.3) - '@typescript-eslint/utils': 8.41.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.8.3) + '@typescript-eslint/eslint-plugin': 8.42.0(@typescript-eslint/parser@8.42.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) + '@typescript-eslint/parser': 8.42.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) + '@typescript-eslint/typescript-estree': 8.42.0(typescript@5.9.2) + '@typescript-eslint/utils': 8.42.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) eslint: 9.34.0(jiti@2.5.1) - typescript: 5.8.3 + typescript: 5.9.2 transitivePeerDependencies: - supports-color - typescript@5.8.3: {} + typescript@5.9.2: {} unbox-primitive@1.1.0: dependencies: @@ -6882,9 +6846,9 @@ snapshots: dependencies: punycode: 2.3.1 - use-sync-external-store@1.5.0(react@18.3.1): + use-sync-external-store@1.5.0(react@19.1.1): dependencies: - react: 18.3.1 + react: 19.1.1 uuid@11.1.0: {} @@ -6905,7 +6869,7 @@ snapshots: debug: 4.4.1 es-module-lexer: 1.7.0 pathe: 2.0.3 - vite: 7.1.3(@types/node@22.15.30)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.7.1) + vite: 7.1.4(@types/node@22.15.30)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.7.1) transitivePeerDependencies: - '@types/node' - jiti @@ -6920,18 +6884,18 @@ snapshots: - tsx - yaml - vite-tsconfig-paths@5.1.4(typescript@5.8.3)(vite@7.1.3(@types/node@22.15.30)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.7.1)): + vite-tsconfig-paths@5.1.4(typescript@5.9.2)(vite@7.1.4(@types/node@22.15.30)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.7.1)): dependencies: debug: 4.4.1 globrex: 0.1.2 - tsconfck: 3.1.6(typescript@5.8.3) + tsconfck: 3.1.6(typescript@5.9.2) optionalDependencies: - vite: 7.1.3(@types/node@22.15.30)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.7.1) + vite: 7.1.4(@types/node@22.15.30)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.7.1) transitivePeerDependencies: - supports-color - typescript - vite@7.1.3(@types/node@22.15.30)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.7.1): + vite@7.1.4(@types/node@22.15.30)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.7.1): dependencies: esbuild: 0.25.9 fdir: 6.5.0(picomatch@4.0.3) @@ -6950,7 +6914,7 @@ snapshots: dependencies: '@types/chai': 5.2.2 '@vitest/expect': 3.2.4 - '@vitest/mocker': 3.2.4(vite@7.1.3(@types/node@22.15.30)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.7.1)) + '@vitest/mocker': 3.2.4(vite@7.1.4(@types/node@22.15.30)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.7.1)) '@vitest/pretty-format': 3.2.4 '@vitest/runner': 3.2.4 '@vitest/snapshot': 3.2.4 @@ -6968,7 +6932,7 @@ snapshots: tinyglobby: 0.2.14 tinypool: 1.1.1 tinyrainbow: 2.0.0 - vite: 7.1.3(@types/node@22.15.30)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.7.1) + vite: 7.1.4(@types/node@22.15.30)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.7.1) vite-node: 3.2.4(@types/node@22.15.30)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.7.1) why-is-node-running: 2.3.0 optionalDependencies: diff --git a/client/src/App.test.tsx b/client/src/App.test.tsx index 730e58da8..d67f84890 100644 --- a/client/src/App.test.tsx +++ b/client/src/App.test.tsx @@ -1,10 +1,11 @@ -import ReactDOM from 'react-dom'; +import { createRoot } from 'react-dom/client'; import { it } from 'vitest'; import App from './App'; it('renders without crashing', () => { const div = document.createElement('div'); - ReactDOM.render(, div); - ReactDOM.unmountComponentAtNode(div); + const root = createRoot(div); + root.render(); + root.unmount(); }); diff --git a/client/src/App.tsx b/client/src/App.tsx index 634c7417f..41b60acfb 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -4,7 +4,7 @@ import { LocalizationProvider } from '@mui/x-date-pickers'; import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns'; import * as Sentry from '@sentry/react'; import React, { useContext, useEffect, useMemo } from 'react'; -import { Outlet } from 'react-router-dom'; +import { Outlet } from 'react-router'; import getCourseInfo from './api/getCourseInfo'; import getCoursesList from './api/getCoursesList'; diff --git a/client/src/components/EventShareModal.tsx b/client/src/components/EventShareModal.tsx index 6afe045d3..dfbfe323e 100644 --- a/client/src/components/EventShareModal.tsx +++ b/client/src/components/EventShareModal.tsx @@ -3,7 +3,7 @@ import { Card, CardProps, Dialog, IconButton } from '@mui/material'; import { styled } from '@mui/material/styles'; import isBase64 from 'is-base64'; import { useContext, useEffect, useState } from 'react'; -import { useNavigate, useParams } from 'react-router-dom'; +import { useNavigate, useParams } from 'react-router'; import { AppContext } from '../context/AppContext'; import { CourseContext } from '../context/CourseContext'; diff --git a/client/src/components/controls/CourseSelect.tsx b/client/src/components/controls/CourseSelect.tsx index 988a180ec..5e3337483 100644 --- a/client/src/components/controls/CourseSelect.tsx +++ b/client/src/components/controls/CourseSelect.tsx @@ -197,7 +197,7 @@ const CourseSelect: React.FC = ({ assignedColors, handleSelec Science: 'Faculty of Science', }; - const searchTimer = useRef(); + const searchTimer = useRef(undefined); const listRef = useRef(null); const { coursesList } = useContext(AppContext); diff --git a/client/src/components/landingPage/HeroSection/HeroSection.tsx b/client/src/components/landingPage/HeroSection/HeroSection.tsx index 410471108..e80d7d1df 100644 --- a/client/src/components/landingPage/HeroSection/HeroSection.tsx +++ b/client/src/components/landingPage/HeroSection/HeroSection.tsx @@ -1,5 +1,5 @@ import { NavigateNext } from '@mui/icons-material'; -import { useNavigate } from 'react-router-dom'; +import { useNavigate } from 'react-router'; import notangles from '../../../assets/notangles_1.png'; import { useAuth } from '../../../hooks/useAuth'; diff --git a/client/src/components/login/AuthGuard.tsx b/client/src/components/login/AuthGuard.tsx index ce55e9c7c..6aee8da57 100644 --- a/client/src/components/login/AuthGuard.tsx +++ b/client/src/components/login/AuthGuard.tsx @@ -1,4 +1,5 @@ -import { Navigate } from 'react-router-dom'; +import type { JSX } from 'react'; +import { Navigate } from 'react-router'; import { useAuth } from '../../hooks/useAuth'; import PageLoading from '../pageLoading/PageLoading'; diff --git a/client/src/components/timetable/DroppedCards.tsx b/client/src/components/timetable/DroppedCards.tsx index cdae9f56e..d8eaabd2e 100644 --- a/client/src/components/timetable/DroppedCards.tsx +++ b/client/src/components/timetable/DroppedCards.tsx @@ -1,4 +1,4 @@ -import React, { useContext, useLayoutEffect, useRef, useState } from 'react'; +import React, { type JSX, useContext, useLayoutEffect, useRef, useState } from 'react'; import { useGetUserSettingsQuery } from '../../api/user/queries'; import { unknownErrorMessage } from '../../constants/timetable'; diff --git a/client/src/components/timetable/DroppedClass.tsx b/client/src/components/timetable/DroppedClass.tsx index da5a22248..6372c1751 100644 --- a/client/src/components/timetable/DroppedClass.tsx +++ b/client/src/components/timetable/DroppedClass.tsx @@ -1,6 +1,5 @@ import { ContentPaste, MoreHoriz } from '@mui/icons-material'; -import { Grid, ListItemIcon, ListItemText, MenuItem } from '@mui/material'; -import TouchRipple from '@mui/material/ButtonBase/TouchRipple'; +import { Grid, ListItemIcon, ListItemText, MenuItem, TouchRippleActions } from '@mui/material'; import React, { useContext, useEffect, useRef, useState } from 'react'; import { useGetUserSettingsQuery } from '../../api/user/queries'; @@ -13,6 +12,7 @@ import { StyledMenu } from '../../styles/CustomEventStyles'; import { ExpandButton, StyledCard, + StyledCardButtonBase, StyledCardInfo, StyledCardInner, StyledCardInnerGrid, @@ -54,16 +54,14 @@ const DroppedClass: React.FC = ({ setErrorVisibility(true); } - if (!currCourse) return <>; + const element = useRef(null); + const rippleRef = useRef(null); const handleClose = (value: ClassData) => { handleSelectClass(value); setPopupOpen(!popupOpen); }; - const element = useRef(null); - const rippleRef = useRef(null); - let timer: number | null = null; let rippleStopped = false; let ignoreMouse = false; @@ -81,7 +79,7 @@ const DroppedClass: React.FC = ({ const eventCopy = { ...eventDown }; - if ('start' in rippleRef.current) { + if (rippleRef.current !== null) { rippleStopped = false; rippleRef.current.start(eventCopy); } @@ -105,16 +103,16 @@ const DroppedClass: React.FC = ({ window.removeEventListener('mousemove', onUp); window.removeEventListener('touchmove', onUp); - if ((timer || !eventUp.type.includes('move')) && rippleRef.current && 'stop' in rippleRef.current) { + if (timer || !eventUp.type.includes('move')) { window.removeEventListener('mouseup', onUp); window.removeEventListener('touchend', onUp); - if (!rippleStopped && 'stop' in rippleRef.current) { + if (!rippleStopped) { rippleStopped = true; setTimeout(() => { try { - rippleRef.current.stop(eventUp); + rippleRef.current?.stop(eventUp); } catch (error) { setAlertMsg(unknownErrorMessage); setErrorVisibility(true); @@ -152,6 +150,8 @@ const DroppedClass: React.FC = ({ }; }); + if (!currCourse) return <>; + let activityMaxPeriods = 0; if (classCard.type === 'inventory') { activityMaxPeriods = Math.max( @@ -203,34 +203,35 @@ const DroppedClass: React.FC = ({ hasClash={clashColour !== 'transparent'} clashColour={clashColour} > - - - - {classCard.courseCode} {classCard.activity} - - - {classCard.type === 'class' ? ( - !hideClassInfo && - ) : ( - <> - {activityMaxPeriods} class - {activityMaxPeriods !== 1 && 'es'} - - )} - - - - - {classCard.type === 'class' && fullscreenVisible && ( - { - setPopupOpen(true); - }} - sx={{ color: '#f5f5f5' }} - > - - - )} + + + + + {classCard.courseCode} {classCard.activity} + + + {classCard.type === 'class' ? ( + !hideClassInfo && + ) : ( + <> + {activityMaxPeriods} class + {activityMaxPeriods !== 1 && 'es'} + + )} + + + + {classCard.type === 'class' && fullscreenVisible && ( + { + setPopupOpen(true); + }} + sx={{ color: '#f5f5f5' }} + > + + + )} + {classCard.type === 'class' && ( diff --git a/client/src/components/timetable/DroppedEvent.tsx b/client/src/components/timetable/DroppedEvent.tsx index e070b4be7..a407864d3 100644 --- a/client/src/components/timetable/DroppedEvent.tsx +++ b/client/src/components/timetable/DroppedEvent.tsx @@ -1,6 +1,5 @@ import { Delete, LocationOn, MoreHoriz } from '@mui/icons-material'; -import { Grid, ListItemIcon, ListItemText, MenuItem } from '@mui/material'; -import TouchRipple from '@mui/material/ButtonBase/TouchRipple'; +import { Grid, ListItemIcon, ListItemText, MenuItem, TouchRippleActions } from '@mui/material'; import { styled } from '@mui/material/styles'; import React, { useContext, useEffect, useRef, useState } from 'react'; @@ -14,6 +13,7 @@ import { StyledMenu } from '../../styles/CustomEventStyles'; import { ExpandButton, StyledCard, + StyledCardButtonBase, StyledCardInfo, StyledCardInner, StyledCardInnerGrid, @@ -53,7 +53,7 @@ const DroppedEvent: React.FC = ({ const { createdEvents, setCreatedEvents } = useContext(CourseContext); const element = useRef(null); - const rippleRef = useRef(null); + const rippleRef = useRef(null); let timer: number | null = null; let rippleStopped = false; @@ -77,7 +77,7 @@ const DroppedEvent: React.FC = ({ const eventCopy = { ...eventDown }; - if (rippleRef.current && 'start' in rippleRef.current) { + if (rippleRef.current !== null) { rippleStopped = false; rippleRef.current.start(eventCopy); } @@ -101,16 +101,16 @@ const DroppedEvent: React.FC = ({ window.removeEventListener('mousemove', onUp); window.removeEventListener('touchmove', onUp); - if ((timer || !eventUp.type.includes('move')) && rippleRef.current && 'stop' in rippleRef.current) { + if (timer || !eventUp.type.includes('move')) { window.removeEventListener('mouseup', onUp); window.removeEventListener('touchend', onUp); - if (!rippleStopped && 'stop' in rippleRef.current) { + if (!rippleStopped) { rippleStopped = true; setTimeout(() => { try { - rippleRef.current.stop(eventUp); + rippleRef.current?.stop(eventUp); } catch (error) { setAlertMsg(unknownErrorMessage); setErrorVisibility(true); @@ -227,29 +227,30 @@ const DroppedEvent: React.FC = ({ clashColour={'none'} backgroundColour={useColorDecoder(eventPeriod.event.color, preferredTheme).toString()} > - - - {eventPeriod.event.name} - {/* only display location on card if event not less than one hour */} - {!isLessThanOneHour && eventPeriod.event.location && ( - - - {eventPeriod.event.location} - - )} - - - - {fullscreenVisible && ( - { - setPopupOpen(true); - }} - sx={{ color: '#f5f5f5' }} - > - - - )} + + + + {eventPeriod.event.name} + {/* only display location on card if event not less than one hour */} + {!isLessThanOneHour && eventPeriod.event.location && ( + + + {eventPeriod.event.location} + + )} + + + {fullscreenVisible && ( + { + setPopupOpen(true); + }} + sx={{ color: '#f5f5f5' }} + > + + + )} + { - + } path="/" /> ; +}) => ( + + {children} + +); + export const StyledCardInner = styled(Card, { shouldForwardProp: (prop) => !['hasClash', 'isSquareEdges', 'clashColour', 'backgroundColour'].includes(prop.toString()), From 184dc62f0afa5e8fa1f82c03bee5276387bed43f Mon Sep 17 00:00:00 2001 From: Lucas Date: Mon, 8 Sep 2025 14:44:47 +1000 Subject: [PATCH 22/33] Implement Google and GitHub sign in (#1058) * Add GitHub auth * Add Google auth * Enable frontend auths button * Fix bug with Google and GitHub passport login * Refactor and add logout route * Add logout button to frontend * Fix logout redirect * Fix hero section button when logged in * Fix props after rename * Apply lint fixes --- .../components/controls/Autotimetabler.tsx | 4 +- .../src/components/controls/ColorPicker.tsx | 3 +- .../landingPage/HeroSection/HeroSection.tsx | 14 +-- .../components/landingPage/LandingPage.tsx | 2 +- client/src/components/login/AuthModal.tsx | 2 - client/src/components/sidebar/UserAccount.tsx | 68 +++----------- .../sidebar/friends/AddAFriendTab.tsx | 5 +- .../sidebar/friends/RequestsTab.tsx | 8 +- .../sidebar/friends/UserProfile.tsx | 24 ++--- .../sidebar/friends/YourFriendsTab.tsx | 8 +- .../timetable/ExpandedClassView.tsx | 6 +- server/.env.example | 22 +++++ server/package.json | 4 + server/pnpm-lock.yaml | 90 +++++++++++++++++++ server/src/auth/auth.controller.ts | 63 ++++++++++--- server/src/auth/auth.module.ts | 16 ++-- server/src/auth/github.strategy.ts | 54 +++++++++++ server/src/auth/google.strategy.ts | 56 ++++++++++++ server/src/timetable/timetable.controller.ts | 1 - server/src/user/user.service.ts | 8 ++ 20 files changed, 332 insertions(+), 126 deletions(-) create mode 100644 server/.env.example create mode 100644 server/src/auth/github.strategy.ts create mode 100644 server/src/auth/google.strategy.ts diff --git a/client/src/components/controls/Autotimetabler.tsx b/client/src/components/controls/Autotimetabler.tsx index c05ba5c4b..599ee01dc 100644 --- a/client/src/components/controls/Autotimetabler.tsx +++ b/client/src/components/controls/Autotimetabler.tsx @@ -332,7 +332,7 @@ const Autotimetabler: React.FC = ({ handleSelectClass }) => step={1} value={breaksBetweenClasses} onChange={(e, v) => { - setBreaksBetweenClasses(v as number); + setBreaksBetweenClasses(v); }} min={0} max={5} @@ -351,7 +351,7 @@ const Autotimetabler: React.FC = ({ handleSelectClass }) => step={1} value={daysAtUni} onChange={(e, v) => { - setDaysAtUni(v as number); + setDaysAtUni(v); }} min={1} max={5} diff --git a/client/src/components/controls/ColorPicker.tsx b/client/src/components/controls/ColorPicker.tsx index 7c6a766a3..bfc00316c 100644 --- a/client/src/components/controls/ColorPicker.tsx +++ b/client/src/components/controls/ColorPicker.tsx @@ -1,10 +1,9 @@ import { Box, Button, ButtonGroup, List, ListItem, Popover, TextField } from '@mui/material'; import { Colorful } from '@uiw/react-color'; -import { useContext, useEffect, useState } from 'react'; +import { useEffect, useState } from 'react'; import { useGetUserSettingsQuery } from '../../api/user/queries'; import { colors } from '../../constants/timetable'; -import { AppContext } from '../../context/AppContext'; import { useColorDecoder } from '../../hooks/useColorDecoder'; import { ColorPickerProps } from '../../interfaces/PropTypes'; import { ColorIndicatorBox, StyledButtonContainer } from '../../styles/ControlStyles'; diff --git a/client/src/components/landingPage/HeroSection/HeroSection.tsx b/client/src/components/landingPage/HeroSection/HeroSection.tsx index e80d7d1df..29da1ae8e 100644 --- a/client/src/components/landingPage/HeroSection/HeroSection.tsx +++ b/client/src/components/landingPage/HeroSection/HeroSection.tsx @@ -5,15 +5,15 @@ import notangles from '../../../assets/notangles_1.png'; import { useAuth } from '../../../hooks/useAuth'; import { FlipWords } from '../flip-words'; -const HeroSection = ({ handleStartClick }: { handleStartClick: () => void }) => { +const HeroSection = ({ openModal }: { openModal: () => void }) => { const { loggedIn } = useAuth(); const navigate = useNavigate(); - // const handleStartClick = () => { - // // TODO: Phase out the visited item - // localStorage.setItem('visited', 'true'); - // navigate('/home', { replace: true }); - // }; + const handleStartClick = async () => { + // TODO: Phase out the visited item + localStorage.setItem('visited', 'true'); + await navigate('/home', { replace: true }); + }; const words = ['plan', 'create', 'organise', 'optimise', 'design']; @@ -40,7 +40,7 @@ const HeroSection = ({ handleStartClick }: { handleStartClick: () => void }) =>

    @@ -120,7 +119,6 @@ export default function LoginDialog({ open, onClose, onSignIn, loading = false } onSignIn('github'); }} sx={{ mb: 2 }} - disabled > Sign in with GitHub diff --git a/client/src/components/sidebar/UserAccount.tsx b/client/src/components/sidebar/UserAccount.tsx index 310b4ef5a..a1c3ab17f 100644 --- a/client/src/components/sidebar/UserAccount.tsx +++ b/client/src/components/sidebar/UserAccount.tsx @@ -1,11 +1,10 @@ -import { LoginRounded, LogoutRounded } from '@mui/icons-material'; -import { Button, IconButton, Tooltip } from '@mui/material'; +import { LogoutRounded } from '@mui/icons-material'; +import { IconButton, Tooltip } from '@mui/material'; import { styled } from '@mui/material/styles'; import React, { useState } from 'react'; import { API_URL } from '../../api/config'; -import storage from '../../utils/storage'; -import { createDefaultTimetable } from '../../utils/timetableHelpers'; +import { useAuth } from '../../hooks/useAuth'; import StyledDialog from '../StyledDialog'; import UserProfile from './friends/UserProfile'; @@ -28,13 +27,6 @@ const StyledIconButton = styled(IconButton)` color: ${({ theme }) => theme.palette.text.primary}; `; -const StyledButton = styled(Button)` - min-width: 200px; - min-height: 40px; - background-color: ${({ theme }) => theme.palette.background.paper}; - border: 1px solid ${({ theme }) => theme.palette.primary.main}; -`; - const ExpandedContainer = styled('div')` display: flex; align-items: center; @@ -44,47 +36,16 @@ const ExpandedContainer = styled('div')` `; const UserAccount: React.FC = ({ collapsed }) => { - const [windowLocation, setWindowLocation] = useState(''); const [logoutDialog, setLogoutDialog] = useState(false); + const { user } = useAuth(); - const loginCall = async () => { - setWindowLocation(window.location.href); - try { - window.location.href = `${API_URL.server}/auth/login`; - } catch (error) { - console.log(error); - } + const onLogout = () => { + window.location.href = `${API_URL.server}/auth/logout`; }; - const user = { - userID: '', - firstname: 'First', - lastname: 'Last', - email: 'example@user.com', - profileURL: '', - }; - - const logoutCall = async () => { - try { - await fetch(`${API_URL.server}/auth/logout`, { - credentials: 'include', - }); - } catch (error) { - console.log(error); - } - window.location.replace(windowLocation); - storage.set('timetables', createDefaultTimetable(undefined)); - }; - if (!user.userID) { - return collapsed ? ( - - - - - - ) : ( - Log in - ); + // Shouldn't be possible; + if (!user) { + return <>; } return ( @@ -95,7 +56,7 @@ const UserAccount: React.FC = ({ collapsed }) => { setLogoutDialog(false); }} onConfirm={() => { - logoutCall(); + onLogout(); setLogoutDialog(false); }} title="Confirm Log out" @@ -115,15 +76,10 @@ const UserAccount: React.FC = ({ collapsed }) => {
    ) : ( - + {/* TODO: error handling for when logging out */} - + diff --git a/client/src/components/sidebar/friends/AddAFriendTab.tsx b/client/src/components/sidebar/friends/AddAFriendTab.tsx index 6bb2e4250..b601130bc 100644 --- a/client/src/components/sidebar/friends/AddAFriendTab.tsx +++ b/client/src/components/sidebar/friends/AddAFriendTab.tsx @@ -134,9 +134,8 @@ const AddAFriendTab: React.FC<{ user: User; fetchUserInfo: (userID: string) => v isSelected={user.outgoing.map((userRequested) => userRequested.userID).includes(otherUser.userID)} > {user.outgoing.map((userRequested) => userRequested.userID).includes(otherUser.userID) ? ( diff --git a/client/src/components/sidebar/friends/RequestsTab.tsx b/client/src/components/sidebar/friends/RequestsTab.tsx index d252dcd4b..5c84a5464 100644 --- a/client/src/components/sidebar/friends/RequestsTab.tsx +++ b/client/src/components/sidebar/friends/RequestsTab.tsx @@ -75,13 +75,7 @@ const RequestsTab: React.FC<{ user: User; fetchUserInfo: (userID: string) => voi {user.incoming.map((friend: User, i: number) => ( - + handleAcceptRequest(friend.userID)}> diff --git a/client/src/components/sidebar/friends/UserProfile.tsx b/client/src/components/sidebar/friends/UserProfile.tsx index 93c17b6f3..6dc4f963f 100644 --- a/client/src/components/sidebar/friends/UserProfile.tsx +++ b/client/src/components/sidebar/friends/UserProfile.tsx @@ -13,19 +13,13 @@ const StyledFullname = styled('div')` word-break: break-all; `; -const StyledEmail = styled('div')` - color: #949494; - word-break: break-all; -`; - -const UserProfile: React.FC<{ firstname: string; lastname: string; email: string; profileURL: string }> = ({ - firstname, - lastname, - email, +const UserProfile: React.FC<{ firstName: string; lastName: string; profileURL?: string }> = ({ + firstName, + lastName, profileURL, }) => { const getFullName = () => { - let fullname = firstname + ' ' + lastname; + let fullname = firstName + ' ' + lastName; if (fullname.length >= 32) { fullname = fullname.slice(0, 32); return fullname + '...'; @@ -33,24 +27,16 @@ const UserProfile: React.FC<{ firstname: string; lastname: string; email: string return fullname; }; - const getEmail = () => { - if (email.length >= 15) { - email = email.slice(0, 15); - return email + '...'; - } - return email; - }; return (
    {getFullName()} - {getEmail()}
    ); diff --git a/client/src/components/sidebar/friends/YourFriendsTab.tsx b/client/src/components/sidebar/friends/YourFriendsTab.tsx index e23efc13a..003f5b089 100644 --- a/client/src/components/sidebar/friends/YourFriendsTab.tsx +++ b/client/src/components/sidebar/friends/YourFriendsTab.tsx @@ -47,13 +47,7 @@ const YourFriendsTab: React.FC<{ user: User; fetchUserInfo: (userID: string) => {user.friends.map((friend: User, i: number) => ( - + handleRemoveFriend(friend.userID)}> diff --git a/client/src/components/timetable/ExpandedClassView.tsx b/client/src/components/timetable/ExpandedClassView.tsx index d1c535fa9..a4930edfc 100644 --- a/client/src/components/timetable/ExpandedClassView.tsx +++ b/client/src/components/timetable/ExpandedClassView.tsx @@ -175,11 +175,9 @@ const ExpandedClassView: React.FC = ({ code, classPeriod * @param e The HTML event triggered */ const handleLocationChange = (e: SelectChangeEvent) => { - setSelectedIndex(e.target.value as number); + setSelectedIndex(e.target.value); const newPeriod = - duplicateClassData.current.duplicateClasses[e.target.value as number].periods[ - duplicateClassData.current.periodIndex - ]; + duplicateClassData.current.duplicateClasses[e.target.value].periods[duplicateClassData.current.periodIndex]; if (isScheduledPeriod(newPeriod)) setCurrentPeriod(newPeriod); }; diff --git a/server/.env.example b/server/.env.example new file mode 100644 index 000000000..aee652d7c --- /dev/null +++ b/server/.env.example @@ -0,0 +1,22 @@ +NODE_ENV="dev" +PORT=3001 +POSTGRES_USER="postgres" +POSTGRES_DB="notangles-db" +POSTGRES_PASSWORD="postgres" +POSTGRES_PORT="5432" +DATABASE_URL="postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@localhost:${POSTGRES_PORT}/${POSTGRES_DB}?schema=public" +SESSION_SECRET="i-love-notangles" +OAUTH2_CLIENT_PROVIDER_OIDC_ISSUER="https://id.example.com.au" +OAUTH2_CLIENT_REGISTRATION_LOGIN_CLIENT_ID="a-b-c-d-e-f-1234567890" +OAUTH2_CLIENT_REGISTRATION_LOGIN_CLIENT_SECRET="aaazzz123" +OAUTH2_CLIENT_REGISTRATION_LOGIN_SCOPE="openid" +OAUTH2_CLIENT_REGISTRATION_LOGIN_REDIRECT_URI="http://localhost:3001/api/auth/callback/devsoc" +OAUTH2_CLIENT_REGISTRATION_LOGIN_POST_LOGOUT_REDIRECT_URI="http://localhost:3001/api/auth/callback/devsoc" +GITHUB_CLIENT_ID="aaaZZZ123" +GITHUB_CLIENT_SECRET="abcdef1234567890" +GITHUB_REDIRECT_URI="http://localhost:3001/api/auth/callback/github" +GOOGLE_CLIENT_ID="12345-aaazzz123.apps.googleusercontent.com" +GOOGLE_CLIENT_SECRET="AAAZZZ-aaaZZZ123-aaaZZZ" +GOOGLE_REDIRECT_URI="http://localhost:3001/api/auth/callback/google" +CLIENT_HOST_NAME="localhost" +CLIENT_HOST_PORT="5173" diff --git a/server/package.json b/server/package.json index 475b0dad5..9ccf1186c 100644 --- a/server/package.json +++ b/server/package.json @@ -36,6 +36,8 @@ "openid-client": "6.6.2", "passport": "0.7.0", "passport-custom": "1.1.1", + "passport-github2": "0.1.12", + "passport-google-oauth20": "2.0.0", "reflect-metadata": "0.2.2", "rxjs": "7.8.2" }, @@ -60,6 +62,8 @@ "@types/jest": "30.0.0", "@types/node": "22", "@types/passport": "1.0.17", + "@types/passport-github2": "1.2.9", + "@types/passport-google-oauth20": "2.0.16", "@types/supertest": "6.0.3", "eslint": "9.30.1", "eslint-config-prettier": "10.1.5", diff --git a/server/pnpm-lock.yaml b/server/pnpm-lock.yaml index 2151b2909..cad18c966 100644 --- a/server/pnpm-lock.yaml +++ b/server/pnpm-lock.yaml @@ -47,6 +47,12 @@ importers: passport-custom: specifier: 1.1.1 version: 1.1.1 + passport-github2: + specifier: 0.1.12 + version: 0.1.12 + passport-google-oauth20: + specifier: 2.0.0 + version: 2.0.0 reflect-metadata: specifier: 0.2.2 version: 0.2.2 @@ -114,6 +120,12 @@ importers: '@types/passport': specifier: 1.0.17 version: 1.0.17 + '@types/passport-github2': + specifier: 1.2.9 + version: 1.2.9 + '@types/passport-google-oauth20': + specifier: 2.0.16 + version: 2.0.16 '@types/supertest': specifier: 6.0.3 version: 6.0.3 @@ -1756,6 +1768,18 @@ packages: '@types/node@22.15.21': resolution: {integrity: sha512-EV/37Td6c+MgKAbkcLG6vqZ2zEYHD7bvSrzqqs2RIhbA6w3x+Dqz8MZM3sP6kGTeLrdoOgKZe+Xja7tUB2DNkQ==} + '@types/oauth@0.9.6': + resolution: {integrity: sha512-H9TRCVKBNOhZZmyHLqFt9drPM9l+ShWiqqJijU1B8P3DX3ub84NjxDuy+Hjrz+fEca5Kwip3qPMKNyiLgNJtIA==} + + '@types/passport-github2@1.2.9': + resolution: {integrity: sha512-/nMfiPK2E6GKttwBzwj0Wjaot8eHrM57hnWxu52o6becr5/kXlH/4yE2v2rh234WGvSgEEzIII02Nc5oC5xEHA==} + + '@types/passport-google-oauth20@2.0.16': + resolution: {integrity: sha512-ayXK2CJ7uVieqhYOc6k/pIr5pcQxOLB6kBev+QUGS7oEZeTgIs1odDobXRqgfBPvXzl0wXCQHftV5220czZCPA==} + + '@types/passport-oauth2@1.8.0': + resolution: {integrity: sha512-6//z+4orIOy/g3zx17HyQ71GSRK4bs7Sb+zFasRoc2xzlv7ZCJ+vkDBYFci8U6HY+or6Zy7ajf4mz4rK7nsWJQ==} + '@types/passport@1.0.17': resolution: {integrity: sha512-aciLyx+wDwT2t2/kJGJR2AEeBz0nJU4WuRX04Wu9Dqc5lSUtwu0WERPHYsLhF9PtseiAMPBGNUOtFjxZ56prsg==} @@ -2236,6 +2260,10 @@ packages: base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + base64url@3.0.1: + resolution: {integrity: sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A==} + engines: {node: '>=6.0.0'} + bin-version-check@5.1.0: resolution: {integrity: sha512-bYsvMqJ8yNGILLz1KP9zKLzQ6YpljV3ln1gqhuLkUtyfGi3qXKGuK2p+U4NAvjVFzDFiBBtOpCOSFNuYYEGZ5g==} engines: {node: '>=12'} @@ -3839,6 +3867,9 @@ packages: oauth4webapi@3.5.5: resolution: {integrity: sha512-1K88D2GiAydGblHo39NBro5TebGXa+7tYoyIbxvqv3+haDDry7CBE1eSYuNbOSsYCCU6y0gdynVZAkm4YPw4hg==} + oauth@0.10.2: + resolution: {integrity: sha512-JtFnB+8nxDEXgNyniwz573xxbKSOu3R8D40xQKqcjwJ2CDkYqUDI53o6IuzDJBx60Z8VKCm271+t8iFjakrl8Q==} + object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} @@ -3934,6 +3965,18 @@ packages: resolution: {integrity: sha512-/2m7jUGxmCYvoqenLB9UrmkCgPt64h8ZtV+UtuQklZ/Tn1NpKBeOorCYkB/8lMRoiZ5hUrCoMmDtxCS/d38mlg==} engines: {node: '>= 0.10.0'} + passport-github2@0.1.12: + resolution: {integrity: sha512-3nPUCc7ttF/3HSP/k9sAXjz3SkGv5Nki84I05kSQPo01Jqq1NzJACgMblCK0fGcv9pKCG/KXU3AJRDGLqHLoIw==} + engines: {node: '>= 0.8.0'} + + passport-google-oauth20@2.0.0: + resolution: {integrity: sha512-KSk6IJ15RoxuGq7D1UKK/8qKhNfzbLeLrG3gkLZ7p4A6DBCcv7xpyQwuXtWdpyR0+E0mwkpjY1VfPOhxQrKzdQ==} + engines: {node: '>= 0.4.0'} + + passport-oauth2@1.8.0: + resolution: {integrity: sha512-cjsQbOrXIDE4P8nNb3FQRCCmJJ/utnFKEz2NX209f7KOHPoX18gF7gBzBbLLsj2/je4KrgiwLLGjf0lm9rtTBA==} + engines: {node: '>= 0.4.0'} + passport-strategy@1.0.0: resolution: {integrity: sha512-CB97UUvDKJde2V0KDWWB3lyf6PC3FaZP7YxZ2G8OAtn9p4HI9j9JLP9qjOGZFvyl8uwNT8qM+hGnz/n16NI7oA==} engines: {node: '>= 0.4.0'} @@ -4609,6 +4652,9 @@ packages: resolution: {integrity: sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==} engines: {node: '>= 0.8'} + uid2@0.0.4: + resolution: {integrity: sha512-IevTus0SbGwQzYh3+fRsAMTVVPOoIVufzacXcHPmdlle1jUpq7BRL+mw3dgeLanvGZdwwbWhRV6XrcFNdBmjWA==} + uid@2.0.2: resolution: {integrity: sha512-u3xV3X7uzvi5b1MncmZo3i2Aw222Zk1keqLA1YkHldREkAhAqi65wuPfe7lHx8H/Wzy+8CE7S7uS3jekIM5s8g==} engines: {node: '>=8'} @@ -6878,6 +6924,28 @@ snapshots: dependencies: undici-types: 6.21.0 + '@types/oauth@0.9.6': + dependencies: + '@types/node': 22.15.21 + + '@types/passport-github2@1.2.9': + dependencies: + '@types/express': 5.0.3 + '@types/passport': 1.0.17 + '@types/passport-oauth2': 1.8.0 + + '@types/passport-google-oauth20@2.0.16': + dependencies: + '@types/express': 5.0.3 + '@types/passport': 1.0.17 + '@types/passport-oauth2': 1.8.0 + + '@types/passport-oauth2@1.8.0': + dependencies: + '@types/express': 5.0.3 + '@types/oauth': 0.9.6 + '@types/passport': 1.0.17 + '@types/passport@1.0.17': dependencies: '@types/express': 5.0.3 @@ -7451,6 +7519,8 @@ snapshots: base64-js@1.5.1: {} + base64url@3.0.1: {} + bin-version-check@5.1.0: dependencies: bin-version: 6.0.0 @@ -9256,6 +9326,8 @@ snapshots: oauth4webapi@3.5.5: {} + oauth@0.10.2: {} + object-assign@4.1.1: {} object-inspect@1.13.4: {} @@ -9361,6 +9433,22 @@ snapshots: dependencies: passport-strategy: 1.0.0 + passport-github2@0.1.12: + dependencies: + passport-oauth2: 1.8.0 + + passport-google-oauth20@2.0.0: + dependencies: + passport-oauth2: 1.8.0 + + passport-oauth2@1.8.0: + dependencies: + base64url: 3.0.1 + oauth: 0.10.2 + passport-strategy: 1.0.0 + uid2: 0.0.4 + utils-merge: 1.0.1 + passport-strategy@1.0.0: {} passport@0.7.0: @@ -10022,6 +10110,8 @@ snapshots: dependencies: random-bytes: 1.0.0 + uid2@0.0.4: {} + uid@2.0.2: dependencies: '@lukeed/csprng': 1.1.0 diff --git a/server/src/auth/auth.controller.ts b/server/src/auth/auth.controller.ts index e777259c7..5ff252ba0 100644 --- a/server/src/auth/auth.controller.ts +++ b/server/src/auth/auth.controller.ts @@ -1,7 +1,8 @@ -import { Controller, Get, Res, UseGuards } from '@nestjs/common'; +import { Controller, Get, Req, Res, UseGuards } from '@nestjs/common'; import { AuthGuard } from '@nestjs/passport'; -import { Response } from 'express'; +import { Request, Response } from 'express'; import { AuthProvider } from 'src/generated/prisma/enums'; +import { UserService } from 'src/user/user.service'; export interface AuthenticatedRequest extends Request { user: { @@ -14,27 +15,69 @@ export interface AuthenticatedRequest extends Request { @Controller('auth') export class AuthController { + constructor(private userService: UserService) {} + + @Get('login/github') + @UseGuards(AuthGuard('github')) + githubLogin() {} + + @Get('login/google') + @UseGuards(AuthGuard('google')) + googleLogin() {} + @Get('login/devsoc') @UseGuards(AuthGuard('oidc')) - login() {} + devsocLogin() {} + + @Get('callback/github') + @UseGuards(AuthGuard('github')) + githubCallback(@Res() res: Response) { + this.redirectAfterAuth(res); + } + + @Get('callback/google') + @UseGuards(AuthGuard('google')) + googleCallback(@Res() res: Response) { + this.redirectAfterAuth(res); + } @Get('callback/devsoc') @UseGuards(AuthGuard('oidc')) callback(@Res() res: Response) { - res.redirect( - (process.env.NODE_ENV === 'dev' ? `http://` : `https://`) + - `${process.env.CLIENT_HOST_NAME}:${process.env.CLIENT_HOST_PORT}/home`, - ); + this.redirectAfterAuth(res); } @Get('login/guest') @UseGuards(AuthGuard('guest')) guest(@Res() res: Response) { + this.redirectAfterAuth(res); + } + + @Get('logout') + async logout(@Req() req: Request, @Res() res: Response) { + let userId: string | undefined = undefined; + if (req.isAuthenticated() && (req as AuthenticatedRequest).user.isGuest) { + userId = (res.req as AuthenticatedRequest).user.id; + } + + res.clearCookie('connect.sid'); + // eslint-disable-next-line @typescript-eslint/no-unused-vars + req.logout((err) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + req.session?.destroy((err) => { + this.redirectAfterAuth(res, false); + }); + }); + + if (userId) { + await this.userService.deleteUser(userId); + } + } + + private redirectAfterAuth(res: Response, home: boolean = true) { res.redirect( (process.env.NODE_ENV === 'dev' ? `http://` : `https://`) + - `${process.env.CLIENT_HOST_NAME}:${process.env.CLIENT_HOST_PORT}/home`, + `${process.env.CLIENT_HOST_NAME}:${process.env.CLIENT_HOST_PORT}${home ? '/home' : ''}`, ); } - - // TODO: Add logout (and deleting guest users) } diff --git a/server/src/auth/auth.module.ts b/server/src/auth/auth.module.ts index dd46a2d8c..73fed09b2 100644 --- a/server/src/auth/auth.module.ts +++ b/server/src/auth/auth.module.ts @@ -1,11 +1,14 @@ import { Module } from '@nestjs/common'; -import { AuthService } from './auth.service'; -import { getConfig, OidcStrategy } from './oidc.strategy'; -import { GuestStrategy } from './guest.strategy'; import { PassportModule } from '@nestjs/passport'; +import { PrismaService } from 'src/prisma/prisma.service'; +import { UserService } from 'src/user/user.service'; import { AuthController } from './auth.controller'; +import { AuthService } from './auth.service'; +import { GithubStrategy } from './github.strategy'; +import { GoogleStrategy } from './google.strategy'; +import { GuestStrategy } from './guest.strategy'; +import { getConfig, OidcStrategy } from './oidc.strategy'; import { SessionSerializer } from './session.serializer'; -import { PrismaService } from 'src/prisma/prisma.service'; const OidcStrategyFactory = { provide: 'OidcStrategy', @@ -22,11 +25,14 @@ const OidcStrategyFactory = { ], controllers: [AuthController], providers: [ - AuthService, PrismaService, + UserService, OidcStrategyFactory, + GithubStrategy, + GoogleStrategy, GuestStrategy, SessionSerializer, + AuthService, ], }) export class AuthModule {} diff --git a/server/src/auth/github.strategy.ts b/server/src/auth/github.strategy.ts new file mode 100644 index 000000000..3e1815998 --- /dev/null +++ b/server/src/auth/github.strategy.ts @@ -0,0 +1,54 @@ +import { Injectable } from '@nestjs/common'; +import { PassportStrategy } from '@nestjs/passport'; +import { Request } from 'express'; +import { Strategy } from 'passport-github2'; +import { PrismaService } from 'src/prisma/prisma.service'; +import { promisify } from 'util'; + +@Injectable() +export class GithubStrategy extends PassportStrategy(Strategy, 'github') { + constructor(private readonly prisma: PrismaService) { + super({ + clientID: process.env.GITHUB_CLIENT_ID!, + clientSecret: process.env.GITHUB_CLIENT_SECRET!, + callbackURL: process.env.GITHUB_CALLBACK_URL!, + passReqToCallback: true, + scope: ['user:email'], + }); + } + + async validate( + req: Request, + _accessToken: string, + _refreshToken: string, + profile: { id: number; displayName: string | null; email: string }, + ) { + const displayName = profile.displayName?.trim() ?? 'GitHub User'; + + const user = await this.prisma.user.upsert({ + where: { + authProvider_authSubject: { + authProvider: 'GITHUB', + authSubject: profile.id.toString(), + }, + }, + update: { + lastLogin: new Date(), + }, + create: { + authProvider: 'GITHUB', + authSubject: profile.id.toString(), + firstName: displayName.split(' ')[0] || 'GitHub', + lastName: displayName.split(' ').slice(1).join(' ') || 'User', + isGuest: false, + settings: { + create: {}, + }, + }, + }); + + const login = promisify(req.login.bind(req)); + await login(user); + return user; + } +} diff --git a/server/src/auth/google.strategy.ts b/server/src/auth/google.strategy.ts new file mode 100644 index 000000000..3781e4083 --- /dev/null +++ b/server/src/auth/google.strategy.ts @@ -0,0 +1,56 @@ +import { Injectable } from '@nestjs/common'; +import { PassportStrategy } from '@nestjs/passport'; +import { Request } from 'express'; +import { Strategy } from 'passport-google-oauth20'; +import { PrismaService } from 'src/prisma/prisma.service'; +import { promisify } from 'util'; + +@Injectable() +export class GoogleStrategy extends PassportStrategy(Strategy, 'google') { + constructor(private readonly prisma: PrismaService) { + super({ + clientID: process.env.GOOGLE_CLIENT_ID!, + clientSecret: process.env.GOOGLE_CLIENT_SECRET!, + callbackURL: process.env.GOOGLE_REDIRECT_URI!, + scope: ['openid', 'email', 'profile'], + passReqToCallback: true, + }); + } + + async validate( + req: Request, + _accessToken: string, + _refreshToken: string, + profile: { + id: string; + name: { givenName: string; familyName: string }; + emails: { value: string; verified: boolean }[]; + }, + ) { + const user = await this.prisma.user.upsert({ + where: { + authProvider_authSubject: { + authProvider: 'GOOGLE', + authSubject: profile.id, + }, + }, + update: { + lastLogin: new Date(), + }, + create: { + authProvider: 'GOOGLE', + authSubject: profile.id, + firstName: profile.name.givenName, + lastName: profile.name.familyName, + isGuest: false, + settings: { + create: {}, + }, + }, + }); + + const login = promisify(req.login.bind(req)); + await login(user); + return user; + } +} diff --git a/server/src/timetable/timetable.controller.ts b/server/src/timetable/timetable.controller.ts index a63632e63..31d1d9cc5 100644 --- a/server/src/timetable/timetable.controller.ts +++ b/server/src/timetable/timetable.controller.ts @@ -12,7 +12,6 @@ import { } from '@nestjs/common'; import { TimetableService } from './timetable.service'; import { AuthenticatedGuard } from 'src/auth/authenticated.guard'; -import { Request } from 'express'; import { AuthenticatedRequest } from 'src/auth/auth.controller'; @Controller('user/timetables') diff --git a/server/src/user/user.service.ts b/server/src/user/user.service.ts index 40c13e820..2df6f138a 100644 --- a/server/src/user/user.service.ts +++ b/server/src/user/user.service.ts @@ -6,6 +6,14 @@ import { UserInfo, UserSettings } from './types'; export class UserService { constructor(private readonly prisma: PrismaService) {} + async deleteUser(userId: string): Promise { + await this.prisma.user.delete({ + where: { + id: userId, + }, + }); + } + async getUserInfo(userId: string): Promise { const data = await this.prisma.user.findUniqueOrThrow({ where: { From 1a313196c9beda92ee774c583c5009fe3be07f97 Mon Sep 17 00:00:00 2001 From: jason4193 <100593637+jason4193@users.noreply.github.com> Date: Mon, 8 Sep 2025 14:17:44 +0800 Subject: [PATCH 23/33] Implement Routes of Course & Class with userCreate for Auth Strategies * Update back the routes of course and class into timetable.controller * Add timetable init for oidc user if no term timetable * Resolved PR review from lucas (implement onboard util function) * Update the logic for create timetable using graphql query * Update google and github auth strategy with userOboard function * Resolve review from lucas --- server/src/app.module.ts | 2 + server/src/auth/auth.module.ts | 8 +- server/src/auth/auth.service.ts | 134 ++++++++++++++++++- server/src/auth/github.strategy.ts | 30 ++--- server/src/auth/google.strategy.ts | 30 ++--- server/src/auth/guest.strategy.ts | 23 +--- server/src/auth/oidc.strategy.ts | 35 ++--- server/src/graphql/graphql.service.ts | 16 +++ server/src/graphql/queries.ts | 12 ++ server/src/timetable/timetable.controller.ts | 104 ++++++++++++++ server/src/timetable/timetable.module.ts | 5 +- server/src/timetable/types.ts | 7 + 12 files changed, 312 insertions(+), 94 deletions(-) diff --git a/server/src/app.module.ts b/server/src/app.module.ts index 78eafda57..6654b8744 100644 --- a/server/src/app.module.ts +++ b/server/src/app.module.ts @@ -5,6 +5,7 @@ import { ConfigModule } from '@nestjs/config'; import config from './config'; import { UserModule } from './user/user.module'; import { AuthModule } from './auth/auth.module'; +import { TimetableModule } from './timetable/timetable.module'; @Module({ imports: [ @@ -14,6 +15,7 @@ import { AuthModule } from './auth/auth.module'; expandVariables: true, }), UserModule, + TimetableModule, AuthModule, ], controllers: [AppController], diff --git a/server/src/auth/auth.module.ts b/server/src/auth/auth.module.ts index 73fed09b2..aedc63d95 100644 --- a/server/src/auth/auth.module.ts +++ b/server/src/auth/auth.module.ts @@ -9,14 +9,15 @@ import { GoogleStrategy } from './google.strategy'; import { GuestStrategy } from './guest.strategy'; import { getConfig, OidcStrategy } from './oidc.strategy'; import { SessionSerializer } from './session.serializer'; +import { GraphqlService } from 'src/graphql/graphql.service'; const OidcStrategyFactory = { provide: 'OidcStrategy', - useFactory: async (prismaService: PrismaService) => { + useFactory: async (authService: AuthService) => { const config = await getConfig(); - return new OidcStrategy(config, prismaService); + return new OidcStrategy(config, authService); }, - inject: [PrismaService], + inject: [AuthService], }; @Module({ @@ -27,6 +28,7 @@ const OidcStrategyFactory = { providers: [ PrismaService, UserService, + GraphqlService, OidcStrategyFactory, GithubStrategy, GoogleStrategy, diff --git a/server/src/auth/auth.service.ts b/server/src/auth/auth.service.ts index a41c649f9..01b800adf 100644 --- a/server/src/auth/auth.service.ts +++ b/server/src/auth/auth.service.ts @@ -1,4 +1,136 @@ import { Injectable } from '@nestjs/common'; +import { PrismaService } from 'src/prisma/prisma.service'; +import { AuthProvider, Prisma, User } from 'src/generated/prisma/client'; +import { Term } from 'src/timetable/types'; +import { GraphqlService } from 'src/graphql/graphql.service'; + +interface OnboardParams { + firstName: string; + lastName: string; + isGuest: boolean; + provider?: AuthProvider; + subject?: string; +} @Injectable() -export class AuthService {} +export class AuthService { + constructor( + private readonly prisma: PrismaService, + private readonly graphql: GraphqlService, + ) {} + + private readonly TIMETABLE_DEFAULT_NAME = 'My Timetable'; + + async createUser(params: OnboardParams): Promise { + if (!params.isGuest) { + return await this.createAuthUser(params); + } else { + return await this.createGuest(params); + } + } + + private async createAuthUser(params: OnboardParams): Promise { + const { provider, subject } = params; + + if (provider === undefined || subject === undefined) { + throw new Error('Provider and subject must be defined for auth users'); + } + const currentYear = new Date().getFullYear().toString(); + const { availableTerms } = + await this.graphql.getAvailableTermsFrom(currentYear); + if (availableTerms.length === 0) { + throw new Error('No available terms found'); + } + + return await this.prisma.$transaction(async (transaction) => { + const user = await transaction.user.upsert({ + where: { + authProvider_authSubject: { + authProvider: provider, + authSubject: subject, + }, + }, + update: { + lastLogin: new Date(), + }, + create: { + authProvider: provider, + authSubject: subject, + firstName: params.firstName, + lastName: params.lastName, + isGuest: params.isGuest, + settings: { create: {} }, + }, + }); + + await this.createDefaultTimetablesIfNotExist( + transaction, + user.id, + availableTerms, + this.TIMETABLE_DEFAULT_NAME, + ); + + return user; + }); + } + + private async createGuest(params: OnboardParams): Promise { + const currentYear = new Date().getFullYear().toString(); + const { availableTerms } = + await this.graphql.getAvailableTermsFrom(currentYear); + if (availableTerms.length === 0) { + throw new Error('No available terms found'); + } + + return await this.prisma.user.create({ + data: { + firstName: params.firstName, + lastName: params.lastName, + isGuest: params.isGuest, + settings: { create: {} }, + timetables: { + create: availableTerms.map((availableTerm) => { + const term = availableTerm.split('-')[0] as Term; + const year = parseInt(availableTerm.split('-')[1]); + return { + name: this.TIMETABLE_DEFAULT_NAME, + year, + term, + }; + }), + }, + }, + }); + } + + private async createDefaultTimetablesIfNotExist( + transaction: Prisma.TransactionClient, + userId: string, + availableTerms: string[], + timetableName: string, + ) { + for (const availableTerm of availableTerms) { + const term = availableTerm.split('-')[0] as Term; + const year = parseInt(availableTerm.split('-')[1]); + const existing = + (await transaction.timetable.count({ + where: { + userId: userId, + year: year, + term: term, + }, + })) > 0; + + if (!existing) { + await transaction.timetable.create({ + data: { + userId: userId, + name: timetableName, + year: year, + term, + }, + }); + } + } + } +} diff --git a/server/src/auth/github.strategy.ts b/server/src/auth/github.strategy.ts index 3e1815998..bcd819ed9 100644 --- a/server/src/auth/github.strategy.ts +++ b/server/src/auth/github.strategy.ts @@ -2,12 +2,12 @@ import { Injectable } from '@nestjs/common'; import { PassportStrategy } from '@nestjs/passport'; import { Request } from 'express'; import { Strategy } from 'passport-github2'; -import { PrismaService } from 'src/prisma/prisma.service'; +import { AuthService } from './auth.service'; import { promisify } from 'util'; @Injectable() export class GithubStrategy extends PassportStrategy(Strategy, 'github') { - constructor(private readonly prisma: PrismaService) { + constructor(private readonly authService: AuthService) { super({ clientID: process.env.GITHUB_CLIENT_ID!, clientSecret: process.env.GITHUB_CLIENT_SECRET!, @@ -25,26 +25,12 @@ export class GithubStrategy extends PassportStrategy(Strategy, 'github') { ) { const displayName = profile.displayName?.trim() ?? 'GitHub User'; - const user = await this.prisma.user.upsert({ - where: { - authProvider_authSubject: { - authProvider: 'GITHUB', - authSubject: profile.id.toString(), - }, - }, - update: { - lastLogin: new Date(), - }, - create: { - authProvider: 'GITHUB', - authSubject: profile.id.toString(), - firstName: displayName.split(' ')[0] || 'GitHub', - lastName: displayName.split(' ').slice(1).join(' ') || 'User', - isGuest: false, - settings: { - create: {}, - }, - }, + const user = await this.authService.createUser({ + firstName: displayName.split(' ')[0] || 'GitHub', + lastName: displayName.split(' ').slice(1).join(' ') || 'User', + isGuest: false, + provider: 'GITHUB', + subject: profile.id.toString(), }); const login = promisify(req.login.bind(req)); diff --git a/server/src/auth/google.strategy.ts b/server/src/auth/google.strategy.ts index 3781e4083..1e7fe5fad 100644 --- a/server/src/auth/google.strategy.ts +++ b/server/src/auth/google.strategy.ts @@ -2,12 +2,12 @@ import { Injectable } from '@nestjs/common'; import { PassportStrategy } from '@nestjs/passport'; import { Request } from 'express'; import { Strategy } from 'passport-google-oauth20'; -import { PrismaService } from 'src/prisma/prisma.service'; +import { AuthService } from './auth.service'; import { promisify } from 'util'; @Injectable() export class GoogleStrategy extends PassportStrategy(Strategy, 'google') { - constructor(private readonly prisma: PrismaService) { + constructor(private readonly authService: AuthService) { super({ clientID: process.env.GOOGLE_CLIENT_ID!, clientSecret: process.env.GOOGLE_CLIENT_SECRET!, @@ -27,26 +27,12 @@ export class GoogleStrategy extends PassportStrategy(Strategy, 'google') { emails: { value: string; verified: boolean }[]; }, ) { - const user = await this.prisma.user.upsert({ - where: { - authProvider_authSubject: { - authProvider: 'GOOGLE', - authSubject: profile.id, - }, - }, - update: { - lastLogin: new Date(), - }, - create: { - authProvider: 'GOOGLE', - authSubject: profile.id, - firstName: profile.name.givenName, - lastName: profile.name.familyName, - isGuest: false, - settings: { - create: {}, - }, - }, + const user = await this.authService.createUser({ + firstName: profile.name.givenName, + lastName: profile.name.familyName, + isGuest: false, + provider: 'GOOGLE', + subject: profile.id, }); const login = promisify(req.login.bind(req)); diff --git a/server/src/auth/guest.strategy.ts b/server/src/auth/guest.strategy.ts index 9d09887de..cc2885fdb 100644 --- a/server/src/auth/guest.strategy.ts +++ b/server/src/auth/guest.strategy.ts @@ -2,32 +2,21 @@ import { Injectable } from '@nestjs/common'; import { PassportStrategy } from '@nestjs/passport'; import { Request } from 'express'; import { Strategy } from 'passport-custom'; -import { PrismaService } from 'src/prisma/prisma.service'; +import { AuthService } from './auth.service'; import { promisify } from 'util'; // TODO: Track usage of guest accounts, delete inactive ones @Injectable() export class GuestStrategy extends PassportStrategy(Strategy, 'guest') { - constructor(private readonly prisma: PrismaService) { - // TODO: How to fix this lint? - // eslint-disable-next-line @typescript-eslint/no-unsafe-call + constructor(private readonly authService: AuthService) { super(); } async validate(req: Request) { - const user = await this.prisma.user.create({ - // TODO: Generate unique names for guest users (to help with debugging) - data: { - firstName: 'Guest', - lastName: 'User', - isGuest: true, - }, - }); - - await this.prisma.settings.create({ - data: { - userId: user.id, - }, + const user = await this.authService.createUser({ + firstName: 'Guest', + lastName: 'User', + isGuest: true, }); const login = promisify(req.login.bind(req)); diff --git a/server/src/auth/oidc.strategy.ts b/server/src/auth/oidc.strategy.ts index b9a8ca423..04731cdb1 100644 --- a/server/src/auth/oidc.strategy.ts +++ b/server/src/auth/oidc.strategy.ts @@ -12,7 +12,7 @@ import { } from 'openid-client'; import { AuthenticateOptions } from 'openid-client/build/passport'; import { promisify } from 'util'; -import { PrismaService } from 'src/prisma/prisma.service'; +import { AuthService } from './auth.service'; const { Strategy } = // eslint-disable-next-line @typescript-eslint/no-require-imports require('openid-client/passport') as typeof import('openid-client/build/passport'); @@ -31,7 +31,7 @@ export const getConfig = async (): Promise => { export class OidcStrategy extends PassportStrategy(Strategy, 'oidc') { constructor( private readonly config: Configuration, - private readonly prisma: PrismaService, + private readonly authService: AuthService, ) { super({ config, @@ -79,33 +79,14 @@ export class OidcStrategy extends PassportStrategy(Strategy, 'oidc') { program: number; }; - const user = await this.prisma.user.upsert({ - where: { - authProvider_authSubject: { - authProvider: 'ZID', - authSubject: userInfo.sub, - }, - }, - update: { - lastLogin: new Date(), - }, - create: { - authProvider: 'ZID', - authSubject: userInfo.sub, - firstName: userData.firstName, - lastName: userData.lastName, - isGuest: false, - }, + const user = await this.authService.createUser({ + provider: 'ZID', + subject: userInfo.sub, + firstName: userData.firstName, + lastName: userData.lastName, + isGuest: false, }); - if (user.createdAt.getTime() === user.lastLogin.getTime()) { - await this.prisma.settings.create({ - data: { - userId: user.id, - }, - }); - } - const login = promisify(req.login.bind(req)); await login(user); return user; diff --git a/server/src/graphql/graphql.service.ts b/server/src/graphql/graphql.service.ts index 9c1aa453e..1d0168d36 100644 --- a/server/src/graphql/graphql.service.ts +++ b/server/src/graphql/graphql.service.ts @@ -27,4 +27,20 @@ export class GraphqlService { const { classDetails } = await this.sdk.ClassDetails({ classId }); return classDetails ? classDetails : undefined; } + + async getAvailableTermsFrom( + currentYear: string = new Date().getFullYear().toString(), + ): Promise<{ availableTerms: string[] }> { + const result = await this.sdk.GetAvailableTerms({ + currentYear: currentYear, + }); + const classes = result.classes ?? []; + const termsSet = new Set(); + for (const cls of classes) { + if (cls.term && cls.year) { + termsSet.add(`${cls.term}-${cls.year}`); + } + } + return { availableTerms: Array.from(termsSet) }; + } } diff --git a/server/src/graphql/queries.ts b/server/src/graphql/queries.ts index 0c70ff204..52f8c31f8 100644 --- a/server/src/graphql/queries.ts +++ b/server/src/graphql/queries.ts @@ -20,3 +20,15 @@ export const CLASS_DETAILS = gql(` } } `); + +export const GET_AVAILABLE_TERMS = gql(` + query GetAvailableTerms($currentYear: String!) { + classes( + where: {term: {_in: ["T1", "T2", "T3", "U1"]}, year: {_gte: $currentYear}} + distinct_on: offering_period + ) { + term + year + } + } +`); diff --git a/server/src/timetable/timetable.controller.ts b/server/src/timetable/timetable.controller.ts index 31d1d9cc5..873bf8d15 100644 --- a/server/src/timetable/timetable.controller.ts +++ b/server/src/timetable/timetable.controller.ts @@ -3,6 +3,7 @@ import { Controller, Delete, Get, + HttpStatus, Param, Patch, Post, @@ -13,6 +14,7 @@ import { import { TimetableService } from './timetable.service'; import { AuthenticatedGuard } from 'src/auth/authenticated.guard'; import { AuthenticatedRequest } from 'src/auth/auth.controller'; +import { AddCourseDto } from './types'; @Controller('user/timetables') export class TimetableController { @@ -98,4 +100,106 @@ export class TimetableController { ) { await this.timetableService.makePrimary(req.user.id, timetableId, data); } + + @Get('courses/:timetableId') + @UseGuards(AuthenticatedGuard) + async getCourseIds( + @Req() req: AuthenticatedRequest, + @Param('timetableId') timetableId: string, + ) { + return await this.timetableService.getCourseIds(req.user.id, timetableId); + } + + @Post('course/:timetableId/:courseId') + @UseGuards(AuthenticatedGuard) + async addCourse( + @Req() req: AuthenticatedRequest, + @Param('timetableId') timetableId: string, + @Param('courseId') courseId: string, + @Body() addCourseDto: AddCourseDto, + ) { + await this.timetableService.addCourse( + req.user.id, + timetableId, + courseId, + addCourseDto, + ); + return HttpStatus.CREATED; + } + + @Delete('course/:timetableId/:courseId') + @UseGuards(AuthenticatedGuard) + async removeCourse( + @Req() req: AuthenticatedRequest, + @Param('timetableId') timetableId: string, + @Param('courseId') courseId: string, + ) { + await this.timetableService.removeCourse( + req.user.id, + timetableId, + courseId, + ); + } + + @Patch('course/:timetableId/:courseId/colour') + @UseGuards(AuthenticatedGuard) + async setCourseColour( + @Req() req: AuthenticatedRequest, + @Param('timetableId') timetableId: string, + @Param('courseId') courseId: string, + @Body('colour') colour: string, + ) { + await this.timetableService.setCourseColour( + req.user.id, + timetableId, + courseId, + colour, + ); + } + + @Get('classes/:timetableId/:courseId') + @UseGuards(AuthenticatedGuard) + async getSelectedClassIds( + @Req() req: AuthenticatedRequest, + @Param('timetableId') timetableId: string, + @Param('courseId') courseId: string, + ) { + return await this.timetableService.getSelectedClassIds( + req.user.id, + timetableId, + courseId, + ); + } + + @Patch('class/:timetableId/:courseId') + @UseGuards(AuthenticatedGuard) + async updateSelectedClass( + @Req() req: AuthenticatedRequest, + @Param('timetableId') timetableId: string, + @Param('courseId') courseId: string, + @Body('classId') classId: string, + ) { + await this.timetableService.updateSelectedClass( + req.user.id, + timetableId, + courseId, + classId, + ); + } + + @Delete('class/:timetableId/:courseId/:classId') + @UseGuards(AuthenticatedGuard) + async removeSelectedClass( + @Req() req: AuthenticatedRequest, + @Param('timetableId') timetableId: string, + @Param('courseId') courseId: string, + @Param('classId') classId: string, + ) { + await this.timetableService.removeSelectedClass( + req.user.id, + timetableId, + courseId, + classId, + ); + } } diff --git a/server/src/timetable/timetable.module.ts b/server/src/timetable/timetable.module.ts index c9cb7f54a..f10a800ed 100644 --- a/server/src/timetable/timetable.module.ts +++ b/server/src/timetable/timetable.module.ts @@ -1,9 +1,10 @@ import { Module } from '@nestjs/common'; import { TimetableController } from './timetable.controller'; import { TimetableService } from './timetable.service'; - +import { PrismaService } from 'src/prisma/prisma.service'; +import { GraphqlService } from 'src/graphql/graphql.service'; @Module({ + providers: [TimetableService, PrismaService, GraphqlService], controllers: [TimetableController], - providers: [TimetableService], }) export class TimetableModule {} diff --git a/server/src/timetable/types.ts b/server/src/timetable/types.ts index a94f50160..c790a14e8 100644 --- a/server/src/timetable/types.ts +++ b/server/src/timetable/types.ts @@ -14,3 +14,10 @@ export class UserTimetable { term: string; primary: boolean; } + +export enum Term { + U1 = 'U1', + T1 = 'T1', + T2 = 'T2', + T3 = 'T3', +} From 91fd8003fc30e9de7ea1a088ab6ca6495a4d6429 Mon Sep 17 00:00:00 2001 From: Mark Tran <29350857+mark-trann@users.noreply.github.com> Date: Wed, 17 Sep 2025 18:41:35 +1000 Subject: [PATCH 24/33] Friends sidebar (#1070) * Remove old friends implementation * Add togglable friends * Move sidebar collapsed state to app context * Remove another old friend component * Add friend list and search bar * Refactor sidebar's collapsed state into an AppContext * MVP of friends list with simple search * reverting auth guard lol * Refactor sidebar styled and fix user account padding * Fix friends list scroll issue * Fix sidebar always scrolling * Remaster the add friends button * Move scrollable component down by 1 layer so that notangles logo is not part of scroll * Add todo comment * undo changes for auth on server * Fix search and add friend buttons on sidebar for collapsed. Also added hover to support future click-on-friend operation * Clicking search button on collapsed sidebar will expand it and focus on form immediately * Hide sidebar scroll (removes weird ui bug in collapsed as well) * Remove empty tag wraps --------- Co-authored-by: Mark Tran <29350857+marktran2@users.noreply.github.com> --- .../src/components/sidebar/CollapseButton.tsx | 9 +- client/src/components/sidebar/CustomModal.tsx | 22 ++- .../src/components/sidebar/DarkModeButton.tsx | 11 +- .../src/components/sidebar/FriendsButton.tsx | 51 +++-- client/src/components/sidebar/Sidebar.tsx | 179 +++++++++++------- client/src/components/sidebar/UserAccount.tsx | 43 ++--- .../sidebar/friends/AddAFriendTab.tsx | 162 ---------------- .../src/components/sidebar/friends/Friend.tsx | 53 ++++++ .../sidebar/friends/FriendsDialog.tsx | 68 ------- .../sidebar/friends/FriendsList.tsx | 73 +++++++ .../sidebar/friends/FriendsTablist.tsx | 82 -------- .../sidebar/friends/RequestsTab.tsx | 98 ---------- .../sidebar/friends/UserProfile.tsx | 32 ++-- .../sidebar/friends/YourFriendsTab.tsx | 63 ------ .../components/sidebar/friends/friends.json | 12 ++ client/src/context/AppContext.tsx | 13 ++ client/src/interfaces/PropTypes.ts | 15 -- 17 files changed, 355 insertions(+), 631 deletions(-) delete mode 100644 client/src/components/sidebar/friends/AddAFriendTab.tsx create mode 100644 client/src/components/sidebar/friends/Friend.tsx delete mode 100644 client/src/components/sidebar/friends/FriendsDialog.tsx create mode 100644 client/src/components/sidebar/friends/FriendsList.tsx delete mode 100644 client/src/components/sidebar/friends/FriendsTablist.tsx delete mode 100644 client/src/components/sidebar/friends/RequestsTab.tsx delete mode 100644 client/src/components/sidebar/friends/YourFriendsTab.tsx create mode 100644 client/src/components/sidebar/friends/friends.json diff --git a/client/src/components/sidebar/CollapseButton.tsx b/client/src/components/sidebar/CollapseButton.tsx index 2eb4511a6..a7ea5ca52 100644 --- a/client/src/components/sidebar/CollapseButton.tsx +++ b/client/src/components/sidebar/CollapseButton.tsx @@ -1,9 +1,11 @@ import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; import { IconButton, Tooltip } from '@mui/material'; import { styled } from '@mui/material/styles'; +import { useContext } from 'react'; + +import { AppContext } from '../../context/AppContext'; interface CollapseButtonProps { - collapsed: boolean; onClick: () => void; toolTipTitle: string; } @@ -19,12 +21,13 @@ const StyledExpandMoreIcon = styled(ExpandMoreIcon, { shouldForwardProp: (prop) transform: ${({ collapsed }) => (collapsed ? 'rotate(270deg)' : 'rotate(90deg)')}; `; -const CollapseButton: React.FC = ({ collapsed, onClick, toolTipTitle }) => { +const CollapseButton: React.FC = ({ onClick, toolTipTitle }) => { + const { sidebarCollapsed } = useContext(AppContext); return ( <> - + diff --git a/client/src/components/sidebar/CustomModal.tsx b/client/src/components/sidebar/CustomModal.tsx index e783c645f..5f70f5fd1 100644 --- a/client/src/components/sidebar/CustomModal.tsx +++ b/client/src/components/sidebar/CustomModal.tsx @@ -1,9 +1,19 @@ import { Close } from '@mui/icons-material'; import { Dialog, DialogContent, DialogTitle, Divider, IconButton, Tooltip, Typography } from '@mui/material'; import { styled } from '@mui/material/styles'; -import React from 'react'; +import { ReactNode, useContext, useState } from 'react'; -import { CustomModalProps } from '../../interfaces/PropTypes'; +import { AppContext } from '../../context/AppContext'; + +interface CustomModalProps { + title: string; + toolTipTitle: string; + showIcon: ReactNode; + description: string; + content: ReactNode; + isClickable: boolean; + isSelected?: boolean; +} const StyledDialogTitle = styled(DialogTitle)` background-color: ${({ theme }) => theme.palette.background.paper}; @@ -45,11 +55,11 @@ const CustomModal: React.FC = ({ showIcon, description, content, - collapsed, isClickable, isSelected = false, }) => { - const [isOpen, setIsOpen] = React.useState(false); + const [isOpen, setIsOpen] = useState(false); + const { sidebarCollapsed } = useContext(AppContext); const toggleIsOpen = () => { if (isClickable) { @@ -59,10 +69,10 @@ const CustomModal: React.FC = ({ return ( <> - + {showIcon} - {collapsed ? '' : title} + {sidebarCollapsed ? '' : title} = ({ collapsed }) => { +const DarkModeButton = () => { const { isDarkMode } = useGetUserSettingsQuery(); const updateUserSettings = useSetUserSettings(); + const { sidebarCollapsed } = useContext(AppContext); return ( <> - + { @@ -33,7 +34,7 @@ const DarkModeButton: React.FC = ({ collapsed }) => { }} > {isDarkMode ? : } - {!collapsed && ( + {!sidebarCollapsed && ( {isDarkMode ? 'Light Mode' : 'Dark Mode'} )} diff --git a/client/src/components/sidebar/FriendsButton.tsx b/client/src/components/sidebar/FriendsButton.tsx index fb8bfdf6d..6982ca640 100644 --- a/client/src/components/sidebar/FriendsButton.tsx +++ b/client/src/components/sidebar/FriendsButton.tsx @@ -1,42 +1,55 @@ -import { SwitchAccount } from '@mui/icons-material'; +import { ArrowDropDown, ArrowDropUp, Person } from '@mui/icons-material'; import { IconButton, Tooltip, Typography } from '@mui/material'; import { styled } from '@mui/material/styles'; -import React from 'react'; +import { Box } from '@mui/system'; +import { useContext, useMemo } from 'react'; + +import { AppContext } from '../../context/AppContext'; interface FriendsButtonProps { - collapsed: boolean; + friendsListOpen: boolean; + handleFriendsListToggle: () => void; } const StyledFriendsButton = styled(IconButton, { shouldForwardProp: (prop) => prop !== 'isSelected' })<{ isSelected: boolean; }>` display: flex; + flex-direction: row; + justify-content: space-between; border-radius: 8px; - gap: 16px; - justify-content: flex-start; - padding: 12px 12px 12px 12px; + padding: 12px; background-color: ${({ isSelected }) => (isSelected ? 'rgb(157, 157, 157, 0.15)' : 'transparent')}; `; +const StyledFriendsContainer = styled(Box)` + display: flex; + justify-content: flex-start; + gap: 16px; +`; + const IndividualComponentTypography = styled(Typography)` font-size: 16px; `; // TODO: Repurpose using Sunny's design for friends -const FriendsButton: React.FC = ({ collapsed }) => { +const FriendsButton = ({ friendsListOpen, handleFriendsListToggle }: FriendsButtonProps) => { + const { sidebarCollapsed } = useContext(AppContext); + const friendToggleArrow = useMemo(() => { + if (sidebarCollapsed) return null; + return friendsListOpen ? : ; + }, [sidebarCollapsed, friendsListOpen]); + return ( - <> - - setGroupsSidebarCollapsed(!groupsSidebarCollapsed)} UNCOMMENT to see shared timetables - isSelected={false} - > - - {collapsed ? '' : 'Shared Timetables'} - - - + + + + + {sidebarCollapsed ? '' : 'Friends'} + + {friendToggleArrow} + + ); }; diff --git a/client/src/components/sidebar/Sidebar.tsx b/client/src/components/sidebar/Sidebar.tsx index bc105da62..04f2c2864 100644 --- a/client/src/components/sidebar/Sidebar.tsx +++ b/client/src/components/sidebar/Sidebar.tsx @@ -1,16 +1,18 @@ -import { CalendarMonth, Description, Info, Security, Settings as SettingsIcon } from '@mui/icons-material'; -import { Divider, Drawer, Typography, useMediaQuery, useTheme } from '@mui/material'; +import { AddCircle, CalendarMonth, Description, Info, Security, Settings as SettingsIcon } from '@mui/icons-material'; +import { Divider, Drawer, IconButton, Tooltip, Typography, useMediaQuery, useTheme } from '@mui/material'; import { styled } from '@mui/material/styles'; -import React, { useMemo, useState } from 'react'; +import { useContext, useMemo, useState } from 'react'; import notanglesLogoGif from '../../assets/notangles.gif'; import notanglesLogo from '../../assets/notangles_1.png'; import { leftContentPadding } from '../../constants/theme'; +import { AppContext } from '../../context/AppContext'; import About from './About'; import Changelog from './Changelog'; import CollapseButton from './CollapseButton'; import CustomModal from './CustomModal'; import DarkModeButton from './DarkModeButton'; +import FriendsList from './friends/FriendsList'; import FriendsButton from './FriendsButton'; import MobileMenuButton from './MobileMenuButton'; import Privacy from './Privacy'; @@ -42,6 +44,7 @@ const StyledDrawer = styled(Drawer, { transition: 'width 0.1s ease', zIndex: 1200, marginRight: leftContentPadding, + height: '100vh', '& .MuiDrawer-paper': { top: 0, @@ -53,6 +56,23 @@ const StyledDrawer = styled(Drawer, { }, })); +const Container = styled('div')` + display: flex; + flex-direction: column; + justify-content: space-between; + height: 100vh; +`; + +const HeaderAndControlsContainer = styled('div')` + flex: 1; + overflow-y: auto; + scrollbar-width: none; + -ms-overflow-style: none; + ::-webkit-scrollbar { + display: none; + } +`; + const SidebarTitle = styled(Typography)` font-weight: 700; font-size: 18px; @@ -71,24 +91,10 @@ const HeaderContainer = styled('div')` padding: 10px 19px 10px 19px; `; -const SideBarContainer = styled('div')` - display: flex; - flex-direction: column; - padding: 20px 16px 20px 16px; - gap: 16px; -`; - -const Container = styled('div')` - display: flex; - flex-direction: column; - justify-content: space-between; - height: 100vh; -`; - const NavComponentsContainer = styled('div')` display: flex; flex-direction: column; - height: 100%; + padding: 20px 16px 20px 16px; gap: 8px; `; @@ -104,7 +110,6 @@ const SidebarFooterText = styled('div')` flex-direction: column; gap: 16px; font-size: 0.8rem; - margin-top: 16px; `; const SidebarFooterWrapper = styled('div')` @@ -112,6 +117,22 @@ const SidebarFooterWrapper = styled('div')` flex-direction: row; `; +const AddFriendsButton = styled(IconButton)` + display: flex; + flex-direction: row; + gap: 16px; + border-radius: 8px; + justify-content: space-around; + padding: 8px; + color: ${({ theme }) => theme.palette.text.primary}; + border: 1px solid; + border-color: ${({ theme }) => theme.palette.primary.main}; +`; + +const StyledAddIcon = styled(AddCircle)` + color: ${({ theme }) => theme.palette.primary.main}; +`; + const modalData = [ { title: 'About', @@ -147,17 +168,17 @@ const modalData = [ }, ]; -const Sidebar: React.FC = () => { +const Sidebar = () => { const theme = useTheme(); const isMobile = useMediaQuery(theme.breakpoints.down('md')); const collapsedWidth = useMemo(() => (isMobile ? 0 : 80), [isMobile]); - const isWide = useMediaQuery(theme.breakpoints.only('xl')); const [currLogo, setCurrLogo] = useState(notanglesLogo); - const [collapsed, setCollapsed] = useState(() => !isWide); + const [friendsListOpen, setFriendsListOpen] = useState(false); + const { sidebarCollapsed, setSidebarCollapsed } = useContext(AppContext); const handleCollapse = (val: boolean) => { - setCollapsed(val); + setSidebarCollapsed(val); // forces window resize event upon sidebar state changing to adjust position of cards // Not currently used, but here is how you would do it if needed // setTimeout(() => window.dispatchEvent(new Event('resize')), 120); @@ -173,75 +194,89 @@ const Sidebar: React.FC = () => { showIcon={modal.showIcon} description={modal.description} content={modal.content} - collapsed={collapsed} isClickable={modal.isClickable} /> )), - [collapsed], + [], ); return ( <> { handleCollapse(true); }} elevation={0} > -
    - - - { - setCurrLogo(notanglesLogoGif); - }} - onMouseOut={() => { - setCurrLogo(notanglesLogo); - }} - /> - - {!collapsed && ( + + + { + setCurrLogo(notanglesLogoGif); + }} + onMouseOut={() => { + setCurrLogo(notanglesLogo); + }} + /> + + {!sidebarCollapsed && ( + <> + Notangles + + )} + + + + + + } + description={'Current Timetable'} + content={null} + // currently not clickable since this is our current page + isClickable={false} + // hardcoded until we move away from single page site + isSelected={true} + /> + { + setFriendsListOpen((prev) => !prev); + }} + /> + {!friendsListOpen ? ( <> - Notangles + + {modalComponents} + ) : ( + )} - - - - - - - } - description={'Current Timetable'} - content={null} - collapsed={collapsed} - // currently not clickable since this is our current page - isClickable={false} - // hardcoded until we move away from single page site - isSelected={true} - /> - - - {modalComponents} - - -
    + + - - - {!isMobile && !collapsed ? ( + {friendsListOpen && ( + + {!sidebarCollapsed && Add Friends} + + + + + )} + + + {!isMobile && !sidebarCollapsed ? ( @@ -250,7 +285,6 @@ const Sidebar: React.FC = () => { {import.meta.env.VITE_COMMIT?.substring(0, 7) ?? 'unknown commit'} { handleCollapse(true); }} @@ -261,7 +295,6 @@ const Sidebar: React.FC = () => { ) : ( !isMobile && ( { handleCollapse(false); }} @@ -277,7 +310,7 @@ const Sidebar: React.FC = () => { onClick={() => { handleCollapse(false); }} - toolTipTitle={collapsed ? 'Expand' : 'Collapse'} + toolTipTitle={sidebarCollapsed ? 'Expand' : 'Collapse'} /> )} diff --git a/client/src/components/sidebar/UserAccount.tsx b/client/src/components/sidebar/UserAccount.tsx index a1c3ab17f..17cc8a1b8 100644 --- a/client/src/components/sidebar/UserAccount.tsx +++ b/client/src/components/sidebar/UserAccount.tsx @@ -1,17 +1,14 @@ import { LogoutRounded } from '@mui/icons-material'; import { IconButton, Tooltip } from '@mui/material'; import { styled } from '@mui/material/styles'; -import React, { useState } from 'react'; +import { useContext, useState } from 'react'; import { API_URL } from '../../api/config'; +import { AppContext } from '../../context/AppContext'; import { useAuth } from '../../hooks/useAuth'; import StyledDialog from '../StyledDialog'; import UserProfile from './friends/UserProfile'; -interface UserAccountProps { - collapsed: boolean; -} - const UserAuth = styled('div')` display: flex; align-items: center; @@ -27,17 +24,20 @@ const StyledIconButton = styled(IconButton)` color: ${({ theme }) => theme.palette.text.primary}; `; -const ExpandedContainer = styled('div')` - display: flex; - align-items: center; - justify-content: space-between; - width: 100%; - padding: 10px 12px; -`; +const ExpandedContainer = styled('div', { + shouldForwardProp: (prop) => prop !== 'sidebarCollapsed', +})<{ sidebarCollapsed: boolean }>(({ sidebarCollapsed }) => ({ + display: 'flex', + alignItems: 'center', + justifyContent: sidebarCollapsed ? 'center' : 'space-between', + width: '100%', + padding: '10px 6px', +})); -const UserAccount: React.FC = ({ collapsed }) => { +const UserAccount = () => { const [logoutDialog, setLogoutDialog] = useState(false); const { user } = useAuth(); + const { sidebarCollapsed } = useContext(AppContext); const onLogout = () => { window.location.href = `${API_URL.server}/auth/logout`; @@ -64,7 +64,10 @@ const UserAccount: React.FC = ({ collapsed }) => { confirmButtonText="Log out" /> - {collapsed ? ( + + {!sidebarCollapsed && ( + + )} { @@ -74,17 +77,7 @@ const UserAccount: React.FC = ({ collapsed }) => { - ) : ( - - - - {/* TODO: error handling for when logging out */} - - - - - - )} + ); diff --git a/client/src/components/sidebar/friends/AddAFriendTab.tsx b/client/src/components/sidebar/friends/AddAFriendTab.tsx deleted file mode 100644 index b601130bc..000000000 --- a/client/src/components/sidebar/friends/AddAFriendTab.tsx +++ /dev/null @@ -1,162 +0,0 @@ -import styled from '@emotion/styled'; -import { Add, Close } from '@mui/icons-material'; -import { IconButton, TextField, Tooltip } from '@mui/material'; -import { useEffect, useState } from 'react'; - -import { API_URL } from '../../../api/config'; -import NetworkError from '../../../interfaces/NetworkError'; -import { User } from './User'; -import UserProfile from './UserProfile'; - -const StyledContainer = styled('div')` - display: flex; - flex-direction: column; - gap: 12px; -`; - -const StyledUsersContainer = styled('div')` - display: flex; - flex-direction: column; - gap: 2px; -`; - -const StyledItem = styled('div')<{ isSelected: boolean }>(({ isSelected }) => ({ - display: 'flex', - justifyContent: 'space-between', - padding: '12px 8px', - borderRadius: '8px', - backgroundColor: isSelected ? '#e1eaef' : '', -})); - -const AddAFriendTab: React.FC<{ user: User; fetchUserInfo: (userID: string) => void }> = ({ user, fetchUserInfo }) => { - const [otherUsers, setOtherUsers] = useState([]); - const [searchQuery, setSearchQuery] = useState(''); - - const getNonFriendUsers = async () => { - try { - const res = await fetch(`${API_URL.server}/user/all`, { - method: 'GET', - headers: { - Accept: 'application/json', - 'Content-Type': 'application/json', - }, - credentials: 'include', - }); - if (res.status !== 200) throw new NetworkError("Couldn't get response"); - const getUsersStatus = await res.json(); - console.log('get all users request status', getUsersStatus); - const allUsers = getUsersStatus.data; - const excludingLoggedUser = allUsers.filter((userData: User) => userData.userID !== user.userID); - const nonFriendUsers = excludingLoggedUser.filter( - (userData: User) => !user.friends.map((friend) => friend.userID).includes(userData.userID), - ); - setOtherUsers(nonFriendUsers); - } catch (error) { - throw new NetworkError(`Couldn't get response cause encountered error: ${error}`); - } - }; - - useEffect(() => { - getNonFriendUsers(); - }, [user]); - - const handleSearchChange = (event: React.ChangeEvent) => { - setSearchQuery(event.target.value); - }; - - const filteredUsers = otherUsers.filter( - (user) => - user.firstname.toLowerCase().includes(searchQuery.toLowerCase()) || - user.lastname.toLowerCase().includes(searchQuery.toLowerCase()) || - user.email.toLowerCase().includes(searchQuery.toLowerCase()) || - user.userID.toLowerCase().includes(searchQuery.toLowerCase()), - ); - - const handleSendRequest = async (otherUserID: string) => { - try { - const res = await fetch(`${API_URL.server}/friend/request`, { - method: 'POST', - headers: { - Accept: 'application/json', - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - senderId: user.userID, - sendeeId: otherUserID, - }), - credentials: 'include', - }); - if (res.status !== 201) throw new NetworkError("Couldn't get response"); - const acceptRequestStatus = await res.json(); - console.log('send request status', acceptRequestStatus); - fetchUserInfo(user.userID); - } catch (error) { - throw new NetworkError(`Couldn't get response cause encountered error: ${error}`); - } - }; - - const handleCancelRequest = async (otherUserID: string) => { - try { - const res = await fetch(`${API_URL.server}/friend/request`, { - method: 'DELETE', - headers: { - Accept: 'application/json', - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - sendeeId: otherUserID, - senderId: user.userID, - }), - credentials: 'include', - }); - if (res.status !== 200) throw new NetworkError("Couldn't get response"); - const declineRequestStatus = await res.json(); - console.log('decline request status', declineRequestStatus); - fetchUserInfo(user.userID); - } catch (error) { - throw new NetworkError(`Couldn't get response cause encountered error: ${error}`); - } - }; - - return ( - - - - {filteredUsers.map((otherUser) => ( - userRequested.userID).includes(otherUser.userID)} - > - - {user.outgoing.map((userRequested) => userRequested.userID).includes(otherUser.userID) ? ( - - handleCancelRequest(otherUser.userID)}> - - - - ) : ( - - handleSendRequest(otherUser.userID)}> - - - - )} - - ))} - {otherUsers.length === 0 &&
    You are friends with everyone! There is no one else to add.
    } -
    -
    - ); -}; - -export default AddAFriendTab; diff --git a/client/src/components/sidebar/friends/Friend.tsx b/client/src/components/sidebar/friends/Friend.tsx new file mode 100644 index 000000000..2fbd142da --- /dev/null +++ b/client/src/components/sidebar/friends/Friend.tsx @@ -0,0 +1,53 @@ +import MoreVertIcon from '@mui/icons-material/MoreVert'; +import { IconButton, styled, Tooltip } from '@mui/material'; +import { Box } from '@mui/system'; +import { useContext, useState } from 'react'; + +import { useGetUserSettingsQuery } from '../../../api/user/queries'; +import { AppContext } from '../../../context/AppContext'; +import UserProfile from './UserProfile'; + +const StyledFriendContainer = styled(Box, { + shouldForwardProp: (prop) => prop !== 'isDarkMode' && prop !== 'sidebarCollapsed', +})<{ isDarkMode: boolean; sidebarCollapsed: boolean }>` + display: flex; + flex-direction: row; + justify-content: ${({ sidebarCollapsed }) => (sidebarCollapsed ? 'center' : 'space-between')}; + align-items: center; + padding: 4px; + cursor: pointer; + border-radius: 8px; + + &:hover { + background-color: ${({ theme, isDarkMode }) => + isDarkMode ? theme.palette.secondary.dark : theme.palette.secondary.light} +`; + +interface FriendProps { + firstName: string; +} + +const Friend = ({ firstName }: FriendProps) => { + const [kebabOpen, setKebabOpen] = useState(false); + const { sidebarCollapsed } = useContext(AppContext); + const { isDarkMode } = useGetUserSettingsQuery(); + + return ( + + + + {!sidebarCollapsed && ( + { + setKebabOpen((prev) => !prev); + }} + > + + + )} + + + ); +}; + +export default Friend; diff --git a/client/src/components/sidebar/friends/FriendsDialog.tsx b/client/src/components/sidebar/friends/FriendsDialog.tsx deleted file mode 100644 index 061a34701..000000000 --- a/client/src/components/sidebar/friends/FriendsDialog.tsx +++ /dev/null @@ -1,68 +0,0 @@ -import { Group } from '@mui/icons-material'; -import { Close as CloseIcon } from '@mui/icons-material'; -import { Badge, Dialog, DialogTitle, IconButton, Paper, styled, Typography } from '@mui/material'; -import React, { useState } from 'react'; - -import FriendsTablist from './FriendsTablist'; -import { User } from './User'; - -const StyledDialogTitle = styled(DialogTitle)` - background-color: ${({ theme }) => theme.palette.background.paper}; - padding: 30px 30px 0px 30px; - display: flex; - flex-direction: row; - justify-content: space-between; -`; - -const StyledPaper = styled(Paper)` - height: 80vh; - overflow: hidden; - display: flex; - flex-direction: column; -`; - -const FriendsDialog: React.FC<{ user: User; fetchUserInfo: (userID: string) => void }> = ({ user, fetchUserInfo }) => { - const [isOpen, setIsOpen] = useState(false); - - const handleClose = () => { - setIsOpen(false); - }; - - return ( - <> - { - setIsOpen(true); - }} - > - - - - - - - <> - - Friends -
    - - - -
    -
    - - -
    - - ); -}; - -export default FriendsDialog; diff --git a/client/src/components/sidebar/friends/FriendsList.tsx b/client/src/components/sidebar/friends/FriendsList.tsx new file mode 100644 index 000000000..210dfb560 --- /dev/null +++ b/client/src/components/sidebar/friends/FriendsList.tsx @@ -0,0 +1,73 @@ +import { Search } from '@mui/icons-material'; +import SearchIcon from '@mui/icons-material/Search'; +import { FormControl, IconButton, InputAdornment, InputLabel, OutlinedInput } from '@mui/material'; +import { Box, styled } from '@mui/system'; +import { useContext, useMemo, useState } from 'react'; + +import { AppContext } from '../../../context/AppContext'; +import Friend from './Friend'; +import friendList from './friends.json'; + +const FriendsListContainer = styled(Box)` + display: flex; + flex-direction: column; +`; + +const StyledSearchButton = styled(IconButton)` + display: flex; + flex-direction: row; + gap: 16px; + border-radius: 8px; + justify-content: space-around; + padding: 12px; +`; + +const FriendsList = () => { + const [searchVal, setSearchVal] = useState(''); + const { sidebarCollapsed, setSidebarCollapsed } = useContext(AppContext); + + // TODO: implement fuzzy search + const renderedFriends = useMemo(() => { + // TODO: replace hard coded data with integration with server + const filteredFriends = friendList.filter((friend) => friend.toLowerCase().includes(searchVal)); + return filteredFriends.map((friend, index) => ); + }, [searchVal]); + + const handleClickSearchBarIcon = () => { + if (sidebarCollapsed) { + setSidebarCollapsed(false); + // TODO: put form search in focus + } + }; + + return ( + + {sidebarCollapsed ? ( + + + + ) : ( + + Search + + + + } + label="Search" + onChange={(e) => { + setSearchVal(e.target.value.toLowerCase()); + }} + inputRef={(input: HTMLInputElement | null) => { + input?.focus(); + }} + /> + + )} + {renderedFriends} + + ); +}; + +export default FriendsList; diff --git a/client/src/components/sidebar/friends/FriendsTablist.tsx b/client/src/components/sidebar/friends/FriendsTablist.tsx deleted file mode 100644 index c12985682..000000000 --- a/client/src/components/sidebar/friends/FriendsTablist.tsx +++ /dev/null @@ -1,82 +0,0 @@ -import styled from '@emotion/styled'; -import { Badge } from '@mui/material'; -import Box from '@mui/material/Box'; -import Tab from '@mui/material/Tab'; -import Tabs from '@mui/material/Tabs'; -import * as React from 'react'; - -import AddAFriendTab from './AddAFriendTab'; -import RequestsTab from './RequestsTab'; -import { User } from './User'; -import YourFriendsTab from './YourFriendsTab'; - -interface TabPanelProps { - children?: React.ReactNode; - index: number; - value: number; -} - -const MoveTextFromUnderBadge = styled('div')` - margin-right: 12px; -`; - -const CustomTabPanel = (props: TabPanelProps) => { - const { children, value, index, ...other } = props; - - return ( - - ); -}; - -const a11yProps = (index: number) => { - return { - id: `simple-tab-${index}`, - 'aria-controls': `simple-tabpanel-${index}`, - }; -}; - -const FriendsTablist: React.FC<{ user: User; fetchUserInfo: (userID: string) => void }> = ({ user, fetchUserInfo }) => { - const [value, setValue] = React.useState(0); - - const handleChange = (event: React.SyntheticEvent, newValue: number) => { - setValue(newValue); - }; - - return ( - - - - - - Requests - - } - {...a11yProps(1)} - /> - - - - - - - - - - - - - - ); -}; - -export default FriendsTablist; diff --git a/client/src/components/sidebar/friends/RequestsTab.tsx b/client/src/components/sidebar/friends/RequestsTab.tsx deleted file mode 100644 index 5c84a5464..000000000 --- a/client/src/components/sidebar/friends/RequestsTab.tsx +++ /dev/null @@ -1,98 +0,0 @@ -import styled from '@emotion/styled'; -import { Check, Close } from '@mui/icons-material'; -import { IconButton, Tooltip } from '@mui/material'; -import React from 'react'; - -import { API_URL } from '../../../api/config'; -import NetworkError from '../../../interfaces/NetworkError'; -import { User } from './User'; -import UserProfile from './UserProfile'; - -const StyledFriendsListContainer = styled('div')` - display: flex; - flex-direction: column; - gap: 12px; -`; - -const StyledFriendContainer = styled('div')` - display: flex; - justify-content: space-between; -`; - -const StyledActionButtons = styled('div')` - display: flex; - gap: 12px; -`; - -const RequestsTab: React.FC<{ user: User; fetchUserInfo: (userID: string) => void }> = ({ user, fetchUserInfo }) => { - const handleDeclineRequest = async (incomingUserId: string) => { - try { - const res = await fetch(`${API_URL.server}/friend/request`, { - method: 'DELETE', - headers: { - Accept: 'application/json', - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - sendeeId: user.userID, - senderId: incomingUserId, - }), - credentials: 'include', - }); - if (res.status !== 200) throw new NetworkError("Couldn't get response"); - const declineRequestStatus = await res.json(); - console.log('decline request status', declineRequestStatus); - fetchUserInfo(user.userID); - } catch (error) { - throw new NetworkError(`Couldn't get response cause encountered error: ${error}`); - } - }; - - const handleAcceptRequest = async (incomingUserId: string) => { - try { - const res = await fetch(`${API_URL.server}/friend`, { - method: 'POST', - headers: { - Accept: 'application/json', - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - senderId: user.userID, - sendeeId: incomingUserId, - }), - credentials: 'include', - }); - if (res.status !== 201) throw new NetworkError("Couldn't get response"); - const acceptRequestStatus = await res.json(); - console.log('accept request status', acceptRequestStatus); - fetchUserInfo(user.userID); - } catch (error) { - throw new NetworkError(`Couldn't get response cause encountered error: ${error}`); - } - }; - - return ( - - {user.incoming.map((friend: User, i: number) => ( - - - - - handleAcceptRequest(friend.userID)}> - - - - - handleDeclineRequest(friend.userID)}> - - - - - - ))} - {user.incoming.length === 0 &&
    You have no friend requests.
    } -
    - ); -}; - -export default RequestsTab; diff --git a/client/src/components/sidebar/friends/UserProfile.tsx b/client/src/components/sidebar/friends/UserProfile.tsx index 6dc4f963f..9e44dbaa8 100644 --- a/client/src/components/sidebar/friends/UserProfile.tsx +++ b/client/src/components/sidebar/friends/UserProfile.tsx @@ -1,5 +1,7 @@ import styled from '@emotion/styled'; -import React from 'react'; +import React, { useContext } from 'react'; + +import { AppContext } from '../../../context/AppContext'; export const emptyProfile = 'https://cdn.pixabay.com/photo/2015/10/05/22/37/blank-profile-picture-973460_960_720.png'; @@ -7,25 +9,29 @@ const StyledContainer = styled('div')` display: flex; gap: 14px; align-items: center; + user-select: none; `; const StyledFullname = styled('div')` word-break: break-all; + font-size: 0.9rem; `; +const getFullName = (firstName: string, lastName: string) => { + let fullname = firstName + ' ' + lastName; + if (fullname.length >= 32) { + fullname = fullname.slice(0, 32); + return fullname + '...'; + } + return fullname; +}; + const UserProfile: React.FC<{ firstName: string; lastName: string; profileURL?: string }> = ({ firstName, lastName, profileURL, }) => { - const getFullName = () => { - let fullname = firstName + ' ' + lastName; - if (fullname.length >= 32) { - fullname = fullname.slice(0, 32); - return fullname + '...'; - } - return fullname; - }; + const { sidebarCollapsed } = useContext(AppContext); return ( @@ -35,9 +41,11 @@ const UserProfile: React.FC<{ firstName: string; lastName: string; profileURL?: height={34} style={{ borderRadius: 999, backgroundColor: 'white' }} /> -
    - {getFullName()} -
    + {!sidebarCollapsed && ( +
    + {getFullName(firstName, lastName)} +
    + )}
    ); }; diff --git a/client/src/components/sidebar/friends/YourFriendsTab.tsx b/client/src/components/sidebar/friends/YourFriendsTab.tsx deleted file mode 100644 index 003f5b089..000000000 --- a/client/src/components/sidebar/friends/YourFriendsTab.tsx +++ /dev/null @@ -1,63 +0,0 @@ -import styled from '@emotion/styled'; -import DeleteOutlineIcon from '@mui/icons-material/DeleteOutline'; -import { IconButton, Tooltip } from '@mui/material'; -import React from 'react'; - -import { API_URL } from '../../../api/config'; -import NetworkError from '../../../interfaces/NetworkError'; -import { User } from './User'; -import UserProfile from './UserProfile'; - -const StyledContainer = styled('div')` - display: flex; - flex-direction: column; - gap: 12px; -`; - -const StyledItem = styled('div')` - display: flex; - justify-content: space-between; -`; - -const YourFriendsTab: React.FC<{ user: User; fetchUserInfo: (userID: string) => void }> = ({ user, fetchUserInfo }) => { - const handleRemoveFriend = async (friendID: string) => { - try { - const res = await fetch(`${API_URL.server}/friend`, { - method: 'DELETE', - headers: { - Accept: 'application/json', - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - senderId: user.userID, - sendeeId: friendID, - }), - credentials: 'include', - }); - if (res.status !== 200) throw new NetworkError("Couldn't get response"); - const acceptRequestStatus = await res.json(); - console.log('unfriend status', acceptRequestStatus); - fetchUserInfo(user.userID); - } catch (error) { - throw new NetworkError(`Couldn't get response cause encountered error: ${error}`); - } - }; - - return ( - - {user.friends.map((friend: User, i: number) => ( - - - - handleRemoveFriend(friend.userID)}> - - - - - ))} - {user.friends.length === 0 &&
    You currently have no friends.
    } -
    - ); -}; - -export default YourFriendsTab; diff --git a/client/src/components/sidebar/friends/friends.json b/client/src/components/sidebar/friends/friends.json new file mode 100644 index 000000000..bcd1c99a5 --- /dev/null +++ b/client/src/components/sidebar/friends/friends.json @@ -0,0 +1,12 @@ +[ + "Lucas Harvey", + "Mark Tran", + "Ben Quin", + "Jason Poon", + "Fritz Rehde", + "Sunny Chen", + "Ana Kiperas", + "Tet Nay Lin", + "Kai Fox", + "Meredith Zhang" +] diff --git a/client/src/context/AppContext.tsx b/client/src/context/AppContext.tsx index a5830bade..876ee9da6 100644 --- a/client/src/context/AppContext.tsx +++ b/client/src/context/AppContext.tsx @@ -5,6 +5,7 @@ import { CoursesList } from '../interfaces/Courses'; import { CourseDataMap, DisplayTimetablesMap, Term, TermDataList } from '../interfaces/Periods'; import { AppContextProviderProps } from '../interfaces/PropTypes'; import storage from '../utils/storage'; +import { useMediaQuery, useTheme } from '@mui/material'; export interface IAppContext { alertMsg: string; @@ -66,6 +67,9 @@ export interface IAppContext { courseData: CourseDataMap; setCourseData: (newCourseData: CourseDataMap) => void; + + sidebarCollapsed: boolean; + setSidebarCollapsed: (isCollapsed: boolean) => void; } export const AppContext = createContext({ @@ -125,6 +129,9 @@ export const AppContext = createContext({ courseData: { map: [] }, setCourseData: () => {}, + + sidebarCollapsed: false, + setSidebarCollapsed: () => {}, }); const AppContextProvider = ({ children }: AppContextProviderProps) => { @@ -163,6 +170,10 @@ const AppContextProvider = ({ children }: AppContextProviderProps) => { const [displayTimetables, setDisplayTimetables] = useState({}); const [courseData, setCourseData] = useState({ map: [] }); + const theme = useTheme(); + const isWide = useMediaQuery(theme.breakpoints.only('xl')); + const [sidebarCollapsed, setSidebarCollapsed] = useState(() => !isWide); + const initialContext: IAppContext = { alertMsg, setAlertMsg, @@ -202,6 +213,8 @@ const AppContextProvider = ({ children }: AppContextProviderProps) => { setDisplayTimetables, courseData, setCourseData, + sidebarCollapsed, + setSidebarCollapsed, }; return {children}; diff --git a/client/src/interfaces/PropTypes.ts b/client/src/interfaces/PropTypes.ts index d5820f25f..363fbd8f5 100644 --- a/client/src/interfaces/PropTypes.ts +++ b/client/src/interfaces/PropTypes.ts @@ -16,21 +16,6 @@ export interface UserContextProviderProps { children: ReactNode; } -export interface DarkModeButtonProps { - collapsed: boolean; -} - -export interface CustomModalProps { - title: string; - toolTipTitle: string; - showIcon: ReactNode; - description: string; - content: ReactNode; - collapsed: boolean; - isClickable: boolean; - isSelected?: boolean; -} - export interface CourseSelectProps { assignedColors: Record; handleSelect(data: string | string[], a?: boolean, callback?: (_selectedCourses: CourseData[]) => void): void; From 94b7bbd4fc81b7407997a20655e4189f06209f05 Mon Sep 17 00:00:00 2001 From: Mark Tran <29350857+mark-trann@users.noreply.github.com> Date: Wed, 17 Sep 2025 19:33:03 +1000 Subject: [PATCH 25/33] Implement fuzzy search for friend list (#1072) Co-authored-by: Mark Tran <29350857+marktran2@users.noreply.github.com> --- .../components/sidebar/friends/FriendsList.tsx | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/client/src/components/sidebar/friends/FriendsList.tsx b/client/src/components/sidebar/friends/FriendsList.tsx index 210dfb560..e495362a9 100644 --- a/client/src/components/sidebar/friends/FriendsList.tsx +++ b/client/src/components/sidebar/friends/FriendsList.tsx @@ -2,6 +2,7 @@ import { Search } from '@mui/icons-material'; import SearchIcon from '@mui/icons-material/Search'; import { FormControl, IconButton, InputAdornment, InputLabel, OutlinedInput } from '@mui/material'; import { Box, styled } from '@mui/system'; +import Fuse from 'fuse.js'; import { useContext, useMemo, useState } from 'react'; import { AppContext } from '../../../context/AppContext'; @@ -26,17 +27,21 @@ const FriendsList = () => { const [searchVal, setSearchVal] = useState(''); const { sidebarCollapsed, setSidebarCollapsed } = useContext(AppContext); - // TODO: implement fuzzy search const renderedFriends = useMemo(() => { // TODO: replace hard coded data with integration with server - const filteredFriends = friendList.filter((friend) => friend.toLowerCase().includes(searchVal)); - return filteredFriends.map((friend, index) => ); + let friends = friendList; + if (searchVal.length === 0) { + return friends.map((friend, index) => ); + } + + const fuzzy = new Fuse(friendList, { threshold: 0.4 }); + friends = fuzzy.search(searchVal).map((result) => result.item); + return friends.map((friend, index) => ); }, [searchVal]); const handleClickSearchBarIcon = () => { if (sidebarCollapsed) { setSidebarCollapsed(false); - // TODO: put form search in focus } }; @@ -57,7 +62,7 @@ const FriendsList = () => { } label="Search" onChange={(e) => { - setSearchVal(e.target.value.toLowerCase()); + setSearchVal(e.target.value.trim().toLowerCase()); }} inputRef={(input: HTMLInputElement | null) => { input?.focus(); From 1a72f8b94c6c2f3017c8f8bae2d5465d88e20ab9 Mon Sep 17 00:00:00 2001 From: Mark Tran <29350857+mark-trann@users.noreply.github.com> Date: Tue, 23 Sep 2025 13:34:45 +1000 Subject: [PATCH 26/33] Add friends (#1073) * Refactor custom modal to have modal reusable * Add friends modal menu * Add invite code, send request and copy link section of menu * Implement hard-coded copies and alerts * Make borders thinner * Fix snackbar to be closer to add friend menu * Clean up css * Revert back to prev Paper component since it's not happy with div elements for form submissions * Fix variable naming for SettingText --------- Co-authored-by: Mark Tran <29350857+marktran2@users.noreply.github.com> --- .../components/sidebar/AddFriendsButton.tsx | 58 ++++++ .../src/components/sidebar/AddFriendsMenu.tsx | 197 ++++++++++++++++++ ...{CustomModal.tsx => CustomModalOpener.tsx} | 47 +---- client/src/components/sidebar/CustomModel.tsx | 53 +++++ client/src/components/sidebar/Settings.tsx | 20 +- client/src/components/sidebar/Sidebar.tsx | 36 +--- 6 files changed, 332 insertions(+), 79 deletions(-) create mode 100644 client/src/components/sidebar/AddFriendsButton.tsx create mode 100644 client/src/components/sidebar/AddFriendsMenu.tsx rename client/src/components/sidebar/{CustomModal.tsx => CustomModalOpener.tsx} (52%) create mode 100644 client/src/components/sidebar/CustomModel.tsx diff --git a/client/src/components/sidebar/AddFriendsButton.tsx b/client/src/components/sidebar/AddFriendsButton.tsx new file mode 100644 index 000000000..bd47696ee --- /dev/null +++ b/client/src/components/sidebar/AddFriendsButton.tsx @@ -0,0 +1,58 @@ +import { AddCircle } from '@mui/icons-material'; +import { IconButton, Tooltip, Typography } from '@mui/material'; +import { styled } from '@mui/system'; +import { useContext, useState } from 'react'; + +import { AppContext } from '../../context/AppContext'; +import AddFriendsMenu from './AddFriendsMenu'; +import CustomModal from './CustomModel'; + +const StyledAddButton = styled(IconButton)` + display: flex; + flex-direction: row; + gap: 16px; + border-radius: 8px; + justify-content: space-around; + padding: 8px; + color: ${({ theme }) => theme.palette.text.primary}; + border: 1px solid; + border-color: ${({ theme }) => theme.palette.primary.main}; +`; + +const StyledAddIcon = styled(AddCircle)` + color: ${({ theme }) => theme.palette.primary.main}; +`; + +interface AddFriendsButtonProps { + friendsListOpen: boolean; +} + +const AddFriendsButton = ({ friendsListOpen }: AddFriendsButtonProps) => { + const { sidebarCollapsed } = useContext(AppContext); + const [modalOpen, setModalOpen] = useState(false); + + if (!friendsListOpen) return null; + + const toggleModal = () => { + setModalOpen((prev) => !prev); + }; + + return ( + <> + + {!sidebarCollapsed && Add Friends} + + + + + } + isOpen={modalOpen} + toggleIsOpen={toggleModal} + /> + + ); +}; + +export default AddFriendsButton; diff --git a/client/src/components/sidebar/AddFriendsMenu.tsx b/client/src/components/sidebar/AddFriendsMenu.tsx new file mode 100644 index 000000000..ad145b296 --- /dev/null +++ b/client/src/components/sidebar/AddFriendsMenu.tsx @@ -0,0 +1,197 @@ +import { ArrowRight, Cached, ContentCopy } from '@mui/icons-material'; +import { Button, ButtonGroup, CircularProgress, Grid, InputBase, Paper, Snackbar, styled } from '@mui/material'; +import { useMemo, useState } from 'react'; + +import { SettingButton, SettingsItem, SettingsText } from './Settings'; + +const AddFriendText = styled(SettingsText)` + font-weight: 500; +`; +const MenuSubContainer = styled('div')` + display: flex; + flex-direction: column; + width: 100%; +`; + +const InviteCodeButtonGroup = styled(ButtonGroup)` + height: 100%; +`; + +const InviteCodeButton = styled(Button)` + font-size: 1.75rem; + color: ${({ theme }) => theme.palette.text.primary}; + font-weight: bold; + letter-spacing: 0.3rem; + padding: 5px 20px; + border: 0.75px solid; +`; + +const StyledCopyIcon = styled(ContentCopy)` + color: ${({ theme }) => theme.palette.primary.main}; +`; + +const StyledRefreshIcon = styled(Cached)` + color: ${({ theme }) => theme.palette.primary.main}; +`; + +const SendRequestButton = styled(Button)` + text-transform: none; + font-size: 0.75rem; +`; + +const CopyLinkButton = styled(Button)` + text-transform: none; + font-size: 0.75rem; + margin-top: 10px; +`; + +enum State { + Ready, + Success, + Error, +} + +// TODO: replace hard code with server implementation +const code = 'MQ7T2'; +const link = 'http://notangles.devsoc.app/invite?code=MQ7T2'; + +const AddFriendsMenu = () => { + const [codeCopyState, setCodeCopyState] = useState(State.Ready); + const [linkCopyState, setLinkCopyState] = useState(State.Ready); + const [hasSentRequest, setHasSentRequest] = useState(false); + const [isCodeRefreshing, setIsCodeRefreshing] = useState(false); + + const handleCodeCopy = (isCopyingCode: boolean) => { + navigator.clipboard + .writeText(isCopyingCode ? code : link) + .then(() => { + if (isCopyingCode) { + setCodeCopyState(State.Success); + } else { + setLinkCopyState(State.Success); + } + }) + .catch(() => { + if (isCopyingCode) { + setCodeCopyState(State.Error); + } else { + setLinkCopyState(State.Error); + } + }); + }; + + const handleSendRequest = (e: React.FormEvent) => { + e.preventDefault(); + setHasSentRequest(true); + }; + + const snackbarMessage = useMemo(() => { + if (codeCopyState !== State.Ready) { + return codeCopyState === State.Success ? 'Code copied!' : 'Failed to copy code. Please try again.'; + } else if (linkCopyState !== State.Ready) { + return linkCopyState === State.Success ? 'Link copied!' : 'Failed to copy link. Please try again.'; + } else if (hasSentRequest) { + return 'Request has been sent!'; + } else { + return ''; + } + }, [codeCopyState, linkCopyState, hasSentRequest]); + + return ( + <> + + Friend Requests + + + + + Your invite code: + + + + { + handleCodeCopy(true); + }} + > + {code} + + + + + + + + + { + // TODO: actually have it refresh + setIsCodeRefreshing((prev) => !prev); + }} + > + + {isCodeRefreshing ? : } + + + + + + + + + + + Enter friend code: + + + + Send Friend Request + + + + + + + { + handleCodeCopy(false); + }} + > + Copy Invite Link + + + { + setCodeCopyState(State.Ready); + setLinkCopyState(State.Ready); + setHasSentRequest(false); + }} + message={snackbarMessage} + /> + + ); +}; + +export default AddFriendsMenu; diff --git a/client/src/components/sidebar/CustomModal.tsx b/client/src/components/sidebar/CustomModalOpener.tsx similarity index 52% rename from client/src/components/sidebar/CustomModal.tsx rename to client/src/components/sidebar/CustomModalOpener.tsx index 5f70f5fd1..b0601d4d0 100644 --- a/client/src/components/sidebar/CustomModal.tsx +++ b/client/src/components/sidebar/CustomModalOpener.tsx @@ -1,11 +1,11 @@ -import { Close } from '@mui/icons-material'; -import { Dialog, DialogContent, DialogTitle, Divider, IconButton, Tooltip, Typography } from '@mui/material'; +import { IconButton, Tooltip, Typography } from '@mui/material'; import { styled } from '@mui/material/styles'; import { ReactNode, useContext, useState } from 'react'; import { AppContext } from '../../context/AppContext'; +import CustomModal from './CustomModel'; -interface CustomModalProps { +interface CustomModalOpenerProps { title: string; toolTipTitle: string; showIcon: ReactNode; @@ -15,18 +15,6 @@ interface CustomModalProps { isSelected?: boolean; } -const StyledDialogTitle = styled(DialogTitle)` - background-color: ${({ theme }) => theme.palette.background.paper}; - margin: 0; - padding: 20px; -`; - -const CloseButton = styled(IconButton)` - position: absolute; - right: 10px; - top: 10px; -`; - const ShowModalButton = styled(IconButton, { shouldForwardProp: (prop) => prop !== 'isSelected' })<{ isSelected: boolean; }>` @@ -39,17 +27,12 @@ const ShowModalButton = styled(IconButton, { shouldForwardProp: (prop) => prop ! background-color: ${({ isSelected }) => (isSelected ? 'rgb(157, 157, 157, 0.15)' : 'transparent')}; `; -const StyledDialogContent = styled(DialogContent)` - background-color: ${({ theme }) => theme.palette.background.paper}; - padding: 20px; -`; - const IndividualComponentTypography = styled(Typography)` margin: 0px; fontsize: 16px; `; -const CustomModal: React.FC = ({ +const CustomModalOpener: React.FC = ({ title, toolTipTitle, showIcon, @@ -75,27 +58,9 @@ const CustomModal: React.FC = ({ {sidebarCollapsed ? '' : title} - - - - {description} - - - - - - - {content} - + ); }; -export default CustomModal; +export default CustomModalOpener; diff --git a/client/src/components/sidebar/CustomModel.tsx b/client/src/components/sidebar/CustomModel.tsx new file mode 100644 index 000000000..e58ef95b0 --- /dev/null +++ b/client/src/components/sidebar/CustomModel.tsx @@ -0,0 +1,53 @@ +import { Close } from '@mui/icons-material'; +import { Dialog, DialogContent, DialogTitle, Divider, IconButton, styled, Typography } from '@mui/material'; +import { ReactNode } from 'react'; + +const StyledDialogContent = styled(DialogContent)` + background-color: ${({ theme }) => theme.palette.background.paper}; + padding: 20px; +`; + +const StyledDialogTitle = styled(DialogTitle)` + background-color: ${({ theme }) => theme.palette.background.paper}; + margin: 0; + padding: 20px; +`; + +const CloseButton = styled(IconButton)` + position: absolute; + right: 10px; + top: 10px; +`; + +interface CustomModalProps { + description: string; + content: ReactNode; + toggleIsOpen: () => void; + isOpen: boolean; +} + +const CustomModal = ({ description, content, toggleIsOpen, isOpen }: CustomModalProps) => { + return ( + + + + {description} + + + + + + + {content} + + ); +}; + +export default CustomModal; diff --git a/client/src/components/sidebar/Settings.tsx b/client/src/components/sidebar/Settings.tsx index c6dabf74a..f736da4be 100644 --- a/client/src/components/sidebar/Settings.tsx +++ b/client/src/components/sidebar/Settings.tsx @@ -9,22 +9,24 @@ import { UserSettings } from '../../interfaces/User'; import { ColorThemeOptions } from './ColorThemeOptions'; import { ColorThemePreview } from './ColorThemePreview'; -const SettingsItem = styled('div')` +const SettingsPadding = styled('div')` + padding: 1vh 20px; +`; + +export const SettingsItem = styled(SettingsPadding)` display: flex; justify-content: space-between; align-items: center; - padding: 1vh 20px; `; -const SettingText = styled('div')` +export const SettingsText = styled('div')` padding: 1vh 0; `; -const SettingButton = styled('div')` +export const SettingButton = styled(SettingsPadding)` display: flex; justify-content: space-between; align-items: center; - padding: 1vh 20px; border-radius: 1rem; cursor: pointer; &:hover { @@ -77,10 +79,10 @@ const Settings: FC = () => { setIsPreferredThemeOpen(!isPreferredThemeOpen); }} > - + Return - + @@ -90,7 +92,7 @@ const Settings: FC = () => { {!isPreferredThemeOpen && settingsToggles.map((setting) => ( - {setting.desc} + {setting.desc} { setIsPreferredThemeOpen(!isPreferredThemeOpen); }} > - Preferred Theme + Preferred Theme )} diff --git a/client/src/components/sidebar/Sidebar.tsx b/client/src/components/sidebar/Sidebar.tsx index 04f2c2864..d3dd5b738 100644 --- a/client/src/components/sidebar/Sidebar.tsx +++ b/client/src/components/sidebar/Sidebar.tsx @@ -1,5 +1,5 @@ -import { AddCircle, CalendarMonth, Description, Info, Security, Settings as SettingsIcon } from '@mui/icons-material'; -import { Divider, Drawer, IconButton, Tooltip, Typography, useMediaQuery, useTheme } from '@mui/material'; +import { CalendarMonth, Description, Info, Security, Settings as SettingsIcon } from '@mui/icons-material'; +import { Divider, Drawer, Typography, useMediaQuery, useTheme } from '@mui/material'; import { styled } from '@mui/material/styles'; import { useContext, useMemo, useState } from 'react'; @@ -8,9 +8,10 @@ import notanglesLogo from '../../assets/notangles_1.png'; import { leftContentPadding } from '../../constants/theme'; import { AppContext } from '../../context/AppContext'; import About from './About'; +import AddFriendsButton from './AddFriendsButton'; import Changelog from './Changelog'; import CollapseButton from './CollapseButton'; -import CustomModal from './CustomModal'; +import CustomModalOpener from './CustomModalOpener'; import DarkModeButton from './DarkModeButton'; import FriendsList from './friends/FriendsList'; import FriendsButton from './FriendsButton'; @@ -117,22 +118,6 @@ const SidebarFooterWrapper = styled('div')` flex-direction: row; `; -const AddFriendsButton = styled(IconButton)` - display: flex; - flex-direction: row; - gap: 16px; - border-radius: 8px; - justify-content: space-around; - padding: 8px; - color: ${({ theme }) => theme.palette.text.primary}; - border: 1px solid; - border-color: ${({ theme }) => theme.palette.primary.main}; -`; - -const StyledAddIcon = styled(AddCircle)` - color: ${({ theme }) => theme.palette.primary.main}; -`; - const modalData = [ { title: 'About', @@ -187,7 +172,7 @@ const Sidebar = () => { const modalComponents = useMemo( () => modalData.map((modal, index) => ( - { - } @@ -266,14 +251,7 @@ const Sidebar = () => { - {friendsListOpen && ( - - {!sidebarCollapsed && Add Friends} - - - - - )} + {!isMobile && !sidebarCollapsed ? ( From 059fa0c9809c74e14c6f45241c136fccbbf83df1 Mon Sep 17 00:00:00 2001 From: Lucas Date: Wed, 24 Sep 2025 16:06:38 +1000 Subject: [PATCH 27/33] Rename server env vars --- server/.env.example | 16 ++++++++-------- server/prisma/schema.prisma | 2 +- server/src/auth/auth.controller.ts | 2 +- server/src/auth/oidc.strategy.ts | 10 +++++----- server/src/config.ts | 2 +- 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/server/.env.example b/server/.env.example index aee652d7c..e24591667 100644 --- a/server/.env.example +++ b/server/.env.example @@ -1,17 +1,17 @@ -NODE_ENV="dev" +NODE_ENV="development" PORT=3001 POSTGRES_USER="postgres" POSTGRES_DB="notangles-db" POSTGRES_PASSWORD="postgres" POSTGRES_PORT="5432" -DATABASE_URL="postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@localhost:${POSTGRES_PORT}/${POSTGRES_DB}?schema=public" +POSTGRES_URL="postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@localhost:${POSTGRES_PORT}/${POSTGRES_DB}?schema=public" SESSION_SECRET="i-love-notangles" -OAUTH2_CLIENT_PROVIDER_OIDC_ISSUER="https://id.example.com.au" -OAUTH2_CLIENT_REGISTRATION_LOGIN_CLIENT_ID="a-b-c-d-e-f-1234567890" -OAUTH2_CLIENT_REGISTRATION_LOGIN_CLIENT_SECRET="aaazzz123" -OAUTH2_CLIENT_REGISTRATION_LOGIN_SCOPE="openid" -OAUTH2_CLIENT_REGISTRATION_LOGIN_REDIRECT_URI="http://localhost:3001/api/auth/callback/devsoc" -OAUTH2_CLIENT_REGISTRATION_LOGIN_POST_LOGOUT_REDIRECT_URI="http://localhost:3001/api/auth/callback/devsoc" +ZID_CLIENT_PROVIDER_OIDC_ISSUER="https://id.example.com.au" +ZID_CLIENT_REGISTRATION_LOGIN_CLIENT_ID="a-b-c-d-e-f-1234567890" +ZID_CLIENT_REGISTRATION_LOGIN_CLIENT_SECRET="aaazzz123" +ZID_CLIENT_REGISTRATION_LOGIN_SCOPE="openid" +ZID_CLIENT_REGISTRATION_LOGIN_REDIRECT_URI="http://localhost:3001/api/auth/callback/devsoc" +ZID_CLIENT_REGISTRATION_LOGIN_POST_LOGOUT_REDIRECT_URI="http://localhost:3001/api/auth/callback/devsoc" GITHUB_CLIENT_ID="aaaZZZ123" GITHUB_CLIENT_SECRET="abcdef1234567890" GITHUB_REDIRECT_URI="http://localhost:3001/api/auth/callback/github" diff --git a/server/prisma/schema.prisma b/server/prisma/schema.prisma index 65ae11736..4fba3b329 100644 --- a/server/prisma/schema.prisma +++ b/server/prisma/schema.prisma @@ -5,7 +5,7 @@ generator client { datasource db { provider = "postgresql" - url = env("DATABASE_URL") + url = env("POSTGRES_URL") } enum AuthProvider { diff --git a/server/src/auth/auth.controller.ts b/server/src/auth/auth.controller.ts index 5ff252ba0..eb1e25d66 100644 --- a/server/src/auth/auth.controller.ts +++ b/server/src/auth/auth.controller.ts @@ -76,7 +76,7 @@ export class AuthController { private redirectAfterAuth(res: Response, home: boolean = true) { res.redirect( - (process.env.NODE_ENV === 'dev' ? `http://` : `https://`) + + (process.env.NODE_ENV === 'development' ? `http://` : `https://`) + `${process.env.CLIENT_HOST_NAME}:${process.env.CLIENT_HOST_PORT}${home ? '/home' : ''}`, ); } diff --git a/server/src/auth/oidc.strategy.ts b/server/src/auth/oidc.strategy.ts index 04731cdb1..5add31be2 100644 --- a/server/src/auth/oidc.strategy.ts +++ b/server/src/auth/oidc.strategy.ts @@ -20,10 +20,10 @@ const { Strategy } = export const getConfig = async (): Promise => { return await discovery( new URL( - `${process.env.OAUTH2_CLIENT_PROVIDER_OIDC_ISSUER}/.well-known/openid-configuration`, + `${process.env.ZID_CLIENT_PROVIDER_OIDC_ISSUER}/.well-known/openid-configuration`, ), - process.env.OAUTH2_CLIENT_REGISTRATION_LOGIN_CLIENT_ID!, - process.env.OAUTH2_CLIENT_REGISTRATION_LOGIN_CLIENT_SECRET, + process.env.ZID_CLIENT_REGISTRATION_LOGIN_CLIENT_ID!, + process.env.ZID_CLIENT_REGISTRATION_LOGIN_CLIENT_SECRET, ); }; @@ -35,8 +35,8 @@ export class OidcStrategy extends PassportStrategy(Strategy, 'oidc') { ) { super({ config, - scope: process.env.OAUTH2_CLIENT_REGISTRATION_LOGIN_SCOPE!, - callbackURL: process.env.OAUTH2_CLIENT_REGISTRATION_LOGIN_REDIRECT_URI!, + scope: process.env.ZID_CLIENT_REGISTRATION_LOGIN_SCOPE!, + callbackURL: process.env.ZID_CLIENT_REGISTRATION_LOGIN_REDIRECT_URI!, name: 'oidc', passReqToCallback: true, }); diff --git a/server/src/config.ts b/server/src/config.ts index b9331b630..e7de31401 100644 --- a/server/src/config.ts +++ b/server/src/config.ts @@ -1,4 +1,4 @@ export default () => ({ - env: process.env.NODE_ENV || 'dev', + env: process.env.NODE_ENV || 'development', port: parseInt(process.env.PORT ?? '3001', 10), }); From cbbc24347c6970d55011a00eef188f96c056efbb Mon Sep 17 00:00:00 2001 From: jason4193 <100593637+jason4193@users.noreply.github.com> Date: Fri, 10 Oct 2025 07:11:33 +1100 Subject: [PATCH 28/33] Fix Backend Timetable Routes based on IDs (#1079) * Fix the timetables routes to handle by Id & Set init timetable to primary * Use term _eq instead of _like for addCourse * Remove unwanted error log --- server/src/auth/auth.service.ts | 1 + server/src/timetable/timetable.controller.ts | 17 ++----- server/src/timetable/timetable.service.ts | 50 ++++++++------------ server/src/timetable/types.ts | 4 -- 4 files changed, 26 insertions(+), 46 deletions(-) diff --git a/server/src/auth/auth.service.ts b/server/src/auth/auth.service.ts index 01b800adf..9c6d9d696 100644 --- a/server/src/auth/auth.service.ts +++ b/server/src/auth/auth.service.ts @@ -128,6 +128,7 @@ export class AuthService { name: timetableName, year: year, term, + primary: true, }, }); } diff --git a/server/src/timetable/timetable.controller.ts b/server/src/timetable/timetable.controller.ts index 873bf8d15..ca84089b5 100644 --- a/server/src/timetable/timetable.controller.ts +++ b/server/src/timetable/timetable.controller.ts @@ -14,7 +14,6 @@ import { import { TimetableService } from './timetable.service'; import { AuthenticatedGuard } from 'src/auth/authenticated.guard'; import { AuthenticatedRequest } from 'src/auth/auth.controller'; -import { AddCourseDto } from './types'; @Controller('user/timetables') export class TimetableController { @@ -66,15 +65,8 @@ export class TimetableController { async deleteTimetable( @Req() req: AuthenticatedRequest, @Param('id') timetableId: string, - @Query('year') year: string, - @Query('term') term: string, ) { - await this.timetableService.deleteTimetable( - req.user.id, - timetableId, - Number(year), - term, - ); + await this.timetableService.deleteTimetable(req.user.id, timetableId); } @Patch(':id/rename') @@ -96,9 +88,8 @@ export class TimetableController { async makePrimary( @Req() req: AuthenticatedRequest, @Param('id') timetableId: string, - @Body() data: { year: number; term: string }, ) { - await this.timetableService.makePrimary(req.user.id, timetableId, data); + await this.timetableService.makePrimary(req.user.id, timetableId); } @Get('courses/:timetableId') @@ -116,13 +107,13 @@ export class TimetableController { @Req() req: AuthenticatedRequest, @Param('timetableId') timetableId: string, @Param('courseId') courseId: string, - @Body() addCourseDto: AddCourseDto, + @Body('colour') colour: string, ) { await this.timetableService.addCourse( req.user.id, timetableId, courseId, - addCourseDto, + colour, ); return HttpStatus.CREATED; } diff --git a/server/src/timetable/timetable.service.ts b/server/src/timetable/timetable.service.ts index b04b87b32..cee0e06f9 100644 --- a/server/src/timetable/timetable.service.ts +++ b/server/src/timetable/timetable.service.ts @@ -2,7 +2,7 @@ import { HttpException, HttpStatus, Injectable } from '@nestjs/common'; import { PrismaService } from 'src/prisma/prisma.service'; import { GraphqlService } from 'src/graphql/graphql.service'; import { validate } from 'src/utils/validate'; -import { AddCourseDto, CourseDetails, UserTimetable } from './types'; +import { CourseDetails, UserTimetable } from './types'; import type { ClassDetails } from 'src/graphql/types'; @Injectable() @@ -75,11 +75,16 @@ export class TimetableService { userId: string, timetableId: string, courseId: string, - addCourseDto: AddCourseDto, + colour: string, ): Promise { + const timetable = await this.prisma.timetable.findUniqueOrThrow({ + select: { term: true }, + where: { id: timetableId, userId }, + }); + const courseExistsOnGraphQL = await this.graphqlService.courseExists( courseId, - addCourseDto.term, + timetable.term, ); validate( courseExistsOnGraphQL, @@ -87,12 +92,6 @@ export class TimetableService { HttpStatus.NOT_FOUND, ); - const timetableExists = await this.isTimetableOwnedByUser( - userId, - timetableId, - ); - validate(timetableExists, 'Timetable does not exist', HttpStatus.NOT_FOUND); - const courseInTimetable = await this.isCourseInTimetable( timetableId, courseId, @@ -103,13 +102,13 @@ export class TimetableService { HttpStatus.CONFLICT, ); - const colourValid = this.isColourCodeValid(addCourseDto.colour); + const colourValid = this.isColourCodeValid(colour); validate(colourValid, 'Colour code is not valid', HttpStatus.BAD_REQUEST); await this.prisma.course.create({ data: { courseId, - colour: addCourseDto.colour, + colour: colour, selectedClasses: [], timetable: { connect: { id: timetableId } }, }, @@ -355,14 +354,14 @@ export class TimetableService { return timetable.id; } - async deleteTimetable( - userId: string, - timetableId: string, - year: number, - term: string, - ): Promise { + async deleteTimetable(userId: string, timetableId: string): Promise { + const timetable = await this.prisma.timetable.findUniqueOrThrow({ + select: { primary: true, year: true, term: true }, + where: { id: timetableId, userId }, + }); + const numTimetables = await this.prisma.timetable.count({ - where: { userId, year, term }, + where: { userId, year: timetable.year, term: timetable.term }, }); if (numTimetables <= 1) { @@ -372,10 +371,6 @@ export class TimetableService { ); } - const timetable = await this.prisma.timetable.findFirst({ - where: { id: timetableId, userId }, - }); - if (!timetable) { throw new HttpException( 'Timetable does not belong to this user.', @@ -404,12 +399,9 @@ export class TimetableService { }); } - async makePrimary( - userId: string, - timetableId: string, - data: { year: number; term: string }, - ): Promise { + async makePrimary(userId: string, timetableId: string): Promise { const timetable = await this.prisma.timetable.findFirst({ + select: { year: true, term: true }, where: { id: timetableId, userId }, }); @@ -425,8 +417,8 @@ export class TimetableService { where: { userId, primary: true, - year: data.year, - term: data.term, + year: timetable.year, + term: timetable.term, }, data: { primary: false }, }), diff --git a/server/src/timetable/types.ts b/server/src/timetable/types.ts index c790a14e8..de9934ac3 100644 --- a/server/src/timetable/types.ts +++ b/server/src/timetable/types.ts @@ -1,7 +1,3 @@ -export class AddCourseDto { - term: string; - colour: string; -} export class CourseDetails { id: string; selectedClasses: string[]; From b322c291072f13189627e2d1383b450f3b43832b Mon Sep 17 00:00:00 2001 From: anakk25 <106964374+anakk25@users.noreply.github.com> Date: Wed, 22 Oct 2025 11:26:09 +1100 Subject: [PATCH 29/33] 998 adding profile photos for logged in users (#1076) * Refactor settings panel to be flat menu * Add feature to change and remove profile photos (for logged in users) * Fix forward icon and remove duplicate arrow icons in photo upload modal * Add logic to hide profile pic menu option if user is guest * Clean up profile pic components --------- Co-authored-by: Mark Tran <29350857+marktran2@users.noreply.github.com> --- client/package.json | 1 + client/pnpm-lock.yaml | 12 + client/src/api/user/routes.ts | 4 + .../sidebar/ProfilePictureModal.tsx | 258 ++++++++++++++++++ client/src/components/sidebar/Settings.tsx | 109 +++++--- .../src/components/sidebar/canvasPreview.ts | 66 +++++ client/src/hooks/useDebounceEffect.ts | 13 + client/src/interfaces/User.ts | 1 + server/src/user/types.ts | 1 + server/src/user/user.service.ts | 1 + 10 files changed, 434 insertions(+), 32 deletions(-) create mode 100644 client/src/components/sidebar/ProfilePictureModal.tsx create mode 100644 client/src/components/sidebar/canvasPreview.ts create mode 100644 client/src/hooks/useDebounceEffect.ts diff --git a/client/package.json b/client/package.json index 5e56d9cb4..aba3939b0 100644 --- a/client/package.json +++ b/client/package.json @@ -47,6 +47,7 @@ "react": "19.1.1", "react-dom": "19.1.1", "react-router": "7.8.2", + "react-image-crop": "11.0.10", "react-transition-group": "4.4.5", "react-window": "1.8.11", "rxjs": "7.8.2", diff --git a/client/pnpm-lock.yaml b/client/pnpm-lock.yaml index db9efca5f..02285e0e9 100644 --- a/client/pnpm-lock.yaml +++ b/client/pnpm-lock.yaml @@ -98,6 +98,9 @@ importers: react-dom: specifier: 19.1.1 version: 19.1.1(react@19.1.1) + react-image-crop: + specifier: 11.0.10 + version: 11.0.10(react@19.1.1) react-router: specifier: 7.8.2 version: 7.8.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1) @@ -2922,6 +2925,11 @@ packages: peerDependencies: react: ^19.1.1 + react-image-crop@11.0.10: + resolution: {integrity: sha512-+5FfDXUgYLLqBh1Y/uQhIycpHCbXkI50a+nbfkB1C0xXXUTwkisHDo2QCB1SQJyHCqIuia4FeyReqXuMDKWQTQ==} + peerDependencies: + react: '>=16.13.1' + react-is@16.13.1: resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} @@ -6390,6 +6398,10 @@ snapshots: react: 19.1.1 scheduler: 0.26.0 + react-image-crop@11.0.10(react@19.1.1): + dependencies: + react: 19.1.1 + react-is@16.13.1: {} react-is@19.1.1: {} diff --git a/client/src/api/user/routes.ts b/client/src/api/user/routes.ts index b516a9bcb..116ea9a93 100644 --- a/client/src/api/user/routes.ts +++ b/client/src/api/user/routes.ts @@ -19,6 +19,10 @@ export const getUserSettings = async (): Promise => { return (await apiClient.get('/user/settings')).data; }; +export const postUserProfilePicture = async (imgSrc: string): Promise => { + await apiClient.post('/user/profile/picture', { url: imgSrc }); +}; + export const setUserSettings = async (settings: Partial): Promise => { await apiClient.post('/user/settings', settings); }; diff --git a/client/src/components/sidebar/ProfilePictureModal.tsx b/client/src/components/sidebar/ProfilePictureModal.tsx new file mode 100644 index 000000000..90fde6efa --- /dev/null +++ b/client/src/components/sidebar/ProfilePictureModal.tsx @@ -0,0 +1,258 @@ +import React, { useState, useRef, useEffect, useMemo } from 'react'; +import ReactCrop, { Crop, PixelCrop } from 'react-image-crop'; +import CloudUploadIcon from '@mui/icons-material/CloudUpload'; +import Snackbar from '@mui/material/Snackbar'; +import Alert from '@mui/material/Alert'; +import AlertTitle from '@mui/material/AlertTitle'; +import { canvasPreview, centerAspectCrop } from './canvasPreview'; +import { useDebounceEffect } from '../../hooks/useDebounceEffect'; +import { postUserProfilePicture } from '../../api/user/routes'; + +import 'react-image-crop/dist/ReactCrop.css'; +import { styled } from '@mui/material/styles'; +import Button from '@mui/material/Button'; +import DialogTitle from '@mui/material/DialogTitle'; +import Dialog from '@mui/material/Dialog'; +import DialogActions from '@mui/material/DialogActions'; +import { useAuth } from '../../hooks/useAuth'; +import { emptyProfile } from './friends/UserProfile'; + +const MAX_FILE_SIZE_BYTES = 2000000; + +const VisuallyHiddenInput = styled('input')({ + clip: 'rect(0 0 0 0)', + clipPath: 'inset(50%)', + height: 1, + overflow: 'hidden', + position: 'absolute', + bottom: 0, + left: 0, + whiteSpace: 'nowrap', + width: 1, +}); + +const StyledContainer = styled('div')({ + margin: '20px 0', + padding: '0 20px', +}); + +const StyledPromptText = styled('div')({ + fontWeight: 'bold', + marginBottom: '10px', +}); + +const fileButtonStyleProps = { + marginTop: '30px', + textTransform: 'none', + fontSize: '16px', +}; + +const removeButtonStyleProps = { + marginTop: '30px', + marginLeft: '10px', + textTransform: 'none', + fontSize: '16px', +}; + +const saveButtonStyleProps = { + marginTop: '10px', + textTransform: 'none', + fontSize: '16px', + width: '100%', +}; + +// Set width of the crop component (including all child components) to be 100% of the parent +// container (the modal). +// All child components have to be targeted to ensure they also take up 100% width. +const StyledReactCrop = styled(ReactCrop)` + width: 100%; + + & * { + width: 100%; + } +`; + +export default function ProfilePictureModal() { + const [currentImgSrc, setCurrentImgSrc] = useState(''); + const [newImgSrc, setNewImgSrc] = useState(''); + + const imgRef = useRef(null); + const [crop, setCrop] = useState(); + const [completedCrop, setCompletedCrop] = useState(); + const aspect = 1; + const blobUrlRef = useRef(''); + const previewCanvasRef = useRef(null); + + const [errorMsg, setErrorMsg] = useState(''); + + const [successAlertOpen, setSuccessAlertOpen] = useState(false); + const [isErrorAlertOpen, setIsErrorAlertOpen] = useState(false); + + const [isDialogOpen, setIsDialogOpen] = useState(false); + + const { user } = useAuth(); + + useEffect(() => { + setCurrentImgSrc(user?.profilePictureUrl || emptyProfile); + }, [user]); + + const CustomDialog = useMemo(() => ( + + Are you sure you want to reset your current avatar? + + + + + + ), [isDialogOpen]); + + function onSelectFile(e: React.ChangeEvent) { + if (e.target.files && e.target.files.length > 0) { + if (e.target.files[0].size > MAX_FILE_SIZE_BYTES) { + setIsErrorAlertOpen(true); + setErrorMsg('File size exceeds 2MB. Try uploading a smaller file.'); + return; + } + + setCrop(undefined); // Makes crop preview update between images. + const reader = new FileReader(); + reader.addEventListener('load', () => { + setNewImgSrc(reader.result?.toString() || ''); + }); + reader.addEventListener('error', () => { + setIsErrorAlertOpen(true); + setErrorMsg('Error reading file, please try again'); + setNewImgSrc(''); + return; + }); + + reader.readAsDataURL(e.target.files[0]); + } + } + + function onImageLoad(e: React.SyntheticEvent) { + const { width, height } = e.currentTarget; + setCrop(centerAspectCrop(width, height, aspect)); + } + + function getCroppedProfile() { + const canvas = document.querySelector('canvas'); + if (canvas) { + canvas.toBlob((blob) => { + if (blob) { + setCurrentImgSrc(URL.createObjectURL(blob)); + + // blob to base64 string + const reader = new FileReader(); + reader.readAsDataURL(blob); + reader.onloadend = function () { + if (reader.result) { + setCurrentImgSrc(reader.result.toString()); + } + }; + } + }); + } + } + + useDebounceEffect( + async () => { + if (completedCrop?.width && completedCrop?.height && imgRef.current && previewCanvasRef.current) { + canvasPreview(imgRef.current, previewCanvasRef.current, completedCrop); + } + }, + 100, + [completedCrop], + ); + + return ( + + {!newImgSrc && ( +
    + {/* User's current profile picture */} + +
    + )} + {!!newImgSrc && ( + <> + Crop your new profile picture: + setCrop(percentCrop)} + onComplete={(c) => setCompletedCrop(c)} + aspect={aspect} + minWidth={100} + minHeight={100} + circularCrop + > + + + + )} +
    + {completedCrop ? + + : + <> + + + + } +
    + + setSuccessAlertOpen(false)}> + setSuccessAlertOpen(false)} severity="success" variant="filled" sx={{ width: '100%' }}> + Success + Profile picture updated! + + + + setIsErrorAlertOpen(false)}> + setIsErrorAlertOpen(false)} severity="error" variant="filled" sx={{ width: '100%' }}> + Error + {errorMsg} + + + + {CustomDialog} + +
    + +
    +
    + ); +} diff --git a/client/src/components/sidebar/Settings.tsx b/client/src/components/sidebar/Settings.tsx index f736da4be..e62dfbf7b 100644 --- a/client/src/components/sidebar/Settings.tsx +++ b/client/src/components/sidebar/Settings.tsx @@ -1,4 +1,3 @@ -import ArrowBackIosIcon from '@mui/icons-material/ArrowBackIos'; import { Switch } from '@mui/material'; import { styled } from '@mui/material/styles'; import { FC, useMemo, useState } from 'react'; @@ -8,6 +7,9 @@ import { useGetUserSettingsQuery } from '../../api/user/queries'; import { UserSettings } from '../../interfaces/User'; import { ColorThemeOptions } from './ColorThemeOptions'; import { ColorThemePreview } from './ColorThemePreview'; +import { ArrowBackIos, ArrowForwardIosOutlined } from '@mui/icons-material'; +import ProfilePictureModal from './ProfilePictureModal'; +import { useAuth } from '../../hooks/useAuth'; const SettingsPadding = styled('div')` padding: 1vh 20px; @@ -21,6 +23,20 @@ export const SettingsItem = styled(SettingsPadding)` export const SettingsText = styled('div')` padding: 1vh 0; + display: flex; + align-items: center; +`; + +const ReturnText = styled(SettingsText)` + padding: 0; +`; + +const StyledArrowBackIosIcon = styled(ArrowBackIos)` + height: 16px; +`; + +const StyledArrowForwardIcon = styled(ArrowForwardIosOutlined)` + height: 16px; `; export const SettingButton = styled(SettingsPadding)` @@ -56,6 +72,7 @@ const Settings: FC = () => { const settings = useGetUserSettingsQuery(); const { preferredTheme } = settings; const updateUserSettings = useSetUserSettings(); + const { user } = useAuth(); const nonTogglableSet = new Set(['preferredTheme', 'isDarkMode']); @@ -68,53 +85,57 @@ const Settings: FC = () => { })); const [isPreferredThemeOpen, setIsPreferredThemeOpen] = useState(false); + const [isChangeProfilePicOpen, setIsChangeProfilePicOpen] = useState(false); const mainContent = useMemo( () => ( <> {isPreferredThemeOpen && ( - <> - { - setIsPreferredThemeOpen(!isPreferredThemeOpen); - }} - > - - - Return - - - - - - + + + )} + {isChangeProfilePicOpen && } {!isPreferredThemeOpen && + !isChangeProfilePicOpen && settingsToggles.map((setting) => ( - - {setting.desc} - { - updateUserSettings({ - [setting.id]: e.target.checked, - }); - }} - /> - +
    + + {setting.desc} + { + updateUserSettings({ + [setting.id]: e.target.checked, + }); + }} + /> + +
    ))} ), - [isPreferredThemeOpen, preferredTheme, settingsToggles, updateUserSettings], + [isPreferredThemeOpen, isChangeProfilePicOpen, settingsToggles], ); const flatMenuButtons = useMemo(() => { - const isHomepageOpen = !isPreferredThemeOpen; + const isHomepageOpen = !isPreferredThemeOpen && !isChangeProfilePicOpen; return ( <> + {/* Only show option to change profile pic when user is logged in */} + {isHomepageOpen && user?.id && !user.isGuest && ( + { + setIsChangeProfilePicOpen(!isChangeProfilePicOpen); + }} + > + Change Profile Picture + + + )} {isHomepageOpen && ( { @@ -125,9 +146,33 @@ const Settings: FC = () => { )} + {isPreferredThemeOpen && ( + { + setIsPreferredThemeOpen(!isPreferredThemeOpen); + }} + > + + + Return + + + )} + {isChangeProfilePicOpen && ( + { + setIsChangeProfilePicOpen(!isChangeProfilePicOpen); + }} + > + + + Return + + + )} ); - }, [isPreferredThemeOpen, preferredTheme]); + }, [isChangeProfilePicOpen, isPreferredThemeOpen, user]); return ( <> diff --git a/client/src/components/sidebar/canvasPreview.ts b/client/src/components/sidebar/canvasPreview.ts new file mode 100644 index 000000000..16a6685b4 --- /dev/null +++ b/client/src/components/sidebar/canvasPreview.ts @@ -0,0 +1,66 @@ +import { centerCrop, makeAspectCrop, PixelCrop } from 'react-image-crop'; + +const TO_RADIANS = Math.PI / 180; + +export function canvasPreview( + image: HTMLImageElement, + canvas: HTMLCanvasElement, + crop: PixelCrop, + scale = 1, + rotate = 0, +) { + const ctx = canvas.getContext('2d'); + + if (!ctx) { + throw new Error('No 2d context'); + } + + const scaleX = image.naturalWidth / image.width; + const scaleY = image.naturalHeight / image.height; + const pixelRatio = window.devicePixelRatio; + + canvas.width = Math.floor(crop.width * scaleX * pixelRatio); + canvas.height = Math.floor(crop.height * scaleY * pixelRatio); + + ctx.scale(pixelRatio, pixelRatio); + ctx.imageSmoothingQuality = 'high'; + + const cropX = crop.x * scaleX; + const cropY = crop.y * scaleY; + + const rotateRads = rotate * TO_RADIANS; + const centerX = image.naturalWidth / 2; + const centerY = image.naturalHeight / 2; + + ctx.save(); + + // 1) Move the crop origin to the canvas origin (0,0) + ctx.translate(-cropX, -cropY); + // 2) Move the origin to the center of the original position + ctx.translate(centerX, centerY); + // 3) Rotate around the origin + ctx.rotate(rotateRads); + // 4) Scale the image + ctx.scale(scale, scale); + // 5) Move the center of the image to the origin (0,0) + ctx.translate(-centerX, -centerY); + ctx.drawImage(image, 0, 0, image.naturalWidth, image.naturalHeight, 0, 0, image.naturalWidth, image.naturalHeight); + + ctx.restore(); +} + +export function centerAspectCrop(mediaWidth: number, mediaHeight: number, aspect: number) { + return centerCrop( + makeAspectCrop( + { + unit: '%', + width: 90, + }, + aspect, + mediaWidth, + mediaHeight, + ), + mediaWidth, + mediaHeight, + ); +} diff --git a/client/src/hooks/useDebounceEffect.ts b/client/src/hooks/useDebounceEffect.ts new file mode 100644 index 000000000..573be3623 --- /dev/null +++ b/client/src/hooks/useDebounceEffect.ts @@ -0,0 +1,13 @@ +import { DependencyList, useEffect } from 'react'; + +export function useDebounceEffect(fn: () => void, waitTime: number, deps?: DependencyList) { + useEffect(() => { + const t = setTimeout(() => { + fn(); + }, waitTime); + + return () => { + clearTimeout(t); + }; + }, deps); +} diff --git a/client/src/interfaces/User.ts b/client/src/interfaces/User.ts index 7aa85db25..c8e40bc13 100644 --- a/client/src/interfaces/User.ts +++ b/client/src/interfaces/User.ts @@ -3,6 +3,7 @@ export interface UserInfo { firstName: string; lastName: string; profilePictureUrl?: string; + isGuest: boolean; } export interface UserSettings { diff --git a/server/src/user/types.ts b/server/src/user/types.ts index 08515837a..323974dea 100644 --- a/server/src/user/types.ts +++ b/server/src/user/types.ts @@ -3,6 +3,7 @@ export class UserInfo { firstName: string; lastName: string; profilePictureUrl?: string; + isGuest: boolean; } export class UserSettings { diff --git a/server/src/user/user.service.ts b/server/src/user/user.service.ts index 2df6f138a..e8b92cc6d 100644 --- a/server/src/user/user.service.ts +++ b/server/src/user/user.service.ts @@ -26,6 +26,7 @@ export class UserService { firstName: data.firstName, lastName: data.lastName, profilePictureUrl: data.profilePictureUrl ?? undefined, + isGuest: data.isGuest, }; } From 7126e45959af61902f18bf36fe8071a7327e8543 Mon Sep 17 00:00:00 2001 From: fox-58 Date: Wed, 22 Oct 2025 12:05:21 +1100 Subject: [PATCH 30/33] Update backend routes for events (#1018) * Add orutes in controller for events * Resolved conflict * remove need to timetable id * Add get all events * Resolved conflict * Resolved conflict * Fix remove event function * Resolved conflict * Fix delete route and fix ids for events * Remove excess file * Resolved conflict * Fix linting * Basic changes made from review comments * Fix events info except for type parameters * Fix most comments * Change service to use prisma generated data * Fix linting * Fix minor issues with routes * Fix lint * remove console log * Fix env ecample * Fix lint * Fix lint * Add user validation to update event * Clean up Prima schema and migrations --- .../migration.sql | 10 ++ server/prisma/schema.prisma | 13 +- server/src/timetable/timetable.controller.ts | 89 +++++++++++ server/src/timetable/timetable.service.ts | 139 +++++++++++++++++- server/src/timetable/types.ts | 18 +++ 5 files changed, 263 insertions(+), 6 deletions(-) create mode 100644 server/prisma/migrations/20251021051144_add_event_details/migration.sql diff --git a/server/prisma/migrations/20251021051144_add_event_details/migration.sql b/server/prisma/migrations/20251021051144_add_event_details/migration.sql new file mode 100644 index 000000000..004256f37 --- /dev/null +++ b/server/prisma/migrations/20251021051144_add_event_details/migration.sql @@ -0,0 +1,10 @@ +/* + Warnings: + + - Added the required column `title` to the `event` table without a default value. This is not possible if the table is not empty. + +*/ +-- AlterTable +ALTER TABLE "event" ADD COLUMN "description" TEXT, +ADD COLUMN "location" TEXT, +ADD COLUMN "title" TEXT NOT NULL; diff --git a/server/prisma/schema.prisma b/server/prisma/schema.prisma index 4fba3b329..8688b9c59 100644 --- a/server/prisma/schema.prisma +++ b/server/prisma/schema.prisma @@ -107,11 +107,14 @@ model Event { timetable Timetable @relation(fields: [timetableId], references: [id], onDelete: Cascade) timetableId String - colour String - dayOfWeek Int - start Int - end Int - type EventType + title String + location String? + description String? + colour String + dayOfWeek Int + start Int + end Int + type EventType @@map("event") } diff --git a/server/src/timetable/timetable.controller.ts b/server/src/timetable/timetable.controller.ts index ca84089b5..30f15470f 100644 --- a/server/src/timetable/timetable.controller.ts +++ b/server/src/timetable/timetable.controller.ts @@ -3,6 +3,7 @@ import { Controller, Delete, Get, + HttpException, HttpStatus, Param, Patch, @@ -14,6 +15,7 @@ import { import { TimetableService } from './timetable.service'; import { AuthenticatedGuard } from 'src/auth/authenticated.guard'; import { AuthenticatedRequest } from 'src/auth/auth.controller'; +import { EventParametersDto } from './types'; @Controller('user/timetables') export class TimetableController { @@ -193,4 +195,91 @@ export class TimetableController { classId, ); } + + @Get('event/:eventId') + @UseGuards(AuthenticatedGuard) + async getEventById( + @Req() req: AuthenticatedRequest, + @Param('eventId') eventId: string, + ) { + try { + const eventDetails = await this.timetableService.getEvent( + req.user.id, + eventId, + ); + return eventDetails; + } catch (error) { + if (error instanceof HttpException) { + throw error; + } + throw new HttpException( + 'Failed to get event details', + HttpStatus.INTERNAL_SERVER_ERROR, + ); + } + } + + @Post('event/:timetableId') + @UseGuards(AuthenticatedGuard) + async addEvent( + @Req() req: AuthenticatedRequest, + @Param('timetableId') timetableId: string, + @Body() body: { event: EventParametersDto }, + ) { + try { + await this.timetableService.addEvent( + req.user.id, + body.event, + timetableId, + ); + } catch (error) { + if (error instanceof HttpException) { + throw error; + } + throw new HttpException( + 'Failed to add event', + HttpStatus.INTERNAL_SERVER_ERROR, + ); + } + return HttpStatus.CREATED; + } + + @Delete('event/:eventId') + @UseGuards(AuthenticatedGuard) + async deleteEvent( + @Req() req: AuthenticatedRequest, + @Param('eventId') eventId: string, + ) { + try { + await this.timetableService.removeEvent(req.user.id, eventId); + } catch (error) { + if (error instanceof HttpException) { + throw error; + } + throw new HttpException( + 'Failed to delete event', + HttpStatus.INTERNAL_SERVER_ERROR, + ); + } + } + + @Patch('event/:eventId') + @UseGuards(AuthenticatedGuard) + async updateEvent( + @Req() req: AuthenticatedRequest, + @Param('eventId') eventId: string, + @Body() body: EventParametersDto, + ) { + try { + await this.timetableService.updateEvent(req.user.id, eventId, body); + } catch (error) { + if (error instanceof HttpException) { + throw error; + } + throw new HttpException( + 'Failed to update event', + HttpStatus.INTERNAL_SERVER_ERROR, + ); + } + } } diff --git a/server/src/timetable/timetable.service.ts b/server/src/timetable/timetable.service.ts index cee0e06f9..5c1104f30 100644 --- a/server/src/timetable/timetable.service.ts +++ b/server/src/timetable/timetable.service.ts @@ -2,8 +2,11 @@ import { HttpException, HttpStatus, Injectable } from '@nestjs/common'; import { PrismaService } from 'src/prisma/prisma.service'; import { GraphqlService } from 'src/graphql/graphql.service'; import { validate } from 'src/utils/validate'; -import { CourseDetails, UserTimetable } from './types'; +import { CourseDetails, UserTimetable, EventParametersDto } from './types'; import type { ClassDetails } from 'src/graphql/types'; +import { EventType } from '../generated/prisma/enums'; +import { EventMinAggregateOutputType } from '../generated/prisma/models/Event'; +import type { Event } from 'src/generated/prisma/client'; @Injectable() export class TimetableService { @@ -428,4 +431,138 @@ export class TimetableService { }), ]); } + + async getEvent(userId: string, eventId: string): Promise { + try { + const event = await this.prisma.event.findUnique({ + select: { + id: true, + colour: true, + dayOfWeek: true, + start: true, + end: true, + type: true, + title: true, + description: true, + location: true, + timetable: { select: { userId: true, id: true } }, + }, + where: { id: eventId }, + }); + + if (!event || event.timetable.userId !== userId) { + throw new HttpException('Event not found', HttpStatus.NOT_FOUND); + } + + const eventData = { + id: event.id, + timetableId: event.timetable.id, + colour: event.colour, + dayOfWeek: event.dayOfWeek, + start: event.start, + end: event.end, + type: event.type, + title: event.title, + description: event.description ?? null, + location: event.location ?? null, + }; + + return eventData; + } catch { + throw new HttpException('Event not in timetable', HttpStatus.NOT_FOUND); + } + } + + async getAllEvent( + userId: string, + timetableId: string, + ): Promise { + const timetableExists = await this.isTimetableOwnedByUser( + userId, + timetableId, + ); + validate(timetableExists, 'Timetable does not exist', HttpStatus.NOT_FOUND); + + const events = (await this.prisma.event.findMany({ + where: { timetableId }, + })) as EventMinAggregateOutputType[]; + + return events; + } + + async addEvent( + userId: string, + eventDetails: EventParametersDto, + timetableId: string, + ): Promise { + const timetableExists = await this.isTimetableOwnedByUser( + userId, + timetableId, + ); + validate(timetableExists, 'Timetable does not exist', HttpStatus.NOT_FOUND); + + const colourValid = this.isColourCodeValid(eventDetails.colour); + validate(colourValid, 'Colour code is not valid', HttpStatus.BAD_REQUEST); + + if (!(eventDetails.type in EventType)) { + throw new HttpException('Invalid event type', HttpStatus.BAD_REQUEST); + } + + await this.prisma.event.create({ + data: { + title: eventDetails.title, + description: eventDetails.description ?? undefined, + location: eventDetails.location ?? undefined, + colour: eventDetails.colour, + dayOfWeek: eventDetails.dayOfWeek, + start: eventDetails.start, + end: eventDetails.end, + type: eventDetails.type, + timetable: { connect: { id: timetableId } }, + }, + }); + } + + async removeEvent(userId: string, eventId: string): Promise { + if (!(await this.isEventOwnedByUser(userId, eventId))) { + throw new HttpException('Event could not be found', HttpStatus.NOT_FOUND); + } + + await this.prisma.event.delete({ + where: { + id: eventId, + }, + }); + } + + async updateEvent( + userId: string, + eventId: string, + eventDetails: EventParametersDto, + ): Promise { + if (!(await this.isEventOwnedByUser(userId, eventId))) { + throw new HttpException('Event could not be found', HttpStatus.NOT_FOUND); + } + + const dtoKeys = Object.keys(new EventParametersDto()); + + const filteredData = Object.fromEntries( + Object.entries(eventDetails).filter( + ([key, value]) => value !== undefined && dtoKeys.includes(key), + ), + ); + + await this.prisma.event.update({ + where: { id: eventId }, + data: filteredData, + }); + } + + async isEventOwnedByUser(userId: string, eventId: string): Promise { + const hit = await this.prisma.event.findFirst({ + where: { id: eventId, timetable: { userId } }, + select: { id: true }, + }); + return !!hit; + } } diff --git a/server/src/timetable/types.ts b/server/src/timetable/types.ts index de9934ac3..b88c93dbb 100644 --- a/server/src/timetable/types.ts +++ b/server/src/timetable/types.ts @@ -1,3 +1,10 @@ +import { EventType } from '../generated/prisma/enums'; + +export class AddCourseDto { + term: string; + colour: string; +} + export class CourseDetails { id: string; selectedClasses: string[]; @@ -17,3 +24,14 @@ export enum Term { T2 = 'T2', T3 = 'T3', } + +export class EventParametersDto { + colour: string; + dayOfWeek: number; // 0 = Monday, 6 = Sunday + start: number; // Mins since midnight + end: number; // Mins since midnight + type: EventType; + title: string; + description?: string; + location?: string; +} From 9e11b169877726060b17773f13a9168618cacec8 Mon Sep 17 00:00:00 2001 From: Meredith Zhang <90161936+mere-z@users.noreply.github.com> Date: Wed, 29 Oct 2025 17:55:08 +1100 Subject: [PATCH 31/33] Fix sidebar name display (#1085) * Added username shortening functionality * Update client/src/components/sidebar/friends/UserProfile.tsx Fix formatting on getTextWidth function Co-authored-by: Mark Tran <29350857+mark-trann@users.noreply.github.com> * Remove canvas element from DOM after its used to check text width --------- Co-authored-by: Meredith Zhang Co-authored-by: Mark Tran <29350857+mark-trann@users.noreply.github.com> --- .../sidebar/friends/UserProfile.tsx | 32 ++++++++++++++++--- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/client/src/components/sidebar/friends/UserProfile.tsx b/client/src/components/sidebar/friends/UserProfile.tsx index 9e44dbaa8..dfac8be8c 100644 --- a/client/src/components/sidebar/friends/UserProfile.tsx +++ b/client/src/components/sidebar/friends/UserProfile.tsx @@ -13,16 +13,40 @@ const StyledContainer = styled('div')` `; const StyledFullname = styled('div')` - word-break: break-all; font-size: 0.9rem; + white-space: nowrap; `; +const getTextWidth = (text: string, font: string): number => { + let canvas = document.createElement('canvas'); + + const context = canvas.getContext('2d'); + if (!context) { + return 0; + } + + context.font = font; + const metrics = context.measureText(text); + canvas.remove(); + + return metrics.width; +}; + const getFullName = (firstName: string, lastName: string) => { + const font = '400 14.4px Roboto, Helvetica, Arial, sans-serif'; + const maxWidth = 100; + let fullname = firstName + ' ' + lastName; - if (fullname.length >= 32) { - fullname = fullname.slice(0, 32); - return fullname + '...'; + + if (getTextWidth(fullname, font) > maxWidth) { + fullname = firstName + ' ' + lastName[0] + '.'; + let i = 2; + while (getTextWidth(fullname, font) > maxWidth) { + fullname = firstName.slice(0, -i) + '. ' + lastName[0] + '.'; + i++; + } } + return fullname; }; From 6f9f21c397a9b39a9002dd7720b3ed684dc1da17 Mon Sep 17 00:00:00 2001 From: fox-58 Date: Wed, 29 Oct 2025 18:05:57 +1100 Subject: [PATCH 32/33] Clear timetable route (#1086) * Basic start code for clear timetable * Passing linting * Fix clear timetables * Fix linting * Fix userId * return new id and change names * Change variable to underscore --- server/src/timetable/timetable.controller.ts | 10 ++++++++ server/src/timetable/timetable.service.ts | 26 ++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/server/src/timetable/timetable.controller.ts b/server/src/timetable/timetable.controller.ts index 30f15470f..23ec9ecef 100644 --- a/server/src/timetable/timetable.controller.ts +++ b/server/src/timetable/timetable.controller.ts @@ -85,6 +85,16 @@ export class TimetableController { ); } + @Patch('clear') + @UseGuards(AuthenticatedGuard) + async clearTimetables( + @Req() req: AuthenticatedRequest, + @Query('year') year: number, + @Query('term') term: string, + ) { + await this.timetableService.clearTimetables(req.user.id, year, term); + } + @Patch(':id/change-primary') @UseGuards(AuthenticatedGuard) async makePrimary( diff --git a/server/src/timetable/timetable.service.ts b/server/src/timetable/timetable.service.ts index 5c1104f30..b673a5fc0 100644 --- a/server/src/timetable/timetable.service.ts +++ b/server/src/timetable/timetable.service.ts @@ -15,6 +15,8 @@ export class TimetableService { private readonly graphqlService: GraphqlService, ) {} + private readonly TIMETABLE_DEFAULT_NAME = 'My Timetable'; + async isTimetableOwnedByUser( userId: string, timetableId: string, @@ -402,6 +404,30 @@ export class TimetableService { }); } + async clearTimetables( + userId: string, + year: number, + term: string, + ): Promise { + const [_, newTimetable] = await this.prisma.$transaction([ + this.prisma.timetable.deleteMany({ + where: { userId: userId, year: Number(year), term: term }, + }), + this.prisma.timetable.create({ + data: { + userId: userId, + name: this.TIMETABLE_DEFAULT_NAME, + year: Number(year), + term: term, + primary: true, + }, + select: { id: true }, + }), + ]); + + return newTimetable.id; + } + async makePrimary(userId: string, timetableId: string): Promise { const timetable = await this.prisma.timetable.findFirst({ select: { year: true, term: true }, From 4aaa4cb75ef86c109dfd5feb63a52178876a57a8 Mon Sep 17 00:00:00 2001 From: TR-04 Date: Wed, 29 Oct 2025 18:14:54 +1100 Subject: [PATCH 33/33] 1065 friends invite notification (#1081) * make server listen on 0.0.0.0 to accept connections from any external devices * Added pending friend invites badge with hardcoded invite values. Changed friends icon to a group icon instead. * Reverted back to localhost binding * Swapped to use red theme colour instead * Added pr review fix --- .../components/sidebar/AddFriendsButton.tsx | 33 +++++++++++++++---- .../src/components/sidebar/AddFriendsMenu.tsx | 14 +++++++- .../src/components/sidebar/FriendsButton.tsx | 29 ++++++++++++++-- .../sidebar/PendingInvitesBadge.tsx | 27 +++++++++++++++ 4 files changed, 94 insertions(+), 9 deletions(-) create mode 100644 client/src/components/sidebar/PendingInvitesBadge.tsx diff --git a/client/src/components/sidebar/AddFriendsButton.tsx b/client/src/components/sidebar/AddFriendsButton.tsx index bd47696ee..324b88cc5 100644 --- a/client/src/components/sidebar/AddFriendsButton.tsx +++ b/client/src/components/sidebar/AddFriendsButton.tsx @@ -6,6 +6,17 @@ import { useContext, useState } from 'react'; import { AppContext } from '../../context/AppContext'; import AddFriendsMenu from './AddFriendsMenu'; import CustomModal from './CustomModel'; +import PendingInvitesBadge from './PendingInvitesBadge'; + +const BadgeWrapper = styled('div')` + position: relative; +`; + +const BadgePositioner = styled('div')` + position: absolute; + bottom: 29px; + right: 3px; +`; const StyledAddButton = styled(IconButton)` display: flex; @@ -17,12 +28,16 @@ const StyledAddButton = styled(IconButton)` color: ${({ theme }) => theme.palette.text.primary}; border: 1px solid; border-color: ${({ theme }) => theme.palette.primary.main}; + width: 100%; `; const StyledAddIcon = styled(AddCircle)` color: ${({ theme }) => theme.palette.primary.main}; `; +// Hardcoded values to be replaced +const friendInvites = 2; + interface AddFriendsButtonProps { friendsListOpen: boolean; } @@ -39,12 +54,18 @@ const AddFriendsButton = ({ friendsListOpen }: AddFriendsButtonProps) => { return ( <> - - {!sidebarCollapsed && Add Friends} - - - - + + + {!sidebarCollapsed && Add Friends} + + + + + + + + + } diff --git a/client/src/components/sidebar/AddFriendsMenu.tsx b/client/src/components/sidebar/AddFriendsMenu.tsx index ad145b296..1256140df 100644 --- a/client/src/components/sidebar/AddFriendsMenu.tsx +++ b/client/src/components/sidebar/AddFriendsMenu.tsx @@ -3,6 +3,13 @@ import { Button, ButtonGroup, CircularProgress, Grid, InputBase, Paper, Snackbar import { useMemo, useState } from 'react'; import { SettingButton, SettingsItem, SettingsText } from './Settings'; +import PendingInvitesBadge from './PendingInvitesBadge'; + +const RightContainer = styled('div')` + display: flex; + align-items: center; + gap: 10px; +`; const AddFriendText = styled(SettingsText)` font-weight: 500; @@ -54,6 +61,7 @@ enum State { // TODO: replace hard code with server implementation const code = 'MQ7T2'; const link = 'http://notangles.devsoc.app/invite?code=MQ7T2'; +const friendInvites = 2; const AddFriendsMenu = () => { const [codeCopyState, setCodeCopyState] = useState(State.Ready); @@ -101,7 +109,11 @@ const AddFriendsMenu = () => { <> Friend Requests - + + + + + diff --git a/client/src/components/sidebar/FriendsButton.tsx b/client/src/components/sidebar/FriendsButton.tsx index 6982ca640..6ad9357e5 100644 --- a/client/src/components/sidebar/FriendsButton.tsx +++ b/client/src/components/sidebar/FriendsButton.tsx @@ -1,10 +1,12 @@ import { ArrowDropDown, ArrowDropUp, Person } from '@mui/icons-material'; +import GroupIcon from '@mui/icons-material/Group'; import { IconButton, Tooltip, Typography } from '@mui/material'; import { styled } from '@mui/material/styles'; import { Box } from '@mui/system'; import { useContext, useMemo } from 'react'; import { AppContext } from '../../context/AppContext'; +import PendingInvitesBadge from './PendingInvitesBadge'; interface FriendsButtonProps { friendsListOpen: boolean; @@ -32,6 +34,22 @@ const IndividualComponentTypography = styled(Typography)` font-size: 16px; `; +const RightContainer = styled('div')` + display: flex; + align-items: center; + gap: 10px; + position: relative; +`; + +const BadgePositioner = styled('div', { shouldForwardProp: (prop) => prop !== 'sidebarCollapsed' })<{ + sidebarCollapsed: boolean; +}>` + display: ${({ sidebarCollapsed }) => (sidebarCollapsed ? '' : 'flex' )}; + position: ${({ sidebarCollapsed }) => (sidebarCollapsed ? 'absolute' : 'static' )}; + bottom: -2px; + right: 14px; +`; + // TODO: Repurpose using Sunny's design for friends const FriendsButton = ({ friendsListOpen, handleFriendsListToggle }: FriendsButtonProps) => { const { sidebarCollapsed } = useContext(AppContext); @@ -39,15 +57,22 @@ const FriendsButton = ({ friendsListOpen, handleFriendsListToggle }: FriendsButt if (sidebarCollapsed) return null; return friendsListOpen ? : ; }, [sidebarCollapsed, friendsListOpen]); + const friendInvites = 2; // Hardcoded return ( - + {sidebarCollapsed ? '' : 'Friends'} - {friendToggleArrow} + + + + + {friendToggleArrow} + + ); diff --git a/client/src/components/sidebar/PendingInvitesBadge.tsx b/client/src/components/sidebar/PendingInvitesBadge.tsx new file mode 100644 index 000000000..2d8b8aace --- /dev/null +++ b/client/src/components/sidebar/PendingInvitesBadge.tsx @@ -0,0 +1,27 @@ +import { Badge, styled } from "@mui/material"; + +const StyledBadge = styled(Badge)` + & .MuiBadge-badge { + background-color: ${({ theme }) => theme.palette.error.light}; + color: white; + font-weight: 700; + font-size: 10px; + height: 16px; + min-width: 16px; + padding: 0; + border-radius: 50%; + } +`; + +interface PendingInvitesBadgeProps { + count: number; + showBadge?: boolean; +} + +const PendingInvitesBadge = ({ count, showBadge = true }: PendingInvitesBadgeProps) => { + return 0 ? count : 0} />; +}; + +export default PendingInvitesBadge; + +